diff options
author | Neale Ranns <nranns@cisco.com> | 2018-01-03 04:18:48 -0800 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2018-01-09 16:38:19 +0000 |
commit | f068c3ed296c49dfbfe17677fc1ad2428fb4e3e4 (patch) | |
tree | eef3c7c502b68ccdff9c5d80d04850465e25ef01 /src/vnet/fib | |
parent | 0e8cb6c475b616a3296b08d25bcaa1eed3ab0084 (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.h | 2 | ||||
-rw-r--r-- | src/vnet/fib/fib_path.c | 106 | ||||
-rw-r--r-- | src/vnet/fib/fib_test.c | 26 | ||||
-rw-r--r-- | src/vnet/fib/fib_types.h | 4 |
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; /** |