diff options
Diffstat (limited to 'vnet/vnet/l2tp/encap.c')
-rw-r--r-- | vnet/vnet/l2tp/encap.c | 268 |
1 files changed, 139 insertions, 129 deletions
diff --git a/vnet/vnet/l2tp/encap.c b/vnet/vnet/l2tp/encap.c index 08d7015da39..ed7a9580de1 100644 --- a/vnet/vnet/l2tp/encap.c +++ b/vnet/vnet/l2tp/encap.c @@ -28,173 +28,174 @@ _(NETWORK_TO_USER, "L2TP L2 network to user (ip6) pkts") \ _(LOOKUP_FAIL_TO_L3, "L2TP L2 session lookup failed pkts") \ _(ADMIN_DOWN, "L2TP tunnel is down") -static char * l2t_encap_error_strings[] = { +static char *l2t_encap_error_strings[] = { #define _(sym,string) string, foreach_l2t_encap_error #undef _ }; -typedef enum { +typedef enum +{ #define _(sym,str) L2T_ENCAP_ERROR_##sym, - foreach_l2t_encap_error + foreach_l2t_encap_error #undef _ L2T_ENCAP_N_ERROR, } l2t_encap_error_t; -typedef enum { - L2T_ENCAP_NEXT_DROP, - L2T_ENCAP_NEXT_IP6_LOOKUP, - L2T_ENCAP_N_NEXT, +typedef enum +{ + L2T_ENCAP_NEXT_DROP, + L2T_ENCAP_NEXT_IP6_LOOKUP, + L2T_ENCAP_N_NEXT, } l2t_encap_next_t; -typedef struct { +typedef struct +{ u32 cached_session_index; u32 cached_sw_if_index; - vnet_main_t * vnet_main; + vnet_main_t *vnet_main; } l2tp_encap_runtime_t; vlib_node_registration_t l2t_encap_node; #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); - 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); + 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) { - l2tp_encap_runtime_t * rt = (void *) node->runtime_data; - vlib_buffer_t *b = vlib_get_buffer (vm, bi); - vnet_hw_interface_t * hi; + l2tp_encap_runtime_t *rt = (void *) node->runtime_data; + vlib_buffer_t *b = vlib_get_buffer (vm, bi); + vnet_hw_interface_t *hi; - u32 sw_if_index = vnet_buffer(b)->sw_if_index[VLIB_TX]; - u32 session_index = rt->cached_session_index; + u32 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX]; + u32 session_index = rt->cached_session_index; - if (PREDICT_FALSE(rt->cached_sw_if_index != sw_if_index)) + if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index)) { - hi = vnet_get_sup_hw_interface (rt->vnet_main, sw_if_index); - session_index = rt->cached_session_index = hi->dev_instance; - rt->cached_sw_if_index = sw_if_index; + hi = vnet_get_sup_hw_interface (rt->vnet_main, sw_if_index); + session_index = rt->cached_session_index = hi->dev_instance; + rt->cached_sw_if_index = sw_if_index; } - /* Remember mapping index, prefetch the mini counter */ - vnet_buffer(b)->l2t.next_index = L2T_ENCAP_NEXT_IP6_LOOKUP; - vnet_buffer(b)->l2t.session_index = session_index; + /* Remember mapping index, prefetch the mini counter */ + vnet_buffer (b)->l2t.next_index = L2T_ENCAP_NEXT_IP6_LOOKUP; + 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; - vlib_node_t *n = vlib_get_node (vm, l2t_encap_node.index); - u32 node_counter_base_index = n->error_heap_index; - vlib_error_main_t * em = &vm->error_main; - l2tpv3_header_t * l2tp; - u32 session_index; - u32 counter_index; - l2t_session_t *s; - ip6_header_t *ip6; - u16 payload_length; - u32 next_index = L2T_ENCAP_NEXT_IP6_LOOKUP; - - /* Other-than-output pkt? We're done... */ - if (vnet_buffer(b)->l2t.next_index != L2T_ENCAP_NEXT_IP6_LOOKUP) - return vnet_buffer(b)->l2t.next_index; - - em->counters[node_counter_base_index + L2T_ENCAP_ERROR_NETWORK_TO_USER] += 1; - - session_index = vnet_buffer(b)->l2t.session_index; - - counter_index = - session_index_to_counter_index (session_index, - SESSION_COUNTER_NETWORK_TO_USER); - - /* 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)); - - s = pool_elt_at_index (lm->sessions, session_index); - - vnet_buffer(b)->sw_if_index[VLIB_TX] = s->encap_fib_index; - - /* Paint on an l2tpv3 hdr */ - vlib_buffer_advance (b, -(s->l2tp_hdr_size)); - l2tp = vlib_buffer_get_current (b); - - l2tp->session_id = s->remote_session_id; - l2tp->cookie = s->remote_cookie; - if (PREDICT_FALSE (s->l2_sublayer_present)) { - l2tp->l2_specific_sublayer = 0; + vlib_buffer_t *b = vlib_get_buffer (vm, bi); + l2t_main_t *lm = &l2t_main; + vlib_node_t *n = vlib_get_node (vm, l2t_encap_node.index); + u32 node_counter_base_index = n->error_heap_index; + vlib_error_main_t *em = &vm->error_main; + l2tpv3_header_t *l2tp; + u32 session_index; + u32 counter_index; + l2t_session_t *s; + ip6_header_t *ip6; + u16 payload_length; + u32 next_index = L2T_ENCAP_NEXT_IP6_LOOKUP; + + /* Other-than-output pkt? We're done... */ + if (vnet_buffer (b)->l2t.next_index != L2T_ENCAP_NEXT_IP6_LOOKUP) + return vnet_buffer (b)->l2t.next_index; + + em->counters[node_counter_base_index + L2T_ENCAP_ERROR_NETWORK_TO_USER] += + 1; + + session_index = vnet_buffer (b)->l2t.session_index; + + counter_index = + session_index_to_counter_index (session_index, + SESSION_COUNTER_NETWORK_TO_USER); + + /* 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)); + + s = pool_elt_at_index (lm->sessions, session_index); + + vnet_buffer (b)->sw_if_index[VLIB_TX] = s->encap_fib_index; + + /* Paint on an l2tpv3 hdr */ + vlib_buffer_advance (b, -(s->l2tp_hdr_size)); + l2tp = vlib_buffer_get_current (b); + + l2tp->session_id = s->remote_session_id; + l2tp->cookie = s->remote_cookie; + if (PREDICT_FALSE (s->l2_sublayer_present)) + { + l2tp->l2_specific_sublayer = 0; } - /* Paint on an ip6 header */ - vlib_buffer_advance (b, -(sizeof (*ip6))); - ip6 = vlib_buffer_get_current (b); + /* Paint on an ip6 header */ + vlib_buffer_advance (b, -(sizeof (*ip6))); + ip6 = vlib_buffer_get_current (b); - if (PREDICT_FALSE(!(s->admin_up))) { - b->error = node->errors[L2T_ENCAP_ERROR_ADMIN_DOWN]; - next_index = L2T_ENCAP_NEXT_DROP; - goto done; + if (PREDICT_FALSE (!(s->admin_up))) + { + b->error = node->errors[L2T_ENCAP_ERROR_ADMIN_DOWN]; + next_index = L2T_ENCAP_NEXT_DROP; + goto done; } - ip6->ip_version_traffic_class_and_flow_label = - clib_host_to_net_u32 (0x6<<28); - - /* calculate ip6 payload length */ - payload_length = vlib_buffer_length_in_chain (vm, b); - payload_length -= sizeof (*ip6); - - ip6->payload_length = clib_host_to_net_u16 (payload_length); - ip6->protocol = IP_PROTOCOL_L2TP; - ip6->hop_limit = 0xff; - ip6->src_address.as_u64[0] = s->our_address.as_u64[0]; - ip6->src_address.as_u64[1] = s->our_address.as_u64[1]; - ip6->dst_address.as_u64[0] = s->client_address.as_u64[0]; - ip6->dst_address.as_u64[1] = s->client_address.as_u64[1]; - - - done: - 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 = 0; - t->our_address.as_u64[0] = - ip6->src_address.as_u64[0]; - t->our_address.as_u64[1] = - ip6->src_address.as_u64[1]; - t->client_address.as_u64[0] = - ip6->dst_address.as_u64[0]; - t->client_address.as_u64[1] = - ip6->dst_address.as_u64[1]; - t->session_index = session_index; + ip6->ip_version_traffic_class_and_flow_label = + clib_host_to_net_u32 (0x6 << 28); + + /* calculate ip6 payload length */ + payload_length = vlib_buffer_length_in_chain (vm, b); + payload_length -= sizeof (*ip6); + + ip6->payload_length = clib_host_to_net_u16 (payload_length); + ip6->protocol = IP_PROTOCOL_L2TP; + ip6->hop_limit = 0xff; + ip6->src_address.as_u64[0] = s->our_address.as_u64[0]; + ip6->src_address.as_u64[1] = s->our_address.as_u64[1]; + ip6->dst_address.as_u64[0] = s->client_address.as_u64[0]; + ip6->dst_address.as_u64[1] = s->client_address.as_u64[1]; + + +done: + 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 = 0; + t->our_address.as_u64[0] = ip6->src_address.as_u64[0]; + t->our_address.as_u64[1] = ip6->src_address.as_u64[1]; + t->client_address.as_u64[0] = ip6->dst_address.as_u64[0]; + t->client_address.as_u64[1] = ip6->dst_address.as_u64[1]; + t->session_index = session_index; } - return next_index; + return next_index; } #include <vnet/pipeline.h> -uword l2t_encap_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +uword +l2t_encap_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); } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (l2t_encap_node) = { .function = l2t_encap_node_fn, .name = "l2tp-encap", @@ -202,27 +203,36 @@ VLIB_REGISTER_NODE (l2t_encap_node) = { .format_trace = format_l2t_trace, .type = VLIB_NODE_TYPE_INTERNAL, .runtime_data_bytes = sizeof (l2tp_encap_runtime_t), - + .n_errors = ARRAY_LEN(l2t_encap_error_strings), .error_strings = l2t_encap_error_strings, .n_next_nodes = L2T_ENCAP_N_NEXT, - // add dispositions here + /* add dispositions here */ .next_nodes = { - [L2T_ENCAP_NEXT_IP6_LOOKUP] = "ip6-lookup", - [L2T_ENCAP_NEXT_DROP] = "error-drop", + [L2T_ENCAP_NEXT_IP6_LOOKUP] = "ip6-lookup", + [L2T_ENCAP_NEXT_DROP] = "error-drop", }, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (l2t_encap_node, l2t_encap_node_fn) - -void l2tp_encap_init (vlib_main_t * vm) +VLIB_NODE_FUNCTION_MULTIARCH (l2t_encap_node, l2t_encap_node_fn); +void +l2tp_encap_init (vlib_main_t * vm) { - l2tp_encap_runtime_t * rt; + l2tp_encap_runtime_t *rt; rt = vlib_node_get_runtime_data (vm, l2t_encap_node.index); - rt->vnet_main = vnet_get_main(); - rt->cached_sw_if_index = (u32) ~0; - rt->cached_session_index = (u32) ~0; + rt->vnet_main = vnet_get_main (); + rt->cached_sw_if_index = (u32) ~ 0; + rt->cached_session_index = (u32) ~ 0; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |