aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@wasa-ucs-11.cisco.com>2017-03-15 12:34:25 -0400
committerDamjan Marion <dmarion.lists@gmail.com>2017-03-17 11:35:39 +0000
commitb069a6910aa2b95316ccdb5d9e5b95143b9dc7c0 (patch)
tree0fb3292c39de54a2d66778272fe197b319286f96
parentb85e43965ec9e23c4ae14b62f4bbfe839f75c427 (diff)
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 <nranns@wasa-ucs-11.cisco.com>
-rw-r--r--src/vnet/adj/adj.c82
-rw-r--r--src/vnet/adj/adj.h6
-rw-r--r--src/vnet/adj/adj_mcast.c4
-rw-r--r--src/vnet/adj/adj_midchain.c4
-rw-r--r--src/vnet/adj/adj_nbr.c4
-rw-r--r--src/vnet/feature/feature.c2
-rw-r--r--src/vnet/ip/ip4_forward.c21
-rw-r--r--src/vnet/ip/ip6_forward.c21
-rw-r--r--src/vnet/ip/lookup.c8
-rw-r--r--src/vnet/mpls/mpls_output.c42
-rw-r--r--src/vnet/rewrite.c100
-rw-r--r--src/vnet/rewrite.h30
12 files changed, 162 insertions, 162 deletions
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c
index 4ed4999f..f3d483ac 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 fcc5890c..271fdbc6 100644
--- a/src/vnet/adj/adj.h
+++ b/src/vnet/adj/adj.h
@@ -97,6 +97,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 1345aedb..a3ba4d6a 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 7d315651..55b5e44b 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 9e8073d3..9ef3651d 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 80ef08d0..5a4be029 100644
--- a/src/vnet/feature/feature.c
+++ b/src/vnet/feature/feature.c
@@ -14,6 +14,7 @@
*/
#include <vnet/feature/feature.h>
+#include <vnet/adj/adj.h>
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 5472428f..34bc6c5d 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 b80c757a..0b8691bf 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 9ae269cc..dabfa012 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 c06cf917..cf354006 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 8925ad61..c4a171c1 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 ce2bce3a..8435a726 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;