void route_table_mgr::new_route_event(route_val &netlink_route_val) { int number_of_entries = m_tab.entries_num++; netlink_route_val.set_state(true); in_addr_t new_dst_addr = netlink_route_val.get_dst_addr(); in_addr_t new_dst_mask = netlink_route_val.get_dst_mask(); int new_dst_pref_len = netlink_route_val.get_dst_pref_len(); char *new_if_name = (char *) netlink_route_val.get_if_name(); rt_mgr_logdbg("netlink event- route added: dst '%d.%d.%d.%d', netmask '%d.%d.%d.%d', interface '%s'", NIPQUAD(new_dst_addr), NIPQUAD(new_dst_mask), new_if_name); if(find_route_val(netlink_route_val)) { rt_mgr_logdbg("route already exists: dst '%d.%d.%d.%d', netmask '%d.%d.%d.%d', interface '%s'", NIPQUAD(new_dst_addr), NIPQUAD(new_dst_mask), new_if_name); return; } m_tab.value[number_of_entries] = netlink_route_val; in_addr_t common_prefix; // set necessary route_vals as not valid for (int i = 0; i < m_tab.entries_num; i++) { route_val* p_val_from_tbl = &m_tab.value[i]; if (!p_val_from_tbl->is_deleted() && p_val_from_tbl->is_if_up()) { common_prefix = p_val_from_tbl->get_dst_addr() & new_dst_mask; // check if the new route is more specific than an existing route // example: if route table contains entry for- 1.1.1.1/24 // and a new entry for- 1.1.1.1/32 is added // then route might change for some dst ips ---> set as invalid if((common_prefix == (new_dst_addr & new_dst_mask)) && p_val_from_tbl->get_dst_pref_len() < new_dst_pref_len) { p_val_from_tbl->set_state(false); rt_mgr_logdbg("route_val %p is not valid", p_val_from_tbl); p_val_from_tbl->print_route_val(); } } } rt_mgr_logdbg("route added: dst '%d.%d.%d.%d', netmask '%d.%d.%d.%d', interface '%s'", NIPQUAD(new_dst_addr), NIPQUAD(new_dst_mask), new_if_name); if (g_vlogger_level >= VLOG_FUNC) { print_route_tbl(); } update_invalid_entries(); }
route_table_mgr::route_table_mgr() : cache_table_mgr<ip_address,route_val*>("route_table_mgr") { rt_mgr_logdbg(""); m_pid = getpid(); m_buff_size = MSG_BUFF_SIZE; m_seq_num = 0; // Create Socket BULLSEYE_EXCLUDE_BLOCK_START if ((m_fd = orig_os_api.socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) { rt_mgr_logerr("NL socket Creation: "); return; } BULLSEYE_EXCLUDE_BLOCK_END //save the routing table rt_mgr_update_tbl(); // create route_entry for each net_dev- needed for receiving port up/down events for net_dev_entry route_val *p_rtv; for (int i = 0; i < m_rt_tab.entries_num; i++) { p_rtv = &m_rt_tab.rtv[i]; in_addr_t src_addr = p_rtv->get_src_addr(); std::tr1::unordered_map<in_addr_t, route_entry*>::iterator iter = m_rte_list_for_each_net_dev.find(src_addr); // if src_addr of interface exists in the map, no need to create another route_entry if (iter == m_rte_list_for_each_net_dev.end()) { m_rte_list_for_each_net_dev.insert(pair<in_addr_t, route_entry*> (src_addr, create_new_entry(ip_address(src_addr), NULL))); } } print_route_tbl(); // register to netlink event g_p_netlink_handler->register_event(nlgrpROUTE, this); rt_mgr_logdbg("Registered to g_p_netlink_handler"); rt_mgr_logdbg("Done"); }
void route_table_mgr::del_route_event(route_val &netlink_route_val) { in_addr_t del_dst_addr = netlink_route_val.get_dst_addr(); in_addr_t del_dst_mask = netlink_route_val.get_dst_mask(); char *del_if_name = (char *) netlink_route_val.get_if_name(); rt_mgr_logdbg("netlink event- route deleted: dst '%d.%d.%d.%d', netmask '%d.%d.%d.%d', interface '%s'", NIPQUAD(del_dst_addr), NIPQUAD(del_dst_mask), del_if_name); route_val* p_val_from_tbl = find_route_val(netlink_route_val); if(p_val_from_tbl) { rt_mgr_logdbg("found deleted route val[%p]: %s", p_val_from_tbl, p_val_from_tbl->to_str()); p_val_from_tbl->set_deleted(); p_val_from_tbl->set_state(false); return; } rt_mgr_logdbg("route does not exist!"); if (g_vlogger_level >= VLOG_FUNC) { print_route_tbl(); } update_invalid_entries(); }