From b069a6910aa2b95316ccdb5d9e5b95143b9dc7c0 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 15 Mar 2017 12:34:25 -0400 Subject: Cache a 'has-features' flag on the adjacency for faster access. Reclaim the node_index memeber from the rewrite for space - this is only used for formtting before: ip4-rewrite * * * * 2.66e1 256.00 after: ip4-rewrite * * * * 2.40e1 256.00 Change-Id: Ic397150727cad38811564777419ad6bd26b8a3a6 Signed-off-by: Neale Ranns --- src/vnet/adj/adj.c | 82 +++++++++++++++++++++++++++++++----- src/vnet/adj/adj.h | 6 +++ src/vnet/adj/adj_mcast.c | 4 +- src/vnet/adj/adj_midchain.c | 4 +- src/vnet/adj/adj_nbr.c | 4 +- src/vnet/feature/feature.c | 2 + src/vnet/ip/ip4_forward.c | 21 ++++++---- src/vnet/ip/ip6_forward.c | 21 ++++++---- src/vnet/ip/lookup.c | 8 ++-- src/vnet/mpls/mpls_output.c | 42 ++++++++++++------- src/vnet/rewrite.c | 100 +------------------------------------------- src/vnet/rewrite.h | 30 +++++++++---- 12 files changed, 162 insertions(+), 162 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index 4ed4999f516..f3d483ac13f 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -135,16 +135,6 @@ format_ip_adjacency (u8 * s, va_list * args) vlib_get_combined_counter(&adjacency_counters, adj_index, &counts); s = format (s, "\n counts:[%Ld:%Ld]", counts.packets, counts.bytes); s = format (s, "\n locks:%d", adj->ia_node.fn_locks); - s = format (s, " node:[%d]:%U", - adj->rewrite_header.node_index, - format_vlib_node_name, vlib_get_main(), - adj->rewrite_header.node_index); - s = format (s, " next:[%d]:%U", - adj->rewrite_header.next_index, - format_vlib_next_node_name, - vlib_get_main(), - adj->rewrite_header.node_index, - adj->rewrite_header.next_index); s = format(s, "\n children:\n "); s = fib_node_children_format(adj->ia_node.fn_children, s); } @@ -271,6 +261,78 @@ adj_child_remove (adj_index_t adj_index, sibling_index); } +/* + * Context for the walk to update the cached feture flags. + */ +typedef struct adj_feature_update_t_ +{ + u8 arc; + u8 enable; +} adj_feature_update_ctx_t; + +static adj_walk_rc_t +adj_feature_update_walk_cb (adj_index_t ai, + void *arg) +{ + adj_feature_update_ctx_t *ctx = arg; + ip_adjacency_t *adj; + + adj = adj_get(ai); + + /* + * this ugly mess matches the feature arc that is changing with affected + * adjacencies + */ + if (((ctx->arc == ip6_main.lookup_main.output_feature_arc_index) && + (VNET_LINK_IP6 == adj->ia_link)) || + ((ctx->arc == ip4_main.lookup_main.output_feature_arc_index) && + (VNET_LINK_IP4 == adj->ia_link)) || + ((ctx->arc == mpls_main.output_feature_arc_index) && + (VNET_LINK_MPLS == adj->ia_link))) + { + if (ctx->enable) + adj->rewrite_header.flags |= VNET_REWRITE_HAS_FEATURES; + else + adj->rewrite_header.flags &= ~VNET_REWRITE_HAS_FEATURES; + } + return (ADJ_WALK_RC_CONTINUE); +} + +void +adj_feature_update (u32 sw_if_index, + u8 arc_index, + u8 is_enable) +{ + /* + * Walk all the adjacencies on the interface to update the cached + * 'has-features' flag + */ + adj_feature_update_ctx_t ctx = { + .arc = arc_index, + .enable = is_enable, + }; + adj_walk (sw_if_index, adj_feature_update_walk_cb, &ctx); +} + +/** + * @brief Walk the Adjacencies on a given interface + */ +void +adj_walk (u32 sw_if_index, + adj_walk_cb_t cb, + void *ctx) +{ + /* + * walk all the neighbor adjacencies + */ + fib_protocol_t proto; + + FOR_EACH_FIB_IP_PROTOCOL(proto) + { + adj_nbr_walk(sw_if_index, proto, cb, ctx); + } +} + /** * @brief Return the link type of the adjacency */ diff --git a/src/vnet/adj/adj.h b/src/vnet/adj/adj.h index fcc5890c7d7..271fdbc6114 100644 --- a/src/vnet/adj/adj.h +++ b/src/vnet/adj/adj.h @@ -96,6 +96,12 @@ extern u32 adj_get_sw_if_index (adj_index_t ai); */ extern const u8* adj_get_rewrite (adj_index_t ai); +/** + * @brief Notify the adjacency subsystem that the features settings for + * an interface have changed + */ +extern void adj_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable); + /** * @brief * The global adjacnecy pool. Exposed for fast/inline data-plane access diff --git a/src/vnet/adj/adj_mcast.c b/src/vnet/adj/adj_mcast.c index 1345aedbad6..a3ba4d6ab18 100644 --- a/src/vnet/adj/adj_mcast.c +++ b/src/vnet/adj/adj_mcast.c @@ -256,15 +256,13 @@ format_adj_mcast (u8* s, va_list *ap) { index_t index = va_arg(*ap, index_t); CLIB_UNUSED(u32 indent) = va_arg(*ap, u32); - vnet_main_t * vnm = vnet_get_main(); ip_adjacency_t * adj = adj_get(index); s = format(s, "%U-mcast: ", format_fib_protocol, adj->ia_nh_proto); s = format (s, "%U", format_vnet_rewrite, - vnm->vlib_main, &adj->rewrite_header, - sizeof (adj->rewrite_data), 0); + &adj->rewrite_header, sizeof (adj->rewrite_data), 0); return (s); } diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c index 7d31565114e..55b5e44bc43 100644 --- a/src/vnet/adj/adj_midchain.c +++ b/src/vnet/adj/adj_midchain.c @@ -501,7 +501,6 @@ format_adj_midchain (u8* s, va_list *ap) { index_t index = va_arg(*ap, index_t); u32 indent = va_arg(*ap, u32); - vnet_main_t * vnm = vnet_get_main(); ip_adjacency_t * adj = adj_get(index); s = format (s, "%U", format_vnet_link, adj->ia_link); @@ -509,8 +508,7 @@ format_adj_midchain (u8* s, va_list *ap) format_ip46_address, &adj->sub_type.nbr.next_hop); s = format (s, " %U", format_vnet_rewrite, - vnm->vlib_main, &adj->rewrite_header, - sizeof (adj->rewrite_data), indent); + &adj->rewrite_header, sizeof (adj->rewrite_data), indent); s = format (s, "\n%Ustacked-on:\n%U%U", format_white_space, indent, format_white_space, indent+2, diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c index 9e8073d3225..9ef3651de66 100644 --- a/src/vnet/adj/adj_nbr.c +++ b/src/vnet/adj/adj_nbr.c @@ -433,7 +433,6 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, vnet_rewrite_clear_data_internal(&adj->rewrite_header, sizeof(adj->rewrite_data)); } - adj->rewrite_header.node_index = this_node; adj->rewrite_header.next_index = vlib_node_add_next(vlib_get_main(), this_node, next_node); @@ -971,7 +970,6 @@ format_adj_nbr (u8* s, va_list *ap) { index_t index = va_arg(*ap, index_t); CLIB_UNUSED(u32 indent) = va_arg(*ap, u32); - vnet_main_t * vnm = vnet_get_main(); ip_adjacency_t * adj = adj_get(index); s = format (s, "%U", format_vnet_link, adj->ia_link); @@ -980,7 +978,7 @@ format_adj_nbr (u8* s, va_list *ap) adj_proto_to_46(adj->ia_nh_proto)); s = format (s, "%U", format_vnet_rewrite, - vnm->vlib_main, &adj->rewrite_header, sizeof (adj->rewrite_data), 0); + &adj->rewrite_header, sizeof (adj->rewrite_data), 0); return (s); } diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c index 80ef08d04a1..5a4be029dc4 100644 --- a/src/vnet/feature/feature.c +++ b/src/vnet/feature/feature.c @@ -14,6 +14,7 @@ */ #include +#include vnet_feature_main_t feature_main; @@ -229,6 +230,7 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, fm->sw_if_index_has_features[arc_index] = clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index, (feature_count > 0)); + adj_feature_update (sw_if_index, arc_index, (feature_count > 0)); fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count; return 0; diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 5472428fcfd..34bc6c5d212 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -1232,7 +1232,6 @@ format_ip4_rewrite_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *); - vnet_main_t *vnm = vnet_get_main (); uword indent = format_get_indent (s); s = format (s, "tx_sw_if_index %d dpo-idx %d : %U flow hash: 0x%08x", @@ -1241,7 +1240,7 @@ format_ip4_rewrite_trace (u8 * s, va_list * args) s = format (s, "\n%U%U", format_white_space, indent, format_ip_adjacency_packet_data, - vnm, t->dpo_index, t->packet_data, sizeof (t->packet_data)); + t->dpo_index, t->packet_data, sizeof (t->packet_data)); return s; } @@ -2507,8 +2506,10 @@ ip4_rewrite_inline (vlib_main_t * vm, tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index; vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0; - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index0, &next0, p0); + if (PREDICT_FALSE + (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index0, &next0, p0); } if (PREDICT_TRUE (error1 == IP4_ERROR_NONE)) { @@ -2519,8 +2520,10 @@ ip4_rewrite_inline (vlib_main_t * vm, tx_sw_if_index1 = adj1[0].rewrite_header.sw_if_index; vnet_buffer (p1)->sw_if_index[VLIB_TX] = tx_sw_if_index1; - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index1, &next1, p1); + if (PREDICT_FALSE + (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index1, &next1, p1); } /* Guess we are only writing on simple Ethernet header. */ @@ -2671,8 +2674,10 @@ ip4_rewrite_inline (vlib_main_t * vm, adj0->sub_type.midchain.fixup_func (vm, adj0, p0); } - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index0, &next0, p0); + if (PREDICT_FALSE + (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index0, &next0, p0); } diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index b80c757a6d3..0b8691bf3dd 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -961,7 +961,6 @@ format_ip6_rewrite_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); ip6_forward_next_trace_t *t = va_arg (*args, ip6_forward_next_trace_t *); - vnet_main_t *vnm = vnet_get_main (); uword indent = format_get_indent (s); s = format (s, "tx_sw_if_index %d adj-idx %d : %U flow hash: 0x%08x", @@ -970,7 +969,7 @@ format_ip6_rewrite_trace (u8 * s, va_list * args) s = format (s, "\n%U%U", format_white_space, indent, format_ip_adjacency_packet_data, - vnm, t->adj_index, t->packet_data, sizeof (t->packet_data)); + t->adj_index, t->packet_data, sizeof (t->packet_data)); return s; } @@ -2054,8 +2053,10 @@ ip6_rewrite_inline (vlib_main_t * vm, vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0; next0 = adj0[0].rewrite_header.next_index; - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index0, &next0, p0); + if (PREDICT_FALSE + (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index0, &next0, p0); } if (PREDICT_TRUE (error1 == IP6_ERROR_NONE)) { @@ -2066,8 +2067,10 @@ ip6_rewrite_inline (vlib_main_t * vm, vnet_buffer (p1)->sw_if_index[VLIB_TX] = tx_sw_if_index1; next1 = adj1[0].rewrite_header.next_index; - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index1, &next1, p1); + if (PREDICT_FALSE + (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index1, &next1, p1); } /* Guess we are only writing on simple Ethernet header. */ @@ -2182,8 +2185,10 @@ ip6_rewrite_inline (vlib_main_t * vm, vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0; next0 = adj0[0].rewrite_header.next_index; - vnet_feature_arc_start (lm->output_feature_arc_index, - tx_sw_if_index0, &next0, p0); + if (PREDICT_FALSE + (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (lm->output_feature_arc_index, + tx_sw_if_index0, &next0, p0); } if (is_midchain) diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c index 9ae269cc205..dabfa012eb1 100644 --- a/src/vnet/ip/lookup.c +++ b/src/vnet/ip/lookup.c @@ -291,7 +291,6 @@ format_ip_lookup_next (u8 * s, va_list * args) u8 * format_ip_adjacency_packet_data (u8 * s, va_list * args) { - vnet_main_t *vnm = va_arg (*args, vnet_main_t *); u32 adj_index = va_arg (*args, u32); u8 *packet_data = va_arg (*args, u8 *); u32 n_packet_data_bytes = va_arg (*args, u32); @@ -300,10 +299,9 @@ format_ip_adjacency_packet_data (u8 * s, va_list * args) switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_REWRITE: - s = format (s, "%U", - format_vnet_rewrite_header, - vnm->vlib_main, &adj->rewrite_header, packet_data, - n_packet_data_bytes); + case IP_LOOKUP_NEXT_MCAST: + s = + format (s, "%U", format_hex_bytes, packet_data, n_packet_data_bytes); break; default: diff --git a/src/vnet/mpls/mpls_output.c b/src/vnet/mpls/mpls_output.c index c06cf917b88..cf3540067cc 100644 --- a/src/vnet/mpls/mpls_output.c +++ b/src/vnet/mpls/mpls_output.c @@ -35,7 +35,6 @@ format_mpls_output_trace (u8 * s, va_list * args) CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); mpls_output_trace_t * t = va_arg (*args, mpls_output_trace_t *); - vnet_main_t * vnm = vnet_get_main(); uword indent = format_get_indent (s); s = format (s, "adj-idx %d : %U flow hash: 0x%08x", @@ -45,8 +44,7 @@ format_mpls_output_trace (u8 * s, va_list * args) s = format (s, "\n%U%U", format_white_space, indent, format_ip_adjacency_packet_data, - vnm, t->adj_index, - t->packet_data, sizeof (t->packet_data)); + t->adj_index, t->packet_data, sizeof (t->packet_data)); return s; } @@ -59,12 +57,14 @@ mpls_output_inline (vlib_main_t * vm, u32 n_left_from, next_index, * from, * to_next, cpu_index; vlib_node_runtime_t * error_node; u32 n_left_to_next; + mpls_main_t *mm; cpu_index = os_get_cpu_number(); error_node = vlib_node_get_runtime (vm, mpls_output_node.index); from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; next_index = node->cached_next_index; + mm = &mpls_main; while (n_left_from > 0) { @@ -154,10 +154,10 @@ mpls_output_inline (vlib_main_t * vm, next0 = adj0[0].rewrite_header.next_index; error0 = IP4_ERROR_NONE; - if (is_midchain) - { - adj0->sub_type.midchain.fixup_func(vm, adj0, p0); - } + if (PREDICT_FALSE(adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (mm->output_feature_arc_index, + adj0[0].rewrite_header.sw_if_index, + &next0, p0); } else { @@ -175,16 +175,21 @@ mpls_output_inline (vlib_main_t * vm, next1 = adj1[0].rewrite_header.next_index; error1 = IP4_ERROR_NONE; - if (is_midchain) - { - adj1->sub_type.midchain.fixup_func(vm, adj1, p1); - } + if (PREDICT_FALSE(adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (mm->output_feature_arc_index, + adj1[0].rewrite_header.sw_if_index, + &next1, p1); } else { error1 = IP4_ERROR_MTU_EXCEEDED; next1 = MPLS_OUTPUT_NEXT_DROP; } + if (is_midchain) + { + adj0->sub_type.midchain.fixup_func(vm, adj0, p0); + adj1->sub_type.midchain.fixup_func(vm, adj1, p1); + } p0->error = error_node->errors[error0]; p1->error = error_node->errors[error1]; @@ -254,17 +259,22 @@ mpls_output_inline (vlib_main_t * vm, next0 = adj0[0].rewrite_header.next_index; error0 = IP4_ERROR_NONE; - if (is_midchain) - { - adj0->sub_type.midchain.fixup_func(vm, adj0, p0); - } + if (PREDICT_FALSE(adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) + vnet_feature_arc_start (mm->output_feature_arc_index, + adj0[0].rewrite_header.sw_if_index, + &next0, p0); } else { error0 = IP4_ERROR_MTU_EXCEEDED; next0 = MPLS_OUTPUT_NEXT_DROP; } - p0->error = error_node->errors[error0]; + if (is_midchain) + { + adj0->sub_type.midchain.fixup_func(vm, adj0, p0); + } + + p0->error = error_node->errors[error0]; from += 1; n_left_from -= 1; diff --git a/src/vnet/rewrite.c b/src/vnet/rewrite.c index 8925ad6174a..c4a171c17c5 100644 --- a/src/vnet/rewrite.c +++ b/src/vnet/rewrite.c @@ -67,14 +67,10 @@ vnet_rewrite_copy_slow_path (vnet_rewrite_data_t * p0, u8 * format_vnet_rewrite (u8 * s, va_list * args) { - vlib_main_t *vm = va_arg (*args, vlib_main_t *); vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *); u32 max_data_bytes = va_arg (*args, u32); CLIB_UNUSED (uword indent) = va_arg (*args, u32); vnet_main_t *vnm = vnet_get_main (); - vlib_node_t *next; - - next = vlib_get_next_node (vm, rw->node_index, rw->next_index); if (rw->sw_if_index != ~0) { @@ -85,108 +81,17 @@ format_vnet_rewrite (u8 * s, va_list * args) else s = format (s, "DELETED"); } - else - s = format (s, "%v: ", next->name); /* Format rewrite string. */ if (rw->data_bytes > 0) s = format (s, "%U", - next->format_buffer ? next->format_buffer : format_hex_bytes, + format_hex_bytes, rw->data + max_data_bytes - rw->data_bytes, rw->data_bytes); return s; } -u8 * -format_vnet_rewrite_header (u8 * s, va_list * args) -{ - vlib_main_t *vm = va_arg (*args, vlib_main_t *); - vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *); - u8 *packet_data = va_arg (*args, u8 *); - u32 packet_data_bytes = va_arg (*args, u32); - vlib_node_t *next; - - next = vlib_get_next_node (vm, rw->node_index, rw->next_index); - - /* Format rewrite string. */ - s = format (s, "%U", - next->format_buffer ? next->format_buffer : format_hex_bytes, - packet_data, packet_data_bytes); - - return s; -} - -uword -unformat_vnet_rewrite (unformat_input_t * input, va_list * args) -{ - vlib_main_t *vm = va_arg (*args, vlib_main_t *); - vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *); - u32 max_data_bytes = va_arg (*args, u32); - vnet_main_t *vnm = vnet_get_main (); - vlib_node_t *next; - u32 next_index, sw_if_index, max_packet_bytes, error; - u8 *rw_data; - - rw_data = 0; - sw_if_index = ~0; - max_packet_bytes = ~0; - error = 1; - - /* Parse sw interface. */ - if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) - { - vnet_hw_interface_t *hi; - - hi = vnet_get_sup_hw_interface (vnm, sw_if_index); - - next_index = hi->output_node_index; - max_packet_bytes = hi->max_l3_packet_bytes[VLIB_RX]; - } - - else if (unformat (input, "%U", unformat_vlib_node, vm, &next_index)) - ; - - else - goto done; - - next = vlib_get_node (vm, next_index); - - if (next->unformat_buffer - && unformat_user (input, next->unformat_buffer, &rw_data)) - ; - - else if (unformat_user (input, unformat_hex_string, &rw_data) - || unformat (input, "0x%U", unformat_hex_string, &rw_data)) - ; - - else - goto done; - - /* Re-write does not fit. */ - if (vec_len (rw_data) >= max_data_bytes) - goto done; - - { - u32 tmp; - - if (unformat (input, "mtu %d", &tmp) - && tmp < (1 << BITS (rw->max_l3_packet_bytes))) - max_packet_bytes = tmp; - } - - error = 0; - rw->sw_if_index = sw_if_index; - rw->max_l3_packet_bytes = max_packet_bytes; - rw->next_index = vlib_node_add_next (vm, rw->node_index, next_index); - vnet_rewrite_set_data_internal (rw, max_data_bytes, rw_data, - vec_len (rw_data)); - -done: - vec_free (rw_data); - return error == 0; -} - u32 vnet_tx_node_index_for_sw_interface (vnet_main_t * vnm, u32 sw_if_index) { @@ -200,7 +105,6 @@ vnet_rewrite_init (vnet_main_t * vnm, u32 this_node, u32 next_node, vnet_rewrite_header_t * rw) { rw->sw_if_index = sw_if_index; - rw->node_index = this_node; rw->next_index = vlib_node_add_next (vnm->vlib_main, this_node, next_node); rw->max_l3_packet_bytes = vnet_sw_interface_get_mtu (vnm, sw_if_index, VLIB_TX); @@ -249,7 +153,6 @@ vnet_rewrite_for_tunnel (vnet_main_t * vnm, * ipX-forward, this will be interpreted as a FIB number. */ rw->sw_if_index = tx_sw_if_index; - rw->node_index = rewrite_node_index; rw->next_index = vlib_node_add_next (vnm->vlib_main, rewrite_node_index, post_rewrite_node_index); rw->max_l3_packet_bytes = (u16) ~ 0; /* we can't know at this point */ @@ -284,7 +187,6 @@ unserialize_vnet_rewrite (serialize_main_t * m, va_list * va) u8 *p; /* It is up to user to fill these in. */ - rw->node_index = ~0; rw->next_index = ~0; unserialize_integer (m, &rw->sw_if_index, sizeof (rw->sw_if_index)); diff --git a/src/vnet/rewrite.h b/src/vnet/rewrite.h index ce2bce3a3c8..8435a726553 100644 --- a/src/vnet/rewrite.h +++ b/src/vnet/rewrite.h @@ -46,14 +46,22 @@ /* Consider using vector types for speed? */ typedef uword vnet_rewrite_data_t; +/** + * Flags associated with the rewrite/adjacency + */ +typedef enum vnet_rewrite_flags_t_ +{ + /** + * This adjacency/interface has output features configured + */ + VNET_REWRITE_HAS_FEATURES = (1 << 0), +} __attribute__ ((packed)) vnet_rewrite_flags_t; + /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { /* Interface to mark re-written packets with. */ u32 sw_if_index; - /* Packet processing node where rewrite happens. */ - u32 node_index; - /* Next node to feed after packet rewrite is done. */ u16 next_index; @@ -64,6 +72,11 @@ typedef CLIB_PACKED (struct { Used for MTU check after packet rewrite. */ u16 max_l3_packet_bytes; + u16 unused1; + u8 unused2; + + vnet_rewrite_flags_t flags; + /* When dynamically writing a multicast destination L2 addresss * this is the offset within the address to start writing n * bytes of the IP mcast address */ @@ -79,6 +92,13 @@ typedef CLIB_PACKED (struct { }) vnet_rewrite_header_t; /* *INDENT-ON* */ +/** + * At 16 bytes of rewrite herader we have enought space left for a IPv6 + * (40 bytes) + LISP-GPE (8 bytes) in the cache line + */ +STATIC_ASSERT (sizeof (vnet_rewrite_header_t) <= 16, + "Rewrite header too big"); + /* Helper macro for declaring rewrite string w/ given max-size. @@ -317,11 +337,7 @@ u8 *vnet_build_rewrite_for_sw_interface (struct vnet_main_t *vnm, void vnet_update_adjacency_for_sw_interface (struct vnet_main_t *vnm, u32 sw_if_index, u32 ai); -/* Parser for unformat header & rewrite string. */ -unformat_function_t unformat_vnet_rewrite; - format_function_t format_vnet_rewrite; -format_function_t format_vnet_rewrite_header; serialize_function_t serialize_vnet_rewrite, unserialize_vnet_rewrite; -- cgit 1.2.3-korg