X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip_api.c;h=31b7e40a880dd1e78d1a6d64504660c4c5b35dd7;hb=3b93be5d76cbcb5dc3d3aee5c72a797014a346f9;hp=2b85247bb27fefec28435121fbbe81c46d696548;hpb=0012fccda812cb4625355baaf5e76dab4cefcdb5;p=vpp.git diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 2b85247bb27..31b7e40a880 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -74,6 +75,7 @@ _(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \ _(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \ _(MFIB_SIGNAL_DUMP, mfib_signal_dump) \ _(IP_ADDRESS_DUMP, ip_address_dump) \ +_(IP_UNNUMBERED_DUMP, ip_unnumbered_dump) \ _(IP_DUMP, ip_dump) \ _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \ _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \ @@ -83,7 +85,9 @@ _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \ _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \ _(WANT_IP6_RA_EVENTS, want_ip6_ra_events) \ _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \ +_(PROXY_ARP_DUMP, proxy_arp_dump) \ _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \ + _(PROXY_ARP_INTFC_DUMP, proxy_arp_intfc_dump) \ _(RESET_FIB, reset_fib) \ _(IP_ADD_DEL_ROUTE, ip_add_del_route) \ _(IP_TABLE_ADD_DEL, ip_table_add_del) \ @@ -155,7 +159,7 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp) vec_foreach (n, ns) { send_ip_neighbor_details - (sw_if_index, mp->is_ipv6, + (n->key.sw_if_index, mp->is_ipv6, ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0), (u8 *) n->link_layer_address, (u8 *) & (n->key.ip6_address.as_u8), @@ -172,7 +176,7 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp) /* *INDENT-OFF* */ vec_foreach (n, ns) { - send_ip_neighbor_details (sw_if_index, mp->is_ipv6, + send_ip_neighbor_details (n->sw_if_index, mp->is_ipv6, ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0), (u8*) n->ethernet_address, (u8*) & (n->ip4_address.as_u8), @@ -243,7 +247,7 @@ vl_api_ip_fib_dump_t_handler (vl_api_ip_fib_dump_t * mp) ip4_main_t *im = &ip4_main; fib_table_t *fib_table; fib_node_index_t *lfeip; - fib_prefix_t pfx; + const fib_prefix_t *pfx; u32 fib_index; fib_route_path_encode_t *api_rpaths; vl_api_ip_fib_dump_walk_ctx_t ctx = { @@ -268,12 +272,12 @@ vl_api_ip_fib_dump_t_handler (vl_api_ip_fib_dump_t * mp) vec_foreach (lfeip, ctx.feis) { - fib_entry_get_prefix (*lfeip, &pfx); + pfx = fib_entry_get_prefix (*lfeip); fib_index = fib_entry_get_fib_index (*lfeip); - fib_table = fib_table_get (fib_index, pfx.fp_proto); + fib_table = fib_table_get (fib_index, pfx->fp_proto); api_rpaths = NULL; fib_entry_encode (*lfeip, &api_rpaths); - send_ip_fib_details (am, reg, fib_table, &pfx, api_rpaths, mp->context); + send_ip_fib_details (am, reg, fib_table, pfx, api_rpaths, mp->context); vec_free (api_rpaths); } @@ -347,7 +351,7 @@ api_ip6_fib_table_get_all (vl_api_registration_t * reg, .entries = NULL, }; fib_route_path_encode_t *api_rpaths; - fib_prefix_t pfx; + const fib_prefix_t *pfx; BV (clib_bihash_foreach_key_value_pair) ((BVT (clib_bihash) *) & im6->ip6_table[IP6_FIB_TABLE_NON_FWDING]. @@ -357,10 +361,10 @@ api_ip6_fib_table_get_all (vl_api_registration_t * reg, vec_foreach (fib_entry_index, ctx.entries) { - fib_entry_get_prefix (*fib_entry_index, &pfx); + pfx = fib_entry_get_prefix (*fib_entry_index); api_rpaths = NULL; fib_entry_encode (*fib_entry_index, &api_rpaths); - send_ip6_fib_details (am, reg, fib_table, &pfx, api_rpaths, mp->context); + send_ip6_fib_details (am, reg, fib_table, pfx, api_rpaths, mp->context); vec_free (api_rpaths); } @@ -835,26 +839,6 @@ add_del_route_t_handler (u8 is_multipath, path.frp_flags = path_flags; - if (is_multipath) - { - stats_dslock_with_hint (1 /* release hint */ , 10 /* tag */ ); - - - vec_add1 (paths, path); - - if (is_add) - fib_table_entry_path_add2 (fib_index, - prefix, - FIB_SOURCE_API, entry_flags, paths); - else - fib_table_entry_path_remove2 (fib_index, - prefix, FIB_SOURCE_API, paths); - - vec_free (paths); - stats_dsunlock (); - return 0; - } - stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ ); if (is_drop || is_local || is_classify || is_unreach || is_prohibit) @@ -910,6 +894,20 @@ add_del_route_t_handler (u8 is_multipath, fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API); } } + else if (is_multipath) + { + vec_add1 (paths, path); + + if (is_add) + fib_table_entry_path_add2 (fib_index, + prefix, + FIB_SOURCE_API, entry_flags, paths); + else + fib_table_entry_path_remove2 (fib_index, + prefix, FIB_SOURCE_API, paths); + + vec_free (paths); + } else { if (is_add) @@ -1395,8 +1393,11 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) if (mp->is_ipv6) { /* *INDENT-OFF* */ - foreach_ip_interface_address (lm6, ia, sw_if_index, - 1 /* honor unnumbered */, + /* Do not send subnet details of the IP-interface for + * unnumbered interfaces. otherwise listening clients + * will be confused that the subnet is applied on more + * than one interface */ + foreach_ip_interface_address (lm6, ia, sw_if_index, 0, ({ r6 = ip_interface_address_get_address (lm6, ia); u16 prefix_length = ia->address_length; @@ -1408,8 +1409,7 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) else { /* *INDENT-OFF* */ - foreach_ip_interface_address (lm4, ia, sw_if_index, - 1 /* honor unnumbered */, + foreach_ip_interface_address (lm4, ia, sw_if_index, 0, ({ r4 = ip_interface_address_get_address (lm4, ia); u16 prefix_length = ia->address_length; @@ -1421,6 +1421,74 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) BAD_SW_IF_INDEX_LABEL; } +static void +send_ip_unnumbered_details (vpe_api_main_t * am, + vl_api_registration_t * reg, + u32 sw_if_index, u32 ip_sw_if_index, u32 context) +{ + vl_api_ip_unnumbered_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS); + + mp->context = context; + mp->sw_if_index = htonl (sw_if_index); + mp->ip_sw_if_index = htonl (ip_sw_if_index); + + vl_api_send_msg (reg, (u8 *) mp); +} + +static void +vl_api_ip_unnumbered_dump_t_handler (vl_api_ip_unnumbered_dump_t * mp) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_interface_main_t *im = &vnm->interface_main; + int rv __attribute__ ((unused)) = 0; + vpe_api_main_t *am = &vpe_api_main; + vl_api_registration_t *reg; + vnet_sw_interface_t *si; + u32 sw_if_index; + + sw_if_index = ntohl (mp->sw_if_index); + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + if (~0 != sw_if_index) + { + VALIDATE_SW_IF_INDEX (mp); + + si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index)); + + if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) + { + send_ip_unnumbered_details (am, reg, + sw_if_index, + si->unnumbered_sw_if_index, + mp->context); + } + } + else + { + /* *INDENT-OFF* */ + pool_foreach (si, im->sw_interfaces, + ({ + if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) + { + send_ip_unnumbered_details(am, reg, + si->sw_if_index, + si->unnumbered_sw_if_index, + mp->context); + } + })); + /* *INDENT-ON* */ + } + + BAD_SW_IF_INDEX_LABEL; +} + static void vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp) { @@ -1616,7 +1684,7 @@ vl_api_ip6nd_proxy_dump_t_handler (vl_api_ip6nd_proxy_dump_t * mp) .indices = NULL, }; fib_node_index_t *feip; - fib_prefix_t pfx; + const fib_prefix_t *pfx; vl_api_registration_t *reg; reg = vl_api_client_index_to_registration (mp->client_index); @@ -1637,11 +1705,11 @@ vl_api_ip6nd_proxy_dump_t_handler (vl_api_ip6nd_proxy_dump_t * mp) vec_foreach (feip, ctx.indices) { - fib_entry_get_prefix (*feip, &pfx); + pfx = fib_entry_get_prefix (*feip); send_ip6nd_proxy_details (reg, mp->context, - &pfx.fp_addr, + &pfx->fp_addr, fib_entry_get_resolving_interface (*feip)); } @@ -2078,7 +2146,7 @@ handle_ip4_arp_event (u32 pool_index) } } -void +static void handle_ip6_nd_event (u32 pool_index) { vpe_api_main_t *vam = &vpe_api_main; @@ -2389,7 +2457,8 @@ wc_arp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) vl_api_send_msg (vl_reg, (u8 *) event); } })); - /* *INDENT-ON* */ + /* *INDENT-ON* */ + vec_free (ra_events[i].prefixes); } } vlib_process_put_event_data (vm, event_data); @@ -2513,6 +2582,58 @@ reply: REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY); } +static clib_error_t * +want_ip4_arp_events_reaper (u32 client_index) +{ + vpe_client_registration_t *rp; + vl_api_ip4_arp_event_t *event; + u32 *to_delete, *event_id; + vpe_api_main_t *am; + vnet_main_t *vnm; + uword *p; + + am = &vpe_api_main; + vnm = vnet_get_main (); + to_delete = NULL; + + /* clear out all of its pending resolutions */ + /* *INDENT-OFF* */ + pool_foreach(event, am->arp_events, + ({ + if (event->client_index == client_index) + { + vec_add1(to_delete, event - am->arp_events); + } + })); + /* *INDENT-ON* */ + + vec_foreach (event_id, to_delete) + { + event = pool_elt_at_index (am->arp_events, *event_id); + vnet_add_del_ip4_arp_change_event + (vnm, arp_change_delete_callback, + event->pid, &event->address, + ip_resolver_process_node.index, IP4_ARP_EVENT, + ~0 /* pool index, notused */ , 0 /* is_add */ ); + } + vec_free (to_delete); + + /* remove from the registration hash */ + p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index); + + if (p) + { + rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]); + pool_put (am->wc_ip4_arp_events_registrations, rp); + hash_unset (am->wc_ip4_arp_events_registration_hash, client_index); + if (pool_elts (am->wc_ip4_arp_events_registrations) == 0) + wc_arp_set_publisher_node (~0, REPORT_MAX); + } + return (NULL); +} + +VL_MSG_API_REAPER_FUNCTION (want_ip4_arp_events_reaper); + static void vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp) { @@ -2596,6 +2717,59 @@ reply: REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY); } +static clib_error_t * +want_ip6_nd_events_reaper (u32 client_index) +{ + + vpe_client_registration_t *rp; + vl_api_ip6_nd_event_t *event; + u32 *to_delete, *event_id; + vpe_api_main_t *am; + vnet_main_t *vnm; + uword *p; + + am = &vpe_api_main; + vnm = vnet_get_main (); + to_delete = NULL; + + /* clear out all of its pending resolutions */ + /* *INDENT-OFF* */ + pool_foreach(event, am->nd_events, + ({ + if (event->client_index == client_index) + { + vec_add1(to_delete, event - am->nd_events); + } + })); + /* *INDENT-ON* */ + + vec_foreach (event_id, to_delete) + { + event = pool_elt_at_index (am->nd_events, *event_id); + vnet_add_del_ip6_nd_change_event + (vnm, nd_change_delete_callback, + event->pid, &event->address, + ip_resolver_process_node.index, IP6_ND_EVENT, + ~0 /* pool index, notused */ , 0 /* is_add */ ); + } + vec_free (to_delete); + + /* remove from the registration hash */ + p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index); + + if (p) + { + rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]); + pool_put (am->wc_ip6_nd_events_registrations, rp); + hash_unset (am->wc_ip6_nd_events_registration_hash, client_index); + if (pool_elts (am->wc_ip6_nd_events_registrations) == 0) + wc_nd_set_publisher_node (~0, REPORT_MAX); + } + return (NULL); +} + +VL_MSG_API_REAPER_FUNCTION (want_ip6_nd_events_reaper); + static void vl_api_want_ip6_ra_events_t_handler (vl_api_want_ip6_ra_events_t * mp) { @@ -2637,6 +2811,26 @@ reply: REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY); } +static clib_error_t * +want_ip6_ra_events_reaper (u32 client_index) +{ + vpe_api_main_t *am = &vpe_api_main; + vpe_client_registration_t *rp; + uword *p; + + p = hash_get (am->ip6_ra_events_registration_hash, client_index); + + if (p) + { + rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]); + pool_put (am->ip6_ra_events_registrations, rp); + hash_unset (am->ip6_ra_events_registration_hash, client_index); + } + return (NULL); +} + +VL_MSG_API_REAPER_FUNCTION (want_ip6_ra_events_reaper); + static void vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp) { @@ -2644,14 +2838,11 @@ vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp) u32 fib_index; int rv; ip4_main_t *im = &ip4_main; - int vnet_proxy_arp_add_del (ip4_address_t * lo_addr, - ip4_address_t * hi_addr, - u32 fib_index, int is_del); uword *p; stats_dslock_with_hint (1 /* release hint */ , 6 /* tag */ ); - p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id)); + p = hash_get (im->fib_index_by_table_id, ntohl (mp->proxy.vrf_id)); if (!p) { @@ -2661,8 +2852,8 @@ vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp) fib_index = p[0]; - rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->low_address, - (ip4_address_t *) mp->hi_address, + rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->proxy.low_address, + (ip4_address_t *) mp->proxy.hi_address, fib_index, mp->is_add == 0); out: @@ -2670,6 +2861,94 @@ out: REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY); } +typedef struct proxy_arp_walk_ctx_t_ +{ + vl_api_registration_t *reg; + u32 context; +} proxy_arp_walk_ctx_t; + +static walk_rc_t +send_proxy_arp_details (const ip4_address_t * lo_addr, + const ip4_address_t * hi_addr, + u32 fib_index, void *data) +{ + vl_api_proxy_arp_details_t *mp; + proxy_arp_walk_ctx_t *ctx; + + ctx = data; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS); + mp->context = ctx->context; + mp->proxy.vrf_id = htonl (fib_index); + clib_memcpy (mp->proxy.low_address, lo_addr, + sizeof (mp->proxy.low_address)); + clib_memcpy (mp->proxy.hi_address, hi_addr, sizeof (mp->proxy.hi_address)); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (WALK_CONTINUE); +} + +static void +vl_api_proxy_arp_dump_t_handler (vl_api_proxy_arp_dump_t * mp) +{ + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + proxy_arp_walk_ctx_t wctx = { + .reg = reg, + .context = mp->context, + }; + + proxy_arp_walk (send_proxy_arp_details, &wctx); +} + +static walk_rc_t +send_proxy_arp_intfc_details (vnet_main_t * vnm, + vnet_sw_interface_t * si, void *data) +{ + vl_api_proxy_arp_intfc_details_t *mp; + proxy_arp_walk_ctx_t *ctx; + + if (!(si->flags & VNET_SW_INTERFACE_FLAG_PROXY_ARP)) + return (WALK_CONTINUE); + + ctx = data; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS); + mp->context = ctx->context; + mp->sw_if_index = htonl (si->sw_if_index); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (WALK_CONTINUE); +} + +static void +vl_api_proxy_arp_intfc_dump_t_handler (vl_api_proxy_arp_intfc_dump_t * mp) +{ + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + proxy_arp_walk_ctx_t wctx = { + .reg = reg, + .context = mp->context, + }; + + vnet_sw_interface_walk (vnet_get_main (), + send_proxy_arp_intfc_details, &wctx); +} + static void vl_api_proxy_arp_intfc_enable_disable_t_handler (vl_api_proxy_arp_intfc_enable_disable_t * mp) @@ -2709,10 +2988,10 @@ vl_api_ip_probe_neighbor_t_handler (vl_api_ip_probe_neighbor_t * mp) if (mp->is_ipv6) error = ip6_probe_neighbor (vm, (ip6_address_t *) mp->dst_address, - sw_if_index); + sw_if_index, 0); else error = ip4_probe_neighbor (vm, (ip4_address_t *) mp->dst_address, - sw_if_index); + sw_if_index, 0); if (error) {