aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_api.c
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-05-01 05:17:55 -0700
committerOle Trøan <otroan@employees.org>2019-06-18 13:31:39 +0000
commit097fa66b986f06281f603767d321ab13ab6c88c3 (patch)
treeed052819615d08ee4bd0afbc34de7e64e4598105 /src/vnet/fib/fib_api.c
parent39baa32186fd3e4b20d9f58afbbfe7b8daebed62 (diff)
fib: fib api updates
Enhance the route add/del APIs to take a set of paths rather than just one. Most unicast routing protocols calcualte all the available paths in one run of the algorithm so updating all the paths at once is beneficial for the client. two knobs control the behaviour: is_multipath - if set the the set of paths passed will be added to those that already exist, otherwise the set will replace them. is_add - add or remove the set is_add=0, is_multipath=1 and an empty set, results in deleting the route. It is also considerably faster to add multiple paths at once, than one at a time: vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.11 100000 routes in .572240 secs, 174751.80 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.12 100000 routes in .528383 secs, 189256.54 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.13 100000 routes in .757131 secs, 132077.52 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.14 100000 routes in .878317 secs, 113854.12 routes/sec vat# ip_route_add_del 1.1.1.1/32 count 100000 multipath via 10.10.10.11 via 10.10.10.12 via 10.10.10.13 via 10.10.10.14 100000 routes in .900212 secs, 111084.93 routes/sec Change-Id: I416b93f7684745099c1adb0b33edac58c9339c1a Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
Diffstat (limited to 'src/vnet/fib/fib_api.c')
-rw-r--r--src/vnet/fib/fib_api.c608
1 files changed, 403 insertions, 205 deletions
diff --git a/src/vnet/fib/fib_api.c b/src/vnet/fib/fib_api.c
index 12c4f0de13f..5aa5c4ec875 100644
--- a/src/vnet/fib/fib_api.c
+++ b/src/vnet/fib/fib_api.c
@@ -16,10 +16,11 @@
#include <vnet/vnet.h>
#include <vlibmemory/api.h>
#include <vnet/fib/fib_api.h>
+#include <vnet/ip/ip_types_api.h>
#include <vnet/fib/fib_table.h>
#include <vnet/mfib/mfib_table.h>
#include <vnet/bier/bier_disp_table.h>
-#include <vnet/dpo/ip_null_dpo.h>
+#include <vpp/api/types.h>
#include <vnet/vnet_msg_enum.h>
@@ -40,288 +41,485 @@
#include <vlibapi/api_helper_macros.h>
int
-fib_path_api_parse (const vl_api_fib_path_t *in,
- fib_route_path_t *out)
+fib_api_table_id_decode (fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index)
{
- fib_route_path_flags_t path_flags;
- mpls_label_t next_hop_via_label;
- int rv = 0, n_labels;
- u8 ii;
+ *fib_index = fib_table_find(fproto, table_id);
- path_flags = FIB_ROUTE_PATH_FLAG_NONE;
- next_hop_via_label = ntohl (in->via_label);
- clib_memset(out, 0, sizeof(*out));
- out->frp_sw_if_index = ~0;
+ if (INDEX_INVALID == *fib_index)
+ {
+ return VNET_API_ERROR_NO_SUCH_FIB;
+ }
- out->frp_proto = in->afi;
- // .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
- out->frp_sw_if_index = ntohl(in->sw_if_index);
- out->frp_weight = in->weight;
- out->frp_preference = in->preference;
+ return (0);
+}
- if (DPO_PROTO_IP4 == out->frp_proto ||
- DPO_PROTO_IP6 == out->frp_proto ||
- DPO_PROTO_MPLS == out->frp_proto)
- {
- out->frp_fib_index = fib_table_find (dpo_proto_to_fib(out->frp_proto),
- ntohl (in->table_id));
+int
+fib_api_mtable_id_decode (fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index)
+{
+ *fib_index = mfib_table_find(fproto, table_id);
- if (~0 == out->frp_fib_index)
- return (VNET_API_ERROR_NO_SUCH_FIB);
+ if (~0 == *fib_index)
+ {
+ return VNET_API_ERROR_NO_SUCH_FIB;
}
- /*
- * 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))
+ return (0);
+}
+
+static void
+fib_api_next_hop_decode (const vl_api_fib_path_t *in,
+ ip46_address_t *out)
+{
+ if (in->proto == FIB_API_PATH_NH_PROTO_IP4)
+ memcpy (&out->ip4, &in->nh.address.ip4, sizeof (out->ip4));
+ else if (in->proto == FIB_API_PATH_NH_PROTO_IP6)
+ memcpy (&out->ip6, &in->nh.address.ip6, sizeof (out->ip6));
+}
+
+static vl_api_fib_path_nh_proto_t
+fib_api_path_dpo_proto_to_nh (dpo_proto_t dproto)
+{
+ switch (dproto)
{
- out->frp_proto = DPO_PROTO_MPLS;
- out->frp_local_label = next_hop_via_label;
- out->frp_eos = MPLS_NON_EOS;
+ case DPO_PROTO_IP4:
+ return (FIB_API_PATH_NH_PROTO_IP4);
+ case DPO_PROTO_IP6:
+ return (FIB_API_PATH_NH_PROTO_IP6);
+ case DPO_PROTO_MPLS:
+ return (FIB_API_PATH_NH_PROTO_MPLS);
+ case DPO_PROTO_BIER:
+ return (FIB_API_PATH_NH_PROTO_BIER);
+ case DPO_PROTO_ETHERNET:
+ return (FIB_API_PATH_NH_PROTO_ETHERNET);
+ case DPO_PROTO_NSH:
+ ASSERT(0);
+ break;
}
+ return (FIB_API_PATH_NH_PROTO_IP4);
+}
- n_labels = in->n_labels;
- if (n_labels == 0)
- ;
- else
+
+static void
+fib_api_next_hop_encode (const fib_route_path_t *rpath,
+ vl_api_fib_path_t *fp)
+{
+ fp->proto = fib_api_path_dpo_proto_to_nh(rpath->frp_proto);
+
+ if (rpath->frp_proto == DPO_PROTO_IP4)
+ memcpy (&fp->nh.address.ip4,
+ &rpath->frp_addr.ip4,
+ sizeof (rpath->frp_addr.ip4));
+ else if (rpath->frp_proto == DPO_PROTO_IP6)
+ memcpy (&fp->nh.address.ip6,
+ &rpath->frp_addr.ip6,
+ sizeof (rpath->frp_addr.ip6));
+}
+
+static int
+fib_api_path_nh_proto_to_dpo (vl_api_fib_path_nh_proto_t pp,
+ dpo_proto_t *dproto)
+{
+ switch (pp)
{
- vec_validate (out->frp_label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- {
- out->frp_label_stack[ii].fml_value =
- ntohl(in->label_stack[ii].label);
- out->frp_label_stack[ii].fml_ttl =
- in->label_stack[ii].ttl;
- out->frp_label_stack[ii].fml_exp =
- in->label_stack[ii].exp;
- out->frp_label_stack[ii].fml_mode =
- (in->label_stack[ii].is_uniform ?
- FIB_MPLS_LSP_MODE_UNIFORM :
- FIB_MPLS_LSP_MODE_PIPE);
- }
+ case FIB_API_PATH_NH_PROTO_IP4:
+ *dproto = DPO_PROTO_IP4;
+ break;
+ case FIB_API_PATH_NH_PROTO_IP6:
+ *dproto = DPO_PROTO_IP6;
+ break;
+ case FIB_API_PATH_NH_PROTO_MPLS:
+ *dproto = DPO_PROTO_MPLS;
+ break;
+ case FIB_API_PATH_NH_PROTO_BIER:
+ *dproto = DPO_PROTO_BIER;
+ break;
+ case FIB_API_PATH_NH_PROTO_ETHERNET:
+ *dproto = DPO_PROTO_ETHERNET;
+ break;
+ default:
+ return (-1);
}
+ return (0);
+}
+
+int
+fib_api_path_decode (vl_api_fib_path_t *in,
+ fib_route_path_t *out)
+{
+ vnet_classify_main_t *cm = &vnet_classify_main;
+ int rv = 0, n_labels;
+ vnet_main_t *vnm;
+ u8 ii;
+
+ vnm = vnet_get_main ();
+ clib_memset(&out->frp_dpo, 0, sizeof(out->frp_dpo));
+
+ /* enums are u32 */
+ in->flags = ntohl (in->flags);
+ in->type = ntohl (in->type);
+ in->proto = ntohl (in->proto);
- if (in->is_dvr)
- path_flags |= FIB_ROUTE_PATH_DVR;
- if (in->is_resolve_host)
- path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
- if (in->is_resolve_attached)
- path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
- /* if (in->is_interface_rx) */
- /* path_flags |= FIB_ROUTE_PATH_INTF_RX; */
- /* if (in->is_rpf_id) */
- /* path_flags |= FIB_ROUTE_PATH_RPF_ID; */
- if (in->is_source_lookup)
- path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
-
- if (in->is_udp_encap)
+ /*
+ * attributes that apply to all path types
+ */
+ out->frp_flags = 0;
+ out->frp_weight = in->weight;
+ if (0 == out->frp_weight)
{
- path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
- out->frp_udp_encap_id = ntohl(in->next_hop_id);
+ out->frp_weight = 1;
}
- else
+ out->frp_preference = in->preference;
+
+ rv = fib_api_path_nh_proto_to_dpo(in->proto, &out->frp_proto);
+
+ if (0 != rv)
+ return (rv);
+
+ /*
+ * convert the flags and the AFI to determine the path type
+ */
+ if (in->flags & FIB_API_PATH_FLAG_RESOLVE_VIA_HOST)
+ out->frp_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
+ if (in->flags & FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED)
+ out->frp_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+
+ switch (in->type)
{
- if (DPO_PROTO_IP4 == in->afi)
- {
- clib_memcpy (&out->frp_addr.ip4,
- in->next_hop,
- sizeof (out->frp_addr.ip4));
- }
- else if (DPO_PROTO_IP6 == in->afi)
+ case FIB_API_PATH_TYPE_DVR:
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ out->frp_flags |= FIB_ROUTE_PATH_DVR;
+ break;
+ case FIB_API_PATH_TYPE_INTERFACE_RX:
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ out->frp_flags |= FIB_ROUTE_PATH_INTF_RX;
+ break;
+ case FIB_API_PATH_TYPE_DROP:
+ out->frp_flags |= FIB_ROUTE_PATH_DROP;
+ break;
+ case FIB_API_PATH_TYPE_LOCAL:
+ out->frp_flags |= FIB_ROUTE_PATH_LOCAL;
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ break;
+ case FIB_API_PATH_TYPE_ICMP_UNREACH:
+ out->frp_flags |= FIB_ROUTE_PATH_ICMP_UNREACH;
+ break;
+ case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
+ out->frp_flags |= FIB_ROUTE_PATH_ICMP_PROHIBIT;
+ break;
+ case FIB_API_PATH_TYPE_CLASSIFY:
+ out->frp_flags |= FIB_ROUTE_PATH_CLASSIFY;
+
+ if (pool_is_free_index (cm->tables, ntohl (in->nh.classify_table_index)))
{
- clib_memcpy (&out->frp_addr.ip6,
- in->next_hop,
- sizeof (out->frp_addr.ip6));
+ return VNET_API_ERROR_NO_SUCH_TABLE;
}
+ out->frp_classify_table_id = ntohl (in->nh.classify_table_index);
+ break;
+ case FIB_API_PATH_TYPE_UDP_ENCAP:
+ out->frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
+ out->frp_udp_encap_id = ntohl(in->nh.obj_id);
+ break;
+ case FIB_API_PATH_TYPE_BIER_IMP:
+ out->frp_flags |= FIB_ROUTE_PATH_BIER_IMP;
+ out->frp_bier_imp = ntohl (in->nh.obj_id);
+ break;
- if (ip46_address_is_zero(&out->frp_addr))
+ case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
+ out->frp_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
+ /* fall through */
+ case FIB_API_PATH_TYPE_NORMAL:
+ switch (out->frp_proto)
{
- if (DPO_PROTO_BIER == in->afi)
+ case DPO_PROTO_IP4:
+ case DPO_PROTO_IP6:
+ fib_api_next_hop_decode(in, &out->frp_addr);
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ out->frp_rpf_id = ntohl(in->rpf_id);
+
+ if (0 == out->frp_rpf_id)
{
- index_t bdti;
+ /* allow 0 to be an unset value on the API */
+ out->frp_rpf_id = ~0;
+ }
- bdti = bier_disp_table_find(ntohl(in->table_id));
+ if (~0 != out->frp_rpf_id)
+ {
+ out->frp_flags |= FIB_ROUTE_PATH_RPF_ID;
+ }
- if (INDEX_INVALID != bdti)
+ if (~0 == out->frp_sw_if_index)
+ {
+ /* recursive or deag, validate the next-hop FIB */
+ if (~0 != out->frp_rpf_id)
{
- out->frp_fib_index = bdti;
- out->frp_proto = DPO_PROTO_BIER;
+ rv = fib_api_mtable_id_decode(
+ dpo_proto_to_fib(out->frp_proto),
+ ntohl(in->table_id),
+ &out->frp_fib_index);
}
else
{
- rv = VNET_API_ERROR_NO_SUCH_FIB;
+ rv = fib_api_table_id_decode(
+ dpo_proto_to_fib(out->frp_proto),
+ ntohl(in->table_id),
+ &out->frp_fib_index);
+ }
+ if (0 != rv)
+ {
+ return (rv);
}
}
- else if (out->frp_sw_if_index == ~0 &&
- out->frp_fib_index != ~0)
+ else
{
- path_flags |= FIB_ROUTE_PATH_DEAG;
+ if (pool_is_free_index (vnm->interface_main.sw_interfaces,
+ out->frp_sw_if_index))
+ {
+ return VNET_API_ERROR_NO_MATCHING_INTERFACE;
+ }
}
- }
- }
- out->frp_flags = path_flags;
+ if (ip46_address_is_zero(&out->frp_addr))
+ {
+ if (~0 == out->frp_sw_if_index &&
+ ~0 != out->frp_fib_index)
+ {
+ out->frp_flags |= FIB_ROUTE_PATH_DEAG;
+ }
+ }
- return (rv);
-}
+ break;
+ case DPO_PROTO_MPLS:
+ out->frp_local_label = ntohl (in->nh.via_label);
+ out->frp_eos = MPLS_NON_EOS;
+ out->frp_sw_if_index = ~0;
+ break;
+ case DPO_PROTO_BIER:
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ out->frp_rpf_id = ntohl(in->rpf_id);
-void
-fib_prefix_to_api (const fib_prefix_t *pfx,
- u8 address[16],
- u8 *length,
- u8 *is_ip6)
-{
- *length = pfx->fp_len;
- *is_ip6 = (FIB_PROTOCOL_IP6 == pfx->fp_proto ? 1 : 0);
+ if (!(out->frp_flags & FIB_ROUTE_PATH_BIER_IMP))
+ {
+ fib_api_next_hop_decode(in, &out->frp_addr);
- if (FIB_PROTOCOL_IP6 == pfx->fp_proto)
- {
- memcpy (address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
- }
- else
- {
- memcpy (address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
+ if (ip46_address_is_zero(&out->frp_addr))
+ {
+ index_t bdti;
+
+ bdti = bier_disp_table_find(ntohl(in->table_id));
+
+ if (INDEX_INVALID != bdti)
+ {
+ out->frp_fib_index = bdti;
+ }
+ else
+ {
+ return (VNET_API_ERROR_NO_SUCH_FIB);
+ }
+ }
+ }
+ break;
+ case DPO_PROTO_ETHERNET:
+ out->frp_sw_if_index = ntohl(in->sw_if_index);
+ break;
+ case DPO_PROTO_NSH:
+ break;
+ }
}
-}
-static void
-fib_api_path_copy_next_hop (const 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;
-
- 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
+ n_labels = in->n_labels;
+ if (n_labels != 0)
{
- 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;
+ vec_validate (out->frp_label_stack, n_labels - 1);
+ for (ii = 0; ii < n_labels; ii++)
+ {
+ out->frp_label_stack[ii].fml_value =
+ ntohl(in->label_stack[ii].label);
+ out->frp_label_stack[ii].fml_ttl =
+ in->label_stack[ii].ttl;
+ out->frp_label_stack[ii].fml_exp =
+ in->label_stack[ii].exp;
+ out->frp_label_stack[ii].fml_mode =
+ (in->label_stack[ii].is_uniform ?
+ FIB_MPLS_LSP_MODE_UNIFORM :
+ FIB_MPLS_LSP_MODE_PIPE);
+ }
}
- 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));
+
+ return (0);
}
void
-fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
+fib_api_path_encode (const fib_route_path_t * rpath,
vl_api_fib_path_t *out)
{
- int ii;
+ memset (out, 0, sizeof (*out));
- clib_memset (out, 0, sizeof (*out));
- switch (api_rpath->dpo.dpoi_type)
- {
- case DPO_RECEIVE:
- out->is_local = true;
- break;
- case DPO_DROP:
- out->is_drop = true;
- break;
- case DPO_IP_NULL:
- switch (ip_null_dpo_get_action(api_rpath->dpo.dpoi_index))
- {
- case IP_NULL_ACTION_NONE:
- out->is_drop = true;
- break;
- case IP_NULL_ACTION_SEND_ICMP_UNREACH:
- out->is_unreach = true;
- break;
- case IP_NULL_ACTION_SEND_ICMP_PROHIBIT:
- out->is_prohibit = true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- out->weight = api_rpath->rpath.frp_weight;
- out->preference = api_rpath->rpath.frp_preference;
- out->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- out->afi = api_rpath->rpath.frp_proto;
- fib_api_path_copy_next_hop (api_rpath, out);
+ out->weight = rpath->frp_weight;
+ out->preference = rpath->frp_preference;
+ out->sw_if_index = htonl (rpath->frp_sw_if_index);
+ out->proto = fib_api_path_dpo_proto_to_nh(rpath->frp_proto);
+ out->rpf_id = rpath->frp_rpf_id;
+ fib_api_next_hop_encode (rpath, out);
- if (0 != api_rpath->rpath.frp_fib_index)
+ if (0 != rpath->frp_fib_index)
{
- if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
- (DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
+ if ((DPO_PROTO_IP6 == rpath->frp_proto) ||
+ (DPO_PROTO_IP4 == rpath->frp_proto))
{
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RPF_ID)
+ if (rpath->frp_flags & FIB_ROUTE_PATH_RPF_ID)
{
- out->table_id =
- htonl(mfib_table_get_table_id(
- api_rpath->rpath.frp_fib_index,
- dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
+ out->table_id = htonl (mfib_table_get_table_id(
+ rpath->frp_fib_index,
+ dpo_proto_to_fib(rpath->frp_proto)));
}
else
{
- out->table_id =
- htonl(fib_table_get_table_id(
- api_rpath->rpath.frp_fib_index,
- dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
+ out->table_id = htonl (fib_table_get_table_id(
+ rpath->frp_fib_index,
+ dpo_proto_to_fib(rpath->frp_proto)));
}
}
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_DVR)
+ if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
{
- out->is_dvr = 1;
+ out->type = FIB_API_PATH_TYPE_DVR;
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_UNREACH)
{
- out->is_udp_encap = 1;
- out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
+ out->type = FIB_API_PATH_TYPE_ICMP_UNREACH;
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_INTF_RX)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_PROHIBIT)
{
- out->is_interface_rx = 1;
+ out->type = FIB_API_PATH_TYPE_ICMP_PROHIBIT;
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_LOCAL)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
{
- out->is_local = 1;
+ out->type = FIB_API_PATH_TYPE_LOCAL;
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_HOST)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_DROP)
{
- out->is_resolve_host = 1;
+ out->type = FIB_API_PATH_TYPE_DROP;
}
- if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
{
- out->is_resolve_attached = 1;
+ out->type = FIB_API_PATH_TYPE_UDP_ENCAP;
+ out->nh.obj_id = rpath->frp_udp_encap_id;
}
- /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_ATTACHED) { */
- /* out->is_attached = 1; */
- /* } */
- /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_CONNECTED) { */
- /* out->is_connected = 1; */
- /* } */
- if (api_rpath->rpath.frp_label_stack)
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP)
+ {
+ out->type = FIB_API_PATH_TYPE_BIER_IMP;
+ out->nh.obj_id = rpath->frp_bier_imp;
+ }
+ else
+ {
+ out->type = FIB_API_PATH_TYPE_NORMAL;
+ }
+ if (rpath->frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_HOST)
+ {
+ out->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
+ }
+ if (rpath->frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED)
+ {
+ out->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
+ }
+
+ out->flags = htonl (out->flags);
+ out->type = htonl (out->type);
+ out->proto = htonl (out->proto);
+
+ if (rpath->frp_label_stack)
{
- for (ii = 0; ii < vec_len(api_rpath->rpath.frp_label_stack); ii++)
+ int ii;
+
+ for (ii = 0; ii < vec_len(rpath->frp_label_stack); ii++)
{
out->label_stack[ii].label =
- htonl(api_rpath->rpath.frp_label_stack[ii].fml_value);
+ htonl(rpath->frp_label_stack[ii].fml_value);
out->label_stack[ii].ttl =
- api_rpath->rpath.frp_label_stack[ii].fml_ttl;
+ rpath->frp_label_stack[ii].fml_ttl;
out->label_stack[ii].exp =
- api_rpath->rpath.frp_label_stack[ii].fml_exp;
+ rpath->frp_label_stack[ii].fml_exp;
}
out->n_labels = ii;
}
}
+void
+fib_api_route_add_del (u8 is_add,
+ u8 is_multipath,
+ u32 fib_index,
+ const fib_prefix_t * prefix,
+ fib_entry_flag_t entry_flags,
+ fib_route_path_t *rpaths)
+{
+ if (is_multipath)
+ {
+ /* Iterative path add/remove */
+ if (is_add)
+ fib_table_entry_path_add2 (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ entry_flags,
+ rpaths);
+ else
+ fib_table_entry_path_remove2 (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ rpaths);
+ }
+ else
+ {
+ if (is_add)
+ /* path replacement */
+ fib_table_entry_update (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ entry_flags,
+ rpaths);
+ else
+ /* entry delete */
+ fib_table_entry_delete (fib_index,
+ prefix,
+ FIB_SOURCE_API);
+ }
+}
+
+u8*
+format_vl_api_fib_path (u8 * s, va_list * args)
+{
+ const vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t*);
+
+ s = format (s, "sw_if_index %d", ntohl (path->sw_if_index));
+ switch (clib_net_to_host_u32(path->proto))
+ {
+ case FIB_API_PATH_NH_PROTO_IP4:
+ s = format (s, " %U", format_vl_api_address_union,
+ &path->nh.address, ADDRESS_IP4);
+ break;
+ case FIB_API_PATH_NH_PROTO_IP6:
+ s = format (s, " %U", format_vl_api_address_union,
+ &path->nh.address, ADDRESS_IP6);
+ break;
+ default:
+ break;
+ }
+ s = format (s, " weight %d", path->weight);
+ s = format (s, " preference %d", path->preference);
+ s = format (s, " type %d", ntohl(path->type));
+ s = format (s, " proto %d", ntohl(path->proto));
+ s = format (s, " flags %d", ntohl(path->flags));
+ s = format (s, " n_labels %d", ntohl(path->n_labels));
+ s = format (s, " table-id %d", ntohl(path->table_id));
+ s = format (s, " rpf-id %d", ntohl(path->rpf_id));
+
+ return (s);
+}
+
fib_protocol_t
fib_proto_from_api_address_family (int af)
{