bool dst_entry::resolve_neigh() { dst_logdbg(""); bool ret_val = false; ip_address dst_addr = m_dst_ip; if (m_p_rt_val && m_p_rt_val->get_gw_addr() != INADDR_ANY && !dst_addr.is_mc()) { dst_addr = m_p_rt_val->get_gw_addr(); } cache_entry_subject<neigh_key, neigh_val*>* p_ces = NULL; if (m_p_neigh_entry || g_p_neigh_table_mgr->register_observer(neigh_key(dst_addr, m_p_net_dev_val), this, &p_ces)) { if(m_p_neigh_entry == NULL) m_p_neigh_entry = dynamic_cast<neigh_entry*>(p_ces); if (m_p_neigh_entry) { if (m_p_neigh_entry->get_peer_info(m_p_neigh_val)) { dst_logdbg("neigh is valid"); ret_val = true; } else { dst_logdbg("neigh is not valid"); } } } return ret_val; }
void neigh_table_mgr::notify_cb(event *ev) { neigh_mgr_logdbg(""); // Got event from netlink neigh_nl_event* nl_ev = dynamic_cast <neigh_nl_event*> (ev); BULLSEYE_EXCLUDE_BLOCK_START if (nl_ev == NULL) { neigh_mgr_logdbg("Non neigh_nl_event type"); return; } BULLSEYE_EXCLUDE_BLOCK_END const netlink_neigh_info* nl_info = nl_ev->get_neigh_info(); struct in_addr in; if (1 != inet_pton(AF_INET, (const char *)(nl_info->dst_addr_str.c_str()), &in)) { neigh_mgr_logdbg("Ignoring netlink neigh event neigh for IP = %s, not a valid IP", nl_info->dst_addr_str.c_str()); return; } in_addr_t neigh_ip = in.s_addr; // Search for this neigh ip in cache_table m_lock.lock(); net_dev_lst_t* p_ndv_val_lst = g_p_net_device_table_mgr->get_net_device_val_lst_from_index(nl_info->ifindex); //find all neigh entries with an appropriate peer_ip and net_device if (p_ndv_val_lst) { net_dev_lst_t::iterator itr; for (itr = p_ndv_val_lst->begin(); itr != p_ndv_val_lst->end(); ++itr) { net_device_val* p_ndev = dynamic_cast <net_device_val *>(*itr); if (p_ndev) { std::tr1::unordered_map< neigh_key, cache_entry_subject<neigh_key,neigh_val*> *>::iterator cache_itr; cache_itr = m_cache_tbl.find(neigh_key(ip_address(neigh_ip), p_ndev)); if (cache_itr == m_cache_tbl.end()) { neigh_mgr_logdbg("Ignoring netlink neigh event for IP = %s if:%s, index=%d, p_ndev=%p", nl_info->dst_addr_str.c_str(), p_ndev->to_str().c_str(), nl_info->ifindex, p_ndev); } else { neigh_entry *p_ne = dynamic_cast <neigh_entry *>(cache_itr->second); if (p_ne) { // Call the relevant neigh_entry to handle the event p_ne->handle_neigh_event(nl_ev); } } } else { neigh_mgr_logdbg("could not find ndv_val for ifindex=%d", nl_info->ifindex); } } } else { neigh_mgr_logdbg("could not find ndv_val list for ifindex=%d", nl_info->ifindex); } m_lock.unlock(); return; }
bool dst_entry::update_net_dev_val() { bool ret_val = false; net_device_val* new_nd_val = m_p_net_dev_val; if (m_so_bindtodevice_ip && g_p_net_device_table_mgr) { new_nd_val = g_p_net_device_table_mgr->get_net_device_val(m_so_bindtodevice_ip); // TODO should we register to g_p_net_device_table_mgr with m_p_net_dev_entry? // what should we do with an old one? dst_logdbg("getting net_dev_val by bindtodevice ip"); } else if (m_p_rt_entry) { new_nd_val = m_p_rt_entry->get_net_dev_val(); } if (m_p_net_dev_val != new_nd_val) { dst_logdbg("updating net_device"); if (m_p_neigh_entry) { g_p_neigh_table_mgr->unregister_observer(neigh_key(m_dst_ip, m_p_net_dev_val),this); m_p_neigh_entry = NULL; } // Change the net_device, clean old resources... release_ring(); // Save the new net_device m_p_net_dev_val = new_nd_val; if (m_p_net_dev_val) { // more resource clean and alloc... ret_val = alloc_transport_dep_res(); } else { dst_logdbg("Netdev is not offloaded fallback to OS"); } } else { if (m_p_net_dev_val) { // Only if we already had a valid net_device_val which did not change dst_logdbg("no change in net_device"); ret_val = true; } else { dst_logdbg("Netdev is not offloaded fallback to OS"); } } return ret_val; }
void neigh_table_mgr::notify_cb(event *ev) { neigh_mgr_logdbg(""); // Got event from netlink neigh_nl_event* nl_ev = dynamic_cast <neigh_nl_event*> (ev); BULLSEYE_EXCLUDE_BLOCK_START if (nl_ev == NULL) { neigh_mgr_logdbg("Non neigh_nl_event type"); return; } BULLSEYE_EXCLUDE_BLOCK_END const netlink_neigh_info* nl_info = nl_ev->get_neigh_info(); struct in_addr in; if (1 != inet_pton(AF_INET, (const char *)(nl_info->dst_addr_str.c_str()), &in)) { neigh_mgr_logdbg("Ignoring netlink neigh event neigh for IP = %s, not a valid IP", nl_info->dst_addr_str.c_str()); return; } in_addr_t neigh_ip = in.s_addr; // Search for this neigh ip in cache_table m_lock.lock(); net_device_val* p_ndev = g_p_net_device_table_mgr->get_net_device_val(nl_info->ifindex); //find all neigh entries with an appropriate peer_ip and net_device if (p_ndev) { neigh_entry *p_ne = dynamic_cast <neigh_entry *>(get_entry(neigh_key(ip_address(neigh_ip), p_ndev))); if (p_ne) { // Call the relevant neigh_entry to handle the event p_ne->handle_neigh_event(nl_ev); } else { neigh_mgr_logdbg("Ignoring netlink neigh event for IP = %s if:%s, index=%d, p_ndev=%p", nl_info->dst_addr_str.c_str(), p_ndev->to_str().c_str(), nl_info->ifindex, p_ndev); } } else { neigh_mgr_logdbg("could not find ndv_val for ifindex=%d", nl_info->ifindex); } m_lock.unlock(); return; }
dst_entry::~dst_entry() { dst_logdbg("%s", to_str().c_str()); if (m_p_neigh_entry) { g_p_neigh_table_mgr->unregister_observer(neigh_key(m_dst_ip, m_p_net_dev_val),this); } if (m_p_rt_entry) { g_p_route_table_mgr->unregister_observer(route_rule_table_key(m_dst_ip.get_in_addr(), m_bound_ip ? m_bound_ip : m_so_bindtodevice_ip, m_tos), this); m_p_rt_entry = NULL; } if (m_p_ring) { if (m_p_tx_mem_buf_desc_list) { m_p_ring->mem_buf_tx_release(m_p_tx_mem_buf_desc_list, true); m_p_tx_mem_buf_desc_list = NULL; } m_p_net_dev_val->release_ring(m_ring_alloc_logic.get_key()); m_p_ring = NULL; } if (m_p_net_dev_entry && m_p_net_dev_val) { g_p_net_device_table_mgr->unregister_observer(m_p_net_dev_val->get_local_addr(), this); } if (m_p_send_wqe_handler) { delete m_p_send_wqe_handler; m_p_send_wqe_handler = NULL; } if (m_p_neigh_val) { delete m_p_neigh_val; m_p_neigh_val = NULL; } dst_logdbg("Done %s", to_str().c_str()); }