diff options
author | Neale Ranns <nranns@cisco.com> | 2018-02-23 05:29:09 -0800 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-03-09 11:59:58 +0000 |
commit | 31ed74407643595fdce206e9d7487108fb8b33ab (patch) | |
tree | c22c3703c30b7d457b858fe899f56e57613cbb52 /src/vnet/mpls | |
parent | 8f931a47b0fa58d5d33a792062650a42ff8bef70 (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.api | 54 | ||||
-rw-r--r-- | src/vnet/mpls/mpls.c | 3 | ||||
-rw-r--r-- | src/vnet/mpls/mpls_api.c | 34 | ||||
-rw-r--r-- | src/vnet/mpls/mpls_input.c | 35 | ||||
-rw-r--r-- | src/vnet/mpls/mpls_tunnel.c | 16 | ||||
-rw-r--r-- | src/vnet/mpls/mpls_types.h | 8 | ||||
-rw-r--r-- | src/vnet/mpls/packet.h | 26 |
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++) |