aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_api.c
diff options
context:
space:
mode:
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)
{