Beispiel #1
0
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;
}
Beispiel #3
0
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;
}
Beispiel #5
0
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());
}