aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
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
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')
-rw-r--r--src/vnet/CMakeLists.txt1
-rw-r--r--src/vnet/api_errno.h5
-rw-r--r--src/vnet/bier/bier.api21
-rw-r--r--src/vnet/bier/bier_api.c64
-rw-r--r--src/vnet/bier/bier_entry.c2
-rw-r--r--src/vnet/bier/bier_fmask.c12
-rw-r--r--src/vnet/bier/bier_fmask.h2
-rw-r--r--src/vnet/bier/bier_table.c9
-rw-r--r--src/vnet/dhcp/dhcp6_proxy_node.c6
-rw-r--r--src/vnet/dpo/mpls_disposition.c30
-rw-r--r--src/vnet/fib/fib_api.c608
-rw-r--r--src/vnet/fib/fib_api.h73
-rw-r--r--src/vnet/fib/fib_entry.c24
-rw-r--r--src/vnet/fib/fib_entry.h9
-rw-r--r--src/vnet/fib/fib_entry_src.c67
-rw-r--r--src/vnet/fib/fib_path.c138
-rw-r--r--src/vnet/fib/fib_path.h28
-rw-r--r--src/vnet/fib/fib_path_list.c236
-rw-r--r--src/vnet/fib/fib_path_list.h4
-rw-r--r--src/vnet/fib/fib_table.c51
-rw-r--r--src/vnet/fib/fib_types.api127
-rw-r--r--src/vnet/fib/fib_types.c18
-rw-r--r--src/vnet/fib/fib_types.h52
-rw-r--r--src/vnet/fib/mpls_fib.c17
-rw-r--r--src/vnet/geneve/geneve.c12
-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
-rw-r--r--src/vnet/mfib/ip6_mfib.c14
-rw-r--r--src/vnet/mfib/mfib_api.c119
-rw-r--r--src/vnet/mfib/mfib_api.h38
-rw-r--r--src/vnet/mfib/mfib_entry.c224
-rw-r--r--src/vnet/mfib/mfib_entry.h6
-rw-r--r--src/vnet/mfib/mfib_table.c95
-rw-r--r--src/vnet/mfib/mfib_table.h25
-rw-r--r--src/vnet/mfib/mfib_types.api35
-rw-r--r--src/vnet/mpls/mpls.api129
-rw-r--r--src/vnet/mpls/mpls_api.c352
-rw-r--r--src/vnet/mpls/mpls_tunnel.c14
-rw-r--r--src/vnet/udp/udp_encap.c2
-rw-r--r--src/vnet/vxlan-gbp/vxlan_gbp.c8
-rw-r--r--src/vnet/vxlan-gpe/vxlan_gpe.c10
-rw-r--r--src/vnet/vxlan/vxlan.c12
44 files changed, 2080 insertions, 2067 deletions
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index 1d7d4988002..5465d717f8c 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -1455,6 +1455,7 @@ list(APPEND VNET_SOURCES
mfib/mfib_forward.c
mfib/ip4_mfib.c
mfib/ip6_mfib.c
+ mfib/mfib_api.c
mfib/mfib_types.c
mfib/mfib_signal.c
mfib/mfib_itf.c
diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h
index be42086e668..8771d2c1a88 100644
--- a/src/vnet/api_errno.h
+++ b/src/vnet/api_errno.h
@@ -44,7 +44,7 @@ _(FEATURE_DISABLED, -30, "Feature disabled by configuration") \
_(INVALID_REGISTRATION, -31, "Invalid registration") \
_(NEXT_HOP_NOT_IN_FIB, -50, "Next hop not in FIB") \
_(UNKNOWN_DESTINATION, -51, "Unknown destination") \
-_(PREFIX_MATCHES_NEXT_HOP, -52, "Prefix matches next hop") \
+_(NO_PATHS_IN_ROUTE, -52, "No paths specified in route") \
_(NEXT_HOP_NOT_FOUND_MP, -53, "Next hop not found (multipath)") \
_(NO_MATCHING_INTERFACE, -54, "No matching interface for probe") \
_(INVALID_VLAN, -55, "Invalid VLAN") \
@@ -148,7 +148,8 @@ _(BD_ALREADY_HAS_BVI, -152, "Bridge domain already has a BVI interface") \
_(INVALID_PROTOCOL, -153, "Invalid Protocol") \
_(INVALID_ALGORITHM, -154, "Invalid Algorithm") \
_(RSRC_IN_USE, -155, "Resource In Use") \
-_(KEY_LENGTH, -156, "invalid Key Length")
+_(KEY_LENGTH, -156, "invalid Key Length") \
+_(FIB_PATH_UNSUPPORTED_NH_PROTO, -157, "Unsupported FIB Path protocol")
typedef enum
{
diff --git a/src/vnet/bier/bier.api b/src/vnet/bier/bier.api
index b5ac8cabd39..0cc56cab50a 100644
--- a/src/vnet/bier/bier.api
+++ b/src/vnet/bier/bier.api
@@ -1,3 +1,4 @@
+/* Hey Emacs use -*- mode: C -*- */
/*
* Copyright (c) 2016 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +19,7 @@
This file defines vpp BIER control-plane API messages which are generally
called through a shared memory interface.
*/
-option version = "1.1.0";
+option version = "1.2.0";
import "vnet/fib/fib_types.api";
/** \brief BIER Table Identifier
@@ -77,16 +78,21 @@ define bier_table_details
@param br_n_paths - The number of paths
@param br_paths - The array of paths
*/
+typedef bier_route
+{
+ u32 br_bp;
+ vl_api_bier_table_id_t br_tbl_id;
+ u8 br_n_paths;
+ vl_api_fib_path_t br_paths[br_n_paths];
+};
+
autoreply define bier_route_add_del
{
u32 client_index;
u32 context;
- u32 br_bp;
u8 br_is_add;
u8 br_is_replace;
- vl_api_bier_table_id_t br_tbl_id;
- u8 br_n_paths;
- vl_api_fib_path_t br_paths[br_n_paths];
+ vl_api_bier_route_t br_route;
};
define bier_route_dump
@@ -99,10 +105,7 @@ define bier_route_dump
define bier_route_details
{
u32 context;
- u16 br_bp;
- vl_api_bier_table_id_t br_tbl_id;
- u32 br_n_paths;
- vl_api_fib_path_t br_paths[br_n_paths];
+ vl_api_bier_route_t br_route;
};
/** \brief BIER Imposition Add
diff --git a/src/vnet/bier/bier_api.c b/src/vnet/bier/bier_api.c
index d8248b1b2bd..66f6b422810 100644
--- a/src/vnet/bier/bier_api.c
+++ b/src/vnet/bier/bier_api.c
@@ -169,10 +169,10 @@ vl_api_bier_route_add_del_t_handler (vl_api_bier_route_add_del_t * mp)
vnm = vnet_get_main ();
vnm->api_errno = 0;
- bp = ntohl(mp->br_bp);
+ bp = ntohl(mp->br_route.br_bp);
brpaths = NULL;
- if (mp->br_tbl_id.bt_hdr_len_id >= BIER_HDR_LEN_2048)
+ if (mp->br_route.br_tbl_id.bt_hdr_len_id >= BIER_HDR_LEN_2048)
{
rv = VNET_API_ERROR_BIER_BSL_UNSUP;
goto done;
@@ -184,19 +184,19 @@ vl_api_bier_route_add_del_t_handler (vl_api_bier_route_add_del_t * mp)
}
bier_table_id_t bti = {
- .bti_set = mp->br_tbl_id.bt_set,
- .bti_sub_domain = mp->br_tbl_id.bt_sub_domain,
- .bti_hdr_len = mp->br_tbl_id.bt_hdr_len_id,
+ .bti_set = mp->br_route.br_tbl_id.bt_set,
+ .bti_sub_domain = mp->br_route.br_tbl_id.bt_sub_domain,
+ .bti_hdr_len = mp->br_route.br_tbl_id.bt_hdr_len_id,
.bti_type = BIER_TABLE_MPLS_SPF,
.bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
};
- vec_validate(brpaths, mp->br_n_paths - 1);
+ vec_validate(brpaths, mp->br_route.br_n_paths - 1);
vec_foreach_index(ii, brpaths)
{
brpath = &brpaths[ii];
- rv = fib_path_api_parse(&mp->br_paths[ii], brpath);
+ rv = fib_api_path_decode(&mp->br_route.br_paths[ii], brpath);
if (0 != rv)
{
@@ -242,9 +242,12 @@ send_bier_route_details (const bier_table_t *bt,
const bier_entry_t *be,
void *args)
{
- fib_route_path_encode_t *api_rpaths = NULL, *api_rpath;
bier_route_details_walk_t *ctx = args;
vl_api_bier_route_details_t *mp;
+ fib_path_encode_ctx_t path_ctx = {
+ .rpaths = NULL,
+ };
+ fib_route_path_t *rpath;
vl_api_fib_path_t *fp;
u32 n_paths, m_size;
@@ -258,24 +261,25 @@ send_bier_route_details (const bier_table_t *bt,
mp->_vl_msg_id = ntohs(VL_API_BIER_ROUTE_DETAILS);
mp->context = ctx->context;
- mp->br_tbl_id.bt_set = bt->bt_id.bti_set;
- mp->br_tbl_id.bt_sub_domain = bt->bt_id.bti_sub_domain;
- mp->br_tbl_id.bt_hdr_len_id = bt->bt_id.bti_hdr_len;
- mp->br_bp = htons(be->be_bp);
- mp->br_n_paths = htonl(n_paths);
+ mp->br_route.br_tbl_id.bt_set = bt->bt_id.bti_set;
+ mp->br_route.br_tbl_id.bt_sub_domain = bt->bt_id.bti_sub_domain;
+ mp->br_route.br_tbl_id.bt_hdr_len_id = bt->bt_id.bti_hdr_len;
+ mp->br_route.br_bp = htonl(be->be_bp);
+ mp->br_route.br_n_paths = htonl(n_paths);
fib_path_list_walk_w_ext(be->be_path_list,
NULL,
fib_path_encode,
- &api_rpaths);
+ &path_ctx);
- fp = mp->br_paths;
- vec_foreach (api_rpath, api_rpaths)
+ fp = mp->br_route.br_paths;
+ vec_foreach (rpath, path_ctx.rpaths)
{
- fib_api_path_encode(api_rpath, fp);
+ fib_api_path_encode(rpath, fp);
fp++;
}
+ vec_free(path_ctx.rpaths);
vl_api_send_msg (ctx->reg, (u8 *) mp);
}
@@ -506,16 +510,16 @@ vl_api_bier_disp_entry_add_del_t_handler (vl_api_bier_disp_entry_add_del_t * mp)
brp->frp_rpf_id = ntohl(mp->bde_paths[ii].rpf_id);
}
- if (0 == mp->bde_paths[ii].afi)
+ if (FIB_API_PATH_NH_PROTO_IP4 == mp->bde_paths[ii].proto)
{
- clib_memcpy_fast (&brp->frp_addr.ip4,
- mp->bde_paths[ii].next_hop,
+ clib_memcpy (&brp->frp_addr.ip4,
+ &mp->bde_paths[ii].nh.address.ip4,
sizeof (brp->frp_addr.ip4));
}
- else
+ else if (FIB_API_PATH_NH_PROTO_IP6 == mp->bde_paths[ii].proto)
{
- clib_memcpy_fast (&brp->frp_addr.ip6,
- mp->bde_paths[ii].next_hop,
+ clib_memcpy (&brp->frp_addr.ip6,
+ &mp->bde_paths[ii].nh.address.ip6,
sizeof (brp->frp_addr.ip6));
}
if (ip46_address_is_zero(&brp->frp_addr))
@@ -601,7 +605,6 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt,
u16 bp,
void *args)
{
- fib_route_path_encode_t *api_rpaths = NULL, *api_rpath;
bier_disp_entry_details_walk_t *ctx = args;
vl_api_bier_disp_entry_details_t *mp;
bier_hdr_proto_id_t pproto;
@@ -611,8 +614,14 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt,
FOR_EACH_BIER_HDR_PROTO(pproto)
{
fib_node_index_t pl = bde->bde_pl[pproto];
+
if (INDEX_INVALID != pl)
{
+ fib_path_encode_ctx_t path_ctx = {
+ .rpaths = NULL,
+ };
+ fib_route_path_t *rpath;
+
n_paths = fib_path_list_get_n_paths(pl);
m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path_t));
mp = vl_msg_api_alloc(m_size);
@@ -631,16 +640,17 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt,
fib_path_list_walk_w_ext(pl,
NULL,
fib_path_encode,
- &api_rpaths);
+ &path_ctx);
fp = mp->bde_paths;
- vec_foreach (api_rpath, api_rpaths)
+ vec_foreach (rpath, path_ctx.rpaths)
{
- fib_api_path_encode(api_rpath, fp);
+ fib_api_path_encode(rpath, fp);
fp++;
}
vl_api_send_msg (ctx->reg, (u8 *) mp);
+ vec_free(path_ctx.rpaths);
}
}
}
diff --git a/src/vnet/bier/bier_entry.c b/src/vnet/bier/bier_entry.c
index 77d96b80782..e8bf722d88f 100644
--- a/src/vnet/bier/bier_entry.c
+++ b/src/vnet/bier/bier_entry.c
@@ -147,7 +147,7 @@ bier_entry_delete (index_t bei)
be = bier_entry_get(bei);
/*
- * if we still ahve a path-list, unlink from it
+ * if we still have a path-list, unlink from it
*/
if (FIB_NODE_INDEX_INVALID != be->be_path_list)
{
diff --git a/src/vnet/bier/bier_fmask.c b/src/vnet/bier/bier_fmask.c
index b6169d3c4bb..a58a77ff281 100644
--- a/src/vnet/bier/bier_fmask.c
+++ b/src/vnet/bier/bier_fmask.c
@@ -404,7 +404,7 @@ bier_fmask_get_stats (index_t bfmi, u64 * packets, u64 * bytes)
void
bier_fmask_encode (index_t bfmi,
bier_table_id_t *btid,
- fib_route_path_encode_t *rpath)
+ fib_route_path_t *rpath)
{
bier_fmask_t *bfm;
@@ -413,17 +413,17 @@ bier_fmask_encode (index_t bfmi,
clib_memset(rpath, 0, sizeof(*rpath));
- rpath->rpath.frp_sw_if_index = ~0;
+ rpath->frp_sw_if_index = ~0;
switch (bfm->bfm_id->bfmi_nh_type)
{
case BIER_NH_UDP:
- rpath->rpath.frp_flags = FIB_ROUTE_PATH_UDP_ENCAP;
- rpath->rpath.frp_udp_encap_id = bfm->bfm_id->bfmi_id;
+ rpath->frp_flags = FIB_ROUTE_PATH_UDP_ENCAP;
+ rpath->frp_udp_encap_id = bfm->bfm_id->bfmi_id;
break;
case BIER_NH_IP:
- memcpy(&rpath->rpath.frp_addr, &bfm->bfm_id->bfmi_nh,
- sizeof(rpath->rpath.frp_addr));
+ memcpy(&rpath->frp_addr, &bfm->bfm_id->bfmi_nh,
+ sizeof(rpath->frp_addr));
break;
}
}
diff --git a/src/vnet/bier/bier_fmask.h b/src/vnet/bier/bier_fmask.h
index e522b0350e7..87845bb031b 100644
--- a/src/vnet/bier/bier_fmask.h
+++ b/src/vnet/bier/bier_fmask.h
@@ -166,7 +166,7 @@ extern void bier_fmask_child_remove (fib_node_index_t fib_entry_index,
extern void bier_fmask_get_stats (index_t bfmi, u64 * packets, u64 * bytes);
extern void bier_fmask_encode (index_t bfmi,
bier_table_id_t *btid,
- fib_route_path_encode_t *rpath);
+ fib_route_path_t *rpath);
/*
* provided for fast data-path access
diff --git a/src/vnet/bier/bier_table.c b/src/vnet/bier/bier_table.c
index a9f8a6d338f..0e8cc1e88b4 100644
--- a/src/vnet/bier/bier_table.c
+++ b/src/vnet/bier/bier_table.c
@@ -779,9 +779,12 @@ bier_table_ecmp_walk (index_t bti,
bt = bier_table_get(bti);
- fib_path_list_walk(bt->bt_pl,
- bier_table_ecmp_walk_path_list,
- &ewc);
+ if (FIB_NODE_INDEX_INVALID != bt->bt_pl)
+ {
+ fib_path_list_walk(bt->bt_pl,
+ bier_table_ecmp_walk_path_list,
+ &ewc);
+ }
}
void
diff --git a/src/vnet/dhcp/dhcp6_proxy_node.c b/src/vnet/dhcp/dhcp6_proxy_node.c
index a199b7a34e4..a253fa1959f 100644
--- a/src/vnet/dhcp/dhcp6_proxy_node.c
+++ b/src/vnet/dhcp/dhcp6_proxy_node.c
@@ -893,16 +893,16 @@ dhcp6_proxy_set_server (ip46_address_t * addr,
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
if (dhcp_proxy_server_add (FIB_PROTOCOL_IP6, addr, src_addr,
rx_fib_index, server_table_id))
{
mfib_table_entry_path_update (rx_fib_index,
&all_dhcp_servers,
- MFIB_SOURCE_DHCP,
- &path_for_us, MFIB_ITF_FLAG_FORWARD);
+ MFIB_SOURCE_DHCP, &path_for_us);
/*
* Each interface that is enabled in this table, needs to be added
* as an accepting interface, but this is not easily doable in VPP.
diff --git a/src/vnet/dpo/mpls_disposition.c b/src/vnet/dpo/mpls_disposition.c
index cf0b5fcf1ef..7bc2cb65f87 100644
--- a/src/vnet/dpo/mpls_disposition.c
+++ b/src/vnet/dpo/mpls_disposition.c
@@ -88,8 +88,12 @@ format_mpls_disp_dpo (u8 *s, va_list *args)
mdd = mpls_disp_dpo_get(index);
- s = format(s, "mpls-disposition:[%d]:[%U, %U]",
- index,
+ s = format(s, "mpls-disposition:[%d]:[", index);
+
+ if (0 != mdd->mdd_rpf_id)
+ s = format(s, "rpf-id:%d ", mdd->mdd_rpf_id);
+
+ s = format(s, "%U, %U]",
format_dpo_proto, mdd->mdd_payload_proto,
format_fib_mpls_lsp_mode, mdd->mdd_mode);
@@ -132,7 +136,9 @@ mpls_disp_dpo_unlock (dpo_id_t *dpo)
*/
typedef struct mpls_label_disposition_trace_t_
{
- index_t mdd;
+ dpo_proto_t mddt_payload_proto;
+ fib_rpf_id_t mddt_rpf_id;
+ fib_mpls_lsp_mode_t mddt_mode;
} mpls_label_disposition_trace_t;
extern vlib_node_registration_t ip4_mpls_label_disposition_pipe_node;
@@ -293,13 +299,17 @@ mpls_label_disposition_inline (vlib_main_t * vm,
mpls_label_disposition_trace_t *tr =
vlib_add_trace(vm, node, b0, sizeof(*tr));
- tr->mdd = mddi0;
+ tr->mddt_payload_proto = mdd0->mdd_payload_proto;
+ tr->mddt_rpf_id = mdd0->mdd_rpf_id;
+ tr->mddt_mode = mdd0->mdd_mode;
}
if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
{
mpls_label_disposition_trace_t *tr =
vlib_add_trace(vm, node, b1, sizeof(*tr));
- tr->mdd = mddi1;
+ tr->mddt_payload_proto = mdd1->mdd_payload_proto;
+ tr->mddt_rpf_id = mdd1->mdd_rpf_id;
+ tr->mddt_mode = mdd1->mdd_mode;
}
vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
@@ -383,7 +393,9 @@ mpls_label_disposition_inline (vlib_main_t * vm,
{
mpls_label_disposition_trace_t *tr =
vlib_add_trace(vm, node, b0, sizeof(*tr));
- tr->mdd = mddi0;
+ tr->mddt_payload_proto = mdd0->mdd_payload_proto;
+ tr->mddt_rpf_id = mdd0->mdd_rpf_id;
+ tr->mddt_mode = mdd0->mdd_mode;
}
vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
@@ -403,7 +415,11 @@ format_mpls_label_disposition_trace (u8 * s, va_list * args)
t = va_arg(*args, mpls_label_disposition_trace_t *);
- s = format(s, "disp:%d", t->mdd);
+ s = format(s, "rpf-id:%d %U, %U",
+ t->mddt_rpf_id,
+ format_dpo_proto, t->mddt_payload_proto,
+ format_fib_mpls_lsp_mode, t->mddt_mode);
+
return (s);
}
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)
{
diff --git a/src/vnet/fib/fib_api.h b/src/vnet/fib/fib_api.h
index 041f962e3d7..ffff2289b37 100644
--- a/src/vnet/fib/fib_api.h
+++ b/src/vnet/fib/fib_api.h
@@ -17,61 +17,38 @@
#define __FIB_API_H__
#include <vnet/fib/fib_types.h>
+#include <vnet/fib/fib_entry.h>
-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);
-
-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);
-
+/**
+ * Forward declare the API type, no need to include the generated api headers
+ */
struct _vl_api_fib_path;
+struct _vl_api_fib_prefix;
-extern void fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
- struct _vl_api_fib_path *out);
+/**
+ * Encode and decode functions from the API types to internal types
+ */
+extern void fib_api_path_encode(const fib_route_path_t * api_rpath,
+ struct _vl_api_fib_path *out);
+extern int fib_api_path_decode(struct _vl_api_fib_path *in,
+ fib_route_path_t *out);
-void
-fib_prefix_to_api (const fib_prefix_t *pfx,
- u8 address[16],
- u8 *length,
- u8 *is_ip6);
+extern int fib_api_table_id_decode(fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index);
+/**
+ * Adding routes from the API
+ */
+extern 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);
-struct _vl_api_fib_path;
+extern u8* format_vl_api_fib_path(u8 * s, va_list * args);
-extern int fib_path_api_parse(const struct _vl_api_fib_path *in,
- fib_route_path_t *out);
extern fib_protocol_t fib_proto_from_api_address_family (int af);
extern int fib_proto_to_api_address_family (fib_protocol_t fproto);
diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c
index edbfdf6e3a4..6ff692dea98 100644
--- a/src/vnet/fib/fib_entry.c
+++ b/src/vnet/fib/fib_entry.c
@@ -906,21 +906,19 @@ void
fib_entry_path_add (fib_node_index_t fib_entry_index,
fib_source_t source,
fib_entry_flag_t flags,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
fib_source_t best_source;
fib_entry_t *fib_entry;
fib_entry_src_t *bsrc;
- ASSERT(1 == vec_len(rpath));
-
fib_entry = fib_entry_get(fib_entry_index);
ASSERT(NULL != fib_entry);
bsrc = fib_entry_get_best_src_i(fib_entry);
best_source = fib_entry_src_get_source(bsrc);
- fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpath);
+ fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpaths);
fib_entry_source_change(fib_entry, best_source, source);
@@ -1003,7 +1001,7 @@ fib_entry_source_removed (fib_entry_t *fib_entry,
fib_entry_src_flag_t
fib_entry_path_remove (fib_node_index_t fib_entry_index,
fib_source_t source,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
fib_entry_src_flag_t sflag;
fib_source_t best_source;
@@ -1011,8 +1009,6 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index,
fib_entry_t *fib_entry;
fib_entry_src_t *bsrc;
- ASSERT(1 == vec_len(rpath));
-
fib_entry = fib_entry_get(fib_entry_index);
ASSERT(NULL != fib_entry);
@@ -1020,7 +1016,7 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index,
best_source = fib_entry_src_get_source(bsrc);
bflags = fib_entry_src_get_flags(bsrc);
- sflag = fib_entry_src_action_path_remove(fib_entry, source, rpath);
+ sflag = fib_entry_src_action_path_remove(fib_entry, source, rpaths);
FIB_ENTRY_DBG(fib_entry, "path remove:%U", format_fib_source, source);
@@ -1648,11 +1644,13 @@ fib_entry_module_init (void)
fib_entry_logger = vlib_log_register_class("fib", "entry");
}
-void
-fib_entry_encode (fib_node_index_t fib_entry_index,
- fib_route_path_encode_t **api_rpaths)
+fib_route_path_t *
+fib_entry_encode (fib_node_index_t fib_entry_index)
{
fib_path_ext_list_t *ext_list;
+ fib_path_encode_ctx_t ctx = {
+ .rpaths = NULL,
+ };
fib_entry_t *fib_entry;
fib_entry_src_t *bsrc;
@@ -1670,8 +1668,10 @@ fib_entry_encode (fib_node_index_t fib_entry_index,
fib_path_list_walk_w_ext(fib_entry->fe_parent,
ext_list,
fib_path_encode,
- api_rpaths);
+ &ctx);
}
+
+ return (ctx.rpaths);
}
const fib_prefix_t *
diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h
index 8ede39c1e9d..5d0fb24bcb2 100644
--- a/src/vnet/fib/fib_entry.h
+++ b/src/vnet/fib/fib_entry.h
@@ -539,7 +539,7 @@ extern void fib_entry_update (fib_node_index_t fib_entry_index,
extern void fib_entry_path_add(fib_node_index_t fib_entry_index,
fib_source_t source,
fib_entry_flag_t flags,
- const fib_route_path_t *rpath);
+ const fib_route_path_t *rpaths);
extern void fib_entry_special_add(fib_node_index_t fib_entry_index,
fib_source_t source,
fib_entry_flag_t flags,
@@ -553,7 +553,7 @@ extern fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_
extern fib_entry_src_flag_t fib_entry_path_remove(fib_node_index_t fib_entry_index,
fib_source_t source,
- const fib_route_path_t *rpath);
+ const fib_route_path_t *rpaths);
extern void fib_entry_inherit(fib_node_index_t cover,
fib_node_index_t covered);
@@ -601,9 +601,8 @@ extern u32 fib_entry_get_resolving_interface_for_source(
fib_node_index_t fib_entry_index,
fib_source_t source);
-extern void fib_entry_encode(fib_node_index_t fib_entry_index,
- fib_route_path_encode_t **api_rpaths);
-extern const fib_prefix_t *fib_entry_get_prefix(fib_node_index_t fib_entry_index);
+extern fib_route_path_t* fib_entry_encode(fib_node_index_t fib_entry_index);
+extern const fib_prefix_t* fib_entry_get_prefix(fib_node_index_t fib_entry_index);
extern u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index);
extern void fib_entry_set_source_data(fib_node_index_t fib_entry_index,
fib_source_t source,
diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c
index c6c2a04bed7..1766ec765ea 100644
--- a/src/vnet/fib/fib_entry_src.c
+++ b/src/vnet/fib/fib_entry_src.c
@@ -1490,34 +1490,39 @@ fib_entry_src_flags_2_path_list_flags (fib_entry_flag_t eflags)
static void
fib_entry_flags_update (const fib_entry_t *fib_entry,
- const fib_route_path_t *rpath,
+ const fib_route_path_t *rpaths,
fib_path_list_flags_t *pl_flags,
fib_entry_src_t *esrc)
{
- if ((esrc->fes_src == FIB_SOURCE_API) ||
- (esrc->fes_src == FIB_SOURCE_CLI))
- {
- if (fib_path_is_attached(rpath))
- {
- esrc->fes_entry_flags |= FIB_ENTRY_FLAG_ATTACHED;
- }
- else
- {
- esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_ATTACHED;
- }
- if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG)
- {
- esrc->fes_entry_flags |= FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT;
- }
- }
- if (fib_route_attached_cross_table(fib_entry, rpath) &&
- !(esrc->fes_entry_flags & FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT))
- {
- esrc->fes_entry_flags |= FIB_ENTRY_FLAG_IMPORT;
- }
- else
+ const fib_route_path_t *rpath;
+
+ vec_foreach(rpath, rpaths)
{
- esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_IMPORT;
+ if ((esrc->fes_src == FIB_SOURCE_API) ||
+ (esrc->fes_src == FIB_SOURCE_CLI))
+ {
+ if (fib_path_is_attached(rpath))
+ {
+ esrc->fes_entry_flags |= FIB_ENTRY_FLAG_ATTACHED;
+ }
+ else
+ {
+ esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_ATTACHED;
+ }
+ if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG)
+ {
+ esrc->fes_entry_flags |= FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT;
+ }
+ }
+ if (fib_route_attached_cross_table(fib_entry, rpath) &&
+ !(esrc->fes_entry_flags & FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT))
+ {
+ esrc->fes_entry_flags |= FIB_ENTRY_FLAG_IMPORT;
+ }
+ else
+ {
+ esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_IMPORT;
+ }
}
}
@@ -1533,7 +1538,7 @@ fib_entry_t*
fib_entry_src_action_path_add (fib_entry_t *fib_entry,
fib_source_t source,
fib_entry_flag_t flags,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
fib_node_index_t old_path_list, fib_entry_index;
fib_path_list_flags_t pl_flags;
@@ -1550,7 +1555,7 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
const dpo_id_t *dpo;
if (flags == FIB_ENTRY_FLAG_EXCLUSIVE) {
- dpo = &rpath->dpo;
+ dpo = &rpaths->dpo;
} else {
dpo = drop_dpo_get(fib_entry_get_dpo_proto(fib_entry));
}
@@ -1574,10 +1579,10 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_add));
pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
- fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
+ fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc);
FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_add,
- (esrc, fib_entry, pl_flags, rpath));
+ (esrc, fib_entry, pl_flags, rpaths));
fib_entry = fib_entry_get(fib_entry_index);
fib_path_list_lock(esrc->fes_pl);
@@ -1670,7 +1675,7 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
fib_entry_src_flag_t
fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
fib_source_t source,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
fib_path_list_flags_t pl_flags;
fib_node_index_t old_path_list;
@@ -1692,10 +1697,10 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_remove));
pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
- fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
+ fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc);
FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_remove,
- (esrc, pl_flags, rpath));
+ (esrc, pl_flags, rpaths));
/*
* lock the new path-list, unlock the old if it had one
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c
index 67a4bc1d4de..eebba1b1548 100644
--- a/src/vnet/fib/fib_path.c
+++ b/src/vnet/fib/fib_path.c
@@ -24,7 +24,8 @@
#include <vnet/dpo/interface_rx_dpo.h>
#include <vnet/dpo/mpls_disposition.h>
#include <vnet/dpo/dvr_dpo.h>
-#include <vnet/dpo/drop_dpo.h>
+#include <vnet/dpo/ip_null_dpo.h>
+#include <vnet/dpo/classify_dpo.h>
#include <vnet/adj/adj.h>
#include <vnet/adj/adj_mcast.h>
@@ -353,6 +354,12 @@ typedef struct fib_path_t_ {
} udp_encap;
struct {
/**
+ * The UDP Encap object this path resolves through
+ */
+ u32 fp_classify_table_id;
+ } classify;
+ struct {
+ /**
* The interface
*/
u32 fp_interface;
@@ -882,8 +889,8 @@ fib_path_unresolve (fib_path_t *path)
{
fib_entry_child_remove(path->fp_via_fib,
path->fp_sibling);
- fib_table_entry_special_remove(path->recursive.fp_tbl_id,
- fib_entry_get_prefix(path->fp_via_fib),
+ fib_table_entry_special_remove(path->recursive.fp_tbl_id,
+ fib_entry_get_prefix(path->fp_via_fib),
FIB_SOURCE_RR);
fib_table_unlock(path->recursive.fp_tbl_id,
dpo_proto_to_fib(path->fp_nh_proto),
@@ -1244,6 +1251,10 @@ fib_path_route_flags_to_cfg_flags (const fib_route_path_t *rpath)
cfg_flags |= FIB_PATH_CFG_FLAG_DROP;
if (rpath->frp_flags & FIB_ROUTE_PATH_SOURCE_LOOKUP)
cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC;
+ if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_UNREACH)
+ cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_UNREACH;
+ if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_PROHIBIT)
+ cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_PROHIBIT;
return (cfg_flags);
}
@@ -1337,6 +1348,16 @@ fib_path_create (fib_node_index_t pl_index,
path->fp_type = FIB_PATH_TYPE_EXCLUSIVE;
dpo_copy(&path->exclusive.fp_ex_dpo, &rpath->dpo);
}
+ else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) ||
+ (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH))
+ {
+ path->fp_type = FIB_PATH_TYPE_SPECIAL;
+ }
+ else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY))
+ {
+ path->fp_type = FIB_PATH_TYPE_SPECIAL;
+ path->classify.fp_classify_table_id = rpath->frp_classify_table_id;
+ }
else if (~0 != rpath->frp_sw_if_index)
{
if (ip46_address_is_zero(&rpath->frp_addr))
@@ -1730,8 +1751,17 @@ fib_path_cmp_w_route_path (fib_node_index_t path_index,
case FIB_PATH_TYPE_EXCLUSIVE:
res = dpo_cmp(&path->exclusive.fp_ex_dpo, &rpath->dpo);
break;
- case FIB_PATH_TYPE_SPECIAL:
case FIB_PATH_TYPE_RECEIVE:
+ if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
+ {
+ res = 0;
+ }
+ else
+ {
+ res = 1;
+ }
+ break;
+ case FIB_PATH_TYPE_SPECIAL:
res = 0;
break;
}
@@ -2006,11 +2036,33 @@ fib_path_resolve (fib_node_index_t path_index)
break;
}
case FIB_PATH_TYPE_SPECIAL:
- /*
- * Resolve via the drop
- */
- dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
- break;
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT)
+ {
+ ip_null_dpo_add_and_lock (path->fp_nh_proto,
+ IP_NULL_ACTION_SEND_ICMP_PROHIBIT,
+ &path->fp_dpo);
+ }
+ else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH)
+ {
+ ip_null_dpo_add_and_lock (path->fp_nh_proto,
+ IP_NULL_ACTION_SEND_ICMP_UNREACH,
+ &path->fp_dpo);
+ }
+ else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY)
+ {
+ dpo_set (&path->fp_dpo, DPO_CLASSIFY,
+ path->fp_nh_proto,
+ classify_dpo_create (path->fp_nh_proto,
+ path->classify.fp_classify_table_id));
+ }
+ else
+ {
+ /*
+ * Resolve via the drop
+ */
+ dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
+ }
+ break;
case FIB_PATH_TYPE_DEAG:
{
if (DPO_PROTO_BIER == path->fp_nh_proto)
@@ -2459,10 +2511,10 @@ fib_path_contribute_forwarding (fib_node_index_t path_index,
case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
- dpo_copy(dpo, &path->fp_dpo);
- break;
case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
+ dpo_copy(dpo, &path->fp_dpo);
+ break;
case FIB_FORW_CHAIN_TYPE_BIER:
break;
case FIB_FORW_CHAIN_TYPE_ETHERNET:
@@ -2627,73 +2679,83 @@ fib_path_list_walk_rc_t
fib_path_encode (fib_node_index_t path_list_index,
fib_node_index_t path_index,
const fib_path_ext_t *path_ext,
- void *ctx)
+ void *args)
{
- fib_route_path_encode_t **api_rpaths = ctx;
- fib_route_path_encode_t *api_rpath;
+ fib_path_encode_ctx_t *ctx = args;
+ fib_route_path_t *rpath;
fib_path_t *path;
path = fib_path_get(path_index);
if (!path)
return (FIB_PATH_LIST_WALK_CONTINUE);
- vec_add2(*api_rpaths, api_rpath, 1);
- api_rpath->rpath.frp_weight = path->fp_weight;
- api_rpath->rpath.frp_preference = path->fp_preference;
- api_rpath->rpath.frp_proto = path->fp_nh_proto;
- api_rpath->rpath.frp_sw_if_index = ~0;
- api_rpath->rpath.frp_fib_index = 0;
- api_rpath->dpo = path->fp_dpo;
+
+ vec_add2(ctx->rpaths, rpath, 1);
+ rpath->frp_weight = path->fp_weight;
+ rpath->frp_preference = path->fp_preference;
+ rpath->frp_proto = path->fp_nh_proto;
+ rpath->frp_sw_if_index = ~0;
+ rpath->frp_fib_index = 0;
switch (path->fp_type)
{
case FIB_PATH_TYPE_RECEIVE:
- api_rpath->rpath.frp_addr = path->receive.fp_addr;
- api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface;
+ rpath->frp_addr = path->receive.fp_addr;
+ rpath->frp_sw_if_index = path->receive.fp_interface;
+ rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL;
break;
case FIB_PATH_TYPE_ATTACHED:
- api_rpath->rpath.frp_sw_if_index = path->attached.fp_interface;
+ rpath->frp_sw_if_index = path->attached.fp_interface;
break;
case FIB_PATH_TYPE_ATTACHED_NEXT_HOP:
- api_rpath->rpath.frp_sw_if_index = path->attached_next_hop.fp_interface;
- api_rpath->rpath.frp_addr = path->attached_next_hop.fp_nh;
+ rpath->frp_sw_if_index = path->attached_next_hop.fp_interface;
+ rpath->frp_addr = path->attached_next_hop.fp_nh;
break;
case FIB_PATH_TYPE_BIER_FMASK:
- api_rpath->rpath.frp_bier_fmask = path->bier_fmask.fp_bier_fmask;
+ rpath->frp_bier_fmask = path->bier_fmask.fp_bier_fmask;
break;
case FIB_PATH_TYPE_SPECIAL:
break;
case FIB_PATH_TYPE_DEAG:
- api_rpath->rpath.frp_fib_index = path->deag.fp_tbl_id;
+ rpath->frp_fib_index = path->deag.fp_tbl_id;
if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
{
- api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_RPF_ID;
+ rpath->frp_flags |= FIB_ROUTE_PATH_RPF_ID;
}
break;
case FIB_PATH_TYPE_RECURSIVE:
- api_rpath->rpath.frp_addr = path->recursive.fp_nh.fp_ip;
- api_rpath->rpath.frp_fib_index = path->recursive.fp_tbl_id;
+ rpath->frp_addr = path->recursive.fp_nh.fp_ip;
+ rpath->frp_fib_index = path->recursive.fp_tbl_id;
break;
case FIB_PATH_TYPE_DVR:
- api_rpath->rpath.frp_sw_if_index = path->dvr.fp_interface;
- api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_DVR;
+ rpath->frp_sw_if_index = path->dvr.fp_interface;
+ rpath->frp_flags |= FIB_ROUTE_PATH_DVR;
break;
case FIB_PATH_TYPE_UDP_ENCAP:
- api_rpath->rpath.frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
- api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
+ rpath->frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
+ rpath->frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
break;
case FIB_PATH_TYPE_INTF_RX:
- api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface;
- api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_INTF_RX;
+ rpath->frp_sw_if_index = path->receive.fp_interface;
+ rpath->frp_flags |= FIB_ROUTE_PATH_INTF_RX;
break;
+ case FIB_PATH_TYPE_EXCLUSIVE:
+ rpath->frp_flags |= FIB_ROUTE_PATH_EXCLUSIVE;
default:
break;
}
if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS)
{
- api_rpath->rpath.frp_label_stack = path_ext->fpe_path.frp_label_stack;
+ rpath->frp_label_stack = path_ext->fpe_path.frp_label_stack;
}
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP)
+ rpath->frp_flags |= FIB_ROUTE_PATH_DROP;
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH)
+ rpath->frp_flags |= FIB_ROUTE_PATH_ICMP_UNREACH;
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT)
+ rpath->frp_flags |= FIB_ROUTE_PATH_ICMP_PROHIBIT;
+
return (FIB_PATH_LIST_WALK_CONTINUE);
}
diff --git a/src/vnet/fib/fib_path.h b/src/vnet/fib/fib_path.h
index 57dec6d90b4..50aca9e1cf5 100644
--- a/src/vnet/fib/fib_path.h
+++ b/src/vnet/fib/fib_path.h
@@ -80,6 +80,18 @@ typedef enum fib_path_cfg_attribute_t_ {
*/
FIB_PATH_CFG_ATTRIBUTE_LOCAL,
/**
+ * The path reolves via an ICMP unreachable
+ */
+ FIB_PATH_CFG_ATTRIBUTE_ICMP_UNREACH,
+ /**
+ * The path reolves via an ICMP prohibit
+ */
+ FIB_PATH_CFG_ATTRIBUTE_ICMP_PROHIBIT,
+ /**
+ * The path reolves via a classify
+ */
+ FIB_PATH_CFG_ATTRIBUTE_CLASSIFY,
+ /**
* The deag path does a source lookup
*/
FIB_PATH_CFG_ATTRIBUTE_DEAG_SRC,
@@ -100,6 +112,9 @@ typedef enum fib_path_cfg_attribute_t_ {
[FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST] = "resolve-host", \
[FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED] = "resolve-attached", \
[FIB_PATH_CFG_ATTRIBUTE_LOCAL] = "local", \
+ [FIB_PATH_CFG_ATTRIBUTE_ICMP_UNREACH] = "icmp-unreach", \
+ [FIB_PATH_CFG_ATTRIBUTE_ICMP_PROHIBIT] = "icmp-prohibit", \
+ [FIB_PATH_CFG_ATTRIBUTE_CLASSIFY] = "classify", \
[FIB_PATH_CFG_ATTRIBUTE_ATTACHED] = "attached", \
[FIB_PATH_CFG_ATTRIBUTE_INTF_RX] = "interface-rx", \
[FIB_PATH_CFG_ATTRIBUTE_RPF_ID] = "rpf-id", \
@@ -121,6 +136,9 @@ typedef enum fib_path_cfg_flags_t_ {
FIB_PATH_CFG_FLAG_RESOLVE_HOST = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST),
FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED),
FIB_PATH_CFG_FLAG_LOCAL = (1 << FIB_PATH_CFG_ATTRIBUTE_LOCAL),
+ FIB_PATH_CFG_FLAG_ICMP_UNREACH = (1 << FIB_PATH_CFG_ATTRIBUTE_ICMP_UNREACH),
+ FIB_PATH_CFG_FLAG_ICMP_PROHIBIT = (1 << FIB_PATH_CFG_ATTRIBUTE_ICMP_PROHIBIT),
+ FIB_PATH_CFG_FLAG_CLASSIFY = (1 << FIB_PATH_CFG_ATTRIBUTE_CLASSIFY),
FIB_PATH_CFG_FLAG_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_ATTACHED),
FIB_PATH_CFG_FLAG_INTF_RX = (1 << FIB_PATH_CFG_ATTRIBUTE_INTF_RX),
FIB_PATH_CFG_FLAG_RPF_ID = (1 << FIB_PATH_CFG_ATTRIBUTE_RPF_ID),
@@ -181,6 +199,16 @@ extern u16 fib_path_get_preference(fib_node_index_t path_index);
extern u32 fib_path_get_rpf_id(fib_node_index_t path_index);
extern void fib_path_module_init(void);
+
+/**
+ * Path encode context to use when walking a path-list
+ * to encode paths
+ */
+typedef struct fib_path_encode_ctx_t_
+{
+ fib_route_path_t *rpaths;
+} fib_path_encode_ctx_t;
+
extern fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index,
fib_node_index_t path_index,
const struct fib_path_ext_t_ *ext_list,
diff --git a/src/vnet/fib/fib_path_list.c b/src/vnet/fib/fib_path_list.c
index 47170adf864..7c57c807327 100644
--- a/src/vnet/fib/fib_path_list.c
+++ b/src/vnet/fib/fib_path_list.c
@@ -830,12 +830,14 @@ fib_path_list_find_rpath (fib_node_index_t path_list_index,
* The path-list returned could either have been newly created, or
* can be a shared path-list from the data-base.
*/
-fib_node_index_t
-fib_path_list_path_add (fib_node_index_t path_list_index,
- const fib_route_path_t *rpaths)
+fib_node_index_t*
+fib_path_list_paths_add (fib_node_index_t path_list_index,
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t new_path_index, *orig_path_index;
+ fib_node_index_t *new_path_indices, *path_index;
+ const fib_route_path_t *rpath;
fib_path_list_t *path_list;
+ u32 ii;
/*
* alloc the new list before we retrieve the old one, lest
@@ -843,40 +845,65 @@ fib_path_list_path_add (fib_node_index_t path_list_index,
*/
path_list = fib_path_list_get(path_list_index);
- ASSERT(1 == vec_len(rpaths));
ASSERT(!(path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED));
- FIB_PATH_LIST_DBG(path_list, "path-add");
+ FIB_PATH_LIST_DBG(path_list, "paths-add");
- new_path_index = fib_path_create(path_list_index,
- rpaths);
+ new_path_indices = NULL;
+ vec_validate_init_empty(new_path_indices,
+ vec_len(rpaths) - 1,
+ FIB_NODE_INDEX_INVALID);
- vec_foreach (orig_path_index, path_list->fpl_paths)
+ vec_foreach (path_index, path_list->fpl_paths)
{
/*
* don't add duplicate paths
*/
- if (0 == fib_path_cmp(new_path_index, *orig_path_index))
+ int found = 0;
+
+ vec_foreach_index(ii, rpaths)
{
- fib_path_destroy(new_path_index);
- return (*orig_path_index);
+ rpath = &rpaths[ii];
+ if (0 == fib_path_cmp_w_route_path(*path_index, rpath))
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ {
+ new_path_indices[ii] = *path_index;
}
}
/*
- * Add the new path - no sort, no sharing, no key..
+ * new_path_indices array contains INVALID for each path not found
+ * and something valid for matches
*/
- vec_add1(path_list->fpl_paths, new_path_index);
+ vec_foreach_index (ii, new_path_indices)
+ {
+ path_index = &new_path_indices[ii];
+ rpath = &rpaths[ii];
- FIB_PATH_LIST_DBG(path_list, "path-added");
+ if (FIB_NODE_INDEX_INVALID == *path_index)
+ {
+ *path_index = fib_path_create(path_list_index, rpath);
+ /*
+ * Add the new path - no sort, no sharing, no key..
+ */
+ vec_add1(path_list->fpl_paths, *path_index);
- /*
- * no shared path list requested. resolve and use the one
- * just created.
- */
- fib_path_resolve(new_path_index);
+ /*
+ * no shared path list requested. resolve and use the one
+ * just created.
+ */
+ fib_path_resolve(*path_index);
+ }
+ }
+
+ FIB_PATH_LIST_DBG(path_list, "paths-added");
- return (new_path_index);
+ return (new_path_indices);
}
fib_node_index_t
@@ -884,14 +911,13 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index,
fib_path_list_flags_t flags,
const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index, new_path_index, *orig_path_index;
+ fib_node_index_t new_path_index, *orig_path_index;
fib_path_list_t *path_list, *orig_path_list;
fib_node_index_t exist_path_list_index;
fib_node_index_t path_list_index;
+ const fib_route_path_t *rpath;
fib_node_index_t pi;
- ASSERT(1 == vec_len(rpaths));
-
/*
* alloc the new list before we retrieve the old one, lest
* the alloc result in a realloc
@@ -905,32 +931,50 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index,
flags = fib_path_list_flags_fixup(flags);
path_list->fpl_flags = flags;
- vec_validate(path_list->fpl_paths, vec_len(orig_path_list->fpl_paths));
+ vec_validate(path_list->fpl_paths,
+ (vec_len(orig_path_list->fpl_paths) +
+ vec_len(rpaths) - 1));
pi = 0;
- new_path_index = fib_path_create(path_list_index,
- rpaths);
-
- vec_foreach (orig_path_index, orig_path_list->fpl_paths)
+ vec_foreach(orig_path_index, orig_path_list->fpl_paths)
{
/*
- * don't add duplicate paths
- * In the unlikely event the path is a duplicate, then we'll
- * find a matching path-list later and this one will be toast.
+ * copy the original paths over to the new list
*/
- if (0 != fib_path_cmp(new_path_index, *orig_path_index))
+ path_list->fpl_paths[pi++] = fib_path_copy(*orig_path_index,
+ path_list_index);
+ }
+ vec_foreach(rpath, rpaths)
+ {
+ int duplicate = 0;
+
+ new_path_index = fib_path_create(path_list_index, rpath);
+
+ vec_foreach(orig_path_index, orig_path_list->fpl_paths)
{
- path_index = fib_path_copy(*orig_path_index, path_list_index);
- path_list->fpl_paths[pi++] = path_index;
+ /*
+ * don't add duplicate paths
+ * In the unlikely event the path is a duplicate, then we'll
+ * find a matching path-list later and this one will be toast.
+ */
+ if (0 == fib_path_cmp(new_path_index, *orig_path_index))
+ {
+ duplicate = 1;
+ break;
+ }
+ }
+ if (duplicate)
+ {
+ _vec_len(path_list->fpl_paths) =
+ vec_len(path_list->fpl_paths) - 1;
+ fib_path_destroy(new_path_index);
}
else
{
- _vec_len(path_list->fpl_paths) = vec_len(orig_path_list->fpl_paths);
+ path_list->fpl_paths[pi++] = new_path_index;
}
}
- path_list->fpl_paths[pi] = new_path_index;
-
/*
* we sort the paths since the key for the path-list is
* the description of the paths it contains. The paths need to
@@ -978,51 +1022,60 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index,
}
/*
- * fib_path_list_path_remove
+ * fib_path_list_paths_remove
*/
-fib_node_index_t
-fib_path_list_path_remove (fib_node_index_t path_list_index,
+fib_node_index_t*
+fib_path_list_paths_remove (fib_node_index_t path_list_index,
const fib_route_path_t *rpaths)
{
- fib_node_index_t match_path_index, tmp_path_index;
+ fib_node_index_t *match_path_indices;
fib_path_list_t *path_list;
- fib_node_index_t pi;
+ i32 ii, jj;
path_list = fib_path_list_get(path_list_index);
+ match_path_indices = NULL;
+ vec_validate_init_empty(match_path_indices,
+ vec_len(rpaths) - 1,
+ FIB_NODE_INDEX_INVALID);
- ASSERT(1 == vec_len(rpaths));
ASSERT(!(path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED));
FIB_PATH_LIST_DBG(path_list, "path-remove");
/*
- * create a representation of the path to be removed, so it
- * can be used as a comparison object during the copy.
+ * the number of existing paths is likely to be larger than the
+ * number of paths being added.
+ * walk in reverse so the vec_del is ok
*/
- tmp_path_index = fib_path_create(path_list_index,
- rpaths);
- match_path_index = FIB_NODE_INDEX_INVALID;
-
- vec_foreach_index (pi, path_list->fpl_paths)
+ vec_foreach_index_backwards(ii, path_list->fpl_paths)
{
- if (0 == fib_path_cmp(tmp_path_index,
- path_list->fpl_paths[pi]))
+ int found = ~0;
+
+ vec_foreach_index(jj, rpaths)
{
+ if (0 == fib_path_cmp_w_route_path(path_list->fpl_paths[ii],
+ &rpaths[jj]))
+ {
+ found = jj;
+ break;
+ }
+ }
+ if (~0 != found)
+ {
+ fib_node_index_t match_path_index;
/*
* match - remove it
*/
- match_path_index = path_list->fpl_paths[pi];
+ match_path_index = path_list->fpl_paths[ii];
+ vec_del1(path_list->fpl_paths, ii);
fib_path_destroy(match_path_index);
- vec_del1(path_list->fpl_paths, pi);
- }
+ match_path_indices[jj] = match_path_index;
+ }
}
- /*
- * done with the temporary now
- */
- fib_path_destroy(tmp_path_index);
+ FIB_PATH_LIST_DBG(path_list, "paths-removed");
- return (match_path_index);
+ return (match_path_indices);
}
/*
@@ -1035,10 +1088,11 @@ fib_path_list_path_remove (fib_node_index_t path_list_index,
fib_node_index_t
fib_path_list_copy_and_path_remove (fib_node_index_t orig_path_list_index,
fib_path_list_flags_t flags,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index, *orig_path_index, path_list_index, tmp_path_index;
+ fib_node_index_t *orig_path_index, path_list_index, tmp_path_index;
fib_path_list_t *path_list, *orig_path_list;
+ const fib_route_path_t *rpath;
fib_node_index_t pi;
path_list = fib_path_list_alloc(&path_list_index);
@@ -1053,44 +1107,42 @@ fib_path_list_copy_and_path_remove (fib_node_index_t orig_path_list_index,
* allocate as many paths as we might need in one go, rather than
* using vec_add to do a few at a time.
*/
- if (vec_len(orig_path_list->fpl_paths) > 1)
- {
- vec_validate(path_list->fpl_paths, vec_len(orig_path_list->fpl_paths) - 2);
- }
+ vec_validate(path_list->fpl_paths,
+ vec_len(orig_path_list->fpl_paths) - 1);
pi = 0;
/*
* create a representation of the path to be removed, so it
* can be used as a comparison object during the copy.
*/
- tmp_path_index = fib_path_create(path_list_index, rpath);
-
- vec_foreach (orig_path_index, orig_path_list->fpl_paths)
+ vec_foreach(orig_path_index, orig_path_list->fpl_paths)
{
- if (0 != fib_path_cmp(tmp_path_index, *orig_path_index)) {
- path_index = fib_path_copy(*orig_path_index, path_list_index);
- if (pi < vec_len(path_list->fpl_paths))
- {
- path_list->fpl_paths[pi++] = path_index;
- }
- else
- {
- /*
- * this is the unlikely case that the path being
- * removed does not match one in the path-list, so
- * we end up with as many paths as we started with.
- * the paths vector was sized above with the expectation
- * that we would have 1 less.
- */
- vec_add1(path_list->fpl_paths, path_index);
- }
- }
+ /*
+ * copy the original paths over to the new list
+ */
+ path_list->fpl_paths[pi++] = fib_path_copy(*orig_path_index,
+ path_list_index);
}
+ vec_foreach(rpath, rpaths)
+ {
+ int found = 0;
+ tmp_path_index = fib_path_create(path_list_index, rpath);
- /*
- * done with the temporary now
- */
- fib_path_destroy(tmp_path_index);
+ vec_foreach_index(pi, path_list->fpl_paths)
+ {
+ if (0 == fib_path_cmp(tmp_path_index, path_list->fpl_paths[pi]))
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ {
+ fib_path_destroy(path_list->fpl_paths[pi]);
+ vec_del1(path_list->fpl_paths, pi);
+ }
+ fib_path_destroy(tmp_path_index);
+ }
/*
* if there are no paths, then the new path-list is aborted
diff --git a/src/vnet/fib/fib_path_list.h b/src/vnet/fib/fib_path_list.h
index 380eb1a6864..06c1b14204b 100644
--- a/src/vnet/fib/fib_path_list.h
+++ b/src/vnet/fib/fib_path_list.h
@@ -118,10 +118,10 @@ extern fib_node_index_t fib_path_list_copy_and_path_remove(
fib_node_index_t pl_index,
fib_path_list_flags_t flags,
const fib_route_path_t *path);
-extern fib_node_index_t fib_path_list_path_add (
+extern fib_node_index_t* fib_path_list_paths_add (
fib_node_index_t path_list_index,
const fib_route_path_t *rpaths);
-extern fib_node_index_t fib_path_list_path_remove (
+extern fib_node_index_t* fib_path_list_paths_remove (
fib_node_index_t path_list_index,
const fib_route_path_t *rpaths);
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index 56c8f030fda..3778fa9a944 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -481,7 +481,7 @@ fib_table_entry_special_remove (u32 fib_index,
*/
static void
fib_table_route_path_fixup (const fib_prefix_t *prefix,
- fib_entry_flag_t eflags,
+ fib_entry_flag_t *eflags,
fib_route_path_t *path)
{
/*
@@ -496,7 +496,8 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
/* Prefix recurses via itse;f */
path->frp_flags |= FIB_ROUTE_PATH_DROP;
}
- if (fib_prefix_is_host(prefix) &&
+ if (!(path->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
+ fib_prefix_is_host(prefix) &&
ip46_address_is_zero(&path->frp_addr) &&
path->frp_sw_if_index != ~0 &&
path->frp_proto != DPO_PROTO_ETHERNET)
@@ -504,18 +505,27 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
path->frp_addr = prefix->fp_addr;
path->frp_flags |= FIB_ROUTE_PATH_ATTACHED;
}
- if (eflags & FIB_ENTRY_FLAG_DROP)
+ if (*eflags & FIB_ENTRY_FLAG_DROP)
{
path->frp_flags |= FIB_ROUTE_PATH_DROP;
}
- if (eflags & FIB_ENTRY_FLAG_LOCAL)
+ if (*eflags & FIB_ENTRY_FLAG_LOCAL)
{
path->frp_flags |= FIB_ROUTE_PATH_LOCAL;
}
- if (eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
+ if (*eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
{
path->frp_flags |= FIB_ROUTE_PATH_EXCLUSIVE;
}
+ if (path->frp_flags & FIB_ROUTE_PATH_LOCAL)
+ {
+ *eflags |= FIB_ENTRY_FLAG_LOCAL;
+
+ if (path->frp_sw_if_index != ~0)
+ {
+ *eflags |= FIB_ENTRY_FLAG_CONNECTED;
+ }
+ }
}
fib_node_index_t
@@ -538,6 +548,7 @@ fib_table_entry_path_add (u32 fib_index,
.frp_fib_index = next_hop_fib_index,
.frp_weight = next_hop_weight,
.frp_flags = path_flags,
+ .frp_rpf_id = INDEX_INVALID,
.frp_label_stack = next_hop_labels,
};
fib_node_index_t fib_entry_index;
@@ -557,7 +568,7 @@ fib_table_entry_path_add2 (u32 fib_index,
const fib_prefix_t *prefix,
fib_source_t source,
fib_entry_flag_t flags,
- fib_route_path_t *rpath)
+ fib_route_path_t *rpaths)
{
fib_node_index_t fib_entry_index;
fib_table_t *fib_table;
@@ -566,16 +577,16 @@ fib_table_entry_path_add2 (u32 fib_index,
fib_table = fib_table_get(fib_index, prefix->fp_proto);
fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
- for (ii = 0; ii < vec_len(rpath); ii++)
+ for (ii = 0; ii < vec_len(rpaths); ii++)
{
- fib_table_route_path_fixup(prefix, flags, &rpath[ii]);
+ fib_table_route_path_fixup(prefix, &flags, &rpaths[ii]);
}
if (FIB_NODE_INDEX_INVALID == fib_entry_index)
{
fib_entry_index = fib_entry_create(fib_index, prefix,
source, flags,
- rpath);
+ rpaths);
fib_table_entry_insert(fib_table, prefix, fib_entry_index);
fib_table->ft_src_route_counts[source]++;
@@ -585,7 +596,7 @@ fib_table_entry_path_add2 (u32 fib_index,
int was_sourced;
was_sourced = fib_entry_is_sourced(fib_entry_index, source);
- fib_entry_path_add(fib_entry_index, source, flags, rpath);;
+ fib_entry_path_add(fib_entry_index, source, flags, rpaths);;
if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
{
@@ -600,7 +611,7 @@ void
fib_table_entry_path_remove2 (u32 fib_index,
const fib_prefix_t *prefix,
fib_source_t source,
- fib_route_path_t *rpath)
+ fib_route_path_t *rpaths)
{
/*
* 1 is it present
@@ -609,8 +620,8 @@ fib_table_entry_path_remove2 (u32 fib_index,
* no => cover walk
*/
fib_node_index_t fib_entry_index;
+ fib_route_path_t *rpath;
fib_table_t *fib_table;
- u32 ii;
fib_table = fib_table_get(fib_index, prefix->fp_proto);
fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
@@ -640,16 +651,16 @@ fib_table_entry_path_remove2 (u32 fib_index,
*/
fib_entry_lock(fib_entry_index);
- for (ii = 0; ii < vec_len(rpath); ii++)
+ vec_foreach(rpath, rpaths)
{
- fib_table_route_path_fixup(
- prefix,
- fib_entry_get_flags_for_source(fib_entry_index,
- source),
- &rpath[ii]);
+ fib_entry_flag_t eflags;
+
+ eflags = fib_entry_get_flags_for_source(fib_entry_index,
+ source);
+ fib_table_route_path_fixup(prefix, &eflags, rpath);
}
- src_flag = fib_entry_path_remove(fib_entry_index, source, rpath);
+ src_flag = fib_entry_path_remove(fib_entry_index, source, rpaths);
if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
{
@@ -735,7 +746,7 @@ fib_table_entry_update (u32 fib_index,
for (ii = 0; ii < vec_len(paths); ii++)
{
- fib_table_route_path_fixup(prefix, flags, &paths[ii]);
+ fib_table_route_path_fixup(prefix, &flags, &paths[ii]);
}
/*
* sort the paths provided by the control plane. this means
diff --git a/src/vnet/fib/fib_types.api b/src/vnet/fib/fib_types.api
index 8268870c0a7..9073192c3c4 100644
--- a/src/vnet/fib/fib_types.api
+++ b/src/vnet/fib/fib_types.api
@@ -1,5 +1,6 @@
+/* Hey Emacs use -*- mode: C -*- */
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2018 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -12,10 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
+option version = "2.0.0";
+import "vnet/ip/ip_types.api";
+
/** \brief MPLS label
*/
-typeonly define fib_mpls_label
+typedef fib_mpls_label
{
u8 is_uniform;
u32 label;
@@ -23,48 +27,101 @@ typeonly define fib_mpls_label
u8 exp;
};
+/** brief A path's nexthop protocol
+ */
+enum fib_path_nh_proto
+{
+ FIB_API_PATH_NH_PROTO_IP4 = 0,
+ FIB_API_PATH_NH_PROTO_IP6,
+ FIB_API_PATH_NH_PROTO_MPLS,
+ FIB_API_PATH_NH_PROTO_ETHERNET,
+ FIB_API_PATH_NH_PROTO_BIER,
+};
+
+/** \brief Flags for the path
+ */
+enum fib_path_flags
+{
+ FIB_API_PATH_FLAG_NONE = 0,
+ /* the path must resolve via an attached route */
+ FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED,
+ /* the path must resolve via a host route */
+ FIB_API_PATH_FLAG_RESOLVE_VIA_HOST,
+};
+
+/* \brief A description of the 'next-hop' for a path
+ * this can be something that needs resolving like an IP address
+ * (into an adjacency or another FIB entry) or the index of another
+ * VPP object that was previously created (i.e. a UDP encap object)
+ */
+typedef fib_path_nh
+{
+ /* proto = IP[46] */
+ vl_api_address_union_t address;
+ /* proto = MPLS */
+ u32 via_label;
+ /* proto = ANY, determined by path type */
+ u32 obj_id;
+ /* path-type = CLASSIFY */
+ u32 classify_table_index;
+};
+
+enum fib_path_type
+{
+ /* Normal Paths */
+ FIB_API_PATH_TYPE_NORMAL = 0,
+ /* local/for-us/receive = packet sent to VPP's L4 stack */
+ FIB_API_PATH_TYPE_LOCAL,
+ /* packet is dropped */
+ FIB_API_PATH_TYPE_DROP,
+ /* Packet is UDP encapped - set obj_id in fib_path_nh_id */
+ FIB_API_PATH_TYPE_UDP_ENCAP,
+ /* Packet is BIER encapped - set obj_id in fib_path_nh_id */
+ FIB_API_PATH_TYPE_BIER_IMP,
+ /* packet will generated ICMP unreach to sender */
+ FIB_API_PATH_TYPE_ICMP_UNREACH,
+ /* packet will generated ICMP prohibt to sender */
+ FIB_API_PATH_TYPE_ICMP_PROHIBIT,
+ /* perform a lookup based on the packet's source address */
+ FIB_API_PATH_TYPE_SOURCE_LOOKUP,
+ /* Distributed Virtual router, packet is forwarded with the original
+ L2 header unchanged */
+ FIB_API_PATH_TYPE_DVR,
+ /* packet's RX interface is changed */
+ FIB_API_PATH_TYPE_INTERFACE_RX,
+ /* packet will be sent to a classify table */
+ FIB_API_PATH_TYPE_CLASSIFY,
+};
+
/** \brief FIB path
@param sw_if_index - index of the interface
+ @param table_id - The table ID in which to find the next-hop address
+ (for recursive routes, i.e. when the interface is
+ not given)
@param weight - The weight, for UCMP
@param preference - The preference of the path. lowest preference
- is prefered
- @param is_local - local if non-zero, else remote
- @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_udp_encap - The path describes a UDP-o-IP encapsulation.
- @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 afi - dpo_proto_t protocol that describes the next-hop address
- @param via_label - The next-hop is a resolved via a local label
- @param next_hop[16] - the next hop address
- @param next_hop_id - Used when the path resolves via an object
- that has a unique identifier. e.g. the UDP
- encap object
+ is prefered
+ @param rpf-id - For paths that pop to multicast, this the the
+ RPF ID the packet will be given (0 and ~0 => unset)
+ @param type - the path type
+ @param flags - path flags
+ @param proto - protocol that describes the next-hop address
+ @param nh - the next-hop/net resolving object
+ @param n_labels - the number of labels present in the stack
+ @param label_stack - a stack of MPLS labels
*/
-typeonly define fib_path
+typedef fib_path
{
u32 sw_if_index;
u32 table_id;
+ u32 rpf_id;
u8 weight;
u8 preference;
- u8 is_local;
- u8 is_drop;
- u8 is_udp_encap;
- u8 is_unreach;
- u8 is_prohibit;
- u8 is_resolve_host;
- u8 is_resolve_attached;
- u8 is_dvr;
- u8 is_source_lookup;
- u8 is_interface_rx;
- u8 afi;
- u8 next_hop[16];
- u32 next_hop_id;
- u32 rpf_id;
- u32 via_label;
+
+ vl_api_fib_path_type_t type;
+ vl_api_fib_path_flags_t flags;
+ vl_api_fib_path_nh_proto_t proto;
+ vl_api_fib_path_nh_t nh;
u8 n_labels;
vl_api_fib_mpls_label_t label_stack[16];
};
diff --git a/src/vnet/fib/fib_types.c b/src/vnet/fib/fib_types.c
index 7f0f13079ee..4b1280f6fa8 100644
--- a/src/vnet/fib/fib_types.c
+++ b/src/vnet/fib/fib_types.c
@@ -598,7 +598,14 @@ unformat_fib_route_path (unformat_input_t * input, va_list * args)
rpath->frp_proto = DPO_PROTO_IP4;
rpath->frp_flags = FIB_ROUTE_PATH_INTF_RX;
}
- else if (unformat (input, "out-labels"))
+ else if (unformat (input, "local"))
+ {
+ clib_memset (&rpath->frp_addr, 0, sizeof (rpath->frp_addr));
+ rpath->frp_sw_if_index = ~0;
+ rpath->frp_weight = 1;
+ rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL;
+ }
+ else if (unformat (input, "out-labels"))
{
while (unformat (input, "%U",
unformat_mpls_unicast_label, &out_label))
@@ -615,6 +622,15 @@ unformat_fib_route_path (unformat_input_t * input, va_list * args)
{
rpath->frp_proto = *payload_proto;
}
+ else if (unformat (input, "via"))
+ {
+ /* new path, back up and return */
+ unformat_put_input (input);
+ unformat_put_input (input);
+ unformat_put_input (input);
+ unformat_put_input (input);
+ break;
+ }
else
{
return (0);
diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h
index 472ce888b4e..77b133fa9db 100644
--- a/src/vnet/fib/fib_types.h
+++ b/src/vnet/fib/fib_types.h
@@ -379,6 +379,10 @@ typedef enum fib_route_path_flags_t_
* A path that resolves via a DVR DPO
*/
FIB_ROUTE_PATH_DVR = (1 << 14),
+
+ FIB_ROUTE_PATH_ICMP_UNREACH = (1 << 15),
+ FIB_ROUTE_PATH_ICMP_PROHIBIT = (1 << 16),
+ FIB_ROUTE_PATH_CLASSIFY = (1 << 17),
} fib_route_path_flags_t;
/**
@@ -496,18 +500,24 @@ typedef struct fib_route_path_t_ {
*/
mpls_eos_bit_t frp_eos;
};
- };
- union {
/**
- * The interface.
- * Will be invalid for recursive paths.
+ * A path via a BIER imposition object.
+ * Present in an mfib path list
*/
- u32 frp_sw_if_index;
- /**
- * The RPF-ID
- */
- fib_rpf_id_t frp_rpf_id;
+ index_t frp_bier_imp;
};
+
+ /**
+ * The interface.
+ * Will be invalid for recursive paths.
+ */
+ u32 frp_sw_if_index;
+
+ /**
+ * The RPF-ID
+ */
+ fib_rpf_id_t frp_rpf_id;
+
union {
/**
* The FIB index to lookup the nexthop
@@ -523,7 +533,6 @@ typedef struct fib_route_path_t_ {
* The outgoing MPLS label Stack. NULL implies no label.
*/
fib_mpls_label_t *frp_label_stack;
-
/**
* Exclusive DPO
*/
@@ -540,20 +549,24 @@ typedef struct fib_route_path_t_ {
bier_table_id_t frp_bier_tbl;
/**
- * A path via a BIER imposition object.
- * Present in an mfib path list
+ * UDP encap ID
*/
- index_t frp_bier_imp;
+ u32 frp_udp_encap_id;
/**
- * UDP encap ID
+ * Classify table ID
*/
- u32 frp_udp_encap_id;
+ u32 frp_classify_table_id;
/**
* Resolving via a BIER Fmask
*/
index_t frp_bier_fmask;
+
+ /**
+ * The DPO for use with exclusive paths
+ */
+ dpo_id_t frp_dpo;
};
/**
* [un]equal cost path weight
@@ -582,15 +595,6 @@ extern uword unformat_fib_route_path(unformat_input_t * input, va_list * args);
#define FIB_ROUTE_PATH_HELP "[next-hop-address] [next-hop-interface] [next-hop-table <value>] [weight <value>] [preference <value>] [udp-encap-id <value>] [ip4-lookup-in-table <value>] [ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] [resolve-via-host] [resolve-via-connected] [rx-ip4 <interface>] [out-labels <value value value>]"
/**
- * @brief
- * A representation of a fib path for fib_path_encode to convey the information to the caller
- */
-typedef struct fib_route_path_encode_t_ {
- fib_route_path_t rpath;
- dpo_id_t dpo;
-} fib_route_path_encode_t;
-
-/**
* return code to control pat-hlist walk
*/
typedef enum fib_path_list_walk_rc_t_
diff --git a/src/vnet/fib/mpls_fib.c b/src/vnet/fib/mpls_fib.c
index 6440689eab5..6f59eb3ee44 100644
--- a/src/vnet/fib/mpls_fib.c
+++ b/src/vnet/fib/mpls_fib.c
@@ -442,11 +442,24 @@ mpls_fib_show (vlib_main_t * vm,
pool_foreach (fib_table, mpls_main.fibs,
({
+ fib_source_t source;
+ u8 *s = NULL;
+
if (table_id >= 0 && table_id != fib_table->ft_table_id)
continue;
- vlib_cli_output (vm, "%v, fib_index %d",
- fib_table->ft_desc, mpls_main.fibs - fib_table);
+ s = format (s, "%v, fib_index:%d locks:[",
+ fib_table->ft_desc, mpls_main.fibs - fib_table);
+ FOR_EACH_FIB_SOURCE(source)
+ {
+ if (0 != fib_table->ft_locks[source])
+ {
+ s = format(s, "%U:%d, ",
+ format_fib_source, source,
+ fib_table->ft_locks[source]);
+ }
+ }
+ vlib_cli_output (vm, "%v]", s);
if (MPLS_LABEL_INVALID == label)
{
diff --git a/src/vnet/geneve/geneve.c b/src/vnet/geneve/geneve.c
index 8b773c1e009..b0c17e2a988 100644
--- a/src/vnet/geneve/geneve.c
+++ b/src/vnet/geneve/geneve.c
@@ -524,8 +524,9 @@ int vnet_geneve_add_del_tunnel
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
const mfib_prefix_t mpfx = {
.fp_proto = fp,
@@ -539,17 +540,14 @@ int vnet_geneve_add_del_tunnel
* - the accepting interface is that from the API
*/
mfib_table_entry_path_update (t->encap_fib_index,
- &mpfx,
- MFIB_SOURCE_GENEVE,
- &path, MFIB_ITF_FLAG_FORWARD);
+ &mpfx, MFIB_SOURCE_GENEVE, &path);
path.frp_sw_if_index = a->mcast_sw_if_index;
path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
+ path.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT;
mfei = mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
- MFIB_SOURCE_GENEVE,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ MFIB_SOURCE_GENEVE, &path);
/*
* Create the mcast adjacency to send traffic to the group
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;
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c
index 31a92687e1a..5b15c8d1736 100644
--- a/src/vnet/mfib/ip6_mfib.c
+++ b/src/vnet/mfib/ip6_mfib.c
@@ -141,8 +141,9 @@ ip6_create_mfib_with_table_id (u32 table_id,
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
pool_get_aligned(ip6_main.mfibs, mfib_table, CLIB_CACHE_LINE_BYTES);
@@ -180,8 +181,7 @@ ip6_create_mfib_with_table_id (u32 table_id,
mfib_table_entry_path_update(mfib_table->mft_index,
&pfx,
MFIB_SOURCE_SPECIAL,
- &path_for_us,
- MFIB_ITF_FLAG_FORWARD);
+ &path_for_us);
}));
return (mfib_table->mft_index);
@@ -200,7 +200,7 @@ ip6_mfib_table_destroy (ip6_mfib_t *mfib)
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
};
@@ -236,7 +236,8 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
.frp_addr = zero_addr,
.frp_sw_if_index = sw_if_index,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
+ .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
};
mfib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP6,
@@ -253,8 +254,7 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
mfib_table_entry_path_update(mfib_index,
&pfx,
MFIB_SOURCE_SPECIAL,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ &path);
});
}
else
diff --git a/src/vnet/mfib/mfib_api.c b/src/vnet/mfib/mfib_api.c
new file mode 100644
index 00000000000..bcab83ba0e5
--- /dev/null
+++ b/src/vnet/mfib/mfib_api.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/vnet.h>
+#include <vlibmemory/api.h>
+#include <vnet/mfib/mfib_api.h>
+#include <vnet/mfib/mfib_table.h>
+#include <vnet/fib/fib_api.h>
+#include <vnet/ip/ip_types_api.h>
+
+#include <vnet/vnet_msg_enum.h>
+
+#define vl_typedefs /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_typedefs
+
+#define vl_endianfun /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_endianfun
+
+/* instantiate all the print functions we know about */
+#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
+#define vl_printfun
+#include <vnet/vnet_all_api_h.h>
+#undef vl_printfun
+
+static vl_api_mfib_itf_flags_t
+mfib_api_path_itf_flags_encode (mfib_itf_flags_t flags)
+{
+ vl_api_mfib_itf_flags_t out = MFIB_API_ITF_FLAG_NONE;
+
+ switch (flags)
+ {
+ case MFIB_ITF_FLAG_NONE:
+ out = MFIB_API_ITF_FLAG_NONE;
+ break;
+ case MFIB_ITF_FLAG_NEGATE_SIGNAL:
+ out = MFIB_API_ITF_FLAG_NEGATE_SIGNAL;
+ break;
+ case MFIB_ITF_FLAG_ACCEPT:
+ out = MFIB_API_ITF_FLAG_ACCEPT;
+ break;
+ case MFIB_ITF_FLAG_FORWARD:
+ out = MFIB_API_ITF_FLAG_FORWARD;
+ break;
+ case MFIB_ITF_FLAG_SIGNAL_PRESENT:
+ out = MFIB_API_ITF_FLAG_SIGNAL_PRESENT;
+ break;
+ case MFIB_ITF_FLAG_DONT_PRESERVE:
+ out = MFIB_API_ITF_FLAG_DONT_PRESERVE;
+ break;
+ }
+ return (ntohl(out));
+}
+
+void
+mfib_api_path_encode (const fib_route_path_t *in,
+ vl_api_mfib_path_t *out)
+{
+ out->itf_flags = mfib_api_path_itf_flags_encode(in->frp_mitf_flags);
+
+ fib_api_path_encode(in, &out->path);
+}
+
+static void
+mfib_api_path_itf_flags_decode (vl_api_mfib_itf_flags_t in,
+ mfib_itf_flags_t *out)
+{
+ in = clib_net_to_host_u32(in);
+
+ if (in & MFIB_API_ITF_FLAG_NONE)
+ *out |= MFIB_ITF_FLAG_NONE;
+ if (in & MFIB_API_ITF_FLAG_NEGATE_SIGNAL)
+ *out |= MFIB_ITF_FLAG_NEGATE_SIGNAL;
+ if (in & MFIB_API_ITF_FLAG_ACCEPT)
+ *out |= MFIB_ITF_FLAG_ACCEPT;
+ if (in & MFIB_API_ITF_FLAG_FORWARD)
+ *out |= MFIB_ITF_FLAG_FORWARD;
+ if (in & MFIB_API_ITF_FLAG_SIGNAL_PRESENT)
+ *out |= MFIB_ITF_FLAG_SIGNAL_PRESENT;
+ if (in & MFIB_API_ITF_FLAG_DONT_PRESERVE)
+ *out |= MFIB_ITF_FLAG_DONT_PRESERVE;
+}
+
+int
+mfib_api_path_decode (vl_api_mfib_path_t *in,
+ fib_route_path_t *out)
+{
+ mfib_api_path_itf_flags_decode(in->itf_flags, &out->frp_mitf_flags);
+
+ return (fib_api_path_decode(&in->path, out));
+}
+
+int
+mfib_api_table_id_decode (fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index)
+{
+ *fib_index = mfib_table_find(fproto, table_id);
+
+ if (INDEX_INVALID == *fib_index)
+ {
+ return VNET_API_ERROR_NO_SUCH_FIB;
+ }
+
+ return (0);
+}
diff --git a/src/vnet/mfib/mfib_api.h b/src/vnet/mfib/mfib_api.h
new file mode 100644
index 00000000000..f9c0a74bedb
--- /dev/null
+++ b/src/vnet/mfib/mfib_api.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MFIB_API_H__
+#define __MFIB_API_H__
+
+#include <vnet/mfib/mfib_types.h>
+
+/**
+ * Forward declare the API type, no need to include the generated api headers
+ */
+struct _vl_api_mfib_path;
+
+/**
+ * Encode and decode functions from the API types to internal types
+ */
+extern void mfib_api_path_encode(const fib_route_path_t *in,
+ struct _vl_api_mfib_path *out);
+extern int mfib_api_path_decode(struct _vl_api_mfib_path *in,
+ fib_route_path_t *out);
+
+extern int mfib_api_table_id_decode(fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index);
+
+#endif /* __MFIB_API_H__ */
diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c
index 18562219ce2..f169dc0886e 100644
--- a/src/vnet/mfib/mfib_entry.c
+++ b/src/vnet/mfib/mfib_entry.c
@@ -673,21 +673,12 @@ mfib_entry_stack (mfib_entry_t *mfib_entry,
&bw_ctx);
}
-static fib_node_index_t
-mfib_entry_src_path_add (mfib_entry_src_t *msrc,
- const fib_route_path_t *rpath)
+static fib_node_index_t*
+mfib_entry_src_paths_add (mfib_entry_src_t *msrc,
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index;
- fib_route_path_t *rpaths;
-
ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags));
- /*
- * path-lists require a vector of paths
- */
- rpaths = NULL;
- vec_add1(rpaths, rpath[0]);
-
if (FIB_NODE_INDEX_INVALID == msrc->mfes_pl)
{
/* A non-shared path-list */
@@ -696,33 +687,16 @@ mfib_entry_src_path_add (mfib_entry_src_t *msrc,
fib_path_list_lock(msrc->mfes_pl);
}
- path_index = fib_path_list_path_add(msrc->mfes_pl, rpaths);
-
- vec_free(rpaths);
-
- return (path_index);
+ return (fib_path_list_paths_add(msrc->mfes_pl, rpaths));
}
-static fib_node_index_t
-mfib_entry_src_path_remove (mfib_entry_src_t *msrc,
- const fib_route_path_t *rpath)
+static fib_node_index_t*
+mfib_entry_src_paths_remove (mfib_entry_src_t *msrc,
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index;
- fib_route_path_t *rpaths;
-
ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags));
- /*
- * path-lists require a vector of paths
- */
- rpaths = NULL;
- vec_add1(rpaths, rpath[0]);
-
- path_index = fib_path_list_path_remove(msrc->mfes_pl, rpaths);
-
- vec_free(rpaths);
-
- return (path_index);
+ return (fib_path_list_paths_remove(msrc->mfes_pl, rpaths));
}
static void
@@ -819,7 +793,12 @@ mfib_entry_src_ok_for_delete (const mfib_entry_src_t *msrc)
{
return ((INDEX_INVALID == msrc->mfes_cover &&
MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags &&
- 0 == fib_path_list_get_n_paths(msrc->mfes_pl)));
+ 0 == fib_path_list_get_n_paths(msrc->mfes_pl)) &&
+ (0 == hash_elts(msrc->mfes_itfs)));
+
+ /* return ((MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags) && */
+ /* (0 == fib_path_list_get_n_paths(msrc->mfes_pl)) && */
+ /* (0 == hash_elts(msrc->mfes_itfs))); */
}
@@ -931,18 +910,26 @@ mfib_entry_itf_remove (mfib_entry_src_t *msrc,
hash_unset(msrc->mfes_itfs, sw_if_index);
}
+static int
+mfib_entry_path_itf_based (const fib_route_path_t *rpath)
+{
+ return (!(rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP) &&
+ ~0 != rpath->frp_sw_if_index);
+}
+
void
mfib_entry_path_update (fib_node_index_t mfib_entry_index,
mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t itf_flags)
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index;
+ fib_node_index_t* path_indices, path_index;
+ const fib_route_path_t *rpath;
mfib_source_t current_best;
mfib_path_ext_t *path_ext;
mfib_entry_t *mfib_entry;
mfib_entry_src_t *msrc;
mfib_itf_flags_t old;
+ u32 ii;
mfib_entry = mfib_entry_get(mfib_entry_index);
ASSERT(NULL != mfib_entry);
@@ -953,61 +940,73 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index,
* add the path to the path-list. If it's a duplicate we'll get
* back the original path.
*/
- path_index = mfib_entry_src_path_add(msrc, rpath);
+ path_indices = mfib_entry_src_paths_add(msrc, rpaths);
- /*
- * find the path extension for that path
- */
- path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index);
-
- if (NULL == path_ext)
+ vec_foreach_index(ii, path_indices)
{
- old = MFIB_ITF_FLAG_NONE;
- path_ext = mfib_path_ext_add(msrc, path_index, itf_flags);
- }
- else
- {
- old = path_ext->mfpe_flags;
- path_ext->mfpe_flags = itf_flags;
- }
+ path_index = path_indices[ii];
+ rpath = &rpaths[ii];
- /*
- * Has the path changed its contribution to the input interface set.
- * Which only paths with interfaces can do...
- */
- if (~0 != rpath[0].frp_sw_if_index)
- {
- mfib_itf_t *mfib_itf;
+ if (FIB_NODE_INDEX_INVALID == path_index)
+ continue;
+
+ /*
+ * find the path extension for that path
+ */
+ path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index);
- if (old != itf_flags)
+ if (NULL == path_ext)
{
- /*
- * change of flag contributions
- */
- mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs,
- rpath[0].frp_sw_if_index);
+ old = MFIB_ITF_FLAG_NONE;
+ path_ext = mfib_path_ext_add(msrc, path_index,
+ rpath->frp_mitf_flags);
+ }
+ else
+ {
+ old = path_ext->mfpe_flags;
+ path_ext->mfpe_flags = rpath->frp_mitf_flags;
+ }
- if (NULL == mfib_itf)
- {
- mfib_entry_itf_add(msrc,
- rpath[0].frp_sw_if_index,
- mfib_itf_create(path_index, itf_flags));
- }
- else
+ /*
+ * Has the path changed its contribution to the input interface set.
+ * Which only paths with interfaces can do...
+ */
+ if (mfib_entry_path_itf_based(rpath))
+ {
+ mfib_itf_t *mfib_itf;
+
+ if (old != rpath->frp_mitf_flags)
{
- if (mfib_itf_update(mfib_itf,
- path_index,
- itf_flags))
+ /*
+ * change of flag contributions
+ */
+ mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs,
+ rpath->frp_sw_if_index);
+
+ if (NULL == mfib_itf)
{
- /*
- * no more interface flags on this path, remove
- * from the data-plane set
- */
- mfib_entry_itf_remove(msrc, rpath[0].frp_sw_if_index);
+ mfib_entry_itf_add(msrc,
+ rpath->frp_sw_if_index,
+ mfib_itf_create(path_index,
+ rpath->frp_mitf_flags));
+ }
+ else
+ {
+ if (mfib_itf_update(mfib_itf,
+ path_index,
+ rpath->frp_mitf_flags))
+ {
+ /*
+ * no more interface flags on this path, remove
+ * from the data-plane set
+ */
+ mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index);
+ }
}
}
}
}
+ vec_free(path_indices);
mfib_entry_recalculate_forwarding(mfib_entry, current_best);
}
@@ -1021,12 +1020,14 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index,
int
mfib_entry_path_remove (fib_node_index_t mfib_entry_index,
mfib_source_t source,
- const fib_route_path_t *rpath)
+ const fib_route_path_t *rpaths)
{
- fib_node_index_t path_index;
+ fib_node_index_t path_index, *path_indices;
+ const fib_route_path_t *rpath;
mfib_source_t current_best;
mfib_entry_t *mfib_entry;
mfib_entry_src_t *msrc;
+ u32 ii;
mfib_entry = mfib_entry_get(mfib_entry_index);
ASSERT(NULL != mfib_entry);
@@ -1042,23 +1043,29 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index,
}
/*
- * remove the path from the path-list. If it's not there we'll get
- * back invalid
+ * remove the paths from the path-list. If it's not there we'll get
+ * back an empty vector
*/
- path_index = mfib_entry_src_path_remove(msrc, rpath);
+ path_indices = mfib_entry_src_paths_remove(msrc, rpaths);
- if (FIB_NODE_INDEX_INVALID != path_index)
+ vec_foreach_index(ii, path_indices)
{
+ path_index = path_indices[ii];
+ rpath = &rpaths[ii];
+
+ if (FIB_NODE_INDEX_INVALID == path_index)
+ continue;
+
/*
* don't need the extension, nor the interface anymore
*/
mfib_path_ext_remove(msrc, path_index);
- if (~0 != rpath[0].frp_sw_if_index)
+ if (mfib_entry_path_itf_based(rpath))
{
mfib_itf_t *mfib_itf;
mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs,
- rpath[0].frp_sw_if_index);
+ rpath->frp_sw_if_index);
if (mfib_itf_update(mfib_itf,
path_index,
@@ -1068,19 +1075,20 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index,
* no more interface flags on this path, remove
* from the data-plane set
*/
- mfib_entry_itf_remove(msrc, rpath[0].frp_sw_if_index);
+ mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index);
}
}
- }
- if (mfib_entry_src_ok_for_delete(msrc))
- {
- /*
- * this source has no interfaces and no flags.
- * it has nothing left to give - remove it
- */
- mfib_entry_src_remove(mfib_entry, source);
+ if (mfib_entry_src_ok_for_delete(msrc))
+ {
+ /*
+ * this source has no interfaces and no flags.
+ * it has nothing left to give - remove it
+ */
+ mfib_entry_src_remove(mfib_entry, source);
+ }
}
+ vec_free(path_indices);
mfib_entry_recalculate_forwarding(mfib_entry, current_best);
@@ -1321,12 +1329,14 @@ mfib_entry_module_init (void)
mfib_entry_logger = vlib_log_register_class("mfib", "entry");
}
-void
-mfib_entry_encode (fib_node_index_t mfib_entry_index,
- fib_route_path_encode_t **api_rpaths)
+fib_route_path_t*
+mfib_entry_encode (fib_node_index_t mfib_entry_index)
{
- fib_route_path_encode_t *api_rpath;
+ fib_path_encode_ctx_t ctx = {
+ .rpaths = NULL,
+ };
mfib_entry_t *mfib_entry;
+ fib_route_path_t *rpath;
mfib_entry_src_t *bsrc;
mfib_entry = mfib_entry_get(mfib_entry_index);
@@ -1337,20 +1347,22 @@ mfib_entry_encode (fib_node_index_t mfib_entry_index,
fib_path_list_walk_w_ext(bsrc->mfes_pl,
NULL,
fib_path_encode,
- api_rpaths);
+ &ctx);
}
- vec_foreach(api_rpath, *api_rpaths)
+ vec_foreach(rpath, ctx.rpaths)
{
mfib_itf_t *mfib_itf;
mfib_itf = mfib_entry_itf_find(bsrc->mfes_itfs,
- api_rpath->rpath.frp_sw_if_index);
+ rpath->frp_sw_if_index);
if (mfib_itf)
{
- api_rpath->rpath.frp_mitf_flags = mfib_itf->mfi_flags;
+ rpath->frp_mitf_flags = mfib_itf->mfi_flags;
}
}
+
+ return (ctx.rpaths);
}
const mfib_prefix_t *
diff --git a/src/vnet/mfib/mfib_entry.h b/src/vnet/mfib/mfib_entry.h
index 8ab7cee5ea7..4a1121bc9d5 100644
--- a/src/vnet/mfib/mfib_entry.h
+++ b/src/vnet/mfib/mfib_entry.h
@@ -135,8 +135,7 @@ extern int mfib_entry_special_add(fib_node_index_t fib_entry_index,
extern void mfib_entry_path_update(fib_node_index_t fib_entry_index,
mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t itf_flags);
+ const fib_route_path_t *rpath);
extern int mfib_entry_path_remove(fib_node_index_t fib_entry_index,
@@ -188,8 +187,7 @@ extern void mfib_entry_contribute_forwarding(
mfib_entry_fwd_flags_t flags,
dpo_id_t *dpo);
-extern void mfib_entry_encode(fib_node_index_t fib_entry_index,
- fib_route_path_encode_t **api_rpaths);
+extern fib_route_path_t* mfib_entry_encode(fib_node_index_t fib_entry_index);
extern void mfib_entry_module_init(void);
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c
index 68154b37ff8..504333a2474 100644
--- a/src/vnet/mfib/mfib_table.c
+++ b/src/vnet/mfib/mfib_table.c
@@ -286,12 +286,11 @@ mfib_table_entry_update (u32 fib_index,
return (mfib_entry_index);
}
-fib_node_index_t
-mfib_table_entry_path_update (u32 fib_index,
- const mfib_prefix_t *prefix,
- mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t itf_flags)
+static fib_node_index_t
+mfib_table_entry_paths_update_i (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
{
fib_node_index_t mfib_entry_index;
mfib_table_t *mfib_table;
@@ -308,30 +307,53 @@ mfib_table_entry_path_update (u32 fib_index,
MFIB_ENTRY_FLAG_NONE,
INDEX_INVALID);
- mfib_entry_path_update(mfib_entry_index,
- source,
- rpath,
- itf_flags);
+ mfib_entry_path_update(mfib_entry_index, source, rpaths);
mfib_table_entry_insert(mfib_table, prefix, mfib_entry_index);
}
else
{
- mfib_entry_path_update(mfib_entry_index,
- source,
- rpath,
- itf_flags);
+ mfib_entry_path_update(mfib_entry_index, source, rpaths);
}
return (mfib_entry_index);
}
-void
-mfib_table_entry_path_remove (u32 fib_index,
+
+fib_node_index_t
+mfib_table_entry_path_update (u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
const fib_route_path_t *rpath)
{
fib_node_index_t mfib_entry_index;
+ fib_route_path_t *rpaths = NULL;
+
+ vec_add1(rpaths, *rpath);
+
+ mfib_entry_index = mfib_table_entry_paths_update_i(fib_index, prefix,
+ source, rpaths);
+
+ vec_free(rpaths);
+ return (mfib_entry_index);
+}
+
+fib_node_index_t
+mfib_table_entry_paths_update (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ return (mfib_table_entry_paths_update_i(fib_index, prefix,
+ source, rpaths));
+}
+
+static void
+mfib_table_entry_paths_remove_i (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ fib_node_index_t mfib_entry_index;
mfib_table_t *mfib_table;
mfib_table = mfib_table_get(fib_index, prefix->fp_proto);
@@ -340,7 +362,7 @@ mfib_table_entry_path_remove (u32 fib_index,
if (FIB_NODE_INDEX_INVALID == mfib_entry_index)
{
/*
- * removing an etry that does not exist. i'll allow it.
+ * removing an entry that does not exist. i'll allow it.
*/
}
else
@@ -354,7 +376,7 @@ mfib_table_entry_path_remove (u32 fib_index,
no_more_sources = mfib_entry_path_remove(mfib_entry_index,
source,
- rpath);
+ rpaths);
if (no_more_sources)
{
@@ -367,6 +389,35 @@ mfib_table_entry_path_remove (u32 fib_index,
mfib_entry_unlock(mfib_entry_index);
}
}
+void
+mfib_table_entry_paths_remove (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ mfib_table_entry_paths_remove_i(fib_index,
+ prefix,
+ source,
+ rpaths);
+}
+
+void
+mfib_table_entry_path_remove (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpath)
+{
+ fib_route_path_t *rpaths = NULL;
+
+ vec_add1(rpaths, *rpath);
+
+ mfib_table_entry_paths_remove_i(fib_index,
+ prefix,
+ source,
+ rpaths);
+
+ vec_free(rpaths);
+}
fib_node_index_t
mfib_table_entry_special_add (u32 fib_index,
@@ -464,12 +515,10 @@ void
mfib_table_entry_delete_index (fib_node_index_t mfib_entry_index,
mfib_source_t source)
{
- const mfib_prefix_t *prefix;
-
- prefix = mfib_entry_get_prefix(mfib_entry_index);
-
mfib_table_entry_delete_i(mfib_entry_get_fib_index(mfib_entry_index),
- mfib_entry_index, prefix, source);
+ mfib_entry_index,
+ mfib_entry_get_prefix(mfib_entry_index),
+ source);
}
u32
diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h
index 6be4f798cd7..47461375a10 100644
--- a/src/vnet/mfib/mfib_table.h
+++ b/src/vnet/mfib/mfib_table.h
@@ -164,8 +164,11 @@ extern fib_node_index_t mfib_table_entry_update(u32 fib_index,
extern fib_node_index_t mfib_table_entry_path_update(u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t flags);
+ const fib_route_path_t *rpath);
+extern fib_node_index_t mfib_table_entry_paths_update(u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpath);
/**
* @brief
@@ -190,6 +193,10 @@ extern void mfib_table_entry_path_remove(u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
const fib_route_path_t *paths);
+extern void mfib_table_entry_paths_remove(u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *paths);
@@ -320,6 +327,20 @@ extern u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
*/
extern u32 mfib_table_find(fib_protocol_t proto, u32 table_id);
+/**
+ * @brief
+ * Get the Table-ID of the FIB from protocol and index
+ *
+ * @param fib_index
+ * The FIB index
+ *
+ * @paran proto
+ * The protocol of the FIB (and thus the entries therein)
+ *
+ * @return fib_index
+ * The tableID of the FIB
+ */
+extern u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
/**
* @brief
diff --git a/src/vnet/mfib/mfib_types.api b/src/vnet/mfib/mfib_types.api
new file mode 100644
index 00000000000..b2ba4329ea5
--- /dev/null
+++ b/src/vnet/mfib/mfib_types.api
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import "vnet/fib/fib_types.api";
+import "vnet/ip/ip_types.api";
+
+enum mfib_itf_flags
+{
+ MFIB_API_ITF_FLAG_NONE = 0,
+ MFIB_API_ITF_FLAG_NEGATE_SIGNAL = 0x1,
+ MFIB_API_ITF_FLAG_ACCEPT = 0x2,
+ MFIB_API_ITF_FLAG_FORWARD = 0x4,
+ MFIB_API_ITF_FLAG_SIGNAL_PRESENT = 0x8,
+ MFIB_API_ITF_FLAG_DONT_PRESERVE = 0x10,
+};
+
+/** \brief mFIB path
+*/
+typeonly define mfib_path
+{
+ vl_api_mfib_itf_flags_t itf_flags;
+ vl_api_fib_path_t path;
+};
diff --git a/src/vnet/mpls/mpls.api b/src/vnet/mpls/mpls.api
index ca1aa3a8513..5d85812807a 100644
--- a/src/vnet/mpls/mpls.api
+++ b/src/vnet/mpls/mpls.api
@@ -15,6 +15,7 @@
option version = "1.1.0";
import "vnet/fib/fib_types.api";
+import "vnet/ip/ip_types.api";
/** \brief Bind/Unbind an MPLS local label to an IP prefix. i.e. create
a per-prefix label entry.
@@ -36,28 +37,24 @@ autoreply define mpls_ip_bind_unbind
u32 mb_label;
u32 mb_ip_table_id;
u8 mb_is_bind;
- u8 mb_is_ip4;
- u8 mb_address_length;
- u8 mb_address[16];
+ vl_api_prefix_t mb_prefix;
};
+typeonly define mpls_tunnel
+{
+ u32 mt_sw_if_index;
+ u32 mt_tunnel_index;
+ u8 mt_l2_only;
+ u8 mt_is_multicast;
+ u8 mt_n_paths;
+ vl_api_fib_path_t mt_paths[mt_n_paths];
+};
define mpls_tunnel_add_del
{
u32 client_index;
u32 context;
- u32 mt_sw_if_index;
u8 mt_is_add;
- u8 mt_l2_only;
- u8 mt_is_multicast;
- u8 mt_next_hop_proto_is_ip4;
- u8 mt_next_hop_weight;
- u8 mt_next_hop_preference;
- u8 mt_next_hop[16];
- u8 mt_next_hop_n_out_labels;
- u32 mt_next_hop_via_label;
- u32 mt_next_hop_sw_if_index;
- u32 mt_next_hop_table_id;
- vl_api_fib_mpls_label_t mt_next_hop_out_label_stack[mt_next_hop_n_out_labels];
+ vl_api_mpls_tunnel_t mt_tunnel;
};
/** \brief Reply for MPLS tunnel add / del request
@@ -90,12 +87,7 @@ define mpls_tunnel_dump
manual_endian manual_print define mpls_tunnel_details
{
u32 context;
- u32 mt_sw_if_index;
- u32 mt_tunnel_index;
- u8 mt_l2_only;
- u8 mt_is_multicast;
- u32 mt_count;
- vl_api_fib_path_t mt_paths[mt_count];
+ vl_api_mpls_tunnel_t mt_tunnel;
};
/** \brief MPLS Route Add / del route
@@ -107,68 +99,71 @@ manual_endian manual_print define mpls_tunnel_details
is not set by the client, then VPP will generate
something meaningfull.
*/
+typeonly define mpls_table
+{
+ u32 mt_table_id;
+ u8 mt_name[64];
+};
autoreply define mpls_table_add_del
{
u32 client_index;
u32 context;
- u32 mt_table_id;
u8 mt_is_add;
- u8 mt_name[64];
+ vl_api_mpls_table_t mt_table;
};
-/** \brief MPLS Route Add / del route
+/** \brief Dump MPLS fib table
@param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
+*/
+define mpls_table_dump
+{
+ u32 client_index;
+ u32 context;
+};
+
+define mpls_table_details
+{
+ u32 context;
+ vl_api_mpls_table_t mt_table;
+};
+
+/** \brief MPLS Route
@param mr_label - The MPLS label value
@param mr_eos - The End of stack bit
+ @param mr_eos_proto - If EOS then this is the DPO packect's proto post pop
@param mr_table_id - The MPLS table-id the route is added in
- @param mr_classify_table_index - If this is a classify route,
- this is the classify table index
- create them
@param mr_is_add - Is this a route add or delete
- @param mr_is_classify - Is this route result a classify
@param mr_is_multicast - Is this a multicast route
+ @param mr_n_paths - The number of paths
+ @param mr_paths - The paths
+*/
+typeonly define mpls_route
+{
+ u32 mr_table_id;
+ u32 mr_label;
+ u8 mr_eos;
+ u8 mr_eos_proto;
+ u8 mr_is_multicast;
+ u8 mr_n_paths;
+ vl_api_fib_path_t mr_paths[mr_n_paths];
+};
+
+/** \brief MPLS Route Add / del route
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param mr_table_id - The MPLS table-id the route is added in
+ @param mr_is_add - Is this a route add or delete
@param mr_is_multipath - Is this route update a multipath - i.e. is this
a path addition to an existing route
- @param mr_is_resolve_host - Recurse resolution constraint via a host prefix
- @param mr_is_resolve_attached - Recurse resolution constraint via attached prefix
- @param mr_is_interface_rx - Interface Receive path
- @param mr_is_interface_rx - RPF-ID Receive path. The next-hop interface
- is used as the RPF-ID
- @param mr_next_hop_proto - The next-hop protocol, of type dpo_proto_t
- @param mr_next_hop_weight - The weight, for UCMP
- @param mr_next_hop[16] - the nextop address
- @param mr_next_hop_sw_if_index - the next-hop SW interface
- @param mr_next_hop_table_id - the next-hop table-id (if appropriate)
- @param mr_next_hop_n_out_labels - the number of labels in the label stack
- @param mr_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 mr_route - The Route
*/
define mpls_route_add_del
{
u32 client_index;
u32 context;
- u32 mr_label;
- u8 mr_eos;
- u32 mr_table_id;
- u32 mr_classify_table_index;
u8 mr_is_add;
- u8 mr_is_classify;
- u8 mr_is_multicast;
u8 mr_is_multipath;
- u8 mr_is_resolve_host;
- u8 mr_is_resolve_attached;
- u8 mr_is_interface_rx;
- u8 mr_is_rpf_id;
- u8 mr_next_hop_proto;
- u8 mr_next_hop_weight;
- u8 mr_next_hop_preference;
- u8 mr_next_hop[16];
- u8 mr_next_hop_n_out_labels;
- u32 mr_next_hop_sw_if_index;
- u32 mr_next_hop_table_id;
- u32 mr_next_hop_via_label;
- vl_api_fib_mpls_label_t mr_next_hop_out_label_stack[mr_next_hop_n_out_labels];
+ vl_api_mpls_route_t mr_route;
};
define mpls_route_add_del_reply
@@ -181,10 +176,11 @@ define mpls_route_add_del_reply
/** \brief Dump MPLS fib table
@param client_index - opaque cookie to identify the sender
*/
-define mpls_fib_dump
+define mpls_route_dump
{
u32 client_index;
u32 context;
+ vl_api_mpls_table_t table;
};
/** \brief mpls FIB table response
@@ -194,15 +190,10 @@ define mpls_fib_dump
@param count - the number of fib_path in path
@param path - array of of fib_path structures
*/
-manual_endian manual_print define mpls_fib_details
+manual_endian manual_print define mpls_route_details
{
u32 context;
- u32 table_id;
- u8 table_name[64];
- u8 eos_bit;
- u32 label;
- u32 count;
- vl_api_fib_path_t path[count];
+ vl_api_mpls_route_t mr_route;
};
/** \brief Enable or Disable MPLS on and interface
diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c
index 52434dae8aa..cb20df5695b 100644
--- a/src/vnet/mpls/mpls_api.c
+++ b/src/vnet/mpls/mpls_api.c
@@ -28,6 +28,7 @@
#include <vnet/fib/fib_api.h>
#include <vnet/fib/mpls_fib.h>
#include <vnet/fib/fib_path_list.h>
+#include <vnet/ip/ip_types_api.h>
#include <vnet/vnet_msg_enum.h>
@@ -54,7 +55,8 @@ _(MPLS_TABLE_ADD_DEL, mpls_table_add_del) \
_(MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del) \
_(MPLS_TUNNEL_DUMP, mpls_tunnel_dump) \
_(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
-_(MPLS_FIB_DUMP, mpls_fib_dump)
+_(MPLS_TABLE_DUMP, mpls_table_dump) \
+_(MPLS_ROUTE_DUMP, mpls_route_dump)
void
mpls_table_delete (u32 table_id, u8 is_api)
@@ -90,9 +92,10 @@ vl_api_mpls_table_add_del_t_handler (vl_api_mpls_table_add_del_t * mp)
vnm->api_errno = 0;
if (mp->mt_is_add)
- mpls_table_create (ntohl (mp->mt_table_id), 1, mp->mt_name);
+ mpls_table_create (ntohl (mp->mt_table.mt_table_id),
+ 1, mp->mt_table.mt_name);
else
- mpls_table_delete (ntohl (mp->mt_table_id), 1);
+ mpls_table_delete (ntohl (mp->mt_table.mt_table_id), 1);
// NB: Nothing sets rv; none of the above returns an error
@@ -104,6 +107,7 @@ mpls_ip_bind_unbind_handler (vnet_main_t * vnm,
vl_api_mpls_ip_bind_unbind_t * mp)
{
u32 mpls_fib_index, ip_fib_index;
+ fib_prefix_t pfx;
mpls_fib_index =
fib_table_find (FIB_PROTOCOL_MPLS, ntohl (mp->mb_mpls_table_id));
@@ -113,30 +117,12 @@ mpls_ip_bind_unbind_handler (vnet_main_t * vnm,
return VNET_API_ERROR_NO_SUCH_FIB;
}
- ip_fib_index = fib_table_find ((mp->mb_is_ip4 ?
- FIB_PROTOCOL_IP4 :
- FIB_PROTOCOL_IP6),
- ntohl (mp->mb_ip_table_id));
+ ip_prefix_decode (&mp->mb_prefix, &pfx);
+
+ ip_fib_index = fib_table_find (pfx.fp_proto, ntohl (mp->mb_ip_table_id));
if (~0 == ip_fib_index)
return VNET_API_ERROR_NO_SUCH_FIB;
- fib_prefix_t pfx = {
- .fp_len = mp->mb_address_length,
- };
-
- if (mp->mb_is_ip4)
- {
- pfx.fp_proto = FIB_PROTOCOL_IP4;
- clib_memcpy (&pfx.fp_addr.ip4, mp->mb_address,
- sizeof (pfx.fp_addr.ip4));
- }
- else
- {
- pfx.fp_proto = FIB_PROTOCOL_IP6;
- clib_memcpy (&pfx.fp_addr.ip6, mp->mb_address,
- sizeof (pfx.fp_addr.ip6));
- }
-
if (mp->mb_is_bind)
fib_table_entry_local_label_add (ip_fib_index, &pfx,
ntohl (mp->mb_label));
@@ -168,92 +154,58 @@ mpls_route_add_del_t_handler (vnet_main_t * vnm,
vl_api_mpls_route_add_del_t * mp,
u32 * stats_index)
{
- fib_mpls_label_t *label_stack = NULL;
- u32 fib_index, next_hop_fib_index;
- int rv, ii, n_labels;;
+ fib_route_path_t *rpaths = NULL, *rpath;
+ vl_api_fib_path_t *apath;
+ u32 fib_index;
+ int rv, ii;
fib_prefix_t pfx = {
.fp_len = 21,
.fp_proto = FIB_PROTOCOL_MPLS,
- .fp_eos = mp->mr_eos,
- .fp_label = ntohl (mp->mr_label),
+ .fp_eos = mp->mr_route.mr_eos,
+ .fp_label = ntohl (mp->mr_route.mr_label),
};
if (pfx.fp_eos)
{
- pfx.fp_payload_proto = mp->mr_next_hop_proto;
+ pfx.fp_payload_proto = mp->mr_route.mr_eos_proto;
}
else
{
pfx.fp_payload_proto = DPO_PROTO_MPLS;
}
- rv = add_del_route_check (FIB_PROTOCOL_MPLS,
- mp->mr_table_id,
- mp->mr_next_hop_sw_if_index,
- pfx.fp_payload_proto,
- mp->mr_next_hop_table_id,
- mp->mr_is_rpf_id,
- &fib_index, &next_hop_fib_index);
-
+ rv = fib_api_table_id_decode (FIB_PROTOCOL_MPLS,
+ ntohl (mp->mr_route.mr_table_id), &fib_index);
if (0 != rv)
- return (rv);
-
- ip46_address_t nh;
- clib_memset (&nh, 0, sizeof (nh));
+ goto out;
- if (DPO_PROTO_IP4 == mp->mr_next_hop_proto)
- memcpy (&nh.ip4, mp->mr_next_hop, sizeof (nh.ip4));
- else if (DPO_PROTO_IP6 == mp->mr_next_hop_proto)
- memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6));
+ vec_validate (rpaths, mp->mr_route.mr_n_paths - 1);
- n_labels = mp->mr_next_hop_n_out_labels;
- if (n_labels == 0)
- ;
- else
+ for (ii = 0; ii < mp->mr_route.mr_n_paths; ii++)
{
- vec_validate (label_stack, n_labels - 1);
- for (ii = 0; ii < n_labels; ii++)
- {
- label_stack[ii].fml_value =
- ntohl (mp->mr_next_hop_out_label_stack[ii].label);
- label_stack[ii].fml_ttl = mp->mr_next_hop_out_label_stack[ii].ttl;
- label_stack[ii].fml_exp = mp->mr_next_hop_out_label_stack[ii].exp;
- label_stack[ii].fml_mode =
- (mp->mr_next_hop_out_label_stack[ii].is_uniform ?
- FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE);
- }
+ apath = &mp->mr_route.mr_paths[ii];
+ rpath = &rpaths[ii];
+
+ rv = fib_api_path_decode (apath, rpath);
+
+ if (0 != rv)
+ goto out;
}
- /* *INDENT-OFF* */
- rv = add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add,
- 0, // mp->is_drop,
- 0, // mp->is_unreach,
- 0, // mp->is_prohibit,
- 0, // mp->is_local,
- mp->mr_is_multicast,
- mp->mr_is_classify,
- mp->mr_classify_table_index,
- mp->mr_is_resolve_host,
- mp->mr_is_resolve_attached,
- mp->mr_is_interface_rx,
- mp->mr_is_rpf_id,
- 0, // l2_bridged
- 0, // is source_lookup
- 0, // is_udp_encap
- fib_index, &pfx,
- mp->mr_next_hop_proto,
- &nh, ~0, // next_hop_id
- ntohl (mp->mr_next_hop_sw_if_index),
- next_hop_fib_index,
- mp->mr_next_hop_weight,
- mp->mr_next_hop_preference,
- ntohl (mp->mr_next_hop_via_label),
- label_stack);
- /* *INDENT-ON* */
+ fib_api_route_add_del (mp->mr_is_add,
+ mp->mr_is_multipath,
+ fib_index,
+ &pfx,
+ (mp->mr_route.mr_is_multicast ?
+ FIB_ENTRY_FLAG_MULTICAST :
+ FIB_ENTRY_FLAG_NONE), rpaths);
if (mp->mr_is_add && 0 == rv)
*stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
+out:
+ vec_free (rpaths);
+
return (rv);
}
@@ -308,73 +260,30 @@ mpls_table_create (u32 table_id, u8 is_api, const u8 * name)
static void
vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp)
{
- u32 tunnel_sw_if_index = ~0, tunnel_index = ~0, next_hop_via_label;
+ u32 tunnel_sw_if_index = ~0, tunnel_index = ~0;
vl_api_mpls_tunnel_add_del_reply_t *rmp;
- fib_route_path_t rpath, *rpaths = NULL;
+ fib_route_path_t *rpath, *rpaths = NULL;
int ii, rv = 0;
- clib_memset (&rpath, 0, sizeof (rpath));
+ vec_validate (rpaths, mp->mt_tunnel.mt_n_paths - 1);
- if (mp->mt_next_hop_proto_is_ip4)
+ for (ii = 0; ii < mp->mt_tunnel.mt_n_paths; ii++)
{
- rpath.frp_proto = DPO_PROTO_IP4;
- clib_memcpy (&rpath.frp_addr.ip4,
- mp->mt_next_hop, sizeof (rpath.frp_addr.ip4));
- }
- else
- {
- rpath.frp_proto = DPO_PROTO_IP6;
- clib_memcpy (&rpath.frp_addr.ip6,
- mp->mt_next_hop, sizeof (rpath.frp_addr.ip6));
- }
- rpath.frp_sw_if_index = ntohl (mp->mt_next_hop_sw_if_index);
- rpath.frp_weight = mp->mt_next_hop_weight;
- rpath.frp_preference = mp->mt_next_hop_preference;
+ rpath = &rpaths[ii];
- next_hop_via_label = ntohl (mp->mt_next_hop_via_label);
- if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
- {
- rpath.frp_proto = DPO_PROTO_MPLS;
- rpath.frp_local_label = next_hop_via_label;
- rpath.frp_eos = MPLS_NON_EOS;
- }
+ rv = fib_api_path_decode (&mp->mt_tunnel.mt_paths[ii], rpath);
- if (rpath.frp_sw_if_index == ~0)
- { /* recursive path, set fib index */
- rpath.frp_fib_index =
- fib_table_find (dpo_proto_to_fib (rpath.frp_proto),
- ntohl (mp->mt_next_hop_table_id));
- if (rpath.frp_fib_index == ~0)
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto out;
- }
+ if (0 != rv)
+ goto out;
}
-
- if (mp->mt_is_add)
- {
- for (ii = 0; ii < mp->mt_next_hop_n_out_labels; ii++)
- {
- fib_mpls_label_t fml = {
- .fml_value = ntohl (mp->mt_next_hop_out_label_stack[ii].label),
- .fml_ttl = mp->mt_next_hop_out_label_stack[ii].ttl,
- .fml_exp = mp->mt_next_hop_out_label_stack[ii].exp,
- .fml_mode = (mp->mt_next_hop_out_label_stack[ii].is_uniform ?
- FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE),
- };
- vec_add1 (rpath.frp_label_stack, fml);
- }
- }
-
- vec_add1 (rpaths, rpath);
-
- tunnel_sw_if_index = ntohl (mp->mt_sw_if_index);
+ tunnel_sw_if_index = ntohl (mp->mt_tunnel.mt_sw_if_index);
if (mp->mt_is_add)
{
if (~0 == tunnel_sw_if_index)
- tunnel_sw_if_index = vnet_mpls_tunnel_create (mp->mt_l2_only,
- mp->mt_is_multicast);
+ tunnel_sw_if_index =
+ vnet_mpls_tunnel_create (mp->mt_tunnel.mt_l2_only,
+ mp->mt_tunnel.mt_is_multicast);
vnet_mpls_tunnel_path_add (tunnel_sw_if_index, rpaths);
tunnel_index = vnet_mpls_tunnel_get_index (tunnel_sw_if_index);
@@ -382,7 +291,7 @@ vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp)
else
{
tunnel_index = vnet_mpls_tunnel_get_index (tunnel_sw_if_index);
- tunnel_sw_if_index = ntohl (mp->mt_sw_if_index);
+ tunnel_sw_if_index = ntohl (mp->mt_tunnel.mt_sw_if_index);
if (!vnet_mpls_tunnel_path_remove (tunnel_sw_if_index, rpaths))
vnet_mpls_tunnel_del (tunnel_sw_if_index);
}
@@ -426,10 +335,13 @@ typedef struct mpls_tunnel_send_walk_ctx_t_
static void
send_mpls_tunnel_entry (u32 mti, void *arg)
{
- fib_route_path_encode_t *api_rpaths = NULL, *api_rpath;
mpls_tunnel_send_walk_ctx_t *ctx;
vl_api_mpls_tunnel_details_t *mp;
+ fib_path_encode_ctx_t path_ctx = {
+ .rpaths = NULL,
+ };
const mpls_tunnel_t *mt;
+ fib_route_path_t *rpath;
vl_api_fib_path_t *fp;
u32 n;
@@ -448,21 +360,25 @@ send_mpls_tunnel_entry (u32 mti, void *arg)
mp->_vl_msg_id = ntohs (VL_API_MPLS_TUNNEL_DETAILS);
mp->context = ctx->context;
- mp->mt_tunnel_index = ntohl (mti);
- mp->mt_sw_if_index = ntohl (mt->mt_sw_if_index);
- mp->mt_count = ntohl (n);
+ mp->mt_tunnel.mt_n_paths = ntohl (n);
+ mp->mt_tunnel.mt_sw_if_index = ntohl (mt->mt_sw_if_index);
+ mp->mt_tunnel.mt_tunnel_index = ntohl (mti);
+ mp->mt_tunnel.mt_l2_only = ! !(MPLS_TUNNEL_FLAG_L2 & mt->mt_flags);
+ mp->mt_tunnel.mt_is_multicast = ! !(MPLS_TUNNEL_FLAG_MCAST & mt->mt_flags);
fib_path_list_walk_w_ext (mt->mt_path_list,
- &mt->mt_path_exts, fib_path_encode, &api_rpaths);
+ &mt->mt_path_exts, fib_path_encode, &path_ctx);
- fp = mp->mt_paths;
- vec_foreach (api_rpath, api_rpaths)
+ fp = mp->mt_tunnel.mt_paths;
+ vec_foreach (rpath, path_ctx.rpaths)
{
- fib_api_path_encode (api_rpath, fp);
+ fib_api_path_encode (rpath, fp);
fp++;
}
vl_api_send_msg (ctx->reg, (u8 *) mp);
+
+ vec_free (path_ctx.rpaths);
}
static void
@@ -483,51 +399,95 @@ vl_api_mpls_tunnel_dump_t_handler (vl_api_mpls_tunnel_dump_t * mp)
}
static void
-send_mpls_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)
+send_mpls_table_details (vpe_api_main_t * am,
+ vl_api_registration_t * reg,
+ u32 context, const fib_table_t * table)
+{
+ vl_api_mpls_table_details_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_TABLE_DETAILS);
+ mp->context = context;
+
+ mp->mt_table.mt_table_id = htonl (table->ft_table_id);
+ memcpy (mp->mt_table.mt_name,
+ table->ft_desc,
+ clib_min (vec_len (table->ft_desc), sizeof (mp->mt_table.mt_name)));
+
+ vl_api_send_msg (reg, (u8 *) mp);
+}
+
+static void
+vl_api_mpls_table_dump_t_handler (vl_api_mpls_table_dump_t * mp)
{
- vl_api_mpls_fib_details_t *mp;
- fib_route_path_encode_t *api_rpath;
+ vpe_api_main_t *am = &vpe_api_main;
+ vl_api_registration_t *reg;
+ mpls_main_t *mm = &mpls_main;
+ fib_table_t *fib_table;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, mm->fibs,
+ ({
+ send_mpls_table_details(am, reg, mp->context, fib_table);
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+send_mpls_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_mpls_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 = fib_entry_encode (fib_entry_index);
+ pfx = fib_entry_get_prefix (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_MPLS_FIB_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_ROUTE_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->eos_bit = pfx->fp_eos;
- mp->label = htonl (pfx->fp_label);
+ mp->mr_route.mr_table_id =
+ htonl (fib_table_get_table_id
+ (fib_entry_get_fib_index (fib_entry_index), pfx->fp_proto));
+ mp->mr_route.mr_eos = pfx->fp_eos;
+ mp->mr_route.mr_eos_proto = pfx->fp_payload_proto;
+ mp->mr_route.mr_label = htonl (pfx->fp_label);
- mp->count = htonl (path_count);
- fp = mp->path;
- vec_foreach (api_rpath, api_rpaths)
+ mp->mr_route.mr_n_paths = path_count;
+ fp = mp->mr_route.mr_paths;
+ vec_foreach (rpath, rpaths)
{
- fib_api_path_encode (api_rpath, fp);
+ fib_api_path_encode (rpath, fp);
fp++;
}
+ vec_free (rpaths);
vl_api_send_msg (reg, (u8 *) mp);
}
-typedef struct vl_api_mpls_fib_dump_table_walk_ctx_t_
+typedef struct vl_api_mpls_route_dump_table_walk_ctx_t_
{
fib_node_index_t *lfeis;
-} vl_api_mpls_fib_dump_table_walk_ctx_t;
+} vl_api_mpls_route_dump_table_walk_ctx_t;
static fib_table_walk_rc_t
-vl_api_mpls_fib_dump_table_walk (fib_node_index_t fei, void *arg)
+vl_api_mpls_route_dump_table_walk (fib_node_index_t fei, void *arg)
{
- vl_api_mpls_fib_dump_table_walk_ctx_t *ctx = arg;
+ vl_api_mpls_route_dump_table_walk_ctx_t *ctx = arg;
vec_add1 (ctx->lfeis, fei);
@@ -535,47 +495,37 @@ vl_api_mpls_fib_dump_table_walk (fib_node_index_t fei, void *arg)
}
static void
-vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp)
+vl_api_mpls_route_dump_t_handler (vl_api_mpls_route_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
vl_api_registration_t *reg;
- mpls_main_t *mm = &mpls_main;
- fib_table_t *fib_table;
- mpls_fib_t *mpls_fib;
fib_node_index_t *lfeip = NULL;
- const fib_prefix_t *pfx;
- u32 fib_index;
- fib_route_path_encode_t *api_rpaths;
- vl_api_mpls_fib_dump_table_walk_ctx_t ctx = {
+ vl_api_mpls_route_dump_table_walk_ctx_t ctx = {
.lfeis = NULL,
};
+ u32 fib_index;
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- /* *INDENT-OFF* */
- pool_foreach (mpls_fib, mm->mpls_fibs,
- ({
- mpls_fib_table_walk (mpls_fib,
- vl_api_mpls_fib_dump_table_walk,
- &ctx);
- }));
- /* *INDENT-ON* */
- vec_sort_with_function (ctx.lfeis, fib_entry_cmp_for_sort);
+ fib_index = fib_table_find (FIB_PROTOCOL_MPLS,
+ ntohl (mp->table.mt_table_id));
- vec_foreach (lfeip, ctx.lfeis)
- {
- 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_mpls_fib_details (am, reg, fib_table, pfx, api_rpaths, mp->context);
- vec_free (api_rpaths);
- }
+ if (INDEX_INVALID != fib_index)
+ {
+ fib_table_walk (fib_index,
+ FIB_PROTOCOL_MPLS,
+ vl_api_mpls_route_dump_table_walk, &ctx);
+ vec_sort_with_function (ctx.lfeis, fib_entry_cmp_for_sort);
- vec_free (ctx.lfeis);
+ vec_foreach (lfeip, ctx.lfeis)
+ {
+ send_mpls_route_details (am, reg, mp->context, *lfeip);
+ }
+
+ vec_free (ctx.lfeis);
+ }
}
/*
diff --git a/src/vnet/mpls/mpls_tunnel.c b/src/vnet/mpls/mpls_tunnel.c
index 8db08c3a387..b7bcbfd14f7 100644
--- a/src/vnet/mpls/mpls_tunnel.c
+++ b/src/vnet/mpls/mpls_tunnel.c
@@ -242,7 +242,7 @@ mpls_tunnel_stack (adj_index_t ai)
mt = mpls_tunnel_get_from_sw_if_index(sw_if_index);
- if (NULL == mt)
+ if (NULL == mt || FIB_NODE_INDEX_INVALID == mt->mt_path_list)
return;
if (FIB_NODE_INDEX_INVALID == mt->mt_path_list)
@@ -654,6 +654,7 @@ void
vnet_mpls_tunnel_path_add (u32 sw_if_index,
fib_route_path_t *rpaths)
{
+ fib_route_path_t *rpath;
mpls_tunnel_t *mt;
u32 mti;
@@ -695,10 +696,13 @@ vnet_mpls_tunnel_path_add (u32 sw_if_index,
*/
fib_path_ext_list_resolve(&mt->mt_path_exts, mt->mt_path_list);
}
- fib_path_ext_list_insert(&mt->mt_path_exts,
- mt->mt_path_list,
- FIB_PATH_EXT_MPLS,
- rpaths);
+ vec_foreach(rpath, rpaths)
+ {
+ fib_path_ext_list_insert(&mt->mt_path_exts,
+ mt->mt_path_list,
+ FIB_PATH_EXT_MPLS,
+ rpath);
+ }
mpls_tunnel_restack(mt);
}
diff --git a/src/vnet/udp/udp_encap.c b/src/vnet/udp/udp_encap.c
index c8268276288..df4a811f3dd 100644
--- a/src/vnet/udp/udp_encap.c
+++ b/src/vnet/udp/udp_encap.c
@@ -211,7 +211,7 @@ format_udp_encap_i (u8 * s, va_list * args)
ue = udp_encap_get (uei);
// FIXME
- s = format (s, "udp-ecap:[%d]: ip-fib-index:%d ", uei, ue->ue_fib_index);
+ s = format (s, "udp-encap:[%d]: ip-fib-index:%d ", uei, ue->ue_fib_index);
if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
{
s = format (s, "ip:[src:%U, dst:%U] udp:[src:%d, dst:%d]",
diff --git a/src/vnet/vxlan-gbp/vxlan_gbp.c b/src/vnet/vxlan-gbp/vxlan_gbp.c
index 001de73b840..7b09b57bd59 100644
--- a/src/vnet/vxlan-gbp/vxlan_gbp.c
+++ b/src/vnet/vxlan-gbp/vxlan_gbp.c
@@ -557,6 +557,7 @@ int vnet_vxlan_gbp_tunnel_add_del
.frp_fib_index = ~0,
.frp_weight = 0,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
const mfib_prefix_t mpfx = {
.fp_proto = fp,
@@ -571,16 +572,15 @@ int vnet_vxlan_gbp_tunnel_add_del
*/
mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
- MFIB_SOURCE_VXLAN_GBP,
- &path, MFIB_ITF_FLAG_FORWARD);
+ MFIB_SOURCE_VXLAN_GBP, &path);
path.frp_sw_if_index = a->mcast_sw_if_index;
path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
+ path.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT;
mfei = mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
MFIB_SOURCE_VXLAN_GBP,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ &path);
/*
* Create the mcast adjacency to send traffic to the group
diff --git a/src/vnet/vxlan-gpe/vxlan_gpe.c b/src/vnet/vxlan-gpe/vxlan_gpe.c
index ca17c12a87b..dd0e544352f 100644
--- a/src/vnet/vxlan-gpe/vxlan_gpe.c
+++ b/src/vnet/vxlan-gpe/vxlan_gpe.c
@@ -646,8 +646,9 @@ int vnet_vxlan_gpe_add_del_tunnel
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
const mfib_prefix_t mpfx = {
.fp_proto = fp,
@@ -662,16 +663,15 @@ int vnet_vxlan_gpe_add_del_tunnel
*/
mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
- MFIB_SOURCE_VXLAN_GPE,
- &path, MFIB_ITF_FLAG_FORWARD);
+ MFIB_SOURCE_VXLAN_GPE, &path);
path.frp_sw_if_index = a->mcast_sw_if_index;
path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
+ path.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT;
mfei = mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
MFIB_SOURCE_VXLAN_GPE,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ &path);
/*
* Create the mcast adjacency to send traffic to the group
diff --git a/src/vnet/vxlan/vxlan.c b/src/vnet/vxlan/vxlan.c
index 52d0812235f..def306a7846 100644
--- a/src/vnet/vxlan/vxlan.c
+++ b/src/vnet/vxlan/vxlan.c
@@ -538,8 +538,9 @@ int vnet_vxlan_add_del_tunnel
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
const mfib_prefix_t mpfx = {
.fp_proto = fp,
@@ -553,17 +554,14 @@ int vnet_vxlan_add_del_tunnel
* - the accepting interface is that from the API
*/
mfib_table_entry_path_update (t->encap_fib_index,
- &mpfx,
- MFIB_SOURCE_VXLAN,
- &path, MFIB_ITF_FLAG_FORWARD);
+ &mpfx, MFIB_SOURCE_VXLAN, &path);
path.frp_sw_if_index = a->mcast_sw_if_index;
path.frp_flags = FIB_ROUTE_PATH_FLAG_NONE;
+ path.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT;
mfei = mfib_table_entry_path_update (t->encap_fib_index,
&mpfx,
- MFIB_SOURCE_VXLAN,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ MFIB_SOURCE_VXLAN, &path);
/*
* Create the mcast adjacency to send traffic to the group