aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip.api281
-rw-r--r--src/vnet/ip/ip_api.c1056
-rw-r--r--src/vnet/ip/ip_types_api.c3
-rw-r--r--src/vnet/ip/lookup.c108
4 files changed, 396 insertions, 1052 deletions
diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api
index afb0960c78a..2dae4385602 100644
--- a/src/vnet/ip/ip.api
+++ b/src/vnet/ip/ip.api
@@ -20,15 +20,13 @@
called through a shared memory interface.
*/
-option version = "2.0.1";
-import "vnet/ip/ip_types.api";
+option version = "3.0.0";
+
import "vnet/fib/fib_types.api";
import "vnet/ethernet/ethernet_types.api";
+import "vnet/mfib/mfib_types.api";
-/** \brief Add / del table request
- A table can be added multiple times, but need be deleted only once.
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
+/** \brief An IP table
@param is_ipv6 - V4 or V6 table
@param table_id - table ID associated with the route
This table ID will apply to both the unicats
@@ -37,70 +35,104 @@ import "vnet/ethernet/ethernet_types.api";
not set by the client, then VPP will generate something
meaningfull.
*/
+typeonly define ip_table
+{
+ u32 table_id;
+ u8 is_ip6;
+ u8 name[64];
+};
+
+/** \brief Add / del table request
+ A table can be added multiple times, but need be deleted only once.
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
autoreply define ip_table_add_del
{
u32 client_index;
u32 context;
- u32 table_id;
- u8 is_ipv6;
u8 is_add;
- u8 name[64];
+ vl_api_ip_table_t table;
};
-/** \brief Dump IP fib table
+/** \brief Dump IP all fib tables
@param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
*/
-define ip_fib_dump
+define ip_table_dump
{
u32 client_index;
u32 context;
};
/** \brief IP FIB table response
- @param table_id - IP fib table id
- @address_length - mask length
- @address - ip4 prefix
- @param count - the number of fib_path in path
- @param path - array of of fib_path structures
+ @param context - sender context
+ @param table - description of the table
*/
-manual_endian manual_print define ip_fib_details
+manual_endian manual_print define ip_table_details
{
u32 context;
+ vl_api_ip_table_t table;
+};
+
+/** \brief An IP route
+ @param table_id The IP table the route is in
+ @param stats_index The index of the route in the stats segment
+ @param prefix the prefix for the route
+ @param n_paths The number of paths the route has
+ @param paths The paths of the route
+*/
+typeonly define ip_route
+{
u32 table_id;
- u8 table_name[64];
- u8 address_length;
- u8 address[4];
- u32 count;
u32 stats_index;
- vl_api_fib_path_t path[count];
+ vl_api_prefix_t prefix;
+ u8 n_paths;
+ vl_api_fib_path_t paths[n_paths];
};
-/** \brief Dump IP6 fib table
+/** \brief Add / del route request
@param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_multipath - Set to 1 if these paths will be added/removed
+ to/from the existing set, or 0 to replace
+ the existing set.
+ is_add=0 & is_multipath=0 implies delete all paths
+ @param is_add - Are the paths being added or removed
*/
-define ip6_fib_dump
+define ip_route_add_del
{
u32 client_index;
u32 context;
+ u8 is_add;
+ u8 is_multipath;
+ vl_api_ip_route_t route;
+};
+define ip_route_add_del_reply
+{
+ u32 context;
+ i32 retval;
+ u32 stats_index;
};
-/** \brief IP6 FIB table entry response
- @param table_id - IP6 fib table id
- @param address_length - mask length
- @param address - ip6 prefix
- @param count - the number of fib_path in path
- @param path - array of of fib_path structures
+/** \brief Dump IP routes from a table
+ @param client_index - opaque cookie to identify the sender
+ @param table - The table from which to dump routes (ony ID an AF are needed)
*/
-manual_endian manual_print define ip6_fib_details
+define ip_route_dump
{
+ u32 client_index;
u32 context;
- u32 table_id;
- u8 table_name[64];
- u8 address_length;
- u8 address[16];
- u32 count;
- u32 stats_index;
- vl_api_fib_path_t path[count];
+ vl_api_ip_table_t table;
+};
+
+/** \brief IP FIB table entry response
+ @param route The route entry in the table
+*/
+manual_endian manual_print define ip_route_details
+{
+ u32 context;
+ vl_api_ip_route_t route;
};
/** \brief IP neighbor flags
@@ -359,76 +391,33 @@ autoreply define sw_interface_ip6_enable_disable
u8 enable; /* set to true if enable */
};
-/** \brief Add / del route request
+/** \brief IPv6 set link local address on interface request
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
- @param sw_if_index - software index of the new vlan's parent interface
- @param vrf_id - fib table /vrf associated with the route
- @param lookup_in_vrf -
- @param classify_table_index -
- @param is_add - 1 if adding the route, 0 if deleting
- @param is_drop - Drop the packet
- @param is_unreach - Drop the packet and rate limit send ICMP unreachable
- @param is_prohibit - Drop the packet and rate limit send ICMP prohibited
- @param is_ipv6 - 0 if an ip4 route, else ip6
- @param is_local - The route will result in packets sent to VPP IP stack
- @param is_udp_encap - The path describes a UDP-o-IP encapsulation.
- @param is_classify -
- @param is_multipath - Set to 1 if this is a multipath route, else 0
- @param is_dvr - Does the route resolve via a DVR interface.
- @param is_source_lookup - The the path is a deaggregate path (i.e. a lookup
- in another table) is the lookup on the packet's
- source address or destination.
- @param next_hop_weight - Weight for Unequal cost multi-path
- @param next_hop_preference - Path that are up that have the best preference are
- are used for forwarding. lower value is better.
- @param next_hop_id - Used when the path resolves via an object that has a unique
- identifier.
- @param dst_address_length -
- @param dst_address[16] -
- @param next_hop_address[16] -
- @param next_hop_n_out_labels - the number of labels in the label stack
- @param next_hop_out_label_stack - the next-hop output label stack, outer most first
- @param next_hop_via_label - The next-hop is a resolved via a local label
+ @param sw_if_index - interface to set link local on
+ @param address[] - the new link local address
*/
-define ip_add_del_route
+autoreply define sw_interface_ip6_set_link_local_address
{
u32 client_index;
u32 context;
- u32 next_hop_sw_if_index;
- u32 table_id;
- u32 classify_table_index;
- u32 next_hop_table_id;
- u32 next_hop_id;
- u8 is_add;
- u8 is_drop;
- u8 is_unreach;
- u8 is_prohibit;
- u8 is_ipv6;
- u8 is_local;
- u8 is_classify;
- u8 is_multipath;
- u8 is_resolve_host;
- u8 is_resolve_attached;
- u8 is_dvr;
- u8 is_source_lookup;
- u8 is_udp_encap;
- u8 next_hop_weight;
- u8 next_hop_preference;
- u8 next_hop_proto;
- u8 dst_address_length;
- u8 dst_address[16];
- u8 next_hop_address[16];
- u8 next_hop_n_out_labels;
- u32 next_hop_via_label;
- vl_api_fib_mpls_label_t next_hop_out_label_stack[next_hop_n_out_labels];
-};
-
-define ip_add_del_route_reply
+ u32 sw_if_index;
+ u8 address[16];
+};
+
+/** \brief Dump IP multicast fib table
+ @param client_index - opaque cookie to identify the sender
+*/
+define ip_mtable_dump
{
+ u32 client_index;
u32 context;
- i32 retval;
- u32 stats_index;
+};
+define ip_mtable_details
+{
+ u32 client_index;
+ u32 context;
+ vl_api_ip_table_t table;
};
/** \brief Add / del route request
@@ -459,105 +448,55 @@ define ip_add_del_route_reply
FIXME not complete yet
*/
-define ip_mroute_add_del
+typedef ip_mroute
{
- u32 client_index;
- u32 context;
- u32 next_hop_sw_if_index;
u32 table_id;
u32 entry_flags;
- u32 itf_flags;
u32 rpf_id;
- u32 bier_imp;
- u16 grp_address_length;
- u8 next_hop_afi;
- u8 is_add;
- u8 is_ipv6;
- u8 is_local;
- u8 grp_address[16];
- u8 src_address[16];
- u8 nh_address[16];
-};
-
-define ip_mroute_add_del_reply
-{
- u32 context;
- i32 retval;
- u32 stats_index;
+ vl_api_mprefix_t prefix;
+ u8 n_paths;
+ vl_api_mfib_path_t paths[n_paths];
};
-/** \brief Dump IP multicast fib table
- @param client_index - opaque cookie to identify the sender
-*/
-define ip_mfib_dump
+define ip_mroute_add_del
{
u32 client_index;
u32 context;
+ u8 is_add;
+ u8 is_multipath;
+ vl_api_ip_mroute_t route;
};
-
-/** \brief IP Multicast FIB table response
- @param table_id - IP fib table id
- @address_length - mask length
- @grp_address - Group address/prefix
- @src_address - Source address
- @param count - the number of fib_path in path
- @param path - array of of fib_path structures
-*/
-typedef mfib_path
-{
- vl_api_fib_path_t path;
- u32 itf_flags;
-};
-
-manual_endian manual_print define ip_mfib_details
+define ip_mroute_add_del_reply
{
u32 context;
- u32 table_id;
- u32 entry_flags;
- u32 rpf_id;
- u8 address_length;
- u8 grp_address[4];
- u8 src_address[4];
- u32 count;
+ i32 retval;
u32 stats_index;
- vl_api_mfib_path_t path[count];
};
-/** \brief Dump IP6 multicast fib table
- @param client_index - opaque cookie to identify the sender
+/** \brief Dump IP multicast fib table
+ @param table - The table from which to dump routes (ony ID an AF are needed)
*/
-define ip6_mfib_dump
+define ip_mroute_dump
{
u32 client_index;
u32 context;
+ vl_api_ip_table_t table;
};
-/** \brief IP6 Multicast FIB table response
- @param table_id - IP fib table id
- @address_length - mask length
- @grp_address - Group address/prefix
- @src_address - Source address
- @param count - the number of fib_path in path
- @param path - array of of fib_path structures
+/** \brief IP Multicast Route Details
+ @param route - Details of the route
*/
-manual_endian manual_print define ip6_mfib_details
+manual_endian manual_print define ip_mroute_details
{
u32 context;
- u32 table_id;
- u8 address_length;
- u8 grp_address[16];
- u8 src_address[16];
- u32 count;
- vl_api_mfib_path_t path[count];
+ vl_api_ip_mroute_t route;
};
define ip_address_details
{
u32 context;
- u8 ip[16];
- u8 prefix_length;
u32 sw_if_index;
- u8 is_ipv6;
+ vl_api_prefix_t prefix;
};
define ip_address_dump
@@ -614,9 +553,7 @@ define mfib_signal_details
u32 context;
u32 sw_if_index;
u32 table_id;
- u16 grp_address_len;
- u8 grp_address[16];
- u8 src_address[16];
+ vl_api_mprefix_t prefix;
u16 ip_packet_len;
u8 ip_packet_data[256];
};
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index bcbcf5ac8d4..4d2f0704ca3 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -29,18 +29,15 @@
#include <vnet/ip/ip_types_api.h>
#include <vnet/ip/ip6_neighbor.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>
@@ -71,10 +68,10 @@
#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_TABLE_DUMP, ip_table_dump) \
+_(IP_ROUTE_DUMP, ip_route_dump) \
+_(IP_MTABLE_DUMP, ip_mtable_dump) \
+_(IP_MROUTE_DUMP, ip_mroute_dump) \
_(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
_(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
_(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
@@ -93,7 +90,7 @@ _(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_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) \
@@ -211,137 +208,104 @@ vl_api_ip_neighbor_dump_t_handler (vl_api_ip_neighbor_dump_t * mp)
}
static void
-send_ip_fib_details (vpe_api_main_t * am,
- vl_api_registration_t * reg,
- const fib_table_t * table,
- const fib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
-{
- vl_api_ip_fib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
- vl_api_fib_path_t *fp;
- int path_count;
+send_ip_table_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, const fib_table_t * table)
+{
+ 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;
clib_memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_IP_TABLE_DETAILS);
mp->context = context;
- mp->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)));
- 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;
- vec_foreach (api_rpath, api_rpaths)
- {
- fib_api_path_encode (api_rpath, fp);
- fp++;
- }
+ 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)));
vl_api_send_msg (reg, (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 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_add1 (ctx->feis, fei);
-
- return (FIB_TABLE_WALK_CONTINUE);
-}
-
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;
vl_api_registration_t *reg;
- ip4_main_t *im = &ip4_main;
fib_table_t *fib_table;
- fib_node_index_t *lfeip;
- const 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,
- };
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,
({
- fib_table_walk(fib_table->ft_index,
- FIB_PROTOCOL_IP4,
- vl_api_ip_fib_dump_walk,
- &ctx);
+ send_ip_table_details(am, reg, mp->context, fib_table);
+ }));
+ pool_foreach (fib_table, ip6_main.fibs,
+ ({
+ /* 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)
- {
- pfx = fib_entry_get_prefix (*lfeip);
- 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, reg, fib_table, 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,
- vl_api_registration_t * reg,
- const fib_table_t * table,
- const fib_prefix_t * pfx,
- fib_route_path_encode_t * api_rpaths, u32 context)
-{
- vl_api_ip6_fib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
+send_ip_route_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, fib_node_index_t fib_entry_index)
+{
+ 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;
clib_memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_IP_ROUTE_DETAILS);
mp->context = context;
- mp->table_id = htonl (table->ft_table_id);
- mp->address_length = pfx->fp_len;
- 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;
- 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)
{
- fib_api_path_encode (api_rpath, fp);
+ fib_api_path_encode (rpath, fp);
fp++;
}
@@ -353,232 +317,144 @@ typedef struct apt_ip6_fib_show_ctx_t_
fib_node_index_t *entries;
} api_ip6_fib_show_ctx_t;
-static fib_table_walk_rc_t
-api_ip6_fib_table_put_entries (fib_node_index_t fei, void *arg)
-{
- api_ip6_fib_show_ctx_t *ctx = arg;
-
- vec_add1 (ctx->entries, fei);
-
- return (FIB_TABLE_WALK_CONTINUE);
-}
-
static void
-api_ip6_fib_table_get_all (vl_api_registration_t * reg,
- 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;
fib_node_index_t *fib_entry_index;
- api_ip6_fib_show_ctx_t ctx = {
- .entries = NULL,
- };
- fib_route_path_encode_t *api_rpaths;
- const fib_prefix_t *pfx;
-
- ip6_fib_table_walk (fib_table->ft_index,
- api_ip6_fib_table_put_entries, &ctx);
-
- vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);
-
- vec_foreach (fib_entry_index, ctx.entries)
- {
- 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);
- vec_free (api_rpaths);
- }
-
- vec_free (ctx.entries);
-}
-
-static void
-vl_api_ip6_fib_dump_t_handler (vl_api_ip6_fib_dump_t * mp)
-{
vl_api_registration_t *reg;
- ip6_main_t *im6 = &ip6_main;
- fib_table_t *fib_table;
+ fib_protocol_t fproto;
+ u32 fib_index;
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- /* *INDENT-OFF* */
- pool_foreach (fib_table, im6->fibs,
- ({
- /* don't send link locals */
- if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
- continue;
-
- api_ip6_fib_table_get_all(reg, mp, fib_table);
- }));
- /* *INDENT-ON* */
-}
-
-static void
-send_ip_mfib_details (vl_api_registration_t * reg,
- u32 context, u32 table_id, fib_node_index_t mfei)
-{
- fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
- vl_api_ip_mfib_details_t *mp;
- const mfib_prefix_t *pfx;
- mfib_entry_t *mfib_entry;
- vl_api_mfib_path_t *fp;
- int path_count;
+ vl_api_ip_fib_dump_walk_ctx_t ctx = {
+ .feis = NULL,
+ };
- mfib_entry = mfib_entry_get (mfei);
- pfx = mfib_entry_get_prefix (mfei);
- mfib_entry_encode (mfei, &api_rpaths);
+ fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
- path_count = vec_len (api_rpaths);
- mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
- if (!mp)
+ if (INDEX_INVALID == fib_index)
return;
- clib_memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP_MFIB_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)
+ fib_table_walk (fib_index, fproto, vl_api_ip_fib_dump_walk, &ctx);
+
+ vec_foreach (fib_entry_index, ctx.feis)
{
- fib_api_path_encode (api_rpath, &fp->path);
- fp->itf_flags = ntohl (api_rpath->rpath.frp_mitf_flags);
- fp++;
+ send_ip_route_details (am, reg, mp->context, *fib_entry_index);
}
- vec_free (api_rpaths);
- vl_api_send_msg (reg, (u8 *) mp);
+ vec_free (ctx.feis);
}
-typedef struct vl_api_ip_mfib_dump_ctc_t_
+static void
+send_ip_mtable_details (vl_api_registration_t * reg,
+ u32 context, const mfib_table_t * mfib_table)
{
- fib_node_index_t *entries;
-} vl_api_ip_mfib_dump_ctc_t;
+ vl_api_ip_mtable_details_t *mp;
-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;
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ if (!mp)
+ return;
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IP_MTABLE_DETAILS);
+ mp->context = context;
- 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)
{
vl_api_registration_t *reg;
- ip4_main_t *im = &ip4_main;
mfib_table_t *mfib_table;
- fib_node_index_t *mfeip;
- vl_api_ip_mfib_dump_ctc_t ctx = {
- .entries = NULL,
- };
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 (reg, mp->context,
- mfib_table->mft_table_id,
- *mfeip);
- }
- vec_reset_length (ctx.entries);
+static int
+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 (0);
}
static void
-send_ip6_mfib_details (vpe_api_main_t * am,
- vl_api_registration_t * reg,
- u32 table_id,
- const 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;
+ 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;
clib_memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_IP6_MFIB_DETAILS);
+ 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)
{
- fib_api_path_encode (api_rpath, &fp->path);
- fp->itf_flags = ntohl (api_rpath->rpath.frp_mitf_flags);
+ mfib_api_path_encode (rpath, fp);
fp++;
}
vl_api_send_msg (reg, (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);
+ 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;
vl_api_registration_t *reg;
- ip6_main_t *im = &ip6_main;
- mfib_table_t *mfib_table;
- const mfib_prefix_t *pfx;
fib_node_index_t *mfeip;
- 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,
};
@@ -586,33 +462,22 @@ vl_api_ip6_mfib_dump_t_handler (vl_api_ip6_mfib_dump_t * mp)
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)
- {
- pfx = mfib_entry_get_prefix (*mfeip);
- mfib_entry_encode (*mfeip, &api_rpaths);
- send_ip6_mfib_details (am, reg,
- 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
@@ -698,7 +563,7 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
ip46_address_t ip;
mac_address_t mac;
ip46_type_t type;
- int rv = 0;
+ int rv;
VALIDATE_SW_IF_INDEX ((&mp->neighbor));
@@ -767,13 +632,14 @@ 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->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
- u32 table_id = ntohl (mp->table_id);
+ 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->name);
+ ip_table_create (fproto, table_id, 1, mp->table.name);
}
else
{
@@ -783,398 +649,71 @@ vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_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,
- u8 is_dvr,
- u8 is_source_lookup,
- u8 is_udp_encap,
- u32 fib_index,
- const fib_prefix_t * prefix,
- dpo_proto_t next_hop_proto,
- const ip46_address_t * next_hop,
- u32 next_hop_id,
- 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,
- fib_mpls_label_t * next_hop_out_label_stack)
-{
- 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;
-
- /*
- * the special INVALID label means we are not recursing via a
- * label. Exp-null value is never a valid via-label so that
- * also means it's not a via-label and means clients that set
- * it to 0 by default get the expected behaviour
- */
- if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != 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_local)
- {
- path_flags |= FIB_ROUTE_PATH_LOCAL;
- if (~0 != next_hop_sw_if_index)
- {
- entry_flags |= (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL);
- }
- }
- if (is_dvr)
- path_flags |= FIB_ROUTE_PATH_DVR;
- 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_source_lookup)
- path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
- if (is_multicast)
- entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
- if (is_udp_encap)
- {
- path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
- path.frp_udp_encap_id = next_hop_id;
- }
- if (path.frp_sw_if_index == ~0 && ip46_address_is_zero (&path.frp_addr)
- && path.frp_fib_index != ~0)
- {
- path_flags |= FIB_ROUTE_PATH_DEAG;
- }
-
- path.frp_flags = path_flags;
-
- if (is_drop || (is_local && (~0 == next_hop_sw_if_index)) ||
- is_classify || is_unreach || is_prohibit)
- {
- /*
- * special route types that link directly to the adj
- */
- if (is_add)
- {
- 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)))
- {
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
-
- dpo_set (&dpo, DPO_CLASSIFY, dproto,
- classify_dpo_create (dproto,
- ntohl (classify_table_index)));
- }
- else
- {
- 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);
- }
- else
- {
- 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)
- {
- vec_add1 (paths, path);
- fib_table_entry_update (fib_index,
- prefix, FIB_SOURCE_API, entry_flags, paths);
- vec_free (paths);
- }
- else
- {
- fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
- }
- }
-
- return (0);
-}
-
-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 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
-{
- vnet_main_t *vnm = vnet_get_main ();
-
- *fib_index = fib_table_find (table_proto, ntohl (table_id));
- if (~0 == *fib_index)
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
-
- 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;
- }
- }
- 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)
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
-
- return (0);
-}
-
static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
- u32 * stats_index)
+ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp, u32 * stats_index)
{
- u32 fib_index, next_hop_fib_index;
- fib_mpls_label_t *label_stack = NULL;
- int rv, ii, n_labels;;
+ 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;
- 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,
- 0, &fib_index, &next_hop_fib_index);
+ entry_flags = FIB_ENTRY_FLAG_NONE;
+ ip_prefix_decode (&mp->route.prefix, &pfx);
+ rv = fib_api_table_id_decode (pfx.fp_proto,
+ ntohl (mp->route.table_id), &fib_index);
if (0 != rv)
- return (rv);
-
- 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));
-
- ip46_address_t nh;
- clib_memset (&nh, 0, sizeof (nh));
- memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+ goto out;
- n_labels = mp->next_hop_n_out_labels;
- if (n_labels == 0)
- ;
- else
+ if (0 == mp->route.n_paths)
{
- vec_validate (label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- {
- label_stack[ii].fml_value =
- ntohl (mp->next_hop_out_label_stack[ii].label);
- label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
- label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
- label_stack[ii].fml_mode =
- (mp->next_hop_out_label_stack[ii].is_uniform ?
- FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE);
- }
+ rv = VNET_API_ERROR_NO_PATHS_IN_ROUTE;
+ goto out;
}
- 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,
- u32 * stats_index)
-{
- fib_mpls_label_t *label_stack = NULL;
- u32 fib_index, next_hop_fib_index;
- int rv, ii, n_labels;;
+ vec_validate (rpaths, mp->route.n_paths - 1);
- 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,
- 0, &fib_index, &next_hop_fib_index);
+ for (ii = 0; ii < mp->route.n_paths; ii++)
+ {
+ apath = &mp->route.paths[ii];
+ rpath = &rpaths[ii];
- if (0 != rv)
- return (rv);
+ rv = fib_api_path_decode (apath, rpath);
- 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));
-
- ip46_address_t nh;
- clib_memset (&nh, 0, sizeof (nh));
- memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+ if ((rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
+ (~0 == rpath->frp_sw_if_index))
+ entry_flags |= (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL);
- n_labels = mp->next_hop_n_out_labels;
- if (n_labels == 0)
- ;
- else
- {
- vec_validate (label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- {
- label_stack[ii].fml_value =
- ntohl (mp->next_hop_out_label_stack[ii].label);
- label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
- label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
- label_stack[ii].fml_mode =
- (mp->next_hop_out_label_stack[ii].is_uniform ?
- FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE);
- }
+ if (0 != rv)
+ goto out;
}
- 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);
+ fib_api_route_add_del (mp->is_add,
+ mp->is_multipath,
+ fib_index, &pfx, entry_flags, rpaths);
if (mp->is_add && 0 == rv)
*stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
+out:
+ vec_free (rpaths);
+
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;
- u32 stats_index;
+ 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;
- stats_index = ~0;
- if (mp->is_ipv6)
- rv = ip6_add_del_route_t_handler (mp, &stats_index);
- else
- rv = ip4_add_del_route_t_handler (mp, &stats_index);
-
- rv = (rv == 0) ? vnm->api_errno : rv;
+ rv = ip_route_add_del_t_handler (mp, &stats_index);
/* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_IP_ADD_DEL_ROUTE_REPLY,
+ REPLY_MACRO2 (VL_API_IP_ROUTE_ADD_DEL_REPLY,
({
rmp->stats_index = htonl (stats_index);
}))
@@ -1221,80 +760,37 @@ ip_table_create (fib_protocol_t fproto,
}
}
-static int
-add_del_mroute_check (fib_protocol_t table_proto,
- u32 table_id,
- u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
-{
- vnet_main_t *vnm = vnet_get_main ();
-
- *fib_index = mfib_table_find (table_proto, ntohl (table_id));
- if (~0 == *fib_index)
- {
- /* No such table */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
-
- if (~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;
- }
- }
-
- return (0);
-}
-
-static fib_node_index_t
+static u32
mroute_add_del_handler (u8 is_add,
- u8 is_local,
+ u8 is_multipath,
u32 fib_index,
const mfib_prefix_t * prefix,
- dpo_proto_t nh_proto,
u32 entry_flags,
- fib_rpf_id_t rpf_id,
- u32 next_hop_sw_if_index,
- ip46_address_t * nh, u32 itf_flags, u32 bier_imp)
+ u32 rpf_id, fib_route_path_t * rpaths)
{
- fib_node_index_t mfib_entry_index = ~0;
-
- fib_route_path_t path = {
- .frp_sw_if_index = next_hop_sw_if_index,
- .frp_proto = nh_proto,
- .frp_addr = *nh,
- };
+ u32 mfib_entry_index = ~0;
- if (is_local)
- path.frp_flags |= FIB_ROUTE_PATH_LOCAL;
-
- if (DPO_PROTO_BIER == nh_proto)
- {
- path.frp_bier_imp = bier_imp;
- path.frp_flags = FIB_ROUTE_PATH_BIER_IMP;
- }
- else if (!is_local && ~0 == next_hop_sw_if_index)
+ if (0 == vec_len (rpaths))
{
mfib_entry_index = mfib_table_entry_update (fib_index, prefix,
MFIB_SOURCE_API,
rpf_id, entry_flags);
- goto done;
- }
-
- if (is_add)
- {
- mfib_entry_index = mfib_table_entry_path_update (fib_index, prefix,
- MFIB_SOURCE_API,
- &path, itf_flags);
}
else
{
- mfib_table_entry_path_remove (fib_index, prefix,
- MFIB_SOURCE_API, &path);
+ if (is_add)
+ {
+ mfib_entry_index =
+ mfib_table_entry_paths_update (fib_index, prefix,
+ MFIB_SOURCE_API, rpaths);
+ }
+ else
+ {
+ mfib_table_entry_paths_remove (fib_index, prefix,
+ MFIB_SOURCE_API, rpaths);
+ }
}
-done:
return (mfib_entry_index);
}
@@ -1302,64 +798,43 @@ static int
api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp,
u32 * stats_index)
{
+ fib_route_path_t *rpath, *rpaths = NULL;
fib_node_index_t mfib_entry_index;
- fib_protocol_t fproto;
- dpo_proto_t nh_proto;
- ip46_address_t nh;
+ mfib_prefix_t pfx;
u32 fib_index;
int rv;
+ u16 ii;
- nh_proto = mp->next_hop_afi;
- 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, &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)
- {
- 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));
- clib_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
+ for (ii = 0; ii < mp->route.n_paths; ii++)
{
- 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));
- clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6));
- if (!ip46_address_is_zero (&pfx.fp_src_addr))
- pfx.fp_len = 256;
+ rpath = &rpaths[ii];
+
+ rv = mfib_api_path_decode (&mp->route.paths[ii], rpath);
+
+ if (0 != rv)
+ goto out;
}
mfib_entry_index = mroute_add_del_handler (mp->is_add,
- mp->is_local,
+ mp->is_add,
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));
+ 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);
}
@@ -1367,14 +842,9 @@ 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;
+ u32 stats_index = ~0;
int rv;
- vnm = vnet_get_main ();
- vnm->api_errno = 0;
- stats_index = ~0;
-
rv = api_mroute_add_del_t_handler (mp, &stats_index);
/* *INDENT-OFF* */
@@ -1406,8 +876,8 @@ send_ip_details (vpe_api_main_t * am,
static void
send_ip_address_details (vpe_api_main_t * am,
vl_api_registration_t * reg,
- u8 * ip, u16 prefix_length,
- u32 sw_if_index, u8 is_ipv6, u32 context)
+ const fib_prefix_t * pfx,
+ u32 sw_if_index, u32 context)
{
vl_api_ip_address_details_t *mp;
@@ -1415,19 +885,9 @@ send_ip_address_details (vpe_api_main_t * am,
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_api_send_msg (reg, (u8 *) mp);
}
@@ -1437,8 +897,6 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
vl_api_registration_t *reg;
- ip6_address_t *r6;
- ip4_address_t *r4;
ip6_main_t *im6 = &ip6_main;
ip4_main_t *im4 = &ip4_main;
ip_lookup_main_t *lm6 = &im6->lookup_main;
@@ -1464,10 +922,12 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
* 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, reg, (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* */
}
@@ -1476,10 +936,13 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
/* *INDENT-OFF* */
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, reg, (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* */
}
@@ -1883,22 +1346,7 @@ vl_mfib_signal_send_one (vl_api_registration_t * reg,
mp->table_id = ntohl (mfib->mft_table_id);
mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
- if (FIB_PROTOCOL_IP4 == prefix->fp_proto)
- {
- mp->grp_address_len = ntohs (prefix->fp_len);
-
- memcpy (mp->grp_address, &prefix->fp_grp_addr.ip4, 4);
- if (prefix->fp_len > 32)
- {
- memcpy (mp->src_address, &prefix->fp_src_addr.ip4, 4);
- }
- }
- else
- {
- mp->grp_address_len = ntohs (prefix->fp_len);
-
- ASSERT (0);
- }
+ ip_mprefix_encode (prefix, &mp->prefix);
if (0 != mfs->mfs_buffer_len)
{
@@ -3369,9 +2817,11 @@ static walk_rc_t
send_ip_punt_redirect_details (u32 rx_sw_if_index,
const ip_punt_redirect_rx_t * ipr, void *arg)
{
- fib_route_path_encode_t *api_rpaths = NULL;
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)
@@ -3381,17 +2831,17 @@ send_ip_punt_redirect_details (u32 rx_sw_if_index,
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, &api_rpaths);
+ 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 (api_rpaths[0].rpath.frp_sw_if_index);
+ mp->punt.tx_sw_if_index = htonl (path_ctx.rpaths[0].frp_sw_if_index);
- ip_address_encode (&api_rpaths[0].rpath.frp_addr,
+ 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 (api_rpaths);
+ vec_free (path_ctx.rpaths);
return (WALK_CONTINUE);
}
@@ -3461,8 +2911,8 @@ ip_api_hookup (vlib_main_t * vm)
/*
* Mark the route add/del API as MP safe
*/
- am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
- am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE_REPLY] = 1;
+ 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
diff --git a/src/vnet/ip/ip_types_api.c b/src/vnet/ip/ip_types_api.c
index fd8d24f36fe..6ad2c366dff 100644
--- a/src/vnet/ip/ip_types_api.c
+++ b/src/vnet/ip/ip_types_api.c
@@ -229,6 +229,9 @@ ip_mprefix_decode (const vl_api_mprefix_t * in, mfib_prefix_t * out)
ip_address_union_decode (&in->grp_address, in->af, &out->fp_grp_addr);
ip_address_union_decode (&in->src_address, in->af, &out->fp_src_addr);
+
+ if (!ip46_address_is_zero (&out->fp_src_addr))
+ out->fp_len = (out->fp_proto == FIB_PROTOCOL_IP6 ? 256 : 64);
}
/*
diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c
index 5c6fec1810b..8c89ed4f490 100644
--- a/src/vnet/ip/lookup.c
+++ b/src/vnet/ip/lookup.c
@@ -441,7 +441,7 @@ vnet_ip_route_cmd (vlib_main_t * vm,
}
else if (0 < vec_len (rpaths))
{
- u32 k, j, n, incr;
+ u32 k, n, incr;
ip46_address_t dst = prefixs[i].fp_addr;
f64 t[2];
n = count;
@@ -451,25 +451,20 @@ vnet_ip_route_cmd (vlib_main_t * vm,
for (k = 0; k < n; k++)
{
- for (j = 0; j < vec_len (rpaths); j++)
- {
- fib_prefix_t rpfx = {
- .fp_len = prefixs[i].fp_len,
- .fp_proto = prefixs[i].fp_proto,
- .fp_addr = dst,
- };
-
- if (is_del)
- fib_table_entry_path_remove2 (fib_index,
- &rpfx,
- FIB_SOURCE_CLI, &rpaths[j]);
- else
- fib_table_entry_path_add2 (fib_index,
- &rpfx,
- FIB_SOURCE_CLI,
- FIB_ENTRY_FLAG_NONE,
- &rpaths[j]);
- }
+ fib_prefix_t rpfx = {
+ .fp_len = prefixs[i].fp_len,
+ .fp_proto = prefixs[i].fp_proto,
+ .fp_addr = dst,
+ };
+
+ if (is_del)
+ fib_table_entry_path_remove2 (fib_index,
+ &rpfx, FIB_SOURCE_CLI, rpaths);
+ else
+ fib_table_entry_path_add2 (fib_index,
+ &rpfx,
+ FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, rpaths);
if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto)
{
@@ -485,9 +480,9 @@ vnet_ip_route_cmd (vlib_main_t * vm,
clib_host_to_net_u64 (incr +
clib_net_to_host_u64 (dst.ip6.as_u64
[bucket]));
-
}
}
+
t[1] = vlib_time_now (vm);
if (count > 1)
vlib_cli_output (vm, "%.6e routes/sec", count / (t[1] - t[0]));
@@ -499,7 +494,6 @@ vnet_ip_route_cmd (vlib_main_t * vm,
}
}
-
done:
vec_free (dpos);
vec_free (prefixs);
@@ -805,20 +799,17 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
unformat_input_t * main_input, vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
+ fib_route_path_t rpath, *rpaths = NULL;
clib_error_t *error = NULL;
- fib_route_path_t rpath;
- u32 table_id, is_del;
- vnet_main_t *vnm;
+ u32 table_id, is_del, payload_proto;
mfib_prefix_t pfx;
u32 fib_index;
- mfib_itf_flags_t iflags = 0;
mfib_entry_flags_t eflags = 0;
u32 gcount, scount, ss, gg, incr;
f64 timet[2];
u32 rpf_id = MFIB_RPF_ID_NONE;
gcount = scount = 1;
- vnm = vnet_get_main ();
is_del = 0;
table_id = 0;
clib_memset (&pfx, 0, sizeof (pfx));
@@ -887,51 +878,6 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
pfx.fp_proto = FIB_PROTOCOL_IP6;
pfx.fp_len = 128;
}
- else if (unformat (line_input, "via %U %U %U",
- unformat_ip4_address, &rpath.frp_addr.ip4,
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index,
- unformat_mfib_itf_flags, &iflags))
- {
- rpath.frp_weight = 1;
- }
- else if (unformat (line_input, "via %U %U %U",
- unformat_ip6_address, &rpath.frp_addr.ip6,
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index,
- unformat_mfib_itf_flags, &iflags))
- {
- rpath.frp_weight = 1;
- }
- else if (unformat (line_input, "via %U %U",
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index,
- unformat_mfib_itf_flags, &iflags))
- {
- clib_memset (&rpath.frp_addr, 0, sizeof (rpath.frp_addr));
- rpath.frp_weight = 1;
- }
- else if (unformat (line_input, "via %U %U",
- unformat_ip4_address, &rpath.frp_addr.ip4,
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index))
- {
- rpath.frp_weight = 1;
- }
- else if (unformat (line_input, "via %U %U",
- unformat_ip6_address, &rpath.frp_addr.ip6,
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index))
- {
- rpath.frp_weight = 1;
- }
- else if (unformat (line_input, "via %U",
- unformat_vnet_sw_interface, vnm,
- &rpath.frp_sw_if_index))
- {
- clib_memset (&rpath.frp_addr, 0, sizeof (rpath.frp_addr));
- rpath.frp_weight = 1;
- }
else if (unformat (line_input, "via local Forward"))
{
clib_memset (&rpath.frp_addr, 0, sizeof (rpath.frp_addr));
@@ -942,9 +888,17 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
* set the path proto appropriately for the prefix
*/
rpath.frp_proto = fib_proto_to_dpo (pfx.fp_proto);
- iflags = MFIB_ITF_FLAG_FORWARD;
+ rpath.frp_mitf_flags = MFIB_ITF_FLAG_FORWARD;
+ }
+ else if (unformat (line_input, "via %U",
+ unformat_fib_route_path, &rpath, &payload_proto))
+ {
+ vec_add1 (rpaths, rpath);
}
else if (unformat (line_input, "%U",
+ unformat_mfib_itf_flags, &rpath.frp_mitf_flags))
+ ;
+ else if (unformat (line_input, "%U",
unformat_mfib_entry_flags, &eflags))
;
else
@@ -987,7 +941,7 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
{
for (gg = 0; gg < gcount; gg++)
{
- if (is_del && 0 == rpath.frp_weight)
+ if (is_del && 0 == vec_len (rpaths))
{
/* no path provided => route delete */
mfib_table_entry_delete (fib_index, &pfx, MFIB_SOURCE_CLI);
@@ -1001,11 +955,10 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
{
if (is_del)
mfib_table_entry_path_remove (fib_index,
- &pfx, MFIB_SOURCE_CLI, &rpath);
+ &pfx, MFIB_SOURCE_CLI, rpaths);
else
mfib_table_entry_path_update (fib_index,
- &pfx, MFIB_SOURCE_CLI, &rpath,
- iflags);
+ &pfx, MFIB_SOURCE_CLI, rpaths);
}
if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
@@ -1050,6 +1003,7 @@ vnet_ip_mroute_cmd (vlib_main_t * vm,
(scount * gcount) / (timet[1] - timet[0]));
done:
+ vec_free (rpaths);
unformat_free (line_input);
return error;