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; }