aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-01-03 04:18:48 -0800
committerOle Trøan <otroan@employees.org>2018-01-09 16:38:19 +0000
commitf068c3ed296c49dfbfe17677fc1ad2428fb4e3e4 (patch)
treeeef3c7c502b68ccdff9c5d80d04850465e25ef01 /src/vnet/fib
parent0e8cb6c475b616a3296b08d25bcaa1eed3ab0084 (diff)
DVR: run L3 output features
- rename l2_bridged to is_dvr. Including on the ip.api this was new in the 18.01 release so no compatability issues. - steal the free space in vnet_buffer_opaque_t for use with flags. - run the ipX-output feature arc from the DVR DPO Change-Id: I040e5976d1dbe076fcdda3a40a7804f56337ce3f Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/fib')
-rw-r--r--src/vnet/fib/fib_api.h2
-rw-r--r--src/vnet/fib/fib_path.c106
-rw-r--r--src/vnet/fib/fib_test.c26
-rw-r--r--src/vnet/fib/fib_types.h4
4 files changed, 86 insertions, 52 deletions
diff --git a/src/vnet/fib/fib_api.h b/src/vnet/fib/fib_api.h
index 655d305372b..bbe4eaac74b 100644
--- a/src/vnet/fib/fib_api.h
+++ b/src/vnet/fib/fib_api.h
@@ -40,7 +40,7 @@ add_del_route_t_handler (u8 is_multipath,
u8 is_resolve_attached,
u8 is_interface_rx,
u8 is_rpf_id,
- u8 is_l2_bridged,
+ u8 is_dvr,
u8 is_source_lookup,
u8 is_udp_encap,
u32 fib_index,
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c
index fddb8ecdd5a..ffb7ad228f1 100644
--- a/src/vnet/fib/fib_path.c
+++ b/src/vnet/fib/fib_path.c
@@ -23,7 +23,7 @@
#include <vnet/dpo/lookup_dpo.h>
#include <vnet/dpo/interface_rx_dpo.h>
#include <vnet/dpo/mpls_disposition.h>
-#include <vnet/dpo/l2_bridge_dpo.h>
+#include <vnet/dpo/dvr_dpo.h>
#include <vnet/dpo/drop_dpo.h>
#include <vnet/adj/adj.h>
@@ -100,6 +100,10 @@ typedef enum fib_path_type_t_ {
*/
FIB_PATH_TYPE_BIER_FMASK,
/**
+ * via a DVR.
+ */
+ FIB_PATH_TYPE_DVR,
+ /**
* Marker. Add new types before this one, then update it.
*/
FIB_PATH_TYPE_LAST = FIB_PATH_TYPE_BIER_FMASK,
@@ -123,6 +127,7 @@ typedef enum fib_path_type_t_ {
[FIB_PATH_TYPE_BIER_IMP] = "bier-imp", \
[FIB_PATH_TYPE_BIER_TABLE] = "bier-table", \
[FIB_PATH_TYPE_BIER_FMASK] = "bier-fmask", \
+ [FIB_PATH_TYPE_DVR] = "dvr", \
}
#define FOR_EACH_FIB_PATH_TYPE(_item) \
@@ -345,6 +350,12 @@ typedef struct fib_path_t_ {
*/
u32 fp_udp_encap_id;
} udp_encap;
+ struct {
+ /**
+ * The interface
+ */
+ u32 fp_interface;
+ } dvr;
};
STRUCT_MARK(path_hash_end);
@@ -574,6 +585,14 @@ format_fib_path (u8 * s, va_list * args)
s = format (s, "via %U", format_bier_imp,
path->bier_imp.fp_bier_imp, 0, BIER_SHOW_BRIEF);
break;
+ case FIB_PATH_TYPE_DVR:
+ s = format (s, " %U",
+ format_vnet_sw_interface_name,
+ vnm,
+ vnet_get_sw_interface(
+ vnm,
+ path->dvr.fp_interface));
+ break;
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_SPECIAL:
@@ -881,12 +900,9 @@ fib_path_unresolve (fib_path_t *path)
adj_unlock(path->fp_dpo.dpoi_index);
break;
case FIB_PATH_TYPE_ATTACHED:
- if (DPO_PROTO_ETHERNET != path->fp_nh_proto)
- {
- adj_child_remove(path->fp_dpo.dpoi_index,
- path->fp_sibling);
- adj_unlock(path->fp_dpo.dpoi_index);
- }
+ adj_child_remove(path->fp_dpo.dpoi_index,
+ path->fp_sibling);
+ adj_unlock(path->fp_dpo.dpoi_index);
break;
case FIB_PATH_TYPE_UDP_ENCAP:
udp_encap_unlock_w_index(path->fp_dpo.dpoi_index);
@@ -898,6 +914,7 @@ fib_path_unresolve (fib_path_t *path)
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_DEAG:
+ case FIB_PATH_TYPE_DVR:
/*
* these hold only the path's DPO, which is reset below.
*/
@@ -1101,6 +1118,7 @@ FIXME comment
}
break;
case FIB_PATH_TYPE_ATTACHED:
+ case FIB_PATH_TYPE_DVR:
/*
* FIXME; this could schedule a lower priority walk, since attached
* routes are not usually in ECMP configurations so the backwalk to
@@ -1299,6 +1317,11 @@ fib_path_create (fib_node_index_t pl_index,
path->fp_type = FIB_PATH_TYPE_DEAG;
path->deag.fp_tbl_id = rpath->frp_fib_index;
}
+ else if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
+ {
+ path->fp_type = FIB_PATH_TYPE_DVR;
+ path->dvr.fp_interface = rpath->frp_sw_if_index;
+ }
else if (~0 != rpath->frp_sw_if_index)
{
if (ip46_address_is_zero(&rpath->frp_addr))
@@ -1546,6 +1569,9 @@ fib_path_cmp_i (const fib_path_t *path1,
case FIB_PATH_TYPE_UDP_ENCAP:
res = (path1->udp_encap.fp_udp_encap_id - path2->udp_encap.fp_udp_encap_id);
break;
+ case FIB_PATH_TYPE_DVR:
+ res = (path1->dvr.fp_interface - path2->dvr.fp_interface);
+ break;
case FIB_PATH_TYPE_SPECIAL:
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_EXCLUSIVE:
@@ -1680,6 +1706,9 @@ fib_path_cmp_w_route_path (fib_node_index_t path_index,
res = (path->deag.fp_rpf_id - rpath->frp_rpf_id);
}
break;
+ case FIB_PATH_TYPE_DVR:
+ res = (path->dvr.fp_interface - rpath->frp_sw_if_index);
+ break;
case FIB_PATH_TYPE_SPECIAL:
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_EXCLUSIVE:
@@ -1776,6 +1805,7 @@ fib_path_recursive_loop_detect (fib_node_index_t path_index,
case FIB_PATH_TYPE_ATTACHED:
case FIB_PATH_TYPE_SPECIAL:
case FIB_PATH_TYPE_DEAG:
+ case FIB_PATH_TYPE_DVR:
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_UDP_ENCAP:
@@ -1821,35 +1851,27 @@ fib_path_resolve (fib_node_index_t path_index)
fib_path_attached_next_hop_set(path);
break;
case FIB_PATH_TYPE_ATTACHED:
- if (DPO_PROTO_ETHERNET == path->fp_nh_proto)
+ /*
+ * path->attached.fp_interface
+ */
+ if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
+ path->attached.fp_interface))
{
- l2_bridge_dpo_add_or_lock(path->attached.fp_interface,
- &path->fp_dpo);
+ path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
}
- else
- {
- /*
- * path->attached.fp_interface
- */
- if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
- path->attached.fp_interface))
- {
- path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
- }
- dpo_set(&path->fp_dpo,
- DPO_ADJACENCY,
- path->fp_nh_proto,
- fib_path_attached_get_adj(path,
- dpo_proto_to_link(path->fp_nh_proto)));
+ dpo_set(&path->fp_dpo,
+ DPO_ADJACENCY,
+ path->fp_nh_proto,
+ fib_path_attached_get_adj(path,
+ dpo_proto_to_link(path->fp_nh_proto)));
- /*
- * become a child of the adjacency so we receive updates
- * when the interface state changes
- */
- path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
- FIB_NODE_TYPE_PATH,
- fib_path_get_index(path));
- }
+ /*
+ * become a child of the adjacency so we receive updates
+ * when the interface state changes
+ */
+ path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
+ FIB_NODE_TYPE_PATH,
+ fib_path_get_index(path));
break;
case FIB_PATH_TYPE_RECURSIVE:
{
@@ -1975,6 +1997,11 @@ fib_path_resolve (fib_node_index_t path_index)
}
break;
}
+ case FIB_PATH_TYPE_DVR:
+ dvr_dpo_add_or_lock(path->attached.fp_interface,
+ path->fp_nh_proto,
+ &path->fp_dpo);
+ break;
case FIB_PATH_TYPE_RECEIVE:
/*
* Resolve via a receive DPO.
@@ -2031,6 +2058,8 @@ fib_path_get_resolving_interface (fib_node_index_t path_index)
return (fib_entry_get_resolving_interface(path->fp_via_fib));
}
break;
+ case FIB_PATH_TYPE_DVR:
+ return (path->dvr.fp_interface);
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_UDP_ENCAP:
case FIB_PATH_TYPE_SPECIAL:
@@ -2059,6 +2088,7 @@ fib_path_get_resolving_index (fib_node_index_t path_index)
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_SPECIAL:
case FIB_PATH_TYPE_DEAG:
+ case FIB_PATH_TYPE_DVR:
case FIB_PATH_TYPE_EXCLUSIVE:
break;
case FIB_PATH_TYPE_UDP_ENCAP:
@@ -2187,6 +2217,9 @@ fib_path_contribute_urpf (fib_node_index_t path_index,
}
break;
}
+ case FIB_PATH_TYPE_DVR:
+ fib_urpf_list_append(urpf, path->dvr.fp_interface);
+ break;
case FIB_PATH_TYPE_DEAG:
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_INTF_RX:
@@ -2250,6 +2283,7 @@ fib_path_stack_mpls_disp (fib_node_index_t path_index,
case FIB_PATH_TYPE_BIER_FMASK:
case FIB_PATH_TYPE_BIER_TABLE:
case FIB_PATH_TYPE_BIER_IMP:
+ case FIB_PATH_TYPE_DVR:
break;
}
}
@@ -2400,11 +2434,6 @@ fib_path_contribute_forwarding (fib_node_index_t path_index,
dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
break;
case FIB_PATH_TYPE_ATTACHED:
- if (DPO_PROTO_ETHERNET == path->fp_nh_proto)
- {
- dpo_copy(dpo, &path->fp_dpo);
- break;
- }
switch (fct)
{
case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
@@ -2462,6 +2491,7 @@ fib_path_contribute_forwarding (fib_node_index_t path_index,
break;
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_SPECIAL:
+ case FIB_PATH_TYPE_DVR:
dpo_copy(dpo, &path->fp_dpo);
break;
}
diff --git a/src/vnet/fib/fib_test.c b/src/vnet/fib/fib_test.c
index 555196d0092..9a8febb1396 100644
--- a/src/vnet/fib/fib_test.c
+++ b/src/vnet/fib/fib_test.c
@@ -28,7 +28,7 @@
#include <vnet/bfd/bfd_main.h>
#include <vnet/dpo/interface_rx_dpo.h>
#include <vnet/dpo/replicate_dpo.h>
-#include <vnet/dpo/l2_bridge_dpo.h>
+#include <vnet/dpo/dvr_dpo.h>
#include <vnet/dpo/mpls_disposition.h>
#include <vnet/mpls/mpls.h>
@@ -550,7 +550,7 @@ fib_test_validate_lb_v (const load_balance_t *lb,
exp->adj.adj);
break;
case FT_LB_L2:
- FIB_TEST_I((DPO_L2_BRIDGE == dpo->dpoi_type),
+ FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
"bucket %d stacks on %U",
bucket,
format_dpo_type, dpo->dpoi_type);
@@ -4116,25 +4116,25 @@ fib_test_v4 (void)
format_ip_flow_hash_config, lb->lb_hash_config);
/*
- * A route via an L2 Bridge
+ * A route via DVR DPO
*/
fei = fib_table_entry_path_add(fib_index,
&pfx_10_10_10_3_s_32,
FIB_SOURCE_API,
FIB_ENTRY_FLAG_NONE,
- DPO_PROTO_ETHERNET,
+ DPO_PROTO_IP4,
&zero_addr,
tm->hw[0]->sw_if_index,
~0,
1,
NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
- dpo_id_t l2_dpo = DPO_INVALID;
- l2_bridge_dpo_add_or_lock(tm->hw[0]->sw_if_index, &l2_dpo);
+ FIB_ROUTE_PATH_DVR);
+ dpo_id_t dvr_dpo = DPO_INVALID;
+ dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
fib_test_lb_bucket_t ip_o_l2 = {
.type = FT_LB_L2,
.adj = {
- .adj = l2_dpo.dpoi_index,
+ .adj = dvr_dpo.dpoi_index,
},
};
@@ -4146,13 +4146,13 @@ fib_test_v4 (void)
fib_table_entry_path_remove(fib_index,
&pfx_10_10_10_3_s_32,
FIB_SOURCE_API,
- DPO_PROTO_ETHERNET,
+ DPO_PROTO_IP4,
&zero_addr,
tm->hw[0]->sw_if_index,
fib_index,
1,
- FIB_ROUTE_PATH_FLAG_NONE);
- dpo_reset(&l2_dpo);
+ FIB_ROUTE_PATH_DVR);
+ dpo_reset(&dvr_dpo);
/*
* CLEANUP
@@ -4253,8 +4253,8 @@ fib_test_v4 (void)
pool_elts(load_balance_map_pool));
FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
pool_elts(load_balance_pool));
- FIB_TEST((0 == pool_elts(l2_bridge_dpo_pool)), "L2 DPO pool size is %d",
- pool_elts(l2_bridge_dpo_pool));
+ FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
+ pool_elts(dvr_dpo_pool));
return 0;
}
diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h
index 5742c69b7c7..e3aef7a58df 100644
--- a/src/vnet/fib/fib_types.h
+++ b/src/vnet/fib/fib_types.h
@@ -344,6 +344,10 @@ typedef enum fib_route_path_flags_t_
* A path that resolves via another table
*/
FIB_ROUTE_PATH_DEAG = (1 << 13),
+ /**
+ * A path that resolves via a DVR DPO
+ */
+ FIB_ROUTE_PATH_DVR = (1 << 14),
} fib_route_path_flags_t;
/**