bool sockinfo::detach_receiver(flow_tuple_with_local_if &flow_key) { si_logdbg("Unregistering receiver: %s", flow_key.to_str()); // TODO ALEXR: DO we need to return a 3 tuple instead of a 5 tuple being removed? // if (peer_ip != INADDR_ANY && peer_port != INPORT_ANY); // Find ring associated with this tuple rx_flow_map_t::iterator rx_flow_iter = m_rx_flow_map.find(flow_key); BULLSEYE_EXCLUDE_BLOCK_START if (rx_flow_iter == m_rx_flow_map.end()) { si_logdbg("Failed to find ring associated with: %s", flow_key.to_str()); return false; } BULLSEYE_EXCLUDE_BLOCK_END ring* p_ring = rx_flow_iter->second; si_logdbg("Detaching %s from ring %p", flow_key.to_str(), p_ring); // Detach tuple unlock_rx_q(); p_ring->detach_flow(flow_key, this); lock_rx_q(); // Un-map flow from local map #ifndef DEFINED_SOCKETXTREME // is not defined rx_del_ring_cb(flow_key, p_ring); #endif // DEFINED_SOCKETXTREME m_rx_flow_map.erase(rx_flow_iter); return destroy_nd_resources((const ip_address)flow_key.get_local_if()); }
net_device_resources_t* sockinfo::create_nd_resources(const ip_address ip_local) { net_device_resources_t* p_nd_resources = NULL; // Check if we are already registered to net_device with the local ip as observers rx_net_device_map_t::iterator rx_nd_iter = m_rx_nd_map.find(ip_local.get_in_addr()); if (rx_nd_iter == m_rx_nd_map.end()) { // Need to register as observer to net_device net_device_resources_t nd_resources; nd_resources.refcnt = 0; nd_resources.p_nde = NULL; nd_resources.p_ndv = NULL; nd_resources.p_ring = NULL; BULLSEYE_EXCLUDE_BLOCK_START cache_entry_subject<ip_address, net_device_val*>* p_ces = NULL; if (!g_p_net_device_table_mgr->register_observer(ip_local, &m_rx_nd_observer, &p_ces)) { si_logdbg("Failed registering as observer for local ip %s", ip_local.to_str().c_str()); goto err; } nd_resources.p_nde = (net_device_entry*)p_ces; if (!nd_resources.p_nde) { si_logerr("Got NULL net_devide_entry for local ip %s", ip_local.to_str().c_str()); goto err; } if (!nd_resources.p_nde->get_val(nd_resources.p_ndv)) { si_logerr("Got net_device_val=NULL (interface is not offloaded) for local ip %s", ip_local.to_str().c_str()); goto err; } unlock_rx_q(); m_rx_ring_map_lock.lock(); resource_allocation_key *key; if (m_rx_ring_map.size() && m_ring_alloc_logic.is_logic_support_migration()) { key = m_ring_alloc_logic.get_key(); } else { key = m_ring_alloc_logic.create_new_key(ip_local.get_in_addr()); } nd_resources.p_ring = nd_resources.p_ndv->reserve_ring(key); m_rx_ring_map_lock.unlock(); lock_rx_q(); if (!nd_resources.p_ring) { si_logdbg("Failed to reserve ring for allocation key %s on ip %s", m_ring_alloc_logic.get_key()->to_str(), ip_local.to_str().c_str()); goto err; } // Add new net_device to rx_map m_rx_nd_map[ip_local.get_in_addr()] = nd_resources; rx_nd_iter = m_rx_nd_map.find(ip_local.get_in_addr()); if (rx_nd_iter == m_rx_nd_map.end()) { si_logerr("Failed to find rx_nd_iter"); goto err; } BULLSEYE_EXCLUDE_BLOCK_END }
bool sockinfo::attach_receiver(flow_tuple_with_local_if &flow_key) { // This function should be called from within mutex protected context of the sockinfo!!! si_logdbg("Attaching to %s", flow_key.to_str()); // Protect against local loopback used as local_if & peer_ip // rdma_cm will accept it but we don't want to offload it if (flow_key.is_local_loopback()) { si_logdbg("VMA does not offload local loopback IP address"); return false; } if (m_rx_flow_map.find(flow_key) != m_rx_flow_map.end()) { si_logdbg("already attached %s", flow_key.to_str()); return false; } // Allocate resources on specific interface (create ring) net_device_resources_t* p_nd_resources = create_nd_resources((const ip_address)flow_key.get_local_if()); if (NULL == p_nd_resources) { // any error which occurred inside create_nd_resources() was already printed. No need to reprint errors here return false; } // Map flow in local map m_rx_flow_map[flow_key] = p_nd_resources->p_ring; #ifndef DEFINED_SOCKETXTREME // is not defined // Save the new CQ from ring rx_add_ring_cb(flow_key, p_nd_resources->p_ring); #endif // DEFINED_SOCKETXTREME // Attach tuple BULLSEYE_EXCLUDE_BLOCK_START unlock_rx_q(); if (!p_nd_resources->p_ring->attach_flow(flow_key, this)) { lock_rx_q(); si_logdbg("Failed to attach %s to ring %p", flow_key.to_str(), p_nd_resources->p_ring); return false; } set_rx_packet_processor(); lock_rx_q(); BULLSEYE_EXCLUDE_BLOCK_END // Registered as receiver successfully si_logdbg("Attached %s to ring %p", flow_key.to_str(), p_nd_resources->p_ring); // Verify 5 tuple over 3 tuple if (flow_key.is_5_tuple()) { // Check and remove lesser 3 tuple flow_tuple_with_local_if flow_key_3t(flow_key.get_dst_ip(), flow_key.get_dst_port(), INADDR_ANY, INPORT_ANY, flow_key.get_protocol(), flow_key.get_local_if()); rx_flow_map_t::iterator rx_flow_iter = m_rx_flow_map.find(flow_key_3t); if (rx_flow_iter != m_rx_flow_map.end()) { si_logdbg("Removing (and detaching) 3 tuple now that we added a stronger 5 tuple"); detach_receiver(flow_key_3t); } } return true; }
bool sockinfo::attach_receiver(flow_tuple_with_local_if &flow_key) { // This function should be called from within mutex protected context of the sockinfo!!! si_logdbg("Attaching to %s", flow_key.to_str()); // Protect against local loopback used as local_if & peer_ip // rdma_cm will accept it but we don't want to offload it if (flow_key.is_local_loopback()) { si_logdbg("VMA does not offload local loopback IP address"); return false; } if (m_rx_flow_map.find(flow_key) != m_rx_flow_map.end()) { si_logdbg("already attached %s", flow_key.to_str()); return false; } net_device_resources_t* p_nd_resources = NULL; // Check if we are already registered to net_device with the local ip as observers ip_address ip_local(flow_key.get_local_if()); rx_net_device_map_t::iterator rx_nd_iter = m_rx_nd_map.find(ip_local.get_in_addr()); if (rx_nd_iter == m_rx_nd_map.end()) { // Need to register as observer to net_device net_device_resources_t nd_resources; nd_resources.refcnt = 0; nd_resources.p_nde = NULL; nd_resources.p_ndv = NULL; nd_resources.p_ring = NULL; BULLSEYE_EXCLUDE_BLOCK_START cache_entry_subject<ip_address, net_device_val*>* p_ces = NULL; if (!g_p_net_device_table_mgr->register_observer(ip_local, &m_rx_nd_observer, &p_ces)) { si_logdbg("Failed registering as observer for local ip %s", ip_local.to_str().c_str()); return false; } nd_resources.p_nde = (net_device_entry*)p_ces; if (!nd_resources.p_nde) { si_logerr("Got NULL net_devide_entry for local ip %s", ip_local.to_str().c_str()); return false; } if (!nd_resources.p_nde->get_val(nd_resources.p_ndv)) { si_logerr("Got net_device_val=NULL (interface is not offloaded) for local ip %s", ip_local.to_str().c_str()); return false; } unlock_rx_q(); m_rx_ring_map_lock.lock(); resource_allocation_key key = 0; if (m_rx_ring_map.size()) { key = m_ring_alloc_logic.get_key(); } else { key = m_ring_alloc_logic.create_new_key(); } nd_resources.p_ring = nd_resources.p_ndv->reserve_ring(key); m_rx_ring_map_lock.unlock(); lock_rx_q(); if (!nd_resources.p_ring) { si_logdbg("Failed to reserve ring for allocation key %d on lip %s", m_ring_alloc_logic.get_key(), ip_local.to_str().c_str()); return false; } // Add new net_device to rx_map m_rx_nd_map[ip_local.get_in_addr()] = nd_resources; rx_nd_iter = m_rx_nd_map.find(ip_local.get_in_addr()); if (rx_nd_iter == m_rx_nd_map.end()) { si_logerr("Failed to find rx_nd_iter"); return false; } BULLSEYE_EXCLUDE_BLOCK_END }