#include <vnet/interface.h>
#include <vnet/api_errno.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/ethernet_types_api.h>
#include <vnet/ip/ip.h>
-#include <vnet/ip/ip6_neighbor.h>
+#include <vnet/ip/ip_types_api.h>
+#include <vnet/ip/ip_punt_drop.h>
+#include <vnet/ip/ip_types_api.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_api.h>
-#include <vnet/dpo/drop_dpo.h>
-#include <vnet/dpo/receive_dpo.h>
-#include <vnet/dpo/lookup_dpo.h>
-#include <vnet/dpo/classify_dpo.h>
-#include <vnet/dpo/ip_null_dpo.h>
#include <vnet/ethernet/arp_packet.h>
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/mfib/ip4_mfib.h>
#include <vnet/mfib/mfib_signal.h>
#include <vnet/mfib/mfib_entry.h>
+#include <vnet/mfib/mfib_api.h>
+#include <vnet/ip/ip_source_and_port_range_check.h>
+#include <vnet/fib/ip4_fib.h>
+#include <vnet/fib/ip6_fib.h>
+#include <vnet/fib/fib_path_list.h>
+#include <vnet/ip/ip6_hop_by_hop.h>
+#include <vnet/ip/ip6_link.h>
+#include <vnet/ip/reass/ip4_sv_reass.h>
+#include <vnet/ip/reass/ip4_full_reass.h>
+#include <vnet/ip/reass/ip6_sv_reass.h>
+#include <vnet/ip/reass/ip6_full_reass.h>
#include <vnet/vnet_msg_enum.h>
#include <vlibapi/api_helper_macros.h>
+#include <vnet/format_fns.h>
#define foreach_ip_api_msg \
-_(IP_FIB_DUMP, ip_fib_dump) \
-_(IP6_FIB_DUMP, ip6_fib_dump) \
-_(IP_MFIB_DUMP, ip_mfib_dump) \
-_(IP6_MFIB_DUMP, ip6_mfib_dump) \
-_(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
+_(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable) \
+_(IP_TABLE_DUMP, ip_table_dump) \
+_(IP_ROUTE_DUMP, ip_route_dump) \
+_(IP_MTABLE_DUMP, ip_mtable_dump) \
+_(IP_MROUTE_DUMP, ip_mroute_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) \
-_(IP_ADD_DEL_ROUTE, ip_add_del_route) \
+_(IP_TABLE_REPLACE_BEGIN, ip_table_replace_begin) \
+_(IP_TABLE_REPLACE_END, ip_table_replace_end) \
+_(IP_TABLE_FLUSH, ip_table_flush) \
+_(IP_ROUTE_ADD_DEL, ip_route_add_del) \
+_(IP_TABLE_ADD_DEL, ip_table_add_del) \
+_(IP_PUNT_POLICE, ip_punt_police) \
+_(IP_PUNT_REDIRECT, ip_punt_redirect) \
_(SET_IP_FLOW_HASH,set_ip_flow_hash) \
-_(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
-_(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
-_(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
-_(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
-_(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
-_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
- sw_interface_ip6_set_link_local_address)
-
-extern void stats_dslock_with_hint (int hint, int tag);
-extern void stats_dsunlock (void);
-
-static void
-send_ip_neighbor_details (u8 is_ipv6,
- u8 is_static,
- u8 * mac_address,
- u8 * ip_address,
- unix_shared_memory_queue_t * q, u32 context)
-{
- vl_api_ip_neighbor_details_t *mp;
-
- mp = vl_msg_api_alloc (sizeof (*mp));
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
- mp->context = context;
- mp->is_ipv6 = is_ipv6;
- mp->is_static = is_static;
- memcpy (mp->mac_address, mac_address, 6);
- memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
-
- vl_msg_api_send_shmem (q, (u8 *) & mp);
-}
+_(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, \
+ ip_source_and_port_range_check_add_del) \
+_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
+ ip_source_and_port_range_check_interface_add_del) \
+_(IP_SOURCE_CHECK_INTERFACE_ADD_DEL, \
+ ip_source_check_interface_add_del) \
+ _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
+ sw_interface_ip6_set_link_local_address) \
+_(IP_REASSEMBLY_SET, ip_reassembly_set) \
+_(IP_REASSEMBLY_GET, ip_reassembly_get) \
+_(IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable) \
+_(IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)
static void
-vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
+ vl_api_sw_interface_ip6_enable_disable_t_handler
+ (vl_api_sw_interface_ip6_enable_disable_t * mp)
{
- unix_shared_memory_queue_t *q;
-
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
-
- u32 sw_if_index = ntohl (mp->sw_if_index);
-
- if (mp->is_ipv6)
- {
- ip6_neighbor_t *n, *ns;
-
- ns = ip6_neighbors_entries (sw_if_index);
- /* *INDENT-OFF* */
- vec_foreach (n, ns)
- {
- send_ip_neighbor_details
- (mp->is_ipv6, ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0),
- (u8 *) n->link_layer_address,
- (u8 *) & (n->key.ip6_address.as_u8),
- q, mp->context);
- }
- /* *INDENT-ON* */
- vec_free (ns);
- }
- else
- {
- ethernet_arp_ip4_entry_t *n, *ns;
+ vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
+ int rv = 0;
- ns = ip4_neighbor_entries (sw_if_index);
- /* *INDENT-OFF* */
- vec_foreach (n, ns)
- {
- send_ip_neighbor_details (mp->is_ipv6,
- ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0),
- (u8*) n->ethernet_address,
- (u8*) & (n->ip4_address.as_u8),
- q, mp->context);
- }
- /* *INDENT-ON* */
- vec_free (ns);
- }
-}
+ VALIDATE_SW_IF_INDEX (mp);
+ rv = ((mp->enable == 1) ?
+ ip6_link_enable (ntohl (mp->sw_if_index)) :
+ ip6_link_disable (ntohl (mp->sw_if_index)));
-void
-copy_fib_next_hop (fib_route_path_encode_t * api_rpath, void *fp_arg)
-{
- int is_ip4;
- vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
+ BAD_SW_IF_INDEX_LABEL;
- if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
- if (fp->afi == IP46_TYPE_IP4)
- memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
- sizeof (api_rpath->rpath.frp_addr.ip4));
- else
- memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
- sizeof (api_rpath->rpath.frp_addr.ip6));
+ REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
}
static void
-send_ip_fib_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- u32 table_id, fib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
+send_ip_table_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, const fib_table_t * table)
{
- vl_api_ip_fib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
- vl_api_fib_path_t *fp;
- int path_count;
+ vl_api_ip_table_details_t *mp;
- path_count = vec_len (api_rpaths);
- mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
+ mp = vl_msg_api_alloc (sizeof (*mp));
if (!mp)
return;
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_TABLE_DETAILS);
mp->context = context;
- mp->table_id = htonl (table_id);
- mp->address_length = pfx->fp_len;
- memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
-
- mp->count = htonl (path_count);
- fp = mp->path;
- vec_foreach (api_rpath, api_rpaths)
- {
- memset (fp, 0, sizeof (*fp));
- switch (api_rpath->dpo.dpoi_type)
- {
- case DPO_RECEIVE:
- fp->is_local = true;
- break;
- case DPO_DROP:
- fp->is_drop = true;
- break;
- case DPO_IP_NULL:
- switch (api_rpath->dpo.dpoi_index)
- {
- case IP_NULL_ACTION_NONE:
- fp->is_drop = true;
- break;
- case IP_NULL_ACTION_SEND_ICMP_UNREACH:
- fp->is_unreach = true;
- break;
- case IP_NULL_ACTION_SEND_ICMP_PROHIBIT:
- fp->is_prohibit = true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- fp->weight = api_rpath->rpath.frp_weight;
- fp->preference = api_rpath->rpath.frp_preference;
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- copy_fib_next_hop (api_rpath, fp);
- fp++;
- }
-
- vl_msg_api_send_shmem (q, (u8 *) & mp);
-}
-
-typedef struct vl_api_ip_fib_dump_walk_ctx_t_
-{
- fib_node_index_t *feis;
-} vl_api_ip_fib_dump_walk_ctx_t;
-
-static int
-vl_api_ip_fib_dump_walk (fib_node_index_t fei, void *arg)
-{
- vl_api_ip_fib_dump_walk_ctx_t *ctx = arg;
-
- vec_add1 (ctx->feis, fei);
+ mp->table.is_ip6 = (table->ft_proto == FIB_PROTOCOL_IP6);
+ mp->table.table_id = htonl (table->ft_table_id);
+ memcpy (mp->table.name, table->ft_desc,
+ clib_min (vec_len (table->ft_desc), sizeof (mp->table.name)));
- return (1);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
-vl_api_ip_fib_dump_t_handler (vl_api_ip_fib_dump_t * mp)
+vl_api_ip_table_dump_t_handler (vl_api_ip_table_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
- unix_shared_memory_queue_t *q;
- ip4_main_t *im = &ip4_main;
+ vl_api_registration_t *reg;
fib_table_t *fib_table;
- fib_node_index_t *lfeip;
- fib_prefix_t pfx;
- u32 fib_index;
- fib_route_path_encode_t *api_rpaths;
- vl_api_ip_fib_dump_walk_ctx_t ctx = {
- .feis = NULL,
- };
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
return;
/* *INDENT-OFF* */
- pool_foreach (fib_table, im->fibs,
+ pool_foreach (fib_table, ip4_main.fibs,
+ ({
+ send_ip_table_details(am, reg, mp->context, fib_table);
+ }));
+ pool_foreach (fib_table, ip6_main.fibs,
({
- fib_table_walk(fib_table->ft_index,
- FIB_PROTOCOL_IP4,
- vl_api_ip_fib_dump_walk,
- &ctx);
+ /* don't send link locals */
+ if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
+ continue;
+ send_ip_table_details(am, reg, mp->context, fib_table);
}));
/* *INDENT-ON* */
+}
- vec_sort_with_function (ctx.feis, fib_entry_cmp_for_sort);
+typedef struct vl_api_ip_fib_dump_walk_ctx_t_
+{
+ fib_node_index_t *feis;
+} vl_api_ip_fib_dump_walk_ctx_t;
- vec_foreach (lfeip, ctx.feis)
- {
- fib_entry_get_prefix (*lfeip, &pfx);
- fib_index = fib_entry_get_fib_index (*lfeip);
- fib_table = fib_table_get (fib_index, pfx.fp_proto);
- api_rpaths = NULL;
- fib_entry_encode (*lfeip, &api_rpaths);
- send_ip_fib_details (am, q,
- fib_table->ft_table_id, &pfx, api_rpaths,
- mp->context);
- vec_free (api_rpaths);
- }
+static fib_table_walk_rc_t
+vl_api_ip_fib_dump_walk (fib_node_index_t fei, void *arg)
+{
+ vl_api_ip_fib_dump_walk_ctx_t *ctx = arg;
- vec_free (ctx.feis);
+ vec_add1 (ctx->feis, fei);
+
+ return (FIB_TABLE_WALK_CONTINUE);
}
static void
-send_ip6_fib_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- u32 table_id, fib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
+send_ip_route_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, fib_node_index_t fib_entry_index)
{
- vl_api_ip6_fib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
+ fib_route_path_t *rpaths, *rpath;
+ vl_api_ip_route_details_t *mp;
+ const fib_prefix_t *pfx;
vl_api_fib_path_t *fp;
int path_count;
- path_count = vec_len (api_rpaths);
+ rpaths = NULL;
+ pfx = fib_entry_get_prefix (fib_entry_index);
+ rpaths = fib_entry_encode (fib_entry_index);
+
+ path_count = vec_len (rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
if (!mp)
return;
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_ROUTE_DETAILS);
mp->context = context;
- mp->table_id = htonl (table_id);
- mp->address_length = pfx->fp_len;
- memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
-
- mp->count = htonl (path_count);
- fp = mp->path;
- vec_foreach (api_rpath, api_rpaths)
+ ip_prefix_encode (pfx, &mp->route.prefix);
+ mp->route.table_id =
+ htonl (fib_table_get_table_id
+ (fib_entry_get_fib_index (fib_entry_index), pfx->fp_proto));
+ mp->route.n_paths = path_count;
+ mp->route.stats_index =
+ htonl (fib_table_entry_get_stats_index
+ (fib_entry_get_fib_index (fib_entry_index), pfx));
+
+ fp = mp->route.paths;
+ vec_foreach (rpath, rpaths)
{
- memset (fp, 0, sizeof (*fp));
- switch (api_rpath->dpo.dpoi_type)
- {
- case DPO_RECEIVE:
- fp->is_local = true;
- break;
- case DPO_DROP:
- fp->is_drop = true;
- break;
- case DPO_IP_NULL:
- switch (api_rpath->dpo.dpoi_index)
- {
- case IP_NULL_DPO_ACTION_NUM + IP_NULL_ACTION_NONE:
- fp->is_drop = true;
- break;
- case IP_NULL_DPO_ACTION_NUM + IP_NULL_ACTION_SEND_ICMP_UNREACH:
- fp->is_unreach = true;
- break;
- case IP_NULL_DPO_ACTION_NUM + IP_NULL_ACTION_SEND_ICMP_PROHIBIT:
- fp->is_prohibit = true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- fp->weight = api_rpath->rpath.frp_weight;
- fp->preference = api_rpath->rpath.frp_preference;
- fp->sw_if_index = api_rpath->rpath.frp_sw_if_index;
- copy_fib_next_hop (api_rpath, fp);
+ fib_api_path_encode (rpath, fp);
fp++;
}
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
+ vec_free (rpaths);
}
typedef struct apt_ip6_fib_show_ctx_t_
{
- u32 fib_index;
fib_node_index_t *entries;
} api_ip6_fib_show_ctx_t;
static void
-api_ip6_fib_table_put_entries (clib_bihash_kv_24_8_t * kvp, void *arg)
-{
- api_ip6_fib_show_ctx_t *ctx = arg;
-
- if ((kvp->key[2] >> 32) == ctx->fib_index)
- {
- vec_add1 (ctx->entries, kvp->value);
- }
-}
-
-static void
-api_ip6_fib_table_get_all (unix_shared_memory_queue_t * q,
- vl_api_ip6_fib_dump_t * mp,
- fib_table_t * fib_table)
+vl_api_ip_route_dump_t_handler (vl_api_ip_route_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
- ip6_main_t *im6 = &ip6_main;
fib_node_index_t *fib_entry_index;
- api_ip6_fib_show_ctx_t ctx = {
- .fib_index = fib_table->ft_index,
- .entries = NULL,
- };
- fib_route_path_encode_t *api_rpaths;
- fib_prefix_t pfx;
+ vl_api_registration_t *reg;
+ fib_protocol_t fproto;
+ u32 fib_index;
- BV (clib_bihash_foreach_key_value_pair)
- ((BVT (clib_bihash) *) & im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].
- ip6_hash, api_ip6_fib_table_put_entries, &ctx);
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
- vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);
+ vl_api_ip_fib_dump_walk_ctx_t ctx = {
+ .feis = NULL,
+ };
- vec_foreach (fib_entry_index, ctx.entries)
- {
- fib_entry_get_prefix (*fib_entry_index, &pfx);
- api_rpaths = NULL;
- fib_entry_encode (*fib_entry_index, &api_rpaths);
- send_ip6_fib_details (am, q,
- fib_table->ft_table_id,
- &pfx, api_rpaths, mp->context);
- vec_free (api_rpaths);
- }
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
- vec_free (ctx.entries);
-}
+ if (INDEX_INVALID == fib_index)
+ return;
-static void
-vl_api_ip6_fib_dump_t_handler (vl_api_ip6_fib_dump_t * mp)
-{
- unix_shared_memory_queue_t *q;
- ip6_main_t *im6 = &ip6_main;
- fib_table_t *fib_table;
+ fib_table_walk (fib_index, fproto, vl_api_ip_fib_dump_walk, &ctx);
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ vec_foreach (fib_entry_index, ctx.feis)
+ {
+ send_ip_route_details (am, reg, mp->context, *fib_entry_index);
+ }
- /* *INDENT-OFF* */
- pool_foreach (fib_table, im6->fibs,
- ({
- api_ip6_fib_table_get_all(q, mp, fib_table);
- }));
- /* *INDENT-ON* */
+ vec_free (ctx.feis);
}
static void
-send_ip_mfib_details (unix_shared_memory_queue_t * q,
- u32 context, u32 table_id, fib_node_index_t mfei)
+send_ip_mtable_details (vl_api_registration_t * reg,
+ u32 context, const mfib_table_t * mfib_table)
{
- fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
- vl_api_ip_mfib_details_t *mp;
- mfib_entry_t *mfib_entry;
- vl_api_fib_path_t *fp;
- mfib_prefix_t pfx;
- int path_count;
-
- mfib_entry = mfib_entry_get (mfei);
- mfib_entry_get_prefix (mfei, &pfx);
- mfib_entry_encode (mfei, &api_rpaths);
+ vl_api_ip_mtable_details_t *mp;
- path_count = vec_len (api_rpaths);
- mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
+ mp = vl_msg_api_alloc (sizeof (*mp));
if (!mp)
return;
memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_IP_MTABLE_DETAILS);
mp->context = context;
- mp->rpf_id = mfib_entry->mfe_rpf_id;
- mp->entry_flags = mfib_entry->mfe_flags;
- mp->table_id = htonl (table_id);
- mp->address_length = pfx.fp_len;
- memcpy (mp->grp_address, &pfx.fp_grp_addr.ip4,
- sizeof (pfx.fp_grp_addr.ip4));
- memcpy (mp->src_address, &pfx.fp_src_addr.ip4,
- sizeof (pfx.fp_src_addr.ip4));
-
- mp->count = htonl (path_count);
- fp = mp->path;
- vec_foreach (api_rpath, api_rpaths)
- {
- memset (fp, 0, sizeof (*fp));
-
- fp->weight = 0;
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- copy_fib_next_hop (api_rpath, fp);
- fp++;
- }
- vec_free (api_rpaths);
-
- vl_msg_api_send_shmem (q, (u8 *) & mp);
-}
-
-typedef struct vl_api_ip_mfib_dump_ctc_t_
-{
- fib_node_index_t *entries;
-} vl_api_ip_mfib_dump_ctc_t;
-
-static int
-vl_api_ip_mfib_table_dump_walk (fib_node_index_t fei, void *arg)
-{
- vl_api_ip_mfib_dump_ctc_t *ctx = arg;
-
- vec_add1 (ctx->entries, fei);
+ mp->table.table_id = htonl (mfib_table->mft_table_id);
+ mp->table.is_ip6 = (FIB_PROTOCOL_IP6 == mfib_table->mft_proto);
- return (0);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
-vl_api_ip_mfib_dump_t_handler (vl_api_ip_mfib_dump_t * mp)
+vl_api_ip_mtable_dump_t_handler (vl_api_ip_mtable_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
- ip4_main_t *im = &ip4_main;
+ vl_api_registration_t *reg;
mfib_table_t *mfib_table;
- fib_node_index_t *mfeip;
- vl_api_ip_mfib_dump_ctc_t ctx = {
- .entries = NULL,
- };
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
return;
-
/* *INDENT-OFF* */
- pool_foreach (mfib_table, im->mfibs,
+ pool_foreach (mfib_table, ip4_main.mfibs,
+ ({
+ send_ip_mtable_details (reg, mp->context, mfib_table);
+ }));
+ pool_foreach (mfib_table, ip6_main.mfibs,
({
- ip4_mfib_table_walk(&mfib_table->v4,
- vl_api_ip_mfib_table_dump_walk,
- &ctx);
+ send_ip_mtable_details (reg, mp->context, mfib_table);
+ }));
+ /* *INDENT-ON* */
+}
- vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
+typedef struct vl_api_ip_mfib_dump_ctx_t_
+{
+ fib_node_index_t *entries;
+} vl_api_ip_mfib_dump_ctx_t;
- vec_foreach (mfeip, ctx.entries)
- {
- send_ip_mfib_details (q, mp->context,
- mfib_table->mft_table_id,
- *mfeip);
- }
- vec_reset_length (ctx.entries);
+static walk_rc_t
+mfib_route_dump_walk (fib_node_index_t fei, void *arg)
+{
+ vl_api_ip_mfib_dump_ctx_t *ctx = arg;
- }));
- /* *INDENT-ON* */
+ vec_add1 (ctx->entries, fei);
- vec_free (ctx.entries);
+ return (WALK_CONTINUE);
}
static void
-send_ip6_mfib_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- u32 table_id,
- mfib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
+send_ip_mroute_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, fib_node_index_t mfib_entry_index)
{
- vl_api_ip6_mfib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
- vl_api_fib_path_t *fp;
+ fib_route_path_t *rpaths, *rpath;
+ vl_api_ip_mroute_details_t *mp;
+ const mfib_prefix_t *pfx;
+ vl_api_mfib_path_t *fp;
int path_count;
- path_count = vec_len (api_rpaths);
+ rpaths = NULL;
+ pfx = mfib_entry_get_prefix (mfib_entry_index);
+ rpaths = mfib_entry_encode (mfib_entry_index);
+
+ path_count = vec_len (rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
if (!mp)
return;
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_MROUTE_DETAILS);
mp->context = context;
- mp->table_id = htonl (table_id);
- mp->address_length = pfx->fp_len;
- memcpy (mp->grp_address, &pfx->fp_grp_addr.ip6,
- sizeof (pfx->fp_grp_addr.ip6));
- memcpy (mp->src_address, &pfx->fp_src_addr.ip6,
- sizeof (pfx->fp_src_addr.ip6));
-
- mp->count = htonl (path_count);
- fp = mp->path;
- vec_foreach (api_rpath, api_rpaths)
+ ip_mprefix_encode (pfx, &mp->route.prefix);
+ mp->route.table_id =
+ htonl (mfib_table_get_table_id
+ (mfib_entry_get_fib_index (mfib_entry_index), pfx->fp_proto));
+ mp->route.n_paths = htonl (path_count);
+ fp = mp->route.paths;
+ vec_foreach (rpath, rpaths)
{
- memset (fp, 0, sizeof (*fp));
-
- fp->weight = 0;
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- copy_fib_next_hop (api_rpath, fp);
+ mfib_api_path_encode (rpath, fp);
fp++;
}
- vl_msg_api_send_shmem (q, (u8 *) & mp);
-}
-
-typedef struct vl_api_ip6_mfib_dump_ctc_t_
-{
- fib_node_index_t *entries;
-} vl_api_ip6_mfib_dump_ctc_t;
-
-static int
-vl_api_ip6_mfib_table_dump_walk (fib_node_index_t fei, void *arg)
-{
- vl_api_ip6_mfib_dump_ctc_t *ctx = arg;
-
- vec_add1 (ctx->entries, fei);
-
- return (0);
+ vl_api_send_msg (reg, (u8 *) mp);
+ vec_free (rpaths);
}
static void
-vl_api_ip6_mfib_dump_t_handler (vl_api_ip6_mfib_dump_t * mp)
+vl_api_ip_mroute_dump_t_handler (vl_api_ip_mroute_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
- unix_shared_memory_queue_t *q;
- ip6_main_t *im = &ip6_main;
- mfib_table_t *mfib_table;
+ vl_api_registration_t *reg;
fib_node_index_t *mfeip;
- mfib_prefix_t pfx;
- fib_route_path_encode_t *api_rpaths = NULL;
- vl_api_ip6_mfib_dump_ctc_t ctx = {
+ fib_protocol_t fproto;
+ u32 fib_index;
+
+ vl_api_ip_mfib_dump_ctx_t ctx = {
.entries = NULL,
};
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
return;
+ fproto = fib_ip_proto (mp->table.is_ip6);
+ fib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));
- /* *INDENT-OFF* */
- pool_foreach (mfib_table, im->mfibs,
- ({
- ip6_mfib_table_walk(&mfib_table->v6,
- vl_api_ip6_mfib_table_dump_walk,
- &ctx);
+ if (INDEX_INVALID == fib_index)
+ return;
- vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
+ mfib_table_walk (fib_index, fproto, mfib_route_dump_walk, &ctx);
- vec_foreach(mfeip, ctx.entries)
- {
- mfib_entry_get_prefix (*mfeip, &pfx);
- mfib_entry_encode (*mfeip, &api_rpaths);
- send_ip6_mfib_details (am, q,
- mfib_table->mft_table_id,
- &pfx, api_rpaths,
- mp->context);
- }
- vec_reset_length (api_rpaths);
- vec_reset_length (ctx.entries);
+ vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
- }));
- /* *INDENT-ON* */
+ vec_foreach (mfeip, ctx.entries)
+ {
+ send_ip_mroute_details (am, reg, mp->context, *mfeip);
+ }
vec_free (ctx.entries);
- vec_free (api_rpaths);
}
static void
-vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
- vlib_main_t * vm)
+vl_api_ip_punt_police_t_handler (vl_api_ip_punt_police_t * mp,
+ vlib_main_t * vm)
{
- vl_api_ip_neighbor_add_del_reply_t *rmp;
- vnet_main_t *vnm = vnet_get_main ();
+ vl_api_ip_punt_police_reply_t *rmp;
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.
- */
- 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));
- }
+ if (mp->is_ip6)
+ ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
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);
-
- 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);
- }
+ ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
- BAD_SW_IF_INDEX_LABEL;
-
- stats_dsunlock ();
- REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
+ REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
}
-int
-add_del_route_t_handler (u8 is_multipath,
- u8 is_add,
- u8 is_drop,
- u8 is_unreach,
- u8 is_prohibit,
- u8 is_local,
- u8 is_multicast,
- u8 is_classify,
- u32 classify_table_index,
- u8 is_resolve_host,
- u8 is_resolve_attached,
- u8 is_interface_rx,
- u8 is_rpf_id,
- u32 fib_index,
- const fib_prefix_t * prefix,
- dpo_proto_t next_hop_proto,
- const ip46_address_t * next_hop,
- u32 next_hop_sw_if_index,
- u8 next_hop_fib_index,
- u16 next_hop_weight,
- u16 next_hop_preference,
- mpls_label_t next_hop_via_label,
- mpls_label_t * next_hop_out_label_stack)
+static void
+vl_api_ip_punt_redirect_t_handler (vl_api_ip_punt_redirect_t * mp,
+ vlib_main_t * vm)
{
- vnet_classify_main_t *cm = &vnet_classify_main;
- fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
- fib_route_path_t path = {
- .frp_proto = next_hop_proto,
- .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_fib_index = next_hop_fib_index,
- .frp_weight = next_hop_weight,
- .frp_preference = next_hop_preference,
- .frp_label_stack = next_hop_out_label_stack,
- };
- fib_route_path_t *paths = NULL;
- fib_entry_flag_t entry_flags = FIB_ENTRY_FLAG_NONE;
-
- if (MPLS_LABEL_INVALID != next_hop_via_label)
- {
- path.frp_proto = DPO_PROTO_MPLS;
- path.frp_local_label = next_hop_via_label;
- path.frp_eos = MPLS_NON_EOS;
- }
- if (is_resolve_host)
- path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
- if (is_resolve_attached)
- path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
- if (is_interface_rx)
- path_flags |= FIB_ROUTE_PATH_INTF_RX;
- if (is_rpf_id)
- path_flags |= FIB_ROUTE_PATH_RPF_ID;
- if (is_multicast)
- entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
-
- 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;
- }
+ vl_api_ip_punt_redirect_reply_t *rmp;
+ int rv = 0;
+ ip46_type_t ipv;
+ ip46_address_t nh;
- stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
+ if (!vnet_sw_if_index_is_api_valid (ntohl (mp->punt.tx_sw_if_index)))
+ goto bad_sw_if_index;
- if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
+ ipv = ip_address_decode (&mp->punt.nh, &nh);
+ if (mp->is_add)
{
- /*
- * special route types that link directly to the adj
- */
- if (is_add)
+ if (ipv == IP46_TYPE_IP6)
{
- dpo_id_t dpo = DPO_INVALID;
- dpo_proto_t dproto;
-
- dproto = fib_proto_to_dpo (prefix->fp_proto);
-
- if (is_drop)
- ip_null_dpo_add_and_lock (dproto, IP_NULL_ACTION_NONE, &dpo);
- else if (is_local)
- receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
- else if (is_unreach)
- ip_null_dpo_add_and_lock (dproto,
- IP_NULL_ACTION_SEND_ICMP_UNREACH, &dpo);
- else if (is_prohibit)
- ip_null_dpo_add_and_lock (dproto,
- IP_NULL_ACTION_SEND_ICMP_PROHIBIT,
- &dpo);
- else if (is_classify)
- {
- if (pool_is_free_index (cm->tables,
- ntohl (classify_table_index)))
- {
- stats_dsunlock ();
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
-
- dpo_set (&dpo, DPO_CLASSIFY, dproto,
- classify_dpo_create (dproto,
- ntohl (classify_table_index)));
- }
- else
- {
- stats_dsunlock ();
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
-
- fib_table_entry_special_dpo_update (fib_index,
- prefix,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
- dpo_reset (&dpo);
+ ip6_punt_redirect_add (ntohl (mp->punt.rx_sw_if_index),
+ ntohl (mp->punt.tx_sw_if_index), &nh);
}
- else
+ else if (ipv == IP46_TYPE_IP4)
{
- fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
+ ip4_punt_redirect_add (ntohl (mp->punt.rx_sw_if_index),
+ ntohl (mp->punt.tx_sw_if_index), &nh);
}
}
else
{
- if (is_add)
+ if (ipv == IP46_TYPE_IP6)
{
- vec_add1 (paths, path);
- fib_table_entry_update (fib_index,
- prefix, FIB_SOURCE_API, entry_flags, paths);
- vec_free (paths);
+ ip6_punt_redirect_del (ntohl (mp->punt.rx_sw_if_index));
}
- else
+ else if (ipv == IP46_TYPE_IP4)
{
- fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
+ ip4_punt_redirect_del (ntohl (mp->punt.rx_sw_if_index));
}
}
- stats_dsunlock ();
- return (0);
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
}
-int
-add_del_route_check (fib_protocol_t table_proto,
- u32 table_id,
- u32 next_hop_sw_if_index,
- dpo_proto_t next_hop_table_proto,
- u32 next_hop_table_id,
- u8 create_missing_tables,
- u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
+void
+ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
{
- vnet_main_t *vnm = vnet_get_main ();
+ u32 fib_index, mfib_index;
- *fib_index = fib_table_find (table_proto, ntohl (table_id));
- if (~0 == *fib_index)
+ /*
+ * ignore action on the default table - this is always present
+ * and cannot be added nor deleted from the API
+ */
+ if (0 != table_id)
{
- if (create_missing_tables)
+ /*
+ * The API holds only one lock on the table.
+ * i.e. it can be added many times via the API but needs to be
+ * deleted only once.
+ * The FIB index for unicast and multicast is not necessarily the
+ * same, since internal VPP systesm (like LISP and SR) create
+ * their own unicast tables.
+ */
+ fib_index = fib_table_find (fproto, table_id);
+ mfib_index = mfib_table_find (fproto, table_id);
+
+ if (~0 != fib_index)
{
- *fib_index = fib_table_find_or_create_and_lock (table_proto,
- ntohl (table_id));
+ fib_table_unlock (fib_index, fproto,
+ (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
}
- else
+ if (~0 != mfib_index)
{
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
+ mfib_table_unlock (mfib_index, fproto,
+ (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
}
}
+}
- if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
- {
- if (pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (next_hop_sw_if_index)))
- {
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
- }
+void
+vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
+{
+ vl_api_ip_table_add_del_reply_t *rmp;
+ fib_protocol_t fproto = (mp->table.is_ip6 ?
+ FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ u32 table_id = ntohl (mp->table.table_id);
+ int rv = 0;
+
+ if (mp->is_add)
+ {
+ ip_table_create (fproto, table_id, 1, mp->table.name);
}
else
{
- fib_protocol_t fib_nh_proto;
-
- if (next_hop_table_proto > DPO_PROTO_MPLS)
- return (0);
-
- fib_nh_proto = dpo_proto_to_fib (next_hop_table_proto);
-
- if (is_rpf_id)
- *next_hop_fib_index = mfib_table_find (fib_nh_proto,
- ntohl (next_hop_table_id));
- else
- *next_hop_fib_index = fib_table_find (fib_nh_proto,
- ntohl (next_hop_table_id));
-
- if (~0 == *next_hop_fib_index)
- {
- if (create_missing_tables)
- {
- if (is_rpf_id)
- *next_hop_fib_index =
- mfib_table_find_or_create_and_lock (fib_nh_proto,
- ntohl
- (next_hop_table_id));
- else
- *next_hop_fib_index =
- fib_table_find_or_create_and_lock (fib_nh_proto,
- ntohl
- (next_hop_table_id));
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
+ ip_table_delete (fproto, table_id, 1);
}
- return (0);
+ REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
}
static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp, u32 * stats_index)
{
- u32 fib_index, next_hop_fib_index;
- mpls_label_t *label_stack = NULL;
- int rv, ii, n_labels;;
-
- rv = add_del_route_check (FIB_PROTOCOL_IP4,
- mp->table_id,
- mp->next_hop_sw_if_index,
- DPO_PROTO_IP4,
- mp->next_hop_table_id,
- mp->create_vrf_if_needed, 0,
- &fib_index, &next_hop_fib_index);
+ fib_route_path_t *rpaths = NULL, *rpath;
+ fib_entry_flag_t entry_flags;
+ vl_api_fib_path_t *apath;
+ fib_prefix_t pfx;
+ u32 fib_index;
+ int rv, ii;
- if (0 != rv)
- return (rv);
+ entry_flags = FIB_ENTRY_FLAG_NONE;
+ ip_prefix_decode (&mp->route.prefix, &pfx);
- fib_prefix_t pfx = {
- .fp_len = mp->dst_address_length,
- .fp_proto = FIB_PROTOCOL_IP4,
- };
- clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
+ rv = fib_api_table_id_decode (pfx.fp_proto,
+ ntohl (mp->route.table_id), &fib_index);
+ if (0 != rv)
+ goto out;
- ip46_address_t nh;
- memset (&nh, 0, sizeof (nh));
- memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+ if (0 != mp->route.n_paths)
+ vec_validate (rpaths, mp->route.n_paths - 1);
- n_labels = mp->next_hop_n_out_labels;
- if (n_labels == 0)
- ;
- else if (1 == n_labels)
- vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
- else
+ for (ii = 0; ii < mp->route.n_paths; ii++)
{
- vec_validate (label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
- }
+ apath = &mp->route.paths[ii];
+ rpath = &rpaths[ii];
- 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,
- fib_index, &pfx, DPO_PROTO_IP4,
- &nh,
- 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 = fib_api_path_decode (apath, rpath);
-static int
-ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
-{
- u32 fib_index, next_hop_fib_index;
- mpls_label_t *label_stack = NULL;
- int rv, ii, n_labels;;
-
- rv = add_del_route_check (FIB_PROTOCOL_IP6,
- mp->table_id,
- mp->next_hop_sw_if_index,
- DPO_PROTO_IP6,
- mp->next_hop_table_id,
- mp->create_vrf_if_needed, 0,
- &fib_index, &next_hop_fib_index);
+ if ((rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
+ (~0 == rpath->frp_sw_if_index))
+ entry_flags |= (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL);
- if (0 != rv)
- return (rv);
+ if (0 != rv)
+ goto out;
+ }
- fib_prefix_t pfx = {
- .fp_len = mp->dst_address_length,
- .fp_proto = FIB_PROTOCOL_IP6,
- };
- clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
+ rv = fib_api_route_add_del (mp->is_add,
+ mp->is_multipath,
+ fib_index, &pfx, entry_flags, rpaths);
- ip46_address_t nh;
- memset (&nh, 0, sizeof (nh));
- memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+ if (mp->is_add && 0 == rv)
+ *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
- n_labels = mp->next_hop_n_out_labels;
- if (n_labels == 0)
- ;
- else if (1 == n_labels)
- vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
- else
- {
- vec_validate (label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
- }
+out:
+ vec_free (rpaths);
- 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,
- fib_index, &pfx, DPO_PROTO_IP6,
- &nh, 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));
+ return (rv);
}
void
-vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+vl_api_ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp)
{
- vl_api_ip_add_del_route_reply_t *rmp;
+ vl_api_ip_route_add_del_reply_t *rmp;
+ u32 stats_index = ~0;
int rv;
- vnet_main_t *vnm = vnet_get_main ();
-
- vnm->api_errno = 0;
- if (mp->is_ipv6)
- rv = ip6_add_del_route_t_handler (mp);
- else
- rv = ip4_add_del_route_t_handler (mp);
+ rv = ip_route_add_del_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_ROUTE_ADD_DEL_REPLY,
+ ({
+ rmp->stats_index = htonl (stats_index);
+ }))
+ /* *INDENT-ON* */
}
-static int
-add_del_mroute_check (fib_protocol_t table_proto,
- u32 table_id,
- u32 next_hop_sw_if_index,
- u8 is_local, u8 create_missing_tables, u32 * fib_index)
+void
+ip_table_create (fib_protocol_t fproto,
+ u32 table_id, u8 is_api, const u8 * name)
{
- vnet_main_t *vnm = vnet_get_main ();
+ u32 fib_index, mfib_index;
- *fib_index = mfib_table_find (table_proto, ntohl (table_id));
- if (~0 == *fib_index)
+ /*
+ * ignore action on the default table - this is always present
+ * and cannot be added nor deleted from the API
+ */
+ if (0 != table_id)
{
- if (create_missing_tables)
- {
- *fib_index = mfib_table_find_or_create_and_lock (table_proto,
- ntohl (table_id));
- }
- else
+ /*
+ * The API holds only one lock on the table.
+ * i.e. it can be added many times via the API but needs to be
+ * deleted only once.
+ * The FIB index for unicast and multicast is not necessarily the
+ * same, since internal VPP systesm (like LISP and SR) create
+ * their own unicast tables.
+ */
+ fib_index = fib_table_find (fproto, table_id);
+ mfib_index = mfib_table_find (fproto, table_id);
+
+ if (~0 == fib_index)
{
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
+ fib_table_find_or_create_and_lock_w_name (fproto, table_id,
+ (is_api ?
+ FIB_SOURCE_API :
+ FIB_SOURCE_CLI), name);
}
- }
-
- if (~0 != ntohl (next_hop_sw_if_index))
- {
- if (pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (next_hop_sw_if_index)))
+ if (~0 == mfib_index)
{
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
+ mfib_table_find_or_create_and_lock_w_name (fproto, table_id,
+ (is_api ?
+ MFIB_SOURCE_API :
+ MFIB_SOURCE_CLI), name);
}
}
-
- return (0);
}
-static int
+static u32
mroute_add_del_handler (u8 is_add,
- u8 is_local,
+ u8 is_multipath,
u32 fib_index,
const mfib_prefix_t * prefix,
u32 entry_flags,
- fib_rpf_id_t rpf_id,
- u32 next_hop_sw_if_index, u32 itf_flags)
+ u32 rpf_id, fib_route_path_t * rpaths)
{
- stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
-
- fib_route_path_t path = {
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_proto = fib_proto_to_dpo (prefix->fp_proto),
- };
-
- if (is_local)
- path.frp_flags |= FIB_ROUTE_PATH_LOCAL;
-
+ u32 mfib_entry_index = ~0;
- if (!is_local && ~0 == next_hop_sw_if_index)
+ if (0 == vec_len (rpaths))
{
- 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);
}
else
{
if (is_add)
{
- mfib_table_entry_path_update (fib_index, prefix,
- MFIB_SOURCE_API, &path, itf_flags);
+ mfib_entry_index =
+ mfib_table_entry_paths_update (fib_index, prefix,
+ MFIB_SOURCE_API, rpaths);
}
else
{
- mfib_table_entry_path_remove (fib_index, prefix,
- MFIB_SOURCE_API, &path);
+ mfib_table_entry_paths_remove (fib_index, prefix,
+ MFIB_SOURCE_API, rpaths);
}
}
- 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_protocol_t fproto;
+ fib_route_path_t *rpath, *rpaths = NULL;
+ fib_node_index_t mfib_entry_index;
+ mfib_prefix_t pfx;
u32 fib_index;
int rv;
+ u16 ii;
- fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
- rv = add_del_mroute_check (fproto,
- mp->table_id,
- mp->next_hop_sw_if_index,
- mp->is_local,
- mp->create_vrf_if_needed, &fib_index);
+ ip_mprefix_decode (&mp->route.prefix, &pfx);
+ rv = mfib_api_table_id_decode (pfx.fp_proto,
+ ntohl (mp->route.table_id), &fib_index);
if (0 != rv)
- return (rv);
+ goto out;
- mfib_prefix_t pfx = {
- .fp_len = ntohs (mp->grp_address_length),
- .fp_proto = fproto,
- };
+ vec_validate (rpaths, mp->route.n_paths - 1);
- if (FIB_PROTOCOL_IP4 == fproto)
+ for (ii = 0; ii < mp->route.n_paths; ii++)
{
- clib_memcpy (&pfx.fp_grp_addr.ip4, mp->grp_address,
- sizeof (pfx.fp_grp_addr.ip4));
- clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
- sizeof (pfx.fp_src_addr.ip4));
- }
- else
- {
- clib_memcpy (&pfx.fp_grp_addr.ip6, mp->grp_address,
- sizeof (pfx.fp_grp_addr.ip6));
- clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
- sizeof (pfx.fp_src_addr.ip6));
+ rpath = &rpaths[ii];
+
+ rv = mfib_api_path_decode (&mp->route.paths[ii], rpath);
+
+ if (0 != rv)
+ goto out;
}
- return (mroute_add_del_handler (mp->is_add,
- mp->is_local,
- fib_index, &pfx,
- ntohl (mp->entry_flags),
- ntohl (mp->rpf_id),
- ntohl (mp->next_hop_sw_if_index),
- ntohl (mp->itf_flags)));
+ mfib_entry_index = mroute_add_del_handler (mp->is_add,
+ mp->is_add,
+ fib_index, &pfx,
+ ntohl (mp->route.entry_flags),
+ ntohl (mp->route.rpf_id),
+ rpaths);
+
+ if (~0 != mfib_entry_index)
+ *stats_index = mfib_entry_get_stats_index (mfib_entry_index);
+
+out:
+ 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;
+ u32 stats_index = ~0;
int rv;
- vnet_main_t *vnm = vnet_get_main ();
-
- vnm->api_errno = 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
send_ip_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q, u32 sw_if_index,
- u8 is_ipv6, u32 context)
+ vl_api_registration_t * reg, u32 sw_if_index, u8 is_ipv6,
+ u32 context)
{
vl_api_ip_details_t *mp;
mp = vl_msg_api_alloc (sizeof (*mp));
- memset (mp, 0, sizeof (*mp));
+ clib_memset (mp, 0, sizeof (*mp));
mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
mp->sw_if_index = ntohl (sw_if_index);
mp->is_ipv6 = is_ipv6;
mp->context = context;
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
send_ip_address_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- u8 * ip, u16 prefix_length,
- u32 sw_if_index, u8 is_ipv6, u32 context)
+ vl_api_registration_t * reg,
+ const fib_prefix_t * pfx,
+ u32 sw_if_index, u32 context)
{
vl_api_ip_address_details_t *mp;
mp = vl_msg_api_alloc (sizeof (*mp));
- memset (mp, 0, sizeof (*mp));
+ clib_memset (mp, 0, sizeof (*mp));
mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
- if (is_ipv6)
- {
- clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
- }
- else
- {
- u32 *tp = (u32 *) mp->ip;
- *tp = *(u32 *) ip;
- }
- mp->prefix_length = prefix_length;
+ ip_prefix_encode (pfx, &mp->prefix);
mp->context = context;
mp->sw_if_index = htonl (sw_if_index);
- mp->is_ipv6 = is_ipv6;
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
- unix_shared_memory_queue_t *q;
- ip6_address_t *r6;
- ip4_address_t *r4;
+ vl_api_registration_t *reg;
ip6_main_t *im6 = &ip6_main;
ip4_main_t *im4 = &ip4_main;
ip_lookup_main_t *lm6 = &im6->lookup_main;
sw_if_index = ntohl (mp->sw_if_index);
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
return;
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;
- send_ip_address_details(am, q, (u8*)r6, prefix_length,
- sw_if_index, 1, mp->context);
+ fib_prefix_t pfx = {
+ .fp_addr.ip6 = *(ip6_address_t *)ip_interface_address_get_address (lm6, ia),
+ .fp_len = ia->address_length,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ };
+ send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
}));
/* *INDENT-ON* */
}
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;
- send_ip_address_details(am, q, (u8*)r4, prefix_length,
- sw_if_index, 0, mp->context);
+ fib_prefix_t pfx = {
+ .fp_addr.ip4 = *(ip4_address_t *)ip_interface_address_get_address (lm4, ia),
+ .fp_len = ia->address_length,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ };
+
+ send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
}));
/* *INDENT-ON* */
}
+
+ 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));
+ clib_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;
}
{
vpe_api_main_t *am = &vpe_api_main;
vnet_main_t *vnm = vnet_get_main ();
- vlib_main_t *vm = vlib_get_main ();
+ //vlib_main_t *vm = vlib_get_main ();
vnet_interface_main_t *im = &vnm->interface_main;
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
vnet_sw_interface_t *si, *sorted_sis;
u32 sw_if_index = ~0;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- {
- return;
- }
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
/* Gather interfaces. */
sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
{
if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
{
- if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
- {
- continue;
- }
+ /* if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index)) */
+ /* { */
+ /* continue; */
+ /* } */
sw_if_index = si->sw_if_index;
- send_ip_details (am, q, sw_if_index, mp->is_ipv6, mp->context);
+ send_ip_details (am, reg, sw_if_index, mp->is_ipv6, mp->context);
}
}
+
+ vec_free (sorted_sis);
}
static void
set_ip6_flow_hash (mp);
}
-static void
- vl_api_sw_interface_ip6nd_ra_config_t_handler
- (vl_api_sw_interface_ip6nd_ra_config_t * mp)
+void
+vl_mfib_signal_send_one (vl_api_registration_t * reg,
+ u32 context, const mfib_signal_t * mfs)
{
- vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
- vlib_main_t *vm = vlib_get_main ();
- int rv = 0;
- u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
- default_router;
-
- is_no = mp->is_no == 1;
- suppress = mp->suppress == 1;
- managed = mp->managed == 1;
- other = mp->other == 1;
- ll_option = mp->ll_option == 1;
- send_unicast = mp->send_unicast == 1;
- cease = mp->cease == 1;
- default_router = mp->default_router == 1;
+ vl_api_mfib_signal_details_t *mp;
+ const mfib_prefix_t *prefix;
+ mfib_table_t *mfib;
+ mfib_itf_t *mfi;
- VALIDATE_SW_IF_INDEX (mp);
+ mp = vl_msg_api_alloc (sizeof (*mp));
- rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
- suppress, managed, other,
- ll_option, send_unicast, cease,
- default_router, ntohl (mp->lifetime),
- ntohl (mp->initial_count),
- ntohl (mp->initial_interval),
- ntohl (mp->max_interval),
- ntohl (mp->min_interval), is_no);
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
+ mp->context = context;
- BAD_SW_IF_INDEX_LABEL;
+ mfi = mfib_itf_get (mfs->mfs_itf);
+ prefix = mfib_entry_get_prefix (mfs->mfs_entry);
+ mfib = mfib_table_get (mfib_entry_get_fib_index (mfs->mfs_entry),
+ prefix->fp_proto);
+ mp->table_id = ntohl (mfib->mft_table_id);
+ mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
+
+ ip_mprefix_encode (prefix, &mp->prefix);
+
+ if (0 != mfs->mfs_buffer_len)
+ {
+ mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
- REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
+ memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
+ }
+ else
+ {
+ mp->ip_packet_len = 0;
+ }
+
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
- vl_api_sw_interface_ip6nd_ra_prefix_t_handler
- (vl_api_sw_interface_ip6nd_ra_prefix_t * mp)
+vl_api_mfib_signal_dump_t_handler (vl_api_mfib_signal_dump_t * mp)
{
- vlib_main_t *vm = vlib_get_main ();
- vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
- int rv = 0;
- u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
-
- VALIDATE_SW_IF_INDEX (mp);
+ vl_api_registration_t *reg;
- is_no = mp->is_no == 1;
- use_default = mp->use_default == 1;
- no_advertise = mp->no_advertise == 1;
- off_link = mp->off_link == 1;
- no_autoconfig = mp->no_autoconfig == 1;
- no_onlink = mp->no_onlink == 1;
-
- rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
- (ip6_address_t *) mp->address,
- mp->address_length, use_default,
- ntohl (mp->val_lifetime),
- ntohl (mp->pref_lifetime), no_advertise,
- off_link, no_autoconfig, no_onlink, is_no);
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
+ while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
+ ;
}
static void
-send_ip6nd_proxy_details (unix_shared_memory_queue_t * q,
- u32 context,
- const ip46_address_t * addr, u32 sw_if_index)
+ vl_api_ip_container_proxy_add_del_t_handler
+ (vl_api_ip_container_proxy_add_del_t * mp)
{
- vl_api_ip6nd_proxy_details_t *mp;
+ vl_api_ip_container_proxy_add_del_reply_t *rmp;
+ vnet_ip_container_proxy_args_t args;
+ int rv = 0;
+ clib_error_t *error;
- mp = vl_msg_api_alloc (sizeof (*mp));
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
- mp->context = context;
- mp->sw_if_index = htonl (sw_if_index);
- memcpy (mp->address, addr, 16);
+ clib_memset (&args, 0, sizeof (args));
+
+ ip_prefix_decode (&mp->pfx, &args.prefix);
+
+ args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
+ args.is_add = mp->is_add;
+ if ((error = vnet_ip_container_proxy_add_del (&args)))
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
}
-typedef struct api_ip6nd_proxy_fib_table_walk_ctx_t_
+typedef struct ip_container_proxy_walk_ctx_t_
{
- u32 *indices;
-} api_ip6nd_proxy_fib_table_walk_ctx_t;
+ vl_api_registration_t *reg;
+ u32 context;
+} ip_container_proxy_walk_ctx_t;
static int
-api_ip6nd_proxy_fib_table_walk (fib_node_index_t fei, void *arg)
+ip_container_proxy_send_details (const fib_prefix_t * pfx, u32 sw_if_index,
+ void *args)
{
- api_ip6nd_proxy_fib_table_walk_ctx_t *ctx = arg;
+ vl_api_ip_container_proxy_details_t *mp;
+ ip_container_proxy_walk_ctx_t *ctx = args;
- if (fib_entry_is_sourced (fei, FIB_SOURCE_IP6_ND_PROXY))
- {
- vec_add1 (ctx->indices, fei);
- }
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ if (!mp)
+ return 1;
+
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS);
+ mp->context = ctx->context;
- return (1);
+ 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_ip6nd_proxy_dump_t_handler (vl_api_ip6nd_proxy_dump_t * mp)
+vl_api_ip_container_proxy_dump_t_handler (vl_api_ip_container_proxy_dump_t *
+ mp)
{
- ip6_main_t *im6 = &ip6_main;
- fib_table_t *fib_table;
- api_ip6nd_proxy_fib_table_walk_ctx_t ctx = {
- .indices = NULL,
- };
- fib_node_index_t *feip;
- fib_prefix_t pfx;
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- {
- return;
- }
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
- /* *INDENT-OFF* */
- pool_foreach (fib_table, im6->fibs,
- ({
- fib_table_walk(fib_table->ft_index,
- FIB_PROTOCOL_IP6,
- api_ip6nd_proxy_fib_table_walk,
- &ctx);
- }));
- /* *INDENT-ON* */
+ ip_container_proxy_walk_ctx_t ctx = {
+ .context = mp->context,
+ .reg = reg,
+ };
- vec_sort_with_function (ctx.indices, fib_entry_cmp_for_sort);
+ ip_container_proxy_walk (ip_container_proxy_send_details, &ctx);
+}
- vec_foreach (feip, ctx.indices)
- {
- fib_entry_get_prefix (*feip, &pfx);
+static void
+vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
+{
+ int rv = 0;
+ vl_api_ioam_enable_reply_t *rmp;
+ clib_error_t *error;
- send_ip6nd_proxy_details (q,
- mp->context,
- &pfx.fp_addr,
- fib_entry_get_resolving_interface (*feip));
- }
+ /* Ignoring the profile id as currently a single profile
+ * is supported */
+ error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
+ mp->seqno, mp->analyse);
+ if (error)
+ {
+ clib_error_report (error);
+ rv = clib_error_get_code (error);
+ }
- vec_free (ctx.indices);
+ REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
}
static void
-vl_api_ip6nd_proxy_add_del_t_handler (vl_api_ip6nd_proxy_add_del_t * mp)
+vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
{
- vl_api_ip6nd_proxy_add_del_reply_t *rmp;
int rv = 0;
+ vl_api_ioam_disable_reply_t *rmp;
+ clib_error_t *error;
- VALIDATE_SW_IF_INDEX (mp);
-
- rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index),
- (ip6_address_t *) mp->address, mp->is_del);
+ error = clear_ioam_rewrite_fn ();
+ if (error)
+ {
+ clib_error_report (error);
+ rv = clib_error_get_code (error);
+ }
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
+ REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
}
static void
- vl_api_sw_interface_ip6_enable_disable_t_handler
- (vl_api_sw_interface_ip6_enable_disable_t * mp)
+ vl_api_ip_source_and_port_range_check_add_del_t_handler
+ (vl_api_ip_source_and_port_range_check_add_del_t * mp)
{
- vlib_main_t *vm = vlib_get_main ();
- vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
- vnet_main_t *vnm = vnet_get_main ();
+ vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
int rv = 0;
- clib_error_t *error;
- vnm->api_errno = 0;
+ u8 is_add = mp->is_add;
+ fib_prefix_t pfx;
+ u16 *low_ports = 0;
+ u16 *high_ports = 0;
+ u32 vrf_id;
+ u16 tmp_low, tmp_high;
+ u8 num_ranges;
+ int i;
+
+ ip_prefix_decode (&mp->prefix, &pfx);
+
+ // Validate port range
+ num_ranges = mp->number_of_ranges;
+ if (num_ranges > 32)
+ { // This is size of array in VPE.API
+ rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
+ goto reply;
+ }
+
+ vec_reset_length (low_ports);
+ vec_reset_length (high_ports);
- VALIDATE_SW_IF_INDEX (mp);
+ for (i = 0; i < num_ranges; i++)
+ {
+ tmp_low = mp->low_ports[i];
+ tmp_high = mp->high_ports[i];
+ // If tmp_low <= tmp_high then only need to check tmp_low = 0
+ // If tmp_low <= tmp_high then only need to check tmp_high > 65535
+ if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto reply;
+ }
+ vec_add1 (low_ports, tmp_low);
+ vec_add1 (high_ports, tmp_high + 1);
+ }
- error =
- (mp->enable == 1) ? enable_ip6_interface (vm,
- ntohl (mp->sw_if_index)) :
- disable_ip6_interface (vm, ntohl (mp->sw_if_index));
+ vrf_id = ntohl (mp->vrf_id);
- if (error)
+ if (vrf_id < 1)
{
- clib_error_report (error);
- rv = VNET_API_ERROR_UNSPECIFIED;
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto reply;
+ }
+
+
+ if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
+ {
+ rv = ip6_source_and_port_range_check_add_del (&pfx.fp_addr.ip6,
+ pfx.fp_len,
+ vrf_id,
+ low_ports,
+ high_ports, is_add);
}
else
{
- rv = vnm->api_errno;
+ rv = ip4_source_and_port_range_check_add_del (&pfx.fp_addr.ip4,
+ pfx.fp_len,
+ vrf_id,
+ low_ports,
+ high_ports, is_add);
+ }
+
+reply:
+ vec_free (low_ports);
+ vec_free (high_ports);
+ REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
+}
+
+static void
+ vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
+ (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
+ ip4_main_t *im = &ip4_main;
+ int rv;
+ u32 sw_if_index;
+ u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
+ u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
+ uword *p = 0;
+ int i;
+
+ vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
+ ntohl (mp->tcp_out_vrf_id);
+ vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
+ ntohl (mp->udp_out_vrf_id);
+ vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
+ ntohl (mp->tcp_in_vrf_id);
+ vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
+ ntohl (mp->udp_in_vrf_id);
+
+
+ for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
+ {
+ if (vrf_id[i] != 0 && vrf_id[i] != ~0)
+ {
+ p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
+
+ if (p == 0)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto reply;
+ }
+
+ fib_index[i] = p[0];
+ }
+ else
+ fib_index[i] = ~0;
}
+ sw_if_index = ntohl (mp->sw_if_index);
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv =
+ set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
+ mp->is_add);
BAD_SW_IF_INDEX_LABEL;
+reply:
- REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
+ REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
}
static void
vl_api_sw_interface_ip6_set_link_local_address_t_handler
(vl_api_sw_interface_ip6_set_link_local_address_t * mp)
{
- vlib_main_t *vm = vlib_get_main ();
vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
- int rv = 0;
- clib_error_t *error;
- vnet_main_t *vnm = vnet_get_main ();
+ ip6_address_t ip;
+ int rv;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ ip6_address_decode (mp->ip, &ip);
+
+ rv = ip6_set_link_local_address (ntohl (mp->sw_if_index), &ip);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
+}
+
+typedef union
+{
+ u32 fib_index;
+} ip4_source_check_config_t;
+
+static void
+ vl_api_ip_source_check_interface_add_del_t_handler
+ (vl_api_ip_source_check_interface_add_del_t * mp)
+{
+ vl_api_ip_source_check_interface_add_del_reply_t *rmp;
+ int rv;
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ u8 is_add = mp->is_add;
+ char *feature_name =
+ mp->loose ? "ip4-source-check-via-any" : "ip4-source-check-via-rx";
- vnm->api_errno = 0;
+ ip4_source_check_config_t config;
VALIDATE_SW_IF_INDEX (mp);
- error = set_ip6_link_local_address (vm,
- ntohl (mp->sw_if_index),
- (ip6_address_t *) mp->address);
- if (error)
+ config.fib_index =
+ fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index);
+ rv =
+ vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index,
+ is_add, &config, sizeof (config));
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_IP_SOURCE_CHECK_INTERFACE_ADD_DEL_REPLY);
+}
+
+
+static void
+vl_api_ip_table_replace_begin_t_handler (vl_api_ip_table_replace_begin_t * mp)
+{
+ vl_api_ip_table_replace_begin_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
+
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
+
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ else
{
- clib_error_report (error);
- rv = VNET_API_ERROR_UNSPECIFIED;
+ fib_table_mark (fib_index, fproto, FIB_SOURCE_API);
+ mfib_table_mark (mfib_table_find (fproto, ntohl (mp->table.table_id)),
+ fproto, MFIB_SOURCE_API);
}
+ REPLY_MACRO (VL_API_IP_TABLE_REPLACE_BEGIN_REPLY);
+}
+
+static void
+vl_api_ip_table_replace_end_t_handler (vl_api_ip_table_replace_end_t * mp)
+{
+ vl_api_ip_table_replace_end_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
+
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
+
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
else
{
- rv = vnm->api_errno;
+ fib_table_sweep (fib_index, fproto, FIB_SOURCE_API);
+ mfib_table_sweep (mfib_table_find
+ (fproto, ntohl (mp->table.table_id)), fproto,
+ MFIB_SOURCE_API);
}
+ REPLY_MACRO (VL_API_IP_TABLE_REPLACE_END_REPLY);
+}
- BAD_SW_IF_INDEX_LABEL;
+static void
+vl_api_ip_table_flush_t_handler (vl_api_ip_table_flush_t * mp)
+{
+ vl_api_ip_table_flush_reply_t *rmp;
+ fib_protocol_t fproto;
+ u32 fib_index;
+ int rv = 0;
- REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
+
+ if (INDEX_INVALID == fib_index)
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ else
+ {
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_interface_main_t *im = &vnm->interface_main;
+ vnet_sw_interface_t *si;
+
+ /* Shut down interfaces in this FIB / clean out intfc routes */
+ /* *INDENT-OFF* */
+ pool_foreach (si, im->sw_interfaces,
+ ({
+ if (fib_index == fib_table_get_index_for_sw_if_index (fproto,
+ si->sw_if_index))
+ {
+ u32 flags = si->flags;
+ flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+ vnet_sw_interface_set_flags (vnm, si->sw_if_index, flags);
+ }
+ }));
+ /* *INDENT-ON* */
+
+ fib_table_flush (fib_index, fproto, FIB_SOURCE_API);
+ mfib_table_flush (mfib_table_find (fproto, ntohl (mp->table.table_id)),
+ fproto, MFIB_SOURCE_API);
+ }
+
+ REPLY_MACRO (VL_API_IP_TABLE_FLUSH_REPLY);
}
void
-vl_mfib_signal_send_one (unix_shared_memory_queue_t * q,
- u32 context, const mfib_signal_t * mfs)
+vl_api_ip_reassembly_set_t_handler (vl_api_ip_reassembly_set_t * mp)
{
- vl_api_mfib_signal_details_t *mp;
- mfib_prefix_t prefix;
- mfib_table_t *mfib;
- mfib_itf_t *mfi;
+ vl_api_ip_reassembly_set_reply_t *rmp;
+ int rv = 0;
+ switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
+ {
+ case IP_REASS_TYPE_FULL:
+ if (mp->is_ip6)
+ {
+ rv = ip6_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
+ clib_net_to_host_u32
+ (mp->max_reassemblies),
+ clib_net_to_host_u32
+ (mp->max_reassembly_length),
+ clib_net_to_host_u32
+ (mp->expire_walk_interval_ms));
+ }
+ else
+ {
+ rv = ip4_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
+ clib_net_to_host_u32
+ (mp->max_reassemblies),
+ clib_net_to_host_u32
+ (mp->max_reassembly_length),
+ clib_net_to_host_u32
+ (mp->expire_walk_interval_ms));
+ }
+ break;
+ case IP_REASS_TYPE_SHALLOW_VIRTUAL:
+ if (mp->is_ip6)
+ {
+ rv =
+ ip6_sv_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
+ clib_net_to_host_u32 (mp->max_reassemblies),
+ clib_net_to_host_u32
+ (mp->max_reassembly_length),
+ clib_net_to_host_u32
+ (mp->expire_walk_interval_ms));
+ }
+ else
+ {
+ rv = ip4_sv_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
+ clib_net_to_host_u32 (mp->max_reassemblies),
+ clib_net_to_host_u32
+ (mp->max_reassembly_length),
+ clib_net_to_host_u32
+ (mp->expire_walk_interval_ms));
+ }
+ break;
+ }
- mp = vl_msg_api_alloc (sizeof (*mp));
+ REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
+}
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
- mp->context = context;
+void
+vl_api_ip_reassembly_get_t_handler (vl_api_ip_reassembly_get_t * mp)
+{
+ vl_api_registration_t *rp;
- mfi = mfib_itf_get (mfs->mfs_itf);
- mfib_entry_get_prefix (mfs->mfs_entry, &prefix);
- mfib = mfib_table_get (mfib_entry_get_fib_index (mfs->mfs_entry),
- prefix.fp_proto);
- mp->table_id = ntohl (mfib->mft_table_id);
- mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
+ rp = vl_api_client_index_to_registration (mp->client_index);
+ if (rp == 0)
+ return;
- if (FIB_PROTOCOL_IP4 == prefix.fp_proto)
+ vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
+ rmp->context = mp->context;
+ rmp->retval = 0;
+ u32 timeout_ms;
+ u32 max_reassemblies;
+ u32 max_reassembly_length;
+ u32 expire_walk_interval_ms;
+ switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
{
- mp->grp_address_len = ntohs (prefix.fp_len);
-
- memcpy (mp->grp_address, &prefix.fp_grp_addr.ip4, 4);
- if (prefix.fp_len > 32)
+ case IP_REASS_TYPE_FULL:
+ if (mp->is_ip6)
+ {
+ rmp->is_ip6 = 1;
+ ip6_full_reass_get (&timeout_ms, &max_reassemblies,
+ &max_reassembly_length,
+ &expire_walk_interval_ms);
+ }
+ else
+ {
+ rmp->is_ip6 = 0;
+ ip4_full_reass_get (&timeout_ms, &max_reassemblies,
+ &max_reassembly_length,
+ &expire_walk_interval_ms);
+ }
+ break;
+ case IP_REASS_TYPE_SHALLOW_VIRTUAL:
+ if (mp->is_ip6)
{
- memcpy (mp->src_address, &prefix.fp_src_addr.ip4, 4);
+ rmp->is_ip6 = 1;
+ ip6_sv_reass_get (&timeout_ms, &max_reassemblies,
+ &max_reassembly_length, &expire_walk_interval_ms);
}
+ else
+ {
+ rmp->is_ip6 = 0;
+ ip4_sv_reass_get (&timeout_ms, &max_reassemblies,
+ &max_reassembly_length, &expire_walk_interval_ms);
+ }
+ break;
}
- else
- {
- mp->grp_address_len = ntohs (prefix.fp_len);
+ rmp->timeout_ms = clib_host_to_net_u32 (timeout_ms);
+ rmp->max_reassemblies = clib_host_to_net_u32 (max_reassemblies);
+ rmp->max_reassembly_length = clib_host_to_net_u32 (max_reassembly_length);
+ rmp->expire_walk_interval_ms =
+ clib_host_to_net_u32 (expire_walk_interval_ms);
+ vl_api_send_msg (rp, (u8 *) rmp);
+}
- ASSERT (0);
+void
+ vl_api_ip_reassembly_enable_disable_t_handler
+ (vl_api_ip_reassembly_enable_disable_t * mp)
+{
+ vl_api_ip_reassembly_enable_disable_reply_t *rmp;
+ int rv = 0;
+ switch ((vl_api_ip_reass_type_t) clib_net_to_host_u32 (mp->type))
+ {
+ case IP_REASS_TYPE_FULL:
+ rv =
+ ip4_full_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
+ mp->enable_ip4);
+ if (0 == rv)
+ rv =
+ ip6_full_reass_enable_disable (clib_net_to_host_u32
+ (mp->sw_if_index), mp->enable_ip6);
+ break;
+ case IP_REASS_TYPE_SHALLOW_VIRTUAL:
+ rv =
+ ip4_sv_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
+ mp->enable_ip4);
+ if (0 == rv)
+ {
+ rv =
+ ip6_sv_reass_enable_disable (clib_net_to_host_u32
+ (mp->sw_if_index), mp->enable_ip6);
+ }
+ break;
}
- if (0 != mfs->mfs_buffer_len)
- {
- mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
+ REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
+}
- memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
- }
- else
- {
- mp->ip_packet_len = 0;
- }
+typedef struct ip_punt_redirect_walk_ctx_t_
+{
+ vl_api_registration_t *reg;
+ u32 context;
+} ip_punt_redirect_walk_ctx_t;
+
+static walk_rc_t
+send_ip_punt_redirect_details (u32 rx_sw_if_index,
+ const ip_punt_redirect_rx_t * ipr, void *arg)
+{
+ ip_punt_redirect_walk_ctx_t *ctx = arg;
+ vl_api_ip_punt_redirect_details_t *mp;
+ fib_path_encode_ctx_t path_ctx = {
+ .rpaths = NULL,
+ };
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ if (!mp)
+ return (WALK_STOP);;
+
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_PUNT_REDIRECT_DETAILS);
+ mp->context = ctx->context;
+
+ fib_path_list_walk_w_ext (ipr->pl, NULL, fib_path_encode, &path_ctx);
+
+ mp->punt.rx_sw_if_index = htonl (rx_sw_if_index);
+ mp->punt.tx_sw_if_index = htonl (path_ctx.rpaths[0].frp_sw_if_index);
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ ip_address_encode (&path_ctx.rpaths[0].frp_addr,
+ fib_proto_to_ip46 (ipr->fproto), &mp->punt.nh);
+
+ vl_api_send_msg (ctx->reg, (u8 *) mp);
+
+ vec_free (path_ctx.rpaths);
+
+ return (WALK_CONTINUE);
}
static void
-vl_api_mfib_signal_dump_t_handler (vl_api_mfib_signal_dump_t * mp)
+vl_api_ip_punt_redirect_dump_t_handler (vl_api_ip_punt_redirect_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
+ fib_protocol_t fproto;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
+
+ ip_punt_redirect_walk_ctx_t ctx = {
+ .reg = reg,
+ .context = mp->context,
+ };
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
+ if (~0 != mp->sw_if_index)
{
- return;
- }
+ u32 rx_sw_if_index;
+ index_t pri;
- while (q->cursize < q->maxsize && mfib_signal_send_one (q, mp->context))
- ;
+ rx_sw_if_index = ntohl (mp->sw_if_index);
+ pri = ip_punt_redirect_find (fproto, rx_sw_if_index);
+
+ if (INDEX_INVALID == pri)
+ return;
+
+ send_ip_punt_redirect_details (rx_sw_if_index,
+ ip_punt_redirect_get (pri), &ctx);
+ }
+ else
+ ip_punt_redirect_walk (fproto, send_ip_punt_redirect_details, &ctx);
}
#define vl_msg_name_crc_list
static clib_error_t *
ip_api_hookup (vlib_main_t * vm)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
#define _(N,n) \
vl_msg_api_set_handlers(VL_API_##N, #n, \
foreach_ip_api_msg;
#undef _
+ /*
+ * Mark the route add/del API as MP safe
+ */
+ am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1;
+ am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1;
+
/*
* Set up the (msg_name, crc, message-id) table
*/