bool dst_entry::resolve_net_dev() { bool ret_val = false; cache_entry_subject<route_rule_table_key, route_val*>* p_ces = NULL; if (ZERONET_N(m_dst_ip.get_in_addr())) { dst_logdbg("VMA does not offload zero net IP address"); return ret_val; } if (LOOPBACK_N(m_dst_ip.get_in_addr())) { dst_logdbg("VMA does not offload local loopback IP address"); return ret_val; } route_rule_table_key rtk(m_dst_ip.get_in_addr(), m_bound_ip ? m_bound_ip : m_so_bindtodevice_ip, m_tos); if (m_p_rt_entry || g_p_route_table_mgr->register_observer(rtk, this, &p_ces)) { if (m_p_rt_entry == NULL) { // In case this is the first time we trying to resolve route entry, // means that register_observer was run m_p_rt_entry = dynamic_cast<route_entry*>(p_ces); } if(update_rt_val()) { ret_val = update_net_dev_val(); } } return ret_val; }
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; }
bool dst_entry::update_net_dev_val() { bool ret_val = false; if (m_p_rt_entry && (m_p_net_dev_val != m_p_rt_entry->get_net_dev_val())) { dst_logdbg("updating net_device"); // Change the net_device, clean old resources... release_ring(); // Save the new net_device m_p_net_dev_val = m_p_rt_entry->get_net_dev_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; }
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; }
dst_entry::dst_entry(in_addr_t dst_ip, uint16_t dst_port, uint16_t src_port, int owner_fd): m_dst_ip(dst_ip), m_dst_port(dst_port), m_src_port(src_port), m_bound_ip(0), m_so_bindtodevice_ip(0), m_ring_alloc_logic(owner_fd, this), m_p_tx_mem_buf_desc_list(NULL), m_b_tx_mem_buf_desc_list_pending(false), m_id(0) { dst_logdbg("dst:%s:%d src: %d", m_dst_ip.to_str().c_str(), ntohs(m_dst_port), ntohs(m_src_port)); init_members(); }
bool dst_entry::update_rt_val() { bool ret_val = true; route_val* p_rt_val = NULL; if (m_p_rt_entry && m_p_rt_entry->get_val(p_rt_val)) { if (m_p_rt_val == p_rt_val) { dst_logdbg("no change in route_val"); } else { dst_logdbg("updating route val"); m_p_rt_val = p_rt_val; } } else { dst_logdbg("Route entry is not valid"); ret_val = false; } return ret_val; }
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()); }
bool dst_entry::resolve_ring() { bool ret_val = false; if (m_p_net_dev_val) { if (!m_p_ring) { dst_logdbg("getting a ring"); m_p_ring = m_p_net_dev_val->reserve_ring(m_ring_alloc_logic.create_new_key()); m_max_inline = m_p_ring->get_max_tx_inline(); m_max_inline = std::min(m_max_inline, m_p_net_dev_val->get_mtu() + (uint32_t)m_header.m_transport_header_len); } ret_val = true; } return ret_val; }
bool dst_entry::release_ring() { bool ret_val = false; if (m_p_net_dev_val) { 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; } dst_logdbg("releasing a ring"); m_p_net_dev_val->release_ring(m_ring_alloc_logic.get_key()); m_p_ring = NULL; } ret_val = true; } return ret_val; }
bool dst_entry::resolve_net_dev() { bool ret_val = false; cache_entry_subject<ip_address, route_val*>* p_ces = NULL; if (m_p_rt_entry || g_p_route_table_mgr->register_observer(m_dst_ip, this, &p_ces)) { if (m_p_rt_entry == NULL) { // In case this is the first time we trying to resolve route entry, // means that register_observer was run m_p_rt_entry = dynamic_cast<route_entry*>(p_ces); } if (m_p_rt_entry) { if(update_rt_val()) { ret_val = update_net_dev_val(); } } else { dst_logdbg("Route entry is not exist"); } } return ret_val; }
void dst_entry::notify_cb() { dst_logdbg(""); set_state(false); }