aboutsummaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2016-10-15 17:45:35 -0400
committerChris Luke <chris_luke@comcast.com>2016-10-17 14:15:37 +0000
commitaeb06f4bb55afb8cc181d4c81808652c20d040d4 (patch)
treefcb703eff735feb419c3a640913088d1893aaa60 /vnet
parente11a282cc6ab240417da379ea0367d034e2a87c8 (diff)
Support MPLSoGRE with the new FIB 2.0
Note that the new way to provision MPLSoGRE is using the "normal" GRE tunnel such as in the following example: create gre tunnel src 10.0.3.1 dst 10.0.3.3 set in state gre0 up set int ip addr gre0 10.0.4.1/30 set int mpls gre0 enable ip route table 4 6.0.0.0/24 via 10.0.4.2 gre0 out-label 30 mpls local-label add 30 eos ip4-lookup-in-table 4 The previous CLIs/APIs used to configure MPLSoGRE tunnel such as "create mpls gre tunnel...", "mpls encap|decap add label .." and "show mpls tunnel", etc. can not be used. They will be deprecated in a later update to the VPP code base. Change-Id: I244916841924dc2b87d2143691cd8476716c06b1 Signed-off-by: John Lo <loj@cisco.com>
Diffstat (limited to 'vnet')
-rw-r--r--vnet/vnet/gre/node.c125
-rw-r--r--vnet/vnet/mpls/mpls.c38
-rw-r--r--vnet/vnet/mpls/mpls_output.c14
3 files changed, 50 insertions, 127 deletions
diff --git a/vnet/vnet/gre/node.c b/vnet/vnet/gre/node.c
index b55f5511916..556f1a81837 100644
--- a/vnet/vnet/gre/node.c
+++ b/vnet/vnet/gre/node.c
@@ -68,7 +68,6 @@ gre_input (vlib_main_t * vm,
vlib_frame_t * from_frame)
{
gre_main_t * gm = &gre_main;
- mpls_main_t * mm = &mpls_main;
ip4_main_t * ip4m = &ip4_main;
gre_input_runtime_t * rt = (void *) node->runtime_data;
__attribute__((unused)) u32 n_left_from, next_index, * from, * to_next;
@@ -169,9 +168,10 @@ gre_input (vlib_main_t * vm,
/* RPF check for ip4/ip6 input */
- if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
- || next0 == GRE_INPUT_NEXT_IP6_INPUT
- || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
+ if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+ || next0 == GRE_INPUT_NEXT_IP6_INPUT
+ || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT
+ || next0 == GRE_INPUT_NEXT_MPLS_INPUT))
{
u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
(u64)(vnet_buffer(b0)->gre.src);
@@ -205,40 +205,6 @@ gre_input (vlib_main_t * vm,
tunnel_fib_index = cached_tunnel_fib_index;
}
}
- else if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_MPLS_INPUT))
- {
- u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
- (u64)(vnet_buffer(b0)->gre.src);
-
- if (cached_tunnel_key != key)
- {
- vnet_hw_interface_t * hi;
- mpls_gre_tunnel_t * t;
- uword * p;
-
- p = hash_get (gm->tunnel_by_key, key);
- if (!p)
- {
- next0 = GRE_INPUT_NEXT_DROP;
- b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
- goto drop0;
- }
- t = pool_elt_at_index (mm->gre_tunnels, p[0]);
- hi = vnet_get_hw_interface (gm->vnet_main,
- t->hw_if_index);
- tunnel_sw_if_index = hi->sw_if_index;
- tunnel_fib_index = vec_elt (ip4m->fib_index_by_sw_if_index,
- tunnel_sw_if_index);
-
- cached_tunnel_sw_if_index = tunnel_sw_if_index;
- cached_tunnel_fib_index = tunnel_fib_index;
- }
- else
- {
- tunnel_sw_if_index = cached_tunnel_sw_if_index;
- tunnel_fib_index = cached_tunnel_fib_index;
- }
- }
else
{
next0 = GRE_INPUT_NEXT_DROP;
@@ -256,9 +222,10 @@ gre_input (vlib_main_t * vm,
vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
drop0:
- if (PREDICT_FALSE(next1 == GRE_INPUT_NEXT_IP4_INPUT
- || next1 == GRE_INPUT_NEXT_IP6_INPUT
- || next1 == GRE_INPUT_NEXT_ETHERNET_INPUT))
+ if (PREDICT_TRUE(next1 == GRE_INPUT_NEXT_IP4_INPUT
+ || next1 == GRE_INPUT_NEXT_IP6_INPUT
+ || next1 == GRE_INPUT_NEXT_ETHERNET_INPUT
+ || next1 == GRE_INPUT_NEXT_MPLS_INPUT))
{
u64 key = ((u64)(vnet_buffer(b1)->gre.dst) << 32) |
(u64)(vnet_buffer(b1)->gre.src);
@@ -292,41 +259,6 @@ drop0:
tunnel_fib_index = cached_tunnel_fib_index;
}
}
- else if (PREDICT_TRUE(next1 == GRE_INPUT_NEXT_MPLS_INPUT))
- {
- u64 key = ((u64)(vnet_buffer(b1)->gre.dst) << 32) |
- (u64)(vnet_buffer(b1)->gre.src);
-
- if (cached_tunnel_key != key)
- {
- vnet_hw_interface_t * hi;
- mpls_gre_tunnel_t * t;
- uword * p;
-
- ip4_main_t * ip4m = &ip4_main;
- p = hash_get (gm->tunnel_by_key, key);
- if (!p)
- {
- next1 = GRE_INPUT_NEXT_DROP;
- b1->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
- goto drop1;
- }
- t = pool_elt_at_index (mm->gre_tunnels, p[0]);
- hi = vnet_get_hw_interface (gm->vnet_main,
- t->hw_if_index);
- tunnel_sw_if_index = hi->sw_if_index;
- tunnel_fib_index = vec_elt (ip4m->fib_index_by_sw_if_index,
- tunnel_sw_if_index);
-
- cached_tunnel_sw_if_index = tunnel_sw_if_index;
- cached_tunnel_fib_index = tunnel_fib_index;
- }
- else
- {
- tunnel_sw_if_index = cached_tunnel_sw_if_index;
- tunnel_fib_index = cached_tunnel_fib_index;
- }
- }
else
{
next1 = GRE_INPUT_NEXT_DROP;
@@ -417,9 +349,10 @@ drop1:
so we can increase counters and help forward node to
pick right FIB */
/* RPF check for ip4/ip6 input */
- if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
- || next0 == GRE_INPUT_NEXT_IP6_INPUT
- || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
+ if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+ || next0 == GRE_INPUT_NEXT_IP6_INPUT
+ || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT
+ || next0 == GRE_INPUT_NEXT_MPLS_INPUT))
{
u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
(u64)(vnet_buffer(b0)->gre.src);
@@ -453,40 +386,6 @@ drop1:
tunnel_fib_index = cached_tunnel_fib_index;
}
}
- else if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_MPLS_INPUT))
- {
- u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
- (u64)(vnet_buffer(b0)->gre.src);
-
- if (cached_tunnel_key != key)
- {
- vnet_hw_interface_t * hi;
- mpls_gre_tunnel_t * t;
- uword * p;
-
- p = hash_get (gm->tunnel_by_key, key);
- if (!p)
- {
- next0 = GRE_INPUT_NEXT_DROP;
- b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
- goto drop;
- }
- t = pool_elt_at_index (mm->gre_tunnels, p[0]);
- hi = vnet_get_hw_interface (gm->vnet_main,
- t->hw_if_index);
- tunnel_sw_if_index = hi->sw_if_index;
- tunnel_fib_index = vec_elt (ip4m->fib_index_by_sw_if_index,
- tunnel_sw_if_index);
-
- cached_tunnel_sw_if_index = tunnel_sw_if_index;
- cached_tunnel_fib_index = tunnel_fib_index;
- }
- else
- {
- tunnel_sw_if_index = cached_tunnel_sw_if_index;
- tunnel_fib_index = cached_tunnel_fib_index;
- }
- }
else
{
next0 = GRE_INPUT_NEXT_DROP;
diff --git a/vnet/vnet/mpls/mpls.c b/vnet/vnet/mpls/mpls.c
index de57da880f2..b28736ba5a7 100644
--- a/vnet/vnet/mpls/mpls.c
+++ b/vnet/vnet/mpls/mpls.c
@@ -746,6 +746,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
eos = MPLS_EOS;
is_del = 0;
local_label = MPLS_LABEL_INVALID;
+ memset(&pfx, 0, sizeof(pfx));
/* Get a line of input. */
if (! unformat_user (input, unformat_line_input, line_input))
@@ -754,7 +755,6 @@ vnet_mpls_local_label (vlib_main_t * vm,
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
memset(&rpath, 0, sizeof(rpath));
- memset(&pfx, 0, sizeof(pfx));
if (unformat (line_input, "table %d", &table_id))
;
@@ -763,9 +763,9 @@ vnet_mpls_local_label (vlib_main_t * vm,
else if (unformat (line_input, "add"))
is_del = 0;
else if (unformat (line_input, "eos"))
- eos = MPLS_EOS;
+ pfx.fp_eos = MPLS_EOS;
else if (unformat (line_input, "non-eos"))
- eos = MPLS_NON_EOS;
+ pfx.fp_eos = MPLS_NON_EOS;
else if (unformat (line_input, "%U/%d",
unformat_ip4_address,
&pfx.fp_addr.ip4,
@@ -791,6 +791,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
rpath.frp_label = MPLS_LABEL_INVALID;
rpath.frp_proto = FIB_PROTOCOL_IP4;
rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
+ pfx.fp_payload_proto = FIB_PROTOCOL_IP4;
vec_add1(rpaths, rpath);
}
else if (unformat (line_input,
@@ -801,14 +802,16 @@ vnet_mpls_local_label (vlib_main_t * vm,
rpath.frp_proto = FIB_PROTOCOL_IP6;
rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
vec_add1(rpaths, rpath);
+ pfx.fp_payload_proto = FIB_PROTOCOL_IP6;
}
else if (unformat (line_input,
"mpls-lookup-in-table %d",
&rpath.frp_fib_index))
{
rpath.frp_label = MPLS_LABEL_INVALID;
- rpath.frp_proto = FIB_PROTOCOL_IP4;
+ rpath.frp_proto = FIB_PROTOCOL_MPLS;
rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
+ pfx.fp_payload_proto = FIB_PROTOCOL_MPLS;
vec_add1(rpaths, rpath);
}
else
@@ -851,11 +854,26 @@ vnet_mpls_local_label (vlib_main_t * vm,
else
{
fib_node_index_t lfe, fib_index;
- fib_prefix_t prefix = {
- .fp_proto = FIB_PROTOCOL_MPLS,
- .fp_label = local_label,
- .fp_eos = eos,
- };
+ u32 fi;
+
+ pfx.fp_proto = FIB_PROTOCOL_MPLS;
+ pfx.fp_len = 21;
+ pfx.fp_label = local_label;
+
+ /*
+ * the CLI parsing stored table Ids, swap to FIB indicies
+ */
+ fi = fib_table_id_find_fib_index(pfx.fp_payload_proto,
+ rpaths[0].frp_fib_index);
+
+ if (~0 == fi)
+ {
+ error = clib_error_return(0 , "%U Via table %d does not exist",
+ format_fib_protocol, pfx.fp_payload_proto,
+ rpaths[0].frp_fib_index);
+ goto done;
+ }
+ rpaths[0].frp_fib_index = fi;
fib_index = mpls_fib_index_from_table_id(table_id);
@@ -867,7 +885,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
}
lfe = fib_table_entry_path_add2(fib_index,
- &prefix,
+ &pfx,
FIB_SOURCE_CLI,
FIB_ENTRY_FLAG_NONE,
rpaths);
diff --git a/vnet/vnet/mpls/mpls_output.c b/vnet/vnet/mpls/mpls_output.c
index 299e1dd242a..1d5d18224e3 100644
--- a/vnet/vnet/mpls/mpls_output.c
+++ b/vnet/vnet/mpls/mpls_output.c
@@ -52,7 +52,8 @@ format_mpls_output_trace (u8 * s, va_list * args)
static inline uword
mpls_output_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
+ vlib_frame_t * from_frame,
+ int is_midchain)
{
u32 n_left_from, next_index, * from, * to_next, cpu_index;
vlib_node_runtime_t * error_node;
@@ -121,6 +122,11 @@ mpls_output_inline (vlib_main_t * vm,
vnet_buffer (p0)->sw_if_index[VLIB_TX] =
adj0[0].rewrite_header.sw_if_index;
next0 = adj0[0].rewrite_header.next_index;
+
+ if (is_midchain)
+ {
+ adj0->sub_type.midchain.fixup_func(vm, adj0, p0);
+ }
}
else
{
@@ -165,7 +171,7 @@ mpls_output (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
- return (mpls_output_inline(vm, node, from_frame));
+ return (mpls_output_inline(vm, node, from_frame, /* is_midchain */ 0));
}
VLIB_REGISTER_NODE (mpls_output_node) = {
@@ -193,11 +199,11 @@ mpls_midchain (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
- return (mpls_output_inline(vm, node, from_frame));
+ return (mpls_output_inline(vm, node, from_frame, /* is_midchain */ 1));
}
VLIB_REGISTER_NODE (mpls_midchain_node) = {
- .function = mpls_output,
+ .function = mpls_midchain,
.name = "mpls-midchain",
.vector_size = sizeof (u32),