X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip_api.c;h=4355d11e792ac0661c115ca2e37239dcfb460fbb;hp=48e523f381a29a7ad5f734c9274922375ef25ffc;hb=75b9f45;hpb=f12dad658d03030d1a61ba970e27c8f01763f2e0 diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 48e523f381a..4355d11e792 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -46,6 +45,7 @@ #include #include #include +#include #include @@ -103,6 +103,7 @@ _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \ _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \ sw_interface_ip6_set_link_local_address) \ _(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \ +_(IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump) \ _(IOAM_ENABLE, ioam_enable) \ _(IOAM_DISABLE, ioam_disable) \ _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \ @@ -159,7 +160,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), @@ -176,7 +177,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), @@ -212,6 +213,8 @@ send_ip_fib_details (vpe_api_main_t * am, clib_min (vec_len (table->ft_desc), sizeof (mp->table_name))); mp->address_length = pfx->fp_len; memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4)); + mp->stats_index = + htonl (fib_table_entry_get_stats_index (table->ft_index, pfx)); mp->count = htonl (path_count); fp = mp->path; @@ -247,7 +250,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 = { @@ -272,12 +275,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); } @@ -309,6 +312,8 @@ send_ip6_fib_details (vpe_api_main_t * am, memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6)); memcpy (mp->table_name, table->ft_desc, clib_min (vec_len (table->ft_desc), sizeof (mp->table_name))); + mp->stats_index = + htonl (fib_table_entry_get_stats_index (table->ft_index, pfx)); mp->count = htonl (path_count); fp = mp->path; @@ -351,7 +356,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]. @@ -361,10 +366,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); } @@ -653,53 +658,43 @@ static void vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp, vlib_main_t * vm) { + ip46_address_t ip = ip46_address_initializer; vl_api_ip_neighbor_add_del_reply_t *rmp; - vnet_main_t *vnm = vnet_get_main (); + ip_neighbor_flags_t flags; + u32 stats_index = ~0; int rv = 0; VALIDATE_SW_IF_INDEX (mp); stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ ); - /* - * there's no validation here of the ND/ARP entry being added. - * The expectation is that the FIB will ensure that nothing bad - * will come of adding bogus entries. - */ + flags = IP_NEIGHBOR_FLAG_NODE; + if (mp->is_static) + flags |= IP_NEIGHBOR_FLAG_STATIC; + if (mp->is_no_adj_fib) + flags |= IP_NEIGHBOR_FLAG_NO_ADJ_FIB; + if (mp->is_ipv6) - { - if (mp->is_add) - rv = vnet_set_ip6_ethernet_neighbor - (vm, ntohl (mp->sw_if_index), - (ip6_address_t *) (mp->dst_address), - mp->mac_address, sizeof (mp->mac_address), mp->is_static, - mp->is_no_adj_fib); - else - rv = vnet_unset_ip6_ethernet_neighbor - (vm, ntohl (mp->sw_if_index), - (ip6_address_t *) (mp->dst_address), - mp->mac_address, sizeof (mp->mac_address)); - } + clib_memcpy (&ip.ip6, mp->dst_address, 16); else - { - ethernet_arp_ip4_over_ethernet_address_t a; - - clib_memcpy (&a.ethernet, mp->mac_address, 6); - clib_memcpy (&a.ip4, mp->dst_address, 4); + clib_memcpy (&ip.ip4, mp->dst_address, 4); - if (mp->is_add) - rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), - &a, mp->is_static, - mp->is_no_adj_fib); - else - rv = - vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a); - } + if (mp->is_add) + rv = ip_neighbor_add (&ip, mp->is_ipv6, mp->mac_address, + ntohl (mp->sw_if_index), flags, &stats_index); + else + rv = ip_neighbor_del (&ip, mp->is_ipv6, ntohl (mp->sw_if_index)); stats_dsunlock (); BAD_SW_IF_INDEX_LABEL; - REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY, + ({ + rmp->stats_index = htonl (stats_index); + })); + /* *INDENT-ON* */ } void @@ -839,26 +834,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) @@ -914,6 +889,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) @@ -985,7 +974,8 @@ add_del_route_check (fib_protocol_t table_proto, } static int -ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) +ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp, + u32 * stats_index) { u32 fib_index, next_hop_fib_index; fib_mpls_label_t *label_stack = NULL; @@ -1029,32 +1019,37 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) } } - return (add_del_route_t_handler (mp->is_multipath, - mp->is_add, - mp->is_drop, - mp->is_unreach, - mp->is_prohibit, - mp->is_local, 0, - mp->is_classify, - mp->classify_table_index, - mp->is_resolve_host, - mp->is_resolve_attached, 0, 0, - mp->is_dvr, - mp->is_source_lookup, - mp->is_udp_encap, - fib_index, &pfx, DPO_PROTO_IP4, - &nh, - ntohl (mp->next_hop_id), - ntohl (mp->next_hop_sw_if_index), - next_hop_fib_index, - mp->next_hop_weight, - mp->next_hop_preference, - ntohl (mp->next_hop_via_label), - label_stack)); + rv = add_del_route_t_handler (mp->is_multipath, + mp->is_add, + mp->is_drop, + mp->is_unreach, + mp->is_prohibit, + mp->is_local, 0, + mp->is_classify, + mp->classify_table_index, + mp->is_resolve_host, + mp->is_resolve_attached, 0, 0, + mp->is_dvr, + mp->is_source_lookup, + mp->is_udp_encap, + fib_index, &pfx, DPO_PROTO_IP4, + &nh, + ntohl (mp->next_hop_id), + ntohl (mp->next_hop_sw_if_index), + next_hop_fib_index, + mp->next_hop_weight, + mp->next_hop_preference, + ntohl (mp->next_hop_via_label), label_stack); + + if (mp->is_add && 0 == rv) + *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx); + + return (rv); } static int -ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) +ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp, + u32 * stats_index) { fib_mpls_label_t *label_stack = NULL; u32 fib_index, next_hop_fib_index; @@ -1098,46 +1093,57 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) } } - return (add_del_route_t_handler (mp->is_multipath, - mp->is_add, - mp->is_drop, - mp->is_unreach, - mp->is_prohibit, - mp->is_local, 0, - mp->is_classify, - mp->classify_table_index, - mp->is_resolve_host, - mp->is_resolve_attached, 0, 0, - mp->is_dvr, - mp->is_source_lookup, - mp->is_udp_encap, - fib_index, &pfx, DPO_PROTO_IP6, - &nh, ntohl (mp->next_hop_id), - ntohl (mp->next_hop_sw_if_index), - next_hop_fib_index, - mp->next_hop_weight, - mp->next_hop_preference, - ntohl (mp->next_hop_via_label), - label_stack)); + rv = add_del_route_t_handler (mp->is_multipath, + mp->is_add, + mp->is_drop, + mp->is_unreach, + mp->is_prohibit, + mp->is_local, 0, + mp->is_classify, + mp->classify_table_index, + mp->is_resolve_host, + mp->is_resolve_attached, 0, 0, + mp->is_dvr, + mp->is_source_lookup, + mp->is_udp_encap, + fib_index, &pfx, DPO_PROTO_IP6, + &nh, ntohl (mp->next_hop_id), + ntohl (mp->next_hop_sw_if_index), + next_hop_fib_index, + mp->next_hop_weight, + mp->next_hop_preference, + ntohl (mp->next_hop_via_label), label_stack); + + if (mp->is_add && 0 == rv) + *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx); + + return (rv); } void vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) { vl_api_ip_add_del_route_reply_t *rmp; + u32 stats_index; int rv; vnet_main_t *vnm = vnet_get_main (); vnm->api_errno = 0; + stats_index = ~0; if (mp->is_ipv6) - rv = ip6_add_del_route_t_handler (mp); + rv = ip6_add_del_route_t_handler (mp, &stats_index); else - rv = ip4_add_del_route_t_handler (mp); + rv = ip4_add_del_route_t_handler (mp, &stats_index); rv = (rv == 0) ? vnm->api_errno : rv; - REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY); + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_IP_ADD_DEL_ROUTE_REPLY, + ({ + rmp->stats_index = htonl (stats_index); + })) + /* *INDENT-ON* */ } void @@ -1206,7 +1212,7 @@ add_del_mroute_check (fib_protocol_t table_proto, return (0); } -static int +static fib_node_index_t mroute_add_del_handler (u8 is_add, u8 is_local, u32 fib_index, @@ -1217,6 +1223,8 @@ mroute_add_del_handler (u8 is_add, u32 next_hop_sw_if_index, ip46_address_t * nh, u32 itf_flags, u32 bier_imp) { + fib_node_index_t mfib_entry_index = ~0; + stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ ); fib_route_path_t path = { @@ -1235,15 +1243,17 @@ mroute_add_del_handler (u8 is_add, } else if (!is_local && ~0 == next_hop_sw_if_index) { - mfib_table_entry_update (fib_index, prefix, - MFIB_SOURCE_API, rpf_id, entry_flags); + mfib_entry_index = mfib_table_entry_update (fib_index, prefix, + MFIB_SOURCE_API, + rpf_id, entry_flags); goto done; } if (is_add) { - mfib_table_entry_path_update (fib_index, prefix, - MFIB_SOURCE_API, &path, itf_flags); + mfib_entry_index = mfib_table_entry_path_update (fib_index, prefix, + MFIB_SOURCE_API, + &path, itf_flags); } else { @@ -1253,12 +1263,14 @@ mroute_add_del_handler (u8 is_add, done: stats_dsunlock (); - return (0); + return (mfib_entry_index); } static int -api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) +api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp, + u32 * stats_index) { + fib_node_index_t mfib_entry_index; fib_protocol_t fproto; dpo_proto_t nh_proto; ip46_address_t nh; @@ -1288,6 +1300,8 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) sizeof (pfx.fp_src_addr.ip4)); memset (&nh.ip6, 0, sizeof (nh.ip6)); clib_memcpy (&nh.ip4, mp->nh_address, sizeof (nh.ip4)); + if (!ip46_address_is_zero (&pfx.fp_src_addr)) + pfx.fp_len = 64; } else { @@ -1296,34 +1310,47 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address, sizeof (pfx.fp_src_addr.ip6)); clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6)); + if (!ip46_address_is_zero (&pfx.fp_src_addr)) + pfx.fp_len = 256; } - return (mroute_add_del_handler (mp->is_add, - mp->is_local, - fib_index, &pfx, - nh_proto, - ntohl (mp->entry_flags), - ntohl (mp->rpf_id), - ntohl (mp->next_hop_sw_if_index), - &nh, - ntohl (mp->itf_flags), - ntohl (mp->bier_imp))); + mfib_entry_index = mroute_add_del_handler (mp->is_add, + mp->is_local, + fib_index, &pfx, + nh_proto, + ntohl (mp->entry_flags), + ntohl (mp->rpf_id), + ntohl (mp->next_hop_sw_if_index), + &nh, + ntohl (mp->itf_flags), + ntohl (mp->bier_imp)); + + if (~0 != mfib_entry_index) + *stats_index = mfib_entry_get_stats_index (mfib_entry_index); + + return (rv); } void vl_api_ip_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) { vl_api_ip_mroute_add_del_reply_t *rmp; + vnet_main_t *vnm; + u32 stats_index; int rv; - vnet_main_t *vnm = vnet_get_main (); + vnm = vnet_get_main (); vnm->api_errno = 0; + stats_index = ~0; - rv = api_mroute_add_del_t_handler (mp); - - rv = (rv == 0) ? vnm->api_errno : rv; + rv = api_mroute_add_del_t_handler (mp, &stats_index); - REPLY_MACRO (VL_API_IP_MROUTE_ADD_DEL_REPLY); + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY, + ({ + rmp->stats_index = htonl (stats_index); + })); + /* *INDENT-ON* */ } static void @@ -1424,6 +1451,7 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) })); /* *INDENT-ON* */ } + BAD_SW_IF_INDEX_LABEL; } @@ -1690,7 +1718,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); @@ -1711,11 +1739,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)); } @@ -1918,6 +1946,53 @@ static void REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY); } +typedef struct ip_container_proxy_walk_ctx_t_ +{ + vl_api_registration_t *reg; + u32 context; +} ip_container_proxy_walk_ctx_t; + +static int +ip_container_proxy_send_details (const fib_prefix_t * pfx, u32 sw_if_index, + void *args) +{ + vl_api_ip_container_proxy_details_t *mp; + ip_container_proxy_walk_ctx_t *ctx = args; + + mp = vl_msg_api_alloc (sizeof (*mp)); + if (!mp) + return 1; + + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS); + mp->context = ctx->context; + + mp->sw_if_index = ntohl (sw_if_index); + ip_prefix_encode (pfx, &mp->prefix); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return 1; +} + +static void +vl_api_ip_container_proxy_dump_t_handler (vl_api_ip_container_proxy_dump_t * + mp) +{ + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + ip_container_proxy_walk_ctx_t ctx = { + .context = mp->context, + .reg = reg, + }; + + ip_container_proxy_walk (ip_container_proxy_send_details, &ctx); +} + static void vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp) { @@ -2463,7 +2538,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); @@ -2993,10 +3069,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) {