diff options
author | Neale Ranns <nranns@cisco.com> | 2017-10-03 08:20:21 -0700 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2017-10-05 09:50:26 +0000 |
commit | 6f6311560380d0e992f710558e213df1b098ef94 (patch) | |
tree | 237e34a2165ed5d2fc0848a1daec457ce57acc3e /src/vnet/fib/fib_path.c | |
parent | d3c008d108aa2187d1a2afe2833b4de25ca2c2ab (diff) |
Distributed Virtual Router Support
A distributed virtual router works by attmpeting to switch a packet, but on failing to find a local consumer (i.e. the packet is destined to a locally attached host) then the packet is sent unmodified 'upstream' to where the rest of the 'distributed' router is present. When L3 switching a packet this means the L2 header must not be modifed. This patch adds a 'l2-bridge' object to the L3 FIB which re-injects packets from the L3 path back into the L2 path - use with extreme caution.
Change-Id: I069724eb45956647d7980cbe40a80a788ee6ee82
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/fib/fib_path.c')
-rw-r--r-- | src/vnet/fib/fib_path.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c index f126333425a..889d17def9c 100644 --- a/src/vnet/fib/fib_path.c +++ b/src/vnet/fib/fib_path.c @@ -23,6 +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/adj/adj.h> #include <vnet/adj/adj_mcast.h> @@ -771,11 +772,18 @@ fib_path_unresolve (fib_path_t *path) } break; case FIB_PATH_TYPE_ATTACHED_NEXT_HOP: - case FIB_PATH_TYPE_ATTACHED: adj_child_remove(path->fp_dpo.dpoi_index, path->fp_sibling); 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); + } + break; case FIB_PATH_TYPE_EXCLUSIVE: dpo_reset(&path->exclusive.fp_ex_dpo); break; @@ -1594,28 +1602,35 @@ fib_path_resolve (fib_node_index_t path_index) fib_path_attached_next_hop_set(path); break; case FIB_PATH_TYPE_ATTACHED: - /* - * 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))); - - /* - * 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)); + if (DPO_PROTO_ETHERNET == path->fp_nh_proto) + { + l2_bridge_dpo_add_or_lock(path->attached.fp_interface, + &path->fp_dpo); + } + 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))); + /* + * 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: { @@ -1996,6 +2011,11 @@ 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: |