summaryrefslogtreecommitdiffstats
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
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>
-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),