/* Adjacency taken. */
u32 adj_index;
u32 flow_hash;
-
- /* Packet data, possibly *after* rewrite. */
- u8 packet_data[64 - 1*sizeof(u32)];
} mpls_output_trace_t;
+#define foreach_mpls_output_next \
+_(DROP, "error-drop")
+
+typedef enum {
+#define _(s,n) MPLS_OUTPUT_NEXT_##s,
+ foreach_mpls_output_next
+#undef _
+ MPLS_OUTPUT_N_NEXT,
+} mpls_output_next_t;
+
static u8 *
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",
t->adj_index,
format_ip_adjacency, t->adj_index, FORMAT_IP_ADJACENCY_NONE,
t->flow_hash);
- 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));
return s;
}
vlib_frame_t * from_frame,
int is_midchain)
{
- u32 n_left_from, next_index, * from, * to_next, cpu_index;
+ u32 n_left_from, next_index, * from, * to_next, thread_index;
vlib_node_runtime_t * error_node;
u32 n_left_to_next;
+ mpls_main_t *mm;
- cpu_index = os_get_cpu_number();
+ thread_index = vlib_get_thread_index();
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)
{
adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
adj_index1 = vnet_buffer (p1)->ip.adj_index[VLIB_TX];
- /* We should never rewrite a pkt using the MISS adjacency */
- ASSERT(adj_index0);
- ASSERT(adj_index1);
-
adj0 = adj_get(adj_index0);
adj1 = adj_get(adj_index1);
hdr0 = vlib_buffer_get_current (p0);
/* Update packet buffer attributes/set output interface. */
rw_len0 = adj0[0].rewrite_header.data_bytes;
rw_len1 = adj1[0].rewrite_header.data_bytes;
+ vnet_buffer (p0)->mpls.save_rewrite_length = rw_len0;
+ vnet_buffer (p1)->mpls.save_rewrite_length = rw_len1;
/* Bump the adj counters for packet and bytes */
vlib_increment_combined_counter
(&adjacency_counters,
- cpu_index,
+ thread_index,
adj_index0,
1,
vlib_buffer_length_in_chain (vm, p0) + rw_len0);
vlib_increment_combined_counter
(&adjacency_counters,
- cpu_index,
+ thread_index,
adj_index1,
1,
vlib_buffer_length_in_chain (vm, p1) + rw_len1);
if (PREDICT_TRUE(vlib_buffer_length_in_chain (vm, p0) <=
adj0[0].rewrite_header.max_l3_packet_bytes))
{
- p0->current_data -= rw_len0;
- p0->current_length += rw_len0;
+ vlib_buffer_advance(p0, -rw_len0);
vnet_buffer (p0)->sw_if_index[VLIB_TX] =
adj0[0].rewrite_header.sw_if_index;
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
{
if (PREDICT_TRUE(vlib_buffer_length_in_chain (vm, p1) <=
adj1[0].rewrite_header.max_l3_packet_bytes))
{
- p1->current_data -= rw_len1;
- p1->current_length += rw_len1;
+ vlib_buffer_advance(p1, -rw_len1);
vnet_buffer (p1)->sw_if_index[VLIB_TX] =
adj1[0].rewrite_header.sw_if_index;
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,
+ adj0->sub_type.midchain.fixup_data);
+ adj1->sub_type.midchain.fixup_func
+ (vm, adj1, p1,
+ adj1->sub_type.midchain.fixup_data);
+ }
p0->error = error_node->errors[error0];
p1->error = error_node->errors[error1];
adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
- /* We should never rewrite a pkt using the MISS adjacency */
- ASSERT(adj_index0);
-
adj0 = adj_get(adj_index0);
hdr0 = vlib_buffer_get_current (p0);
/* Update packet buffer attributes/set output interface. */
rw_len0 = adj0[0].rewrite_header.data_bytes;
-
+ vnet_buffer (p0)->mpls.save_rewrite_length = rw_len0;
+
vlib_increment_combined_counter
(&adjacency_counters,
- cpu_index,
+ thread_index,
adj_index0,
1,
vlib_buffer_length_in_chain (vm, p0) + rw_len0);
-
+
/* Check MTU of outgoing interface. */
if (PREDICT_TRUE(vlib_buffer_length_in_chain (vm, p0) <=
adj0[0].rewrite_header.max_l3_packet_bytes))
{
- p0->current_data -= rw_len0;
- p0->current_length += rw_len0;
+ vlib_buffer_advance(p0, -rw_len0);
vnet_buffer (p0)->sw_if_index[VLIB_TX] =
adj0[0].rewrite_header.sw_if_index;
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,
+ adj0->sub_type.midchain.fixup_data);
+ }
+
+ p0->error = error_node->errors[error0];
from += 1;
n_left_from -= 1;
#undef mpls_error
};
-static inline uword
-mpls_output (vlib_main_t * vm,
+VLIB_NODE_FN (mpls_output_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
}
VLIB_REGISTER_NODE (mpls_output_node) = {
- .function = mpls_output,
.name = "mpls-output",
/* Takes a vector of packets. */
.vector_size = sizeof (u32),
.format_trace = format_mpls_output_trace,
};
-VLIB_NODE_FUNCTION_MULTIARCH (mpls_output_node, mpls_output)
-
-static inline uword
-mpls_midchain (vlib_main_t * vm,
+VLIB_NODE_FN (mpls_midchain_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
}
VLIB_REGISTER_NODE (mpls_midchain_node) = {
- .function = mpls_midchain,
.name = "mpls-midchain",
.vector_size = sizeof (u32),
.sibling_of = "mpls-output",
};
-VLIB_NODE_FUNCTION_MULTIARCH (mpls_midchain_node, mpls_midchain)
-
/**
* @brief Next index values from the MPLS incomplete adj node
*/
* We pay a cost for this 'routing' node, but an incomplete adj is the
* exception case.
*/
-static inline uword
-mpls_adj_incomplete (vlib_main_t * vm,
+VLIB_NODE_FN (mpls_adj_incomplete_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
n_left_to_next -= 1;
adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
- ASSERT(adj_index0);
adj0 = adj_get(adj_index0);
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_adj_incomplete_trace_t * t;
- uword indent;
+ u32 indent;
t = va_arg (*args, mpls_adj_incomplete_trace_t *);
indent = format_get_indent (s);
}
VLIB_REGISTER_NODE (mpls_adj_incomplete_node) = {
- .function = mpls_adj_incomplete,
.name = "mpls-adj-incomplete",
.format_trace = format_mpls_adj_incomplete_trace,
/* Takes a vector of packets. */
},
};
-VLIB_NODE_FUNCTION_MULTIARCH (mpls_adj_incomplete_node,
- mpls_adj_incomplete)