aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/l2tp/decap.c
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/l2tp/decap.c')
-rw-r--r--vnet/vnet/l2tp/decap.c348
1 files changed, 184 insertions, 164 deletions
diff --git a/vnet/vnet/l2tp/decap.c b/vnet/vnet/l2tp/decap.c
index 68b7fabe76d..1b97e712b3b 100644
--- a/vnet/vnet/l2tp/decap.c
+++ b/vnet/vnet/l2tp/decap.c
@@ -23,224 +23,232 @@
#include <vnet/l2tp/l2tp.h>
/* Statistics (not really errors) */
-#define foreach_l2t_decap_error \
+#define foreach_l2t_decap_error \
_(USER_TO_NETWORK, "L2TP user (ip6) to L2 network pkts") \
_(SESSION_ID_MISMATCH, "l2tpv3 local session id mismatches") \
_(COOKIE_MISMATCH, "l2tpv3 local cookie mismatches") \
_(NO_SESSION, "l2tpv3 session not found") \
_(ADMIN_DOWN, "l2tpv3 tunnel is down")
-static char * l2t_decap_error_strings[] = {
+static char *l2t_decap_error_strings[] = {
#define _(sym,string) string,
foreach_l2t_decap_error
#undef _
};
-typedef enum {
+typedef enum
+{
#define _(sym,str) L2T_DECAP_ERROR_##sym,
- foreach_l2t_decap_error
+ foreach_l2t_decap_error
#undef _
L2T_DECAP_N_ERROR,
} l2t_DECAP_error_t;
-typedef enum {
- L2T_DECAP_NEXT_DROP,
- L2T_DECAP_NEXT_L2_INPUT,
- L2T_DECAP_N_NEXT,
- /* Pseudo next index */
- L2T_DECAP_NEXT_NO_INTERCEPT = L2T_DECAP_N_NEXT,
+typedef enum
+{
+ L2T_DECAP_NEXT_DROP,
+ L2T_DECAP_NEXT_L2_INPUT,
+ L2T_DECAP_N_NEXT,
+ /* Pseudo next index */
+ L2T_DECAP_NEXT_NO_INTERCEPT = L2T_DECAP_N_NEXT,
} l2t_decap_next_t;
#define NSTAGES 3
-static inline void stage0 (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- u32 buffer_index)
+static inline void
+stage0 (vlib_main_t * vm, vlib_node_runtime_t * node, u32 buffer_index)
{
- vlib_buffer_t *b = vlib_get_buffer (vm, buffer_index);
- vlib_prefetch_buffer_header (b, STORE);
- /* l2tpv3 header is a long way away, need 2 cache lines */
- CLIB_PREFETCH (b->data, 2*CLIB_CACHE_LINE_BYTES, STORE);
+ vlib_buffer_t *b = vlib_get_buffer (vm, buffer_index);
+ vlib_prefetch_buffer_header (b, STORE);
+ /* l2tpv3 header is a long way away, need 2 cache lines */
+ CLIB_PREFETCH (b->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
}
-static inline void stage1 (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- u32 bi)
+static inline void
+stage1 (vlib_main_t * vm, vlib_node_runtime_t * node, u32 bi)
{
- vlib_buffer_t *b = vlib_get_buffer (vm, bi);
- l2t_main_t *lm = &l2t_main;
- ip6_header_t * ip6 = vlib_buffer_get_current (b);
- u32 session_index;
- uword *p = 0;
- l2tpv3_header_t * l2t;
-
- /* Not L2tpv3 (0x73, 0t115)? Use the normal path. */
- if (PREDICT_FALSE(ip6->protocol != IP_PROTOCOL_L2TP)) {
- vnet_buffer(b)->l2t.next_index = L2T_DECAP_NEXT_NO_INTERCEPT;
- return;
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi);
+ l2t_main_t *lm = &l2t_main;
+ ip6_header_t *ip6 = vlib_buffer_get_current (b);
+ u32 session_index;
+ uword *p = 0;
+ l2tpv3_header_t *l2t;
+
+ /* Not L2tpv3 (0x73, 0t115)? Use the normal path. */
+ if (PREDICT_FALSE (ip6->protocol != IP_PROTOCOL_L2TP))
+ {
+ vnet_buffer (b)->l2t.next_index = L2T_DECAP_NEXT_NO_INTERCEPT;
+ return;
}
- /* Make up your minds, people... */
- switch (lm->lookup_type) {
+ /* Make up your minds, people... */
+ switch (lm->lookup_type)
+ {
case L2T_LOOKUP_SRC_ADDRESS:
- p = hash_get_mem (lm->session_by_src_address, &ip6->src_address);
- break;
+ p = hash_get_mem (lm->session_by_src_address, &ip6->src_address);
+ break;
case L2T_LOOKUP_DST_ADDRESS:
- p = hash_get_mem (lm->session_by_dst_address, &ip6->dst_address);
- break;
+ p = hash_get_mem (lm->session_by_dst_address, &ip6->dst_address);
+ break;
case L2T_LOOKUP_SESSION_ID:
- l2t = (l2tpv3_header_t*)(ip6+1);
- p = hash_get (lm->session_by_session_id, l2t->session_id);
- break;
+ l2t = (l2tpv3_header_t *) (ip6 + 1);
+ p = hash_get (lm->session_by_session_id, l2t->session_id);
+ break;
default:
- ASSERT(0);
+ ASSERT (0);
}
- if (PREDICT_FALSE(p == 0)) {
- vnet_buffer(b)->l2t.next_index = L2T_DECAP_NEXT_NO_INTERCEPT;
- return;
- } else {
- session_index = p[0];
+ if (PREDICT_FALSE (p == 0))
+ {
+ vnet_buffer (b)->l2t.next_index = L2T_DECAP_NEXT_NO_INTERCEPT;
+ return;
+ }
+ else
+ {
+ session_index = p[0];
}
- /* Remember mapping index, prefetch the mini counter */
- vnet_buffer(b)->l2t.next_index = L2T_DECAP_NEXT_L2_INPUT;
- vnet_buffer(b)->l2t.session_index = session_index;
+ /* Remember mapping index, prefetch the mini counter */
+ vnet_buffer (b)->l2t.next_index = L2T_DECAP_NEXT_L2_INPUT;
+ vnet_buffer (b)->l2t.session_index = session_index;
- /* $$$$$ prefetch counter */
+ /* $$$$$ prefetch counter */
}
-static inline u32 last_stage (vlib_main_t *vm, vlib_node_runtime_t *node,
- u32 bi)
+static inline u32
+last_stage (vlib_main_t * vm, vlib_node_runtime_t * node, u32 bi)
{
- vlib_buffer_t *b = vlib_get_buffer (vm, bi);
- l2t_main_t *lm = &l2t_main;
- ip6_header_t * ip6 = vlib_buffer_get_current (b);
- vlib_node_t *n = vlib_get_node (vm, node->node_index);
- u32 node_counter_base_index = n->error_heap_index;
- vlib_error_main_t * em = &vm->error_main;
- l2tpv3_header_t * l2tp;
- u32 counter_index;
- l2t_session_t * session;
- u32 session_index;
- u32 next_index;
- u8 l2tp_decap_local = (l2t_decap_local_node.index == n->index);
-
- /* Other-than-output pkt? We're done... */
- if (vnet_buffer(b)->l2t.next_index != L2T_DECAP_NEXT_L2_INPUT) {
- next_index = vnet_buffer(b)->l2t.next_index;
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi);
+ l2t_main_t *lm = &l2t_main;
+ ip6_header_t *ip6 = vlib_buffer_get_current (b);
+ vlib_node_t *n = vlib_get_node (vm, node->node_index);
+ u32 node_counter_base_index = n->error_heap_index;
+ vlib_error_main_t *em = &vm->error_main;
+ l2tpv3_header_t *l2tp;
+ u32 counter_index;
+ l2t_session_t *session;
+ u32 session_index;
+ u32 next_index;
+ u8 l2tp_decap_local = (l2t_decap_local_node.index == n->index);
+
+ /* Other-than-output pkt? We're done... */
+ if (vnet_buffer (b)->l2t.next_index != L2T_DECAP_NEXT_L2_INPUT)
+ {
+ next_index = vnet_buffer (b)->l2t.next_index;
goto done;
}
- em->counters[node_counter_base_index + L2T_DECAP_ERROR_USER_TO_NETWORK] += 1;
-
- session_index = vnet_buffer(b)->l2t.session_index;
-
- counter_index =
- session_index_to_counter_index (session_index,
- SESSION_COUNTER_USER_TO_NETWORK);
-
- /* per-mapping byte stats include the ethernet header */
- vlib_increment_combined_counter (&lm->counter_main,
- os_get_cpu_number(),
- counter_index,
- 1 /* packet_increment */,
- vlib_buffer_length_in_chain (vm, b) +
- sizeof (ethernet_header_t));
-
- session = pool_elt_at_index (lm->sessions, session_index);
-
- l2tp = vlib_buffer_get_current (b) + sizeof (*ip6);
-
- if (PREDICT_FALSE(l2tp->session_id != session->local_session_id)) {
- // Key matched but session id does not. Assume packet is not for us.
- em->counters[node_counter_base_index + L2T_DECAP_ERROR_SESSION_ID_MISMATCH] += 1;
+ em->counters[node_counter_base_index + L2T_DECAP_ERROR_USER_TO_NETWORK] +=
+ 1;
+
+ session_index = vnet_buffer (b)->l2t.session_index;
+
+ counter_index =
+ session_index_to_counter_index (session_index,
+ SESSION_COUNTER_USER_TO_NETWORK);
+
+ /* per-mapping byte stats include the ethernet header */
+ vlib_increment_combined_counter (&lm->counter_main,
+ os_get_cpu_number (),
+ counter_index, 1 /* packet_increment */ ,
+ vlib_buffer_length_in_chain (vm, b) +
+ sizeof (ethernet_header_t));
+
+ session = pool_elt_at_index (lm->sessions, session_index);
+
+ l2tp = vlib_buffer_get_current (b) + sizeof (*ip6);
+
+ if (PREDICT_FALSE (l2tp->session_id != session->local_session_id))
+ {
+ /* Key matched but session id does not. Assume packet is not for us. */
+ em->counters[node_counter_base_index +
+ L2T_DECAP_ERROR_SESSION_ID_MISMATCH] += 1;
next_index = L2T_DECAP_NEXT_NO_INTERCEPT;
goto done;
}
- if (PREDICT_FALSE (l2tp->cookie != session->local_cookie[0])) {
- if (l2tp->cookie != session->local_cookie[1]) {
- // Key and session ID matched, but cookie doesn't. Drop this packet.
- b->error = node->errors[L2T_DECAP_ERROR_COOKIE_MISMATCH];
- next_index = L2T_DECAP_NEXT_DROP;
- goto done;
- }
+ if (PREDICT_FALSE (l2tp->cookie != session->local_cookie[0]))
+ {
+ if (l2tp->cookie != session->local_cookie[1])
+ {
+ /* Key and session ID matched, but cookie doesn't. Drop this packet. */
+ b->error = node->errors[L2T_DECAP_ERROR_COOKIE_MISMATCH];
+ next_index = L2T_DECAP_NEXT_DROP;
+ goto done;
+ }
}
- vnet_buffer(b)->sw_if_index[VLIB_RX] = session->sw_if_index;
+ vnet_buffer (b)->sw_if_index[VLIB_RX] = session->sw_if_index;
- if (PREDICT_FALSE(!(session->admin_up))) {
- b->error = node->errors[L2T_DECAP_ERROR_ADMIN_DOWN];
- next_index = L2T_DECAP_NEXT_DROP;
- goto done;
+ if (PREDICT_FALSE (!(session->admin_up)))
+ {
+ b->error = node->errors[L2T_DECAP_ERROR_ADMIN_DOWN];
+ next_index = L2T_DECAP_NEXT_DROP;
+ goto done;
}
- /* strip the ip6 and L2TP header */
- vlib_buffer_advance (b, sizeof (*ip6) + session->l2tp_hdr_size);
-
- /* Required to make the l2 tag push / pop code work on l2 subifs */
- vnet_update_l2_len (b);
-
- if (PREDICT_FALSE(b->flags & VLIB_BUFFER_IS_TRACED)) {
- l2t_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t));
- t->is_user_to_network = 1;
- t->our_address.as_u64[0] =
- ip6->dst_address.as_u64[0];
- t->our_address.as_u64[1] =
- ip6->dst_address.as_u64[1];
- t->client_address.as_u64[0] =
- ip6->src_address.as_u64[0];
- t->client_address.as_u64[1] =
- ip6->src_address.as_u64[1];
- t->session_index = session_index;
+ /* strip the ip6 and L2TP header */
+ vlib_buffer_advance (b, sizeof (*ip6) + session->l2tp_hdr_size);
+
+ /* Required to make the l2 tag push / pop code work on l2 subifs */
+ vnet_update_l2_len (b);
+
+ if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ l2t_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t));
+ t->is_user_to_network = 1;
+ t->our_address.as_u64[0] = ip6->dst_address.as_u64[0];
+ t->our_address.as_u64[1] = ip6->dst_address.as_u64[1];
+ t->client_address.as_u64[0] = ip6->src_address.as_u64[0];
+ t->client_address.as_u64[1] = ip6->src_address.as_u64[1];
+ t->session_index = session_index;
}
- return L2T_DECAP_NEXT_L2_INPUT;
-
- done:
- if (next_index == L2T_DECAP_NEXT_NO_INTERCEPT) {
- // Small behavioral change between l2tp-decap and l2tp-decap-local
- if (l2tp_decap_local) {
- b->error = node->errors[L2T_DECAP_ERROR_NO_SESSION];
- next_index = L2T_DECAP_NEXT_DROP;
- } else {
- // Go to next node on the ip6 configuration chain
- ip6_main_t * im = &ip6_main;
- ip_lookup_main_t * lm = &im->lookup_main;
- ip_config_main_t * cm = &lm->rx_config_mains[VNET_UNICAST];
- ip6_l2tpv3_config_t * c0;
-
- vnet_get_config_data (&cm->config_main,
- &b->current_config_index,
- &next_index,
- sizeof (c0[0]));
- }
+ return L2T_DECAP_NEXT_L2_INPUT;
+
+done:
+ if (next_index == L2T_DECAP_NEXT_NO_INTERCEPT)
+ {
+ /* Small behavioral change between l2tp-decap and l2tp-decap-local */
+ if (l2tp_decap_local)
+ {
+ b->error = node->errors[L2T_DECAP_ERROR_NO_SESSION];
+ next_index = L2T_DECAP_NEXT_DROP;
+ }
+ else
+ {
+ /* Go to next node on the ip6 configuration chain */
+ ip6_main_t *im = &ip6_main;
+ ip_lookup_main_t *lm = &im->lookup_main;
+ ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST];
+ ip6_l2tpv3_config_t *c0;
+
+ vnet_get_config_data (&cm->config_main,
+ &b->current_config_index,
+ &next_index, sizeof (c0[0]));
+ }
}
- if (PREDICT_FALSE(b->flags & VLIB_BUFFER_IS_TRACED)) {
- l2t_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t));
- t->is_user_to_network = 1;
- t->our_address.as_u64[0] =
- ip6->dst_address.as_u64[0];
- t->our_address.as_u64[1] =
- ip6->dst_address.as_u64[1];
- t->client_address.as_u64[0] =
- ip6->src_address.as_u64[0];
- t->client_address.as_u64[1] =
- ip6->src_address.as_u64[1];
- t->session_index = ~0;
+ if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ l2t_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t));
+ t->is_user_to_network = 1;
+ t->our_address.as_u64[0] = ip6->dst_address.as_u64[0];
+ t->our_address.as_u64[1] = ip6->dst_address.as_u64[1];
+ t->client_address.as_u64[0] = ip6->src_address.as_u64[0];
+ t->client_address.as_u64[1] = ip6->src_address.as_u64[1];
+ t->session_index = ~0;
}
- return next_index;
+ return next_index;
}
#include <vnet/pipeline.h>
-static uword l2t_decap_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+static uword
+l2t_decap_node_fn (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame)
{
- return dispatch_pipeline (vm, node, frame);
+ return dispatch_pipeline (vm, node, frame);
}
/*
@@ -249,13 +257,14 @@ static uword l2t_decap_node_fn (vlib_main_t * vm,
* while l2tp-decap-local drops it.
*/
+/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2t_decap_node) = {
.function = l2t_decap_node_fn,
.name = "l2tp-decap",
.vector_size = sizeof (u32),
.format_trace = format_l2t_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
-
+
.n_errors = ARRAY_LEN(l2t_decap_error_strings),
.error_strings = l2t_decap_error_strings,
@@ -267,9 +276,10 @@ VLIB_REGISTER_NODE (l2t_decap_node) = {
[L2T_DECAP_NEXT_DROP] = "error-drop",
},
};
+/* *INDENT-ON* */
-VLIB_NODE_FUNCTION_MULTIARCH (l2t_decap_node, l2t_decap_node_fn)
-
+VLIB_NODE_FUNCTION_MULTIARCH (l2t_decap_node, l2t_decap_node_fn);
+/* *INDENT-OFF* */
VLIB_REGISTER_NODE (l2t_decap_local_node) = {
.function = l2t_decap_node_fn,
.name = "l2tp-decap-local",
@@ -284,12 +294,22 @@ VLIB_REGISTER_NODE (l2t_decap_local_node) = {
/* edit / add dispositions here */
.next_nodes = {
- [L2T_DECAP_NEXT_L2_INPUT] = "l2-input",
- [L2T_DECAP_NEXT_DROP] = "error-drop",
+ [L2T_DECAP_NEXT_L2_INPUT] = "l2-input",
+ [L2T_DECAP_NEXT_DROP] = "error-drop",
},
};
+/* *INDENT-ON* */
-void l2tp_decap_init (void)
+void
+l2tp_decap_init (void)
{
ip6_register_protocol (IP_PROTOCOL_L2TP, l2t_decap_local_node.index);
}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */