diff options
-rw-r--r-- | src/vat/api_format.c | 16 | ||||
-rw-r--r-- | src/vnet/adj/adj_l2.c | 5 | ||||
-rw-r--r-- | src/vnet/bier/bier.api | 10 | ||||
-rw-r--r-- | src/vnet/bier/bier_api.c | 20 | ||||
-rw-r--r-- | src/vnet/bier/bier_fmask.c | 9 | ||||
-rw-r--r-- | src/vnet/bier/bier_output.c | 4 | ||||
-rw-r--r-- | src/vnet/bier/bier_test.c | 30 | ||||
-rw-r--r-- | src/vnet/buffer.h | 2 | ||||
-rw-r--r-- | src/vnet/dpo/dpo.h | 8 | ||||
-rw-r--r-- | src/vnet/dpo/mpls_disposition.c | 316 | ||||
-rw-r--r-- | src/vnet/dpo/mpls_disposition.h | 15 | ||||
-rw-r--r-- | src/vnet/dpo/mpls_label_dpo.c | 1075 | ||||
-rw-r--r-- | src/vnet/dpo/mpls_label_dpo.h | 65 | ||||
-rw-r--r-- | src/vnet/fib/fib_api.h | 2 | ||||
-rw-r--r-- | src/vnet/fib/fib_entry_src.c | 4 | ||||
-rw-r--r-- | src/vnet/fib/fib_path.c | 20 | ||||
-rw-r--r-- | src/vnet/fib/fib_path.h | 1 | ||||
-rw-r--r-- | src/vnet/fib/fib_path_ext.c | 77 | ||||
-rw-r--r-- | src/vnet/fib/fib_path_ext.h | 34 | ||||
-rw-r--r-- | src/vnet/fib/fib_table.c | 4 | ||||
-rw-r--r-- | src/vnet/fib/fib_table.h | 4 | ||||
-rw-r--r-- | src/vnet/fib/fib_test.c | 205 | ||||
-rw-r--r-- | src/vnet/fib/fib_test.h | 5 | ||||
-rw-r--r-- | src/vnet/fib/fib_types.api | 18 | ||||
-rw-r--r-- | src/vnet/fib/fib_types.c | 53 | ||||
-rw-r--r-- | src/vnet/fib/fib_types.h | 67 | ||||
-rw-r--r-- | src/vnet/ip/ip.api | 32 | ||||
-rw-r--r-- | src/vnet/ip/ip6_packet.h | 18 | @@ -8872,7 +8872,7 @@ api_bier_route_add_del (vat_main_t * vam) } /* Construct the API message */ - M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t)); + M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t)); mp->br_is_add = is_add; mp->br_tbl_id.bt_set = set; @@ -8881,7 +8881,7 @@ api_bier_route_add_del (vat_main_t * vam) mp->br_bp = ntohs (bp); mp->br_n_paths = 1; mp->br_paths[0].n_labels = 1; - mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label); + mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label); mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1); if (next_hop_proto_is_ip4) @@ -19634,7 +19634,7 @@ api_netmap_delete (vat_main_t * vam) } static void -vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp) +vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp) { if (fp->afi == IP46_TYPE_IP6) print (vam->ofp, @@ -19654,7 +19654,7 @@ vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp) static void vl_api_mpls_fib_path_json_print (vat_json_node_t * node, - vl_api_fib_path2_t * fp) + vl_api_fib_path_t * fp) { struct in_addr ip4; struct in6_addr ip6; @@ -19683,7 +19683,7 @@ vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp) { vat_main_t *vam = &vat_main; int count = ntohl (mp->mt_count); - vl_api_fib_path2_t *fp; + vl_api_fib_path_t *fp; i32 i; print (vam->ofp, "[%d]: sw_if_index %d via:", @@ -19707,7 +19707,7 @@ vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp) vat_main_t *vam = &vat_main; vat_json_node_t *node = NULL; int count = ntohl (mp->mt_count); - vl_api_fib_path2_t *fp; + vl_api_fib_path_t *fp; i32 i; if (VAT_JSON_ARRAY != vam->json_tree.type) @@ -19773,7 +19773,7 @@ vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp) { vat_main_t *vam = &vat_main; int count = ntohl (mp->count); - vl_api_fib_path2_t *fp; + vl_api_fib_path_t *fp; int i; print (vam->ofp, @@ -19793,7 +19793,7 @@ static void vl_api_mpls_fib_details_t_handler_json vat_main_t *vam = &vat_main; int count = ntohl (mp->count); vat_json_node_t *node = NULL; - vl_api_fib_path2_t *fp; + vl_api_fib_path_t *fp; int i; if (VAT_JSON_ARRAY != vam->json_tree.type) diff --git a/src/vnet/adj/adj_l2.c b/src/vnet/adj/adj_l2.c index 132ceb28168..09bf468ac40 100644 --- a/src/vnet/adj/adj_l2.c +++ b/src/vnet/adj/adj_l2.c @@ -91,6 +91,11 @@ adj_l2_rewrite_inline (vlib_main_t * vm, rw_len0 = adj0[0].rewrite_header.data_bytes; vnet_buffer(p0)->ip.save_rewrite_length = rw_len0; vnet_buffer(p0)->sw_if_index[VLIB_TX] = adj0->rewrite_header.sw_if_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(p0)->mpls.first = 0; vlib_increment_combined_counter(&adjacency_counters, thread_index, diff --git a/src/vnet/bier/bier.api b/src/vnet/bier/bier.api index 446863c8ee8..d07379e92f0 100644 --- a/src/vnet/bier/bier.api +++ b/src/vnet/bier/bier.api @@ -18,7 +18,7 @@ This file defines vpp BIER control-plane API messages which are generally called through a shared memory interface. */ -option version = "1.0.0"; +option version = "1.1.0"; import "vnet/fib/fib_types.api"; /** \brief BIER Table Indentifier @@ -84,7 +84,7 @@ autoreply define bier_route_add_del u8 br_is_replace; vl_api_bier_table_id_t br_tbl_id; u8 br_n_paths; - vl_api_fib_path3_t br_paths[br_n_paths]; + vl_api_fib_path_t br_paths[br_n_paths]; }; define bier_route_dump @@ -101,7 +101,7 @@ define bier_route_details u16 br_bp; vl_api_bier_table_id_t br_tbl_id; u32 br_n_paths; - vl_api_fib_path3_t br_paths[br_n_paths]; + vl_api_fib_path_t br_paths[br_n_paths]; }; /** \brief BIER Imposition Add @@ -211,7 +211,7 @@ autoreply define bier_disp_entry_add_del u8 bde_is_add; u8 bde_payload_proto; u8 bde_n_paths; - vl_api_fib_path3_t bde_paths[bde_n_paths]; + vl_api_fib_path_t bde_paths[bde_n_paths]; }; define bier_disp_entry_dump @@ -229,7 +229,7 @@ define bier_disp_entry_details u8 bde_is_add; u8 bde_payload_proto; u8 bde_n_paths; - vl_api_fib_path3_t bde_paths[bde_n_paths]; + vl_api_fib_path_t bde_paths[bde_n_paths]; }; /* diff --git a/src/vnet/bier/bier_api.c b/src/vnet/bier/bier_api.c index 4b1d1c28781..77b2cabaa44 100644 --- a/src/vnet/bier/bier_api.c +++ b/src/vnet/bier/bier_api.c @@ -202,8 +202,16 @@ vl_api_bier_route_add_del_t_handler (vl_api_bier_route_add_del_t * mp) mp->br_paths[ii].n_labels - 1); for (jj = 0; jj < mp->br_paths[ii].n_labels; jj++) { - brpath->frp_label_stack[jj] = - ntohl(mp->br_paths[ii].label_stack[jj]); + brpath->frp_label_stack[jj].fml_value = + ntohl(mp->br_paths[ii].label_stack[jj].label); + brpath->frp_label_stack[jj].fml_ttl = + mp->br_paths[ii].label_stack[jj].ttl; + brpath->frp_label_stack[jj].fml_exp = + mp->br_paths[ii].label_stack[jj].exp; + brpath->frp_label_stack[jj].fml_mode = + (mp->br_paths[ii].label_stack[jj].is_uniform ? + FIB_MPLS_LSP_MODE_UNIFORM : + FIB_MPLS_LSP_MODE_PIPE); } if (mp->br_paths[ii].is_udp_encap) @@ -275,11 +283,11 @@ send_bier_route_details (const bier_table_t *bt, fib_route_path_encode_t *api_rpaths = NULL, *api_rpath; bier_route_details_walk_t *ctx = args; vl_api_bier_route_details_t *mp; - vl_api_fib_path3_t *fp; + vl_api_fib_path_t *fp; u32 n_paths, m_size; n_paths = fib_path_list_get_n_paths(be->be_path_list); - m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path3_t)); + m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path_t)); mp = vl_msg_api_alloc(m_size); if (!mp) return; @@ -636,7 +644,7 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt, bier_disp_entry_details_walk_t *ctx = args; vl_api_bier_disp_entry_details_t *mp; bier_hdr_proto_id_t pproto; - vl_api_fib_path3_t *fp; + vl_api_fib_path_t *fp; u32 n_paths, m_size; FOR_EACH_BIER_HDR_PROTO(pproto) @@ -645,7 +653,7 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt, if (INDEX_INVALID != pl) { n_paths = fib_path_list_get_n_paths(pl); - m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path3_t)); + m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path_t)); mp = vl_msg_api_alloc(m_size); if (!mp) return; diff --git a/src/vnet/bier/bier_fmask.c b/src/vnet/bier/bier_fmask.c index 2fc24dca819..31d884af060 100644 --- a/src/vnet/bier/bier_fmask.c +++ b/src/vnet/bier/bier_fmask.c @@ -177,16 +177,13 @@ bier_fmask_init (bier_fmask_t *bfm, if (!(bfm->bfm_flags & BIER_FMASK_FLAG_DISP)) { - /* - * leave this label in host byte order so we can OR in the TTL - */ if (NULL != rpaths->frp_label_stack) { - olabel = rpaths->frp_label_stack[0]; + olabel = rpaths->frp_label_stack[0].fml_value; vnet_mpls_uc_set_label(&bfm->bfm_label, olabel); vnet_mpls_uc_set_exp(&bfm->bfm_label, 0); vnet_mpls_uc_set_s(&bfm->bfm_label, 1); - vnet_mpls_uc_set_ttl(&bfm->bfm_label, 0); + vnet_mpls_uc_set_ttl(&bfm->bfm_label, 64); bfm->bfm_flags |= BIER_FMASK_FLAG_MPLS; } else @@ -207,7 +204,9 @@ bier_fmask_init (bier_fmask_t *bfm, vnet_mpls_uc_set_label(&bfm->bfm_label, id); vnet_mpls_uc_set_s(&bfm->bfm_label, 1); vnet_mpls_uc_set_exp(&bfm->bfm_label, 0); + vnet_mpls_uc_set_ttl(&bfm->bfm_label, 64); } + bfm->bfm_label = clib_host_to_net_u32(bfm->bfm_label); } bfm->bfm_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | diff --git a/src/vnet/bier/bier_output.c b/src/vnet/bier/bier_output.c index db115d3ad5e..01eeffe475c 100644 --- a/src/vnet/bier/bier_output.c +++ b/src/vnet/bier/bier_output.c @@ -140,8 +140,8 @@ bier_output (vlib_main_t * vm, h0 = vlib_buffer_get_current(b0); h0[0] = bfm0->bfm_label; - vnet_mpls_uc_set_ttl(h0, vnet_buffer(b0)->mpls.ttl - 1); - h0[0] = clib_host_to_net_u32(h0[0]); + + ((char*)h0)[3]= vnet_buffer(b0)->mpls.ttl - 1; } /* diff --git a/src/vnet/bier/bier_test.c b/src/vnet/bier/bier_test.c index 08a8c55954d..6c7af829811 100644 --- a/src/vnet/bier/bier_test.c +++ b/src/vnet/bier/bier_test.c @@ -316,7 +316,10 @@ bier_test_mpls_spf (void) .frp_bier_fib_index = bti, .frp_sw_if_index = ~0, }; - vec_add1(path_1_1_1_1.frp_label_stack, 500); + fib_mpls_label_t fml_500 = { + .fml_value = 500, + }; + vec_add1(path_1_1_1_1.frp_label_stack, fml_500); vec_add1(paths_1_1_1_1, path_1_1_1_1); const fib_prefix_t pfx_1_1_1_1_s_32 = { .fp_addr = nh_1_1_1_1, @@ -389,8 +392,10 @@ bier_test_mpls_spf (void) .ttl = 255, }, }; - mpls_label_t *out_lbl_99 = NULL; - vec_add1(out_lbl_99, 99); + fib_mpls_label_t *out_lbl_99 = NULL, fml_99 = { + .fml_value = 99, + }; + vec_add1(out_lbl_99, fml_99); fei = fib_table_entry_update_one_path(0, &pfx_1_1_1_1_s_32, @@ -443,8 +448,10 @@ bier_test_mpls_spf (void) .ttl = 255, }, }; - mpls_label_t *out_lbl_100 = NULL; - vec_add1(out_lbl_100, 100); + fib_mpls_label_t *out_lbl_100 = NULL, fml_100 = { + .fml_value = 100, + }; + vec_add1(out_lbl_100, fml_100); fei = fib_table_entry_path_add(0, &pfx_1_1_1_1_s_32, @@ -505,13 +512,18 @@ bier_test_mpls_spf (void) .frp_bier_fib_index = bti, .frp_sw_if_index = ~0, }; - vec_add1(path_1_1_1_2.frp_label_stack, 501); + fib_mpls_label_t fml_501 = { + .fml_value = 501, + }; + vec_add1(path_1_1_1_2.frp_label_stack, fml_501); vec_add1(paths_1_1_1_2, path_1_1_1_2); input_paths_1_1_1_2 = vec_dup(paths_1_1_1_2); index_t bei_3; - mpls_label_t *out_lbl_101 = NULL; - vec_add1(out_lbl_101, 101); + fib_mpls_label_t *out_lbl_101 = NULL, fml_101 = { + .fml_value = 101, + }; + vec_add1(out_lbl_101, fml_101); fei = fib_table_entry_path_add(0, &pfx_1_1_1_2_s_32, FIB_SOURCE_API, @@ -605,7 +617,7 @@ bier_test_mpls_spf (void) * add the via back */ out_lbl_101 = NULL; - vec_add1(out_lbl_101, 101); + vec_add1(out_lbl_101, fml_101); fei = fib_table_entry_path_add(0, &pfx_1_1_1_2_s_32, FIB_SOURCE_API, diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h index 5aedb431654..7a4bc245a30 100644 --- a/src/vnet/buffer.h +++ b/src/vnet/buffer.h @@ -181,6 +181,8 @@ typedef struct */ struct { + /* do not overlay w/ ip.adj_index[0,1] nor flow hash */ + u32 pad[VLIB_N_RX_TX + 1]; u8 ttl; u8 exp; u8 first; diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h index afee458c02f..4d484786fba 100644 --- a/src/vnet/dpo/dpo.h +++ b/src/vnet/dpo/dpo.h @@ -111,8 +111,8 @@ typedef enum dpo_type_t_ { DPO_LOOKUP, DPO_LISP_CP, DPO_CLASSIFY, - DPO_MPLS_LABEL, - DPO_MPLS_DISPOSITION, + DPO_MPLS_DISPOSITION_PIPE, + DPO_MPLS_DISPOSITION_UNIFORM, DPO_MFIB_ENTRY, DPO_INTERFACE_RX, DPO_INTERFACE_TX, @@ -146,8 +146,8 @@ typedef enum dpo_type_t_ { [DPO_REPLICATE] = "dpo-replicate", \ [DPO_LISP_CP] = "dpo-lisp-cp", \ [DPO_CLASSIFY] = "dpo-classify", \ - [DPO_MPLS_LABEL] = "dpo-mpls-label", \ - [DPO_MPLS_DISPOSITION] = "dpo-mpls-diposition", \ + [DPO_MPLS_DISPOSITION_PIPE] = "dpo-mpls-diposition-pipe", \ + [DPO_MPLS_DISPOSITION_UNIFORM] = "dpo-mpls-diposition-uniform", \ [DPO_MFIB_ENTRY] = "dpo-mfib-entry", \ [DPO_INTERFACE_RX] = "dpo-interface-rx", \ [DPO_INTERFACE_TX] = "dpo-interface-tx", \ diff --git a/src/vnet/dpo/mpls_disposition.c b/src/vnet/dpo/mpls_disposition.c index 77429de4116..2956e541d57 100644 --- a/src/vnet/dpo/mpls_disposition.c +++ b/src/vnet/dpo/mpls_disposition.c @@ -42,38 +42,55 @@ mpls_disp_dpo_get_index (mpls_disp_dpo_t *mdd) return (mdd - mpls_disp_dpo_pool); } -index_t +void mpls_disp_dpo_create (dpo_proto_t payload_proto, fib_rpf_id_t rpf_id, - const dpo_id_t *dpo) + fib_mpls_lsp_mode_t mode, + const dpo_id_t *parent, + dpo_id_t *dpo) { mpls_disp_dpo_t *mdd; + dpo_type_t dtype; mdd = mpls_disp_dpo_alloc(); mdd->mdd_payload_proto = payload_proto; mdd->mdd_rpf_id = rpf_id; - - dpo_stack(DPO_MPLS_DISPOSITION, + mdd->mdd_mode = mode; + dtype = (FIB_MPLS_LSP_MODE_PIPE == mode ? + DPO_MPLS_DISPOSITION_PIPE : + DPO_MPLS_DISPOSITION_UNIFORM); + + /* + * stack this disposition object on the parent given + */ + dpo_stack(dtype, mdd->mdd_payload_proto, &mdd->mdd_dpo, - dpo); - - return (mpls_disp_dpo_get_index(mdd)); + parent); + + /* + * set up the return DPO to refer to this object + */ + dpo_set(dpo, + dtype, + payload_proto, + mpls_disp_dpo_get_index(mdd)); } u8* format_mpls_disp_dpo (u8 *s, va_list *args) { - index_t index = va_arg (*args, index_t); - u32 indent = va_arg (*args, u32); + index_t index = va_arg(*args, index_t); + u32 indent = va_arg(*args, u32); mpls_disp_dpo_t *mdd; mdd = mpls_disp_dpo_get(index); - s = format(s, "mpls-disposition:[%d]:[%U]", + s = format(s, "mpls-disposition:[%d]:[%U, %U]", index, - format_dpo_proto, mdd->mdd_payload_proto); + format_dpo_proto, mdd->mdd_payload_proto, + format_fib_mpls_lsp_mode, mdd->mdd_mode); s = format(s, "\n%U", format_white_space, indent); s = format(s, "%U", format_dpo_id, &mdd->mdd_dpo, indent+2); @@ -116,25 +133,41 @@ typedef struct mpls_label_disposition_trace_t_ index_t mdd; } mpls_label_disposition_trace_t; -extern vlib_node_registration_t ip4_mpls_label_disposition_node; -extern vlib_node_registration_t ip6_mpls_label_disposition_node; +extern vlib_node_registration_t ip4_mpls_label_disposition_pipe_node; +extern vlib_node_registration_t ip6_mpls_label_disposition_pipe_node; +extern vlib_node_registration_t ip4_mpls_label_disposition_uniform_node; +extern vlib_node_registration_t ip6_mpls_label_disposition_uniform_node; always_inline uword mpls_label_disposition_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame, - u8 payload_is_ip4, - u8 payload_is_ip6) + vlib_node_runtime_t * node, + vlib_frame_t * from_frame, + u8 payload_is_ip4, + u8 payload_is_ip6, + fib_mpls_lsp_mode_t mode) { u32 n_left_from, next_index, * from, * to_next; vlib_node_runtime_t *error_node; if (payload_is_ip4) - error_node = vlib_node_get_runtime (vm, ip4_mpls_label_disposition_node.index); + { + if (FIB_MPLS_LSP_MODE_PIPE == mode) + error_node = + vlib_node_get_runtime(vm, ip4_mpls_label_disposition_pipe_node.index); + else + error_node = + vlib_node_get_runtime(vm, ip4_mpls_label_disposition_uniform_node.index); + } else - error_node = vlib_node_get_runtime (vm, ip6_mpls_label_disposition_node.index); - - from = vlib_frame_vector_args (from_frame); + { + if (FIB_MPLS_LSP_MODE_PIPE == mode) + error_node = + vlib_node_get_runtime(vm, ip6_mpls_label_disposition_uniform_node.index); + else + error_node = + vlib_node_get_runtime(vm, ip6_mpls_label_disposition_uniform_node.index); + } + from = vlib_frame_vector_args(from_frame); n_left_from = from_frame->n_vectors; next_index = node->cached_next_index; @@ -159,14 +192,14 @@ mpls_label_disposition_inline (vlib_main_t * vm, { vlib_buffer_t * p2, * p3; - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); + p2 = vlib_get_buffer(vm, from[2]); + p3 = vlib_get_buffer(vm, from[3]); - vlib_prefetch_buffer_header (p2, STORE); - vlib_prefetch_buffer_header (p3, STORE); + vlib_prefetch_buffer_header(p2, STORE); + vlib_prefetch_buffer_header(p3, STORE); - CLIB_PREFETCH (p2->data, sizeof (ip6_header_t), STORE); - CLIB_PREFETCH (p3->data, sizeof (ip6_header_t), STORE); + CLIB_PREFETCH(p2->data, sizeof(ip6_header_t), STORE); + CLIB_PREFETCH(p3->data, sizeof(ip6_header_t), STORE); } from += 2; @@ -174,8 +207,8 @@ mpls_label_disposition_inline (vlib_main_t * vm, n_left_from -= 2; n_left_to_next -= 2; - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); + b0 = vlib_get_buffer(vm, bi0); + b1 = vlib_get_buffer(vm, bi1); /* dst lookup was done by ip4 lookup */ mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; @@ -190,30 +223,62 @@ mpls_label_disposition_inline (vlib_main_t * vm, { ip4_header_t *ip0, *ip1; - ip0 = vlib_buffer_get_current (b0); - ip1 = vlib_buffer_get_current (b1); + ip0 = vlib_buffer_get_current(b0); + ip1 = vlib_buffer_get_current(b1); /* * IPv4 input checks on the exposed IP header * including checksum */ - ip4_input_check_x2 (vm, error_node, - b0, b1, ip0, ip1, - &next0, &next1, 1); + ip4_input_check_x2(vm, error_node, + b0, b1, ip0, ip1, + &next0, &next1, 1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP. recalc the chksum + */ + ip0->ttl = vnet_buffer(b0)->mpls.ttl; + ip1->ttl = vnet_buffer(b1)->mpls.ttl; + ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp); + ip1->tos = mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp); + + ip0->checksum = ip4_header_checksum(ip0); + ip1->checksum = ip4_header_checksum(ip1); + } } else if (payload_is_ip6) { ip6_header_t *ip0, *ip1; - ip0 = vlib_buffer_get_current (b0); - ip1 = vlib_buffer_get_current (b1); + ip0 = vlib_buffer_get_current(b0); + ip1 = vlib_buffer_get_current(b1); /* * IPv6 input checks on the exposed IP header */ - ip6_input_check_x2 (vm, error_node, - b0, b1, ip0, ip1, - &next0, &next1); + ip6_input_check_x2(vm, error_node, + b0, b1, ip0, ip1, + &next0, &next1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP + */ + ip0->hop_limit = vnet_buffer(b0)->mpls.ttl; + ip1->hop_limit = vnet_buffer(b1)->mpls.ttl; + + ip6_set_traffic_class_network_order( + ip0, + mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp)); + ip6_set_traffic_class_network_order( + ip1, + mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp)); + } } vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index; @@ -224,14 +289,14 @@ mpls_label_disposition_inline (vlib_main_t * vm, if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { mpls_label_disposition_trace_t *tr = - vlib_add_trace (vm, node, b0, sizeof (*tr)); + vlib_add_trace(vm, node, b0, sizeof(*tr)); tr->mdd = mddi0; } if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED)) { mpls_label_disposition_trace_t *tr = - vlib_add_trace (vm, node, b1, sizeof (*tr)); + vlib_add_trace(vm, node, b1, sizeof(*tr)); tr->mdd = mddi1; } @@ -254,7 +319,7 @@ mpls_label_disposition_inline (vlib_main_t * vm, n_left_from -= 1; n_left_to_next -= 1; - b0 = vlib_get_buffer (vm, bi0); + b0 = vlib_get_buffer(vm, bi0); /* dst lookup was done by ip4 lookup */ mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; @@ -265,24 +330,48 @@ mpls_label_disposition_inline (vlib_main_t * vm, { ip4_header_t *ip0; - ip0 = vlib_buffer_get_current (b0); + ip0 = vlib_buffer_get_current(b0); /* * IPv4 input checks on the exposed IP header * including checksum */ - ip4_input_check_x1 (vm, error_node, b0, ip0, &next0, 1); + ip4_input_check_x1(vm, error_node, b0, ip0, &next0, 1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP. recalc the chksum + */ + ip0->ttl = vnet_buffer(b0)->mpls.ttl; + ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp); + ip0->checksum = ip4_header_checksum(ip0); + } } else if (payload_is_ip6) { ip6_header_t *ip0; - ip0 = vlib_buffer_get_current (b0); + ip0 = vlib_buffer_get_current(b0); /* * IPv6 input checks on the exposed IP header */ - ip6_input_check_x1 (vm, error_node, b0, ip0, &next0); + ip6_input_check_x1(vm, error_node, b0, ip0, &next0); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP + */ + ip0->hop_limit = vnet_buffer(b0)->mpls.ttl; + + ip6_set_traffic_class_network_order( + ip0, + mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp)); + } } vnet_buffe |