summaryrefslogtreecommitdiffstats
path: root/src/vnet/mpls
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-02-23 05:29:09 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2018-03-09 11:59:58 +0000
commit31ed74407643595fdce206e9d7487108fb8b33ab (patch)
treec22c3703c30b7d457b858fe899f56e57613cbb52 /src/vnet/mpls
parent8f931a47b0fa58d5d33a792062650a42ff8bef70 (diff)
MPLS Unifom mode
- support both pipe and uniform modes for all MPLS LSP - all API programming for output-labels requires that the mode (and associated data) is specificed - API changes in MPLS, BIER and IP are involved - new DPO [sub] types for MPLS labels to handle the two modes. Change-Id: I87b76401e996f10dfbdbe4552ff6b19af958783c Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/mpls')
-rw-r--r--src/vnet/mpls/mpls.api54
-rw-r--r--src/vnet/mpls/mpls.c3
-rw-r--r--src/vnet/mpls/mpls_api.c34
-rw-r--r--src/vnet/mpls/mpls_input.c35
-rw-r--r--src/vnet/mpls/mpls_tunnel.c16
-rw-r--r--src/vnet/mpls/mpls_types.h8
-rw-r--r--src/vnet/mpls/packet.h26
7 files changed, 84 insertions, 92 deletions
diff --git a/src/vnet/mpls/mpls.api b/src/vnet/mpls/mpls.api
index 572ac915a4a..6047d255aa7 100644
--- a/src/vnet/mpls/mpls.api
+++ b/src/vnet/mpls/mpls.api
@@ -13,7 +13,8 @@
* limitations under the License.
*/
-option version = "1.0.1";
+option version = "1.1.0";
+import "vnet/fib/fib_types.api";
/** \brief Bind/Unbind an MPLS local label to an IP prefix. i.e. create
a per-prefix label entry.
@@ -40,21 +41,6 @@ autoreply define mpls_ip_bind_unbind
u8 mb_address[16];
};
-/** \brief MPLS tunnel Add / del route
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param mt_is_add - Is this a route add or delete
- @param mt_sw_if_index - The SW interface index of the tunnel to delete
- @param mt_is_multicast - Is the tunnel's underlying LSP multicast
- @param mt_next_hop_proto_is_ip4 - The next-hop is IPV4
- @param mt_next_hop_weight - The weight, for UCMP
- @param mt_next_hop_preference - The preference
- @param mt_next_hop[16] - the nextop address
- @param mt_next_hop_sw_if_index - the next-hop SW interface
- @param mt_next_hop_table_id - the next-hop table-id (if appropriate)
- @param mt_next_hop_n_out_labels - the number of next-hop output labels
- @param mt_next_hop_out_label_stack - the next-hop output label stack, outer most first
-*/
define mpls_tunnel_add_del
{
u32 client_index;
@@ -70,7 +56,7 @@ define mpls_tunnel_add_del
u8 mt_next_hop_n_out_labels;
u32 mt_next_hop_sw_if_index;
u32 mt_next_hop_table_id;
- u32 mt_next_hop_out_label_stack[mt_next_hop_n_out_labels];
+ vl_api_fib_mpls_label_t mt_next_hop_out_label_stack[mt_next_hop_n_out_labels];
};
/** \brief Reply for MPLS tunnel add / del request
@@ -96,34 +82,6 @@ define mpls_tunnel_dump
i32 tunnel_index;
};
-/** \brief FIB path
- @param sw_if_index - index of the interface
- @param weight - The weight, for UCMP
- @param is_local - local if non-zero, else remote
- @param is_drop - Drop the packet
- @param is_unreach - Drop the packet and rate limit send ICMP unreachable
- @param is_prohibit - Drop the packet and rate limit send ICMP prohibited
- @param afi - the afi of the next hop, IP46_TYPE_IP4=1, IP46_TYPE_IP6=2
- @param next_hop[16] - the next hop address
-
- WARNING: this type is replicated, pending cleanup completion
-
-*/
-typeonly manual_print manual_endian define fib_path2
-{
- u32 sw_if_index;
- u32 table_id;
- u8 weight;
- u8 preference;
- u8 is_local;
- u8 is_drop;
- u8 is_unreach;
- u8 is_prohibit;
- u8 afi;
- u8 next_hop[16];
- u32 labels[16];
-};
-
/** \brief mpls tunnel details
*/
manual_endian manual_print define mpls_tunnel_details
@@ -134,7 +92,7 @@ manual_endian manual_print define mpls_tunnel_details
u8 mt_l2_only;
u8 mt_is_multicast;
u32 mt_count;
- vl_api_fib_path2_t mt_paths[mt_count];
+ vl_api_fib_path_t mt_paths[mt_count];
};
/** \brief MPLS Route Add / del route
@@ -207,7 +165,7 @@ autoreply define mpls_route_add_del
u32 mr_next_hop_sw_if_index;
u32 mr_next_hop_table_id;
u32 mr_next_hop_via_label;
- u32 mr_next_hop_out_label_stack[mr_next_hop_n_out_labels];
+ vl_api_fib_mpls_label_t mr_next_hop_out_label_stack[mr_next_hop_n_out_labels];
};
/** \brief Dump MPLS fib table
@@ -234,7 +192,7 @@ manual_endian manual_print define mpls_fib_details
u8 eos_bit;
u32 label;
u32 count;
- vl_api_fib_path2_t path[count];
+ vl_api_fib_path_t path[count];
};
/** \brief Enable or Disable MPLS on and interface
diff --git a/src/vnet/mpls/mpls.c b/src/vnet/mpls/mpls.c
index 25957fb3fea..be72d3f829f 100644
--- a/src/vnet/mpls/mpls.c
+++ b/src/vnet/mpls/mpls.c
@@ -47,6 +47,9 @@ u8 * format_mpls_unicast_label (u8 * s, va_list * args)
case MPLS_IETF_GAL_LABEL:
s = format (s, "%s", MPLS_IETF_GAL_STRING);
break;
+ case MPLS_LABEL_POP:
+ s = format (s, "pop");
+ break;
default:
s = format (s, "%d", label);
break;
diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c
index 36fa610e8ca..169ee406a91 100644
--- a/src/vnet/mpls/mpls_api.c
+++ b/src/vnet/mpls/mpls_api.c
@@ -170,8 +170,8 @@ static int
mpls_route_add_del_t_handler (vnet_main_t * vnm,
vl_api_mpls_route_add_del_t * mp)
{
+ fib_mpls_label_t *label_stack = NULL;
u32 fib_index, next_hop_fib_index;
- mpls_label_t *label_stack = NULL;
int rv, ii, n_labels;;
fib_prefix_t pfx = {
@@ -211,13 +211,19 @@ mpls_route_add_del_t_handler (vnet_main_t * vnm,
n_labels = mp->mr_next_hop_n_out_labels;
if (n_labels == 0)
;
- else if (1 == n_labels)
- vec_add1 (label_stack, ntohl (mp->mr_next_hop_out_label_stack[0]));
else
{
vec_validate (label_stack, n_labels - 1);
for (ii = 0; ii < n_labels; ii++)
- label_stack[ii] = ntohl (mp->mr_next_hop_out_label_stack[ii]);
+ {
+ label_stack[ii].fml_value =
+ ntohl (mp->mr_next_hop_out_label_stack[ii].label);
+ label_stack[ii].fml_ttl = mp->mr_next_hop_out_label_stack[ii].ttl;
+ label_stack[ii].fml_exp = mp->mr_next_hop_out_label_stack[ii].exp;
+ label_stack[ii].fml_mode =
+ (mp->mr_next_hop_out_label_stack[ii].is_uniform ?
+ FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE);
+ }
}
/* *INDENT-OFF* */
@@ -323,8 +329,16 @@ vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp)
if (mp->mt_is_add)
{
for (ii = 0; ii < mp->mt_next_hop_n_out_labels; ii++)
- vec_add1 (rpath.frp_label_stack,
- ntohl (mp->mt_next_hop_out_label_stack[ii]));
+ {
+ fib_mpls_label_t fml = {
+ .fml_value = ntohl (mp->mt_next_hop_out_label_stack[ii].label),
+ .fml_ttl = mp->mt_next_hop_out_label_stack[ii].ttl,
+ .fml_exp = mp->mt_next_hop_out_label_stack[ii].exp,
+ .fml_mode = (mp->mt_next_hop_out_label_stack[ii].is_uniform ?
+ FIB_MPLS_LSP_MODE_UNIFORM : FIB_MPLS_LSP_MODE_PIPE),
+ };
+ vec_add1 (rpath.frp_label_stack, fml);
+ }
}
vec_add1 (rpaths, rpath);
@@ -388,7 +402,7 @@ send_mpls_tunnel_entry (u32 mti, void *arg)
mpls_tunnel_send_walk_ctx_t *ctx;
vl_api_mpls_tunnel_details_t *mp;
const mpls_tunnel_t *mt;
- vl_api_fib_path2_t *fp;
+ vl_api_fib_path_t *fp;
u32 n;
ctx = arg;
@@ -399,8 +413,8 @@ send_mpls_tunnel_entry (u32 mti, void *arg)
mt = mpls_tunnel_get (mti);
n = fib_path_list_get_n_paths (mt->mt_path_list);
- mp = vl_msg_api_alloc (sizeof (*mp) + n * sizeof (vl_api_fib_path2_t));
- memset (mp, 0, sizeof (*mp) + n * sizeof (vl_api_fib_path2_t));
+ mp = vl_msg_api_alloc (sizeof (*mp) + n * sizeof (vl_api_fib_path_t));
+ memset (mp, 0, sizeof (*mp) + n * sizeof (vl_api_fib_path_t));
mp->_vl_msg_id = ntohs (VL_API_MPLS_TUNNEL_DETAILS);
mp->context = ctx->context;
@@ -456,7 +470,7 @@ send_mpls_fib_details (vpe_api_main_t * am,
{
vl_api_mpls_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
- vl_api_fib_path2_t *fp;
+ vl_api_fib_path_t *fp;
int path_count;
path_count = vec_len (api_rpaths);
diff --git a/src/vnet/mpls/mpls_input.c b/src/vnet/mpls/mpls_input.c
index 86ad8bba270..d1881d4050b 100644
--- a/src/vnet/mpls/mpls_input.c
+++ b/src/vnet/mpls/mpls_input.c
@@ -51,10 +51,11 @@ format_mpls_input_trace (u8 * s, va_list * args)
foreach_mpls_input_next;
#undef _
- s = format (s, "MPLS: next %s[%d] label %d ttl %d",
+ s = format (s, "MPLS: next %s[%d] label %d ttl %d exp %d",
next_name, t->next_index,
vnet_mpls_uc_get_label(label),
- vnet_mpls_uc_get_ttl(label));
+ vnet_mpls_uc_get_ttl(label),
+ vnet_mpls_uc_get_exp(label));
return s;
}
@@ -74,21 +75,13 @@ mpls_input_inline (vlib_main_t * vm,
vlib_frame_t * from_frame)
{
u32 n_left_from, next_index, * from, * to_next;
- mpls_input_runtime_t * rt;
- mpls_main_t * mm;
+ mpls_main_t * mm = &mpls_main;
u32 thread_index = vlib_get_thread_index();
vlib_simple_counter_main_t * cm;
vnet_main_t * vnm = vnet_get_main();
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
- rt = vlib_node_get_runtime_data (vm, mpls_input_node.index);
- mm = rt->mpls_main;
- /*
- * Force an initial lookup every time, in case the control-plane
- * changed the label->FIB mapping.
- */
- rt->last_label = ~0;
next_index = node->cached_next_index;
@@ -279,18 +272,11 @@ VLIB_NODE_FUNCTION_MULTIARCH (mpls_input_node, mpls_input)
static void
mpls_setup_nodes (vlib_main_t * vm)
{
- mpls_input_runtime_t * rt;
pg_node_t * pn;
pn = pg_get_node (mpls_input_node.index);
pn->unformat_edit = unformat_pg_mpls_header;
- rt = vlib_node_get_runtime_data (vm, mpls_input_node.index);
- rt->last_label = (u32) ~0;
- rt->last_inner_fib_index = 0;
- rt->last_outer_fib_index = 0;
- rt->mpls_main = &mpls_main;
-
ethernet_register_input_type (vm, ETHERNET_TYPE_MPLS,
mpls_input_node.index);
}
@@ -309,16 +295,3 @@ static clib_error_t * mpls_input_init (vlib_main_t * vm)
}
VLIB_INIT_FUNCTION (mpls_input_init);
-
-static clib_error_t * mpls_input_worker_init (vlib_main_t * vm)
-{
- mpls_input_runtime_t * rt;
- rt = vlib_node_get_runtime_data (vm, mpls_input_node.index);
- rt->last_label = (u32) ~0;
- rt->last_inner_fib_index = 0;
- rt->last_outer_fib_index = 0;
- rt->mpls_main = &mpls_main;
- return 0;
-}
-
-VLIB_WORKER_INIT_FUNCTION (mpls_input_worker_init);
diff --git a/src/vnet/mpls/mpls_tunnel.c b/src/vnet/mpls/mpls_tunnel.c
index 8ed2c409ce8..c2067d81b00 100644
--- a/src/vnet/mpls/mpls_tunnel.c
+++ b/src/vnet/mpls/mpls_tunnel.c
@@ -123,6 +123,12 @@ mpls_tunnel_collect_forwarding (fib_node_index_t pl_index,
path_ext = fib_path_ext_list_find_by_path_index(&ctx->mt->mt_path_exts,
path_index);
+ /*
+ * we don't want IP TTL decrements for packets hitting the MPLS labels
+ * we stack on, since the IP TTL decrement is done by the adj
+ */
+ path_ext->fpe_mpls_flags |= FIB_PATH_EXT_MPLS_FLAG_NO_IP_TTL_DECR;
+
if (NULL != path_ext)
{
/*
@@ -273,9 +279,8 @@ mpls_tunnel_stack (adj_index_t ai)
mpls_tunnel_mk_lb(mt,
adj->ia_link,
- (VNET_LINK_MPLS == adj_get_link_type(ai) ?
- FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
- FIB_FORW_CHAIN_TYPE_MPLS_EOS),
+ fib_forw_chain_type_from_link_type(
+ adj_get_link_type(ai)),
&dpo);
adj_nbr_midchain_stack(ai, &dpo);
@@ -521,6 +526,11 @@ mpls_tunnel_tx (vlib_main_t * vm,
b0 = vlib_get_buffer(vm, bi0);
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mt->mt_l2_lb.dpoi_index;
+ /* since we are coming out of the L2 world, where the vlib_buffer
+ * union is used for other things, make sure it is clean for
+ * MPLS from now on.
+ */
+ vnet_buffer(b0)->mpls.first = 0;
if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
{
diff --git a/src/vnet/mpls/mpls_types.h b/src/vnet/mpls/mpls_types.h
index f1c3191e00c..c21bdf1eace 100644
--- a/src/vnet/mpls/mpls_types.h
+++ b/src/vnet/mpls/mpls_types.h
@@ -47,6 +47,14 @@
#define MPLS_LABEL_INVALID (MPLS_IETF_MAX_LABEL+1)
+/**
+ * A value that is explicit about the end of the LSP. Specifying
+ * a label value is needed when the mode configuration (pipe/uniform)
+ * is also requested.
+ * imp-null implies a label swap. pop can be used for a deag.
+ */
+#define MPLS_LABEL_POP (MPLS_IETF_MAX_LABEL+2)
+
#define MPLS_LABEL_IS_REAL(_lbl) \
(((_lbl) > MPLS_IETF_MIN_UNRES_LABEL) && \
((_lbl) <= MPLS_IETF_MAX_UNRES_LABEL))
diff --git a/src/vnet/mpls/packet.h b/src/vnet/mpls/packet.h
index bc67445be89..ca6ac407686 100644
--- a/src/vnet/mpls/packet.h
+++ b/src/vnet/mpls/packet.h
@@ -42,6 +42,32 @@ typedef enum mpls_eos_bit_t_
[MPLS_EOS] = "eos", \
}
+/**
+ * The Default TTL added to MPLS label headers when no other value is available
+ */
+#define MPLS_LABEL_DEFAULT_TTL 64
+
+/**
+ * The Default EXP added to MPLS label headers when no other value is available
+ */
+#define MPLS_LABEL_DEFAULT_EXP 0
+
+/**
+ * When in uniform mode convert an IPv[46] DSCP value to an MPLS EXP value
+ */
+static inline u8 ip_dscp_to_mpls_exp (u8 tos)
+{
+ return (tos >> 5);
+}
+
+/**
+ * When in uniform mode convert an MPLS EXP value to an IPv[46] DSCP value
+ */
+static inline u8 mpls_exp_to_ip_dscp (u8 exp)
+{
+ return (exp << 5);
+}
+
#define FOR_EACH_MPLS_EOS_BIT(_eos) \
for (_eos = MPLS_NON_EOS; _eos <= MPLS_EOS; _eos++)