int control_add_ipv4_local_entry(struct in_addr* nexthop, struct in_addr* saddr, uint8_t depth, uint32_t port_id, int32_t socket_id) { int s; uint16_t nexthop_id; s = neighbor4_lookup_nexthop(neighbor4_struct[socket_id], nexthop, &nexthop_id); if (s < 0) { s = neighbor4_add_nexthop(neighbor4_struct[socket_id], nexthop, &nexthop_id, NEI_ACTION_KNI); if (s < 0) { RTE_LOG( ERR, PKTJ_CTRL1, "failed to add a nexthop during route adding...\n"); return -1; } } neighbor4_set_port(neighbor4_struct[socket_id], nexthop_id, port_id); s = rte_lpm_add(ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(saddr->s_addr), depth, nexthop_id); if (s < 0) { RTE_LOG( ERR, PKTJ_CTRL1, "failed to add a route in lpm during route adding...\n"); return -1; } neighbor4_refcount_incr(neighbor4_struct[socket_id], nexthop_id); return nexthop_id; }
static int add_invalid_neighbor4(neighbor_struct_t *neighbor_struct, struct in_addr *ip, uint16_t dst_port) { struct ether_addr invalid_mac = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; uint8_t nexthop_id; if (neighbor4_add_nexthop(neighbor_struct, ip, &nexthop_id, NEI_ACTION_DROP) < 0) { return -1; } neighbor4_refcount_incr(neighbor_struct, nexthop_id); neighbor4_set_lladdr_port(neighbor_struct, nexthop_id, &invalid_mac, &invalid_mac, dst_port, -1); return 0; }
static int neighbor4(neighbor_action_t action, __s32 port_id, struct in_addr* addr, struct ether_addr* lladdr, __u8 flags, __rte_unused __u16 vlan_id, void* args) { // if port_id is not handled // ignore, return immediatly // if neighbor add // lookup neighbor // if exists // update lladdr, set flag as REACHABLE/STALE/DELAY // else // // This should not happen // insert new nexthop // set insert date=now, refcount = 0, flag=REACHABLE/STALE/DELAY // if neighbor delete // lookup neighbor // if exists // if refcount != 0 // set nexthop as invalid // else // set flag empty // else // do nothing // // this should not happen struct control_handle* handle = args; assert(handle != NULL); int s; uint16_t nexthop_id; uint32_t find_id; int32_t socket_id = handle->socket_id; char ipbuf[INET_ADDRSTRLEN]; assert(neighbor4_struct != NULL); if (addr == NULL) return -1; inet_ntop(AF_INET, addr, ipbuf, INET_ADDRSTRLEN); if (action == NEIGHBOR_ADD) { if (lladdr == NULL) return -1; char ibuf[IFNAMSIZ]; unsigned kni_vlan; if_indextoname(port_id, ibuf); s = sscanf(ibuf, "dpdk%10u.%10u", &port_id, &kni_vlan); if (s <= 0) { RTE_LOG(ERR, PKTJ_CTRL1, "received a neighbor " "announce for an unmanaged " "iface %s\n", ibuf); return -1; } s = neighbor4_lookup_nexthop(neighbor4_struct[socket_id], addr, &nexthop_id); if (s < 0) { if (flags != NUD_NONE && flags != NUD_NOARP && flags != NUD_STALE) { RTE_LOG(ERR, PKTJ_CTRL1, "failed to change state in neighbor4 " "table (state %d, %s)...\n", flags, ipbuf); return -1; } { RTE_LOG(DEBUG, PKTJ_CTRL1, "adding ipv4 neighbor %s with port %s " "vlan_id %d...\n", ipbuf, ibuf, kni_vlan); } s = neighbor4_add_nexthop(neighbor4_struct[socket_id], addr, &nexthop_id, NEI_ACTION_FWD); if (s < 0) { RTE_LOG(ERR, PKTJ_CTRL1, "failed to add a " "nexthop in neighbor " "table...\n"); return -1; } if (rte_lpm_lookup(ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(addr->s_addr), &find_id) == 0) { s = rte_lpm_add( ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(addr->s_addr), 32, nexthop_id); if (s < 0) { lpm4_stats[socket_id].nb_add_ko++; RTE_LOG(ERR, PKTJ_CTRL1, "failed to add a route in " "lpm during neighbor " "adding...\n"); return -1; } lpm4_stats[socket_id].nb_add_ok++; } } if (flags == NUD_FAILED) { neighbor4_set_action(neighbor4_struct[socket_id], nexthop_id, NEI_ACTION_KNI); } else { neighbor4_set_action(neighbor4_struct[socket_id], nexthop_id, NEI_ACTION_FWD); } RTE_LOG(DEBUG, PKTJ_CTRL1, "set neighbor4 with port_id %d state %d\n", port_id, flags); neighbor4_set_lladdr_port(neighbor4_struct[socket_id], nexthop_id, &ports_eth_addr[port_id], lladdr, port_id, kni_vlan); neighbor4_set_state(neighbor4_struct[socket_id], nexthop_id, flags); } if (action == NEIGHBOR_DELETE) { if (flags != NUD_FAILED && flags != NUD_STALE) { RTE_LOG( DEBUG, PKTJ_CTRL1, "neighbor4 delete ope failed, bad NUD state: %d \n", flags); return -1; } RTE_LOG(DEBUG, PKTJ_CTRL1, "deleting ipv4 neighbor...\n"); s = neighbor4_lookup_nexthop(neighbor4_struct[socket_id], addr, &nexthop_id); if (s < 0) { RTE_LOG(ERR, PKTJ_CTRL1, "failed to find a nexthop to " "delete in neighbor " "table...\n"); return 0; } neighbor4_delete(neighbor4_struct[socket_id], nexthop_id); // FIXME not thread safe if (neighbor4_struct[socket_id] ->entries.t4[nexthop_id] .neighbor.refcnt == 0) { s = rte_lpm_delete(ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(addr->s_addr), 32); if (s < 0) { lpm4_stats[socket_id].nb_del_ko++; RTE_LOG(ERR, PKTJ_CTRL1, "failed to delete route...\n"); return -1; } lpm4_stats[socket_id].nb_del_ok++; } } RTE_LOG(DEBUG, PKTJ_CTRL1, "neigh %s ope success\n", ipbuf); return 0; }
static int route4(__rte_unused struct rtmsg* route, route_action_t action, struct in_addr* addr, uint8_t depth, struct in_addr* nexthop, uint8_t type, void* args) { // If route add // lookup next hop in neighbor table ipv4 // if not lookup // create next hop, with flag invalid and addr = nexthop // nexthopid = last id // // register new route in lpm, with nexthop id // increment refcount in neighbor // If route delete // lookup next hop in neighbor table ipv4 // if not lookup // then WTF TABLE CORRUPTED // remove route from lpm // decrement refcount in neighbor // if refcount reached 0 // then flag entry empty struct control_handle* handle = args; assert(handle != NULL); uint16_t nexthop_id; int s; int32_t socket_id = handle->socket_id; struct in_addr blackhole_addr4 = {rte_be_to_cpu_32(INADDR_ANY)}; if (type == RTN_BLACKHOLE) { nexthop = &blackhole_addr4; } if (action == ROUTE_ADD) { RTE_LOG(DEBUG, PKTJ_CTRL1, "adding an ipv4 route...\n"); // lookup nexthop s = neighbor4_lookup_nexthop(neighbor4_struct[socket_id], nexthop, &nexthop_id); if (s < 0) { s = neighbor4_add_nexthop(neighbor4_struct[socket_id], nexthop, &nexthop_id, NEI_ACTION_FWD); if (s < 0) { RTE_LOG(ERR, PKTJ_CTRL1, "failed to add a " "nexthop during " "route adding...\n"); return -1; } } s = rte_lpm_add(ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(addr->s_addr), depth, nexthop_id); if (s < 0) { lpm4_stats[socket_id].nb_add_ko++; RTE_LOG(ERR, PKTJ_CTRL1, "failed to add a route in " "lpm during route " "adding...\n"); return -1; } neighbor4_refcount_incr(neighbor4_struct[socket_id], nexthop_id); lpm4_stats[socket_id].nb_add_ok++; } if (action == ROUTE_DELETE) { RTE_LOG(DEBUG, PKTJ_CTRL1, "deleting an ipv4 route...\n"); // lookup nexthop s = neighbor4_lookup_nexthop(neighbor4_struct[socket_id], nexthop, &nexthop_id); if (s < 0) { RTE_LOG(ERR, PKTJ_CTRL1, "failed to find nexthop " "during route deletion...\n"); return -1; } s = rte_lpm_delete(ipv4_pktj_lookup_struct[socket_id], rte_be_to_cpu_32(addr->s_addr), depth); if (s < 0) { lpm4_stats[socket_id].nb_del_ko++; RTE_LOG(ERR, PKTJ_CTRL1, "failed to delete route...\n"); return -1; } neighbor4_refcount_decr(neighbor4_struct[socket_id], nexthop_id); lpm4_stats[socket_id].nb_del_ok++; } RTE_LOG(DEBUG, PKTJ_CTRL1, "route ope success\n"); return 0; }