diff options
Diffstat (limited to 'src/vnet/l2tp')
-rw-r--r-- | src/vnet/l2tp/FEATURE.yaml | 8 | ||||
-rw-r--r-- | src/vnet/l2tp/decap.c | 301 | ||||
-rw-r--r-- | src/vnet/l2tp/encap.c | 235 | ||||
-rw-r--r-- | src/vnet/l2tp/l2tp.api | 115 | ||||
-rw-r--r-- | src/vnet/l2tp/l2tp.c | 764 | ||||
-rw-r--r-- | src/vnet/l2tp/l2tp.h | 148 | ||||
-rw-r--r-- | src/vnet/l2tp/l2tp_api.c | 273 | ||||
-rw-r--r-- | src/vnet/l2tp/packet.h | 44 | ||||
-rw-r--r-- | src/vnet/l2tp/pg.c | 106 |
9 files changed, 0 insertions, 1994 deletions
diff --git a/src/vnet/l2tp/FEATURE.yaml b/src/vnet/l2tp/FEATURE.yaml deleted file mode 100644 index 58df9b2215e..00000000000 --- a/src/vnet/l2tp/FEATURE.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: L2TPv3 -maintainer: unmaintained -features: - - L2TPv3 over IPv6 -description: "An initial and incomplete implementation of L2TPv3 (RFC3931)." -state: experimental -properties: [API, CLI] diff --git a/src/vnet/l2tp/decap.c b/src/vnet/l2tp/decap.c deleted file mode 100644 index 787cc115a7e..00000000000 --- a/src/vnet/l2tp/decap.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * decap.c : L2TPv3 tunnel decapsulation - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vppinfra/error.h> -#include <vppinfra/hash.h> -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/ethernet/ethernet.h> -#include <vnet/l2tp/l2tp.h> -#include <vnet/l2/l2_input.h> - -/* Statistics (not really errors) */ -#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[] = { -#define _(sym,string) string, - foreach_l2t_decap_error -#undef _ -}; - -typedef enum -{ -#define _(sym,str) L2T_DECAP_ERROR_##sym, - 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, -} l2t_decap_next_t; - -#define NSTAGES 3 - -static inline void -stage0 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_buffer_t * b) -{ - 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, vlib_buffer_t * b) -{ - 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) - { - case L2T_LOOKUP_SRC_ADDRESS: - 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; - case L2T_LOOKUP_SESSION_ID: - l2t = (l2tpv3_header_t *) (ip6 + 1); - p = hash_get (lm->session_by_session_id, l2t->session_id); - break; - default: - ASSERT (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; - - /* $$$$$ prefetch counter */ -} - -static inline u32 -last_stage (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_buffer_t * b) -{ - 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 = 0; - 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, - vlib_get_thread_index (), - 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; - } - } - - 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; - } - - /* 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 */ - if (PREDICT_TRUE (session != 0)) - vnet_feature_next (&next_index, 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 = ~0; - } - return next_index; -} - -#include <vnet/pipeline.h> - -VLIB_NODE_FN (l2t_decap_node) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - return dispatch_pipeline (vm, node, frame); -} - -/* - * l2tp-decap and l2tp-decap-local have very slightly different behavior. - * When a packet has no associated session l2tp-decap let it go to ip6 forward, - * while l2tp-decap-local drops it. - */ - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (l2t_decap_node) = { - .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, - - .n_next_nodes = L2T_DECAP_N_NEXT, - - /* edit / add dispositions here */ - .next_nodes = { - [L2T_DECAP_NEXT_L2_INPUT] = "l2-input", - [L2T_DECAP_NEXT_DROP] = "error-drop", - }, -}; -/* *INDENT-ON* */ - -extern vlib_node_function_t l2t_decap_node_fn; - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (l2t_decap_local_node) = { - .function = l2t_decap_node_fn, - .name = "l2tp-decap-local", - .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, - - .n_next_nodes = L2T_DECAP_N_NEXT, - - /* edit / add dispositions here */ - .next_nodes = { - [L2T_DECAP_NEXT_L2_INPUT] = "l2-input", - [L2T_DECAP_NEXT_DROP] = "error-drop", - }, -}; -/* *INDENT-ON* */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/encap.c b/src/vnet/l2tp/encap.c deleted file mode 100644 index 8863ddfa20d..00000000000 --- a/src/vnet/l2tp/encap.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * encap.c : L2TPv3 tunnel encapsulation - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vppinfra/error.h> -#include <vppinfra/hash.h> -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/ethernet/ethernet.h> -#include <vnet/l2tp/l2tp.h> - -/* Statistics (not really errors) */ -#define foreach_l2t_encap_error \ -_(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[] = { -#define _(sym,string) string, - foreach_l2t_encap_error -#undef _ -}; - -typedef enum -{ -#define _(sym,str) L2T_ENCAP_ERROR_##sym, - 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, -} l2t_encap_next_t; - -typedef struct -{ - u32 cached_session_index; - u32 cached_sw_if_index; - vnet_main_t *vnet_main; -} l2tp_encap_runtime_t; - -extern vlib_node_registration_t l2t_encap_node; - -#define NSTAGES 3 - -static inline void -stage0 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_buffer_t * b) -{ - 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, vlib_buffer_t * b) -{ - l2tp_encap_runtime_t *rt = (void *) node->runtime_data; - vnet_hw_interface_t *hi; - - 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)) - { - 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; - - /* $$$$ prefetch counter... */ -} - -static inline u32 -last_stage (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_buffer_t * b) -{ - 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, - vlib_get_thread_index (), - 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); - - 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; - } - - return next_index; -} - -#include <vnet/pipeline.h> - -VLIB_NODE_FN (l2t_encap_node) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - return dispatch_pipeline (vm, node, frame); -} - - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (l2t_encap_node) = { - .name = "l2tp-encap", - .vector_size = sizeof (u32), - .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 */ - .next_nodes = { - [L2T_ENCAP_NEXT_IP6_LOOKUP] = "ip6-lookup", - [L2T_ENCAP_NEXT_DROP] = "error-drop", - }, -}; -/* *INDENT-ON* */ - -#ifndef CLIB_MARCH_VARIANT -void -l2tp_encap_init (vlib_main_t * vm) -{ - 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; -} -#endif /* CLIB_MARCH_VARIANT */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/l2tp.api b/src/vnet/l2tp/l2tp.api deleted file mode 100644 index 618c4122fd6..00000000000 --- a/src/vnet/l2tp/l2tp.api +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2015-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -option version = "2.0.0"; - -import "vnet/interface_types.api"; -import "vnet/ethernet/ethernet_types.api"; -import "vnet/ip/ip_types.api"; - -/** \brief l2tpv3 tunnel interface create request - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param client_address - remote client tunnel ip address - @param client_address - local tunnel ip address - @param is_ipv6 - ipv6 if non-zero, else ipv4 - @param local_session_id - local tunnel session id - @param remote_session_id - remote tunnel session id - @param local_cookie - local tunnel cookie - @param l2_sublayer_present - l2 sublayer is present in packets if non-zero - @param encap_vrf_id - fib identifier used for outgoing encapsulated packets -*/ -define l2tpv3_create_tunnel -{ - u32 client_index; - u32 context; - vl_api_address_t client_address; - vl_api_address_t our_address; - u32 local_session_id; - u32 remote_session_id; - u64 local_cookie; - u64 remote_cookie; - bool l2_sublayer_present; - u32 encap_vrf_id; -}; - -/** \brief l2tpv3 tunnel interface create response - @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param sw_if_index - index of the new tunnel interface -*/ -define l2tpv3_create_tunnel_reply -{ - u32 context; - i32 retval; - vl_api_interface_index_t sw_if_index; -}; - -autoreply define l2tpv3_set_tunnel_cookies -{ - u32 client_index; - u32 context; - vl_api_interface_index_t sw_if_index; - u64 new_local_cookie; - u64 new_remote_cookie; -}; - -define sw_if_l2tpv3_tunnel_details -{ - u32 context; - vl_api_interface_index_t sw_if_index; - string interface_name[64]; - vl_api_address_t client_address; - vl_api_address_t our_address; - u32 local_session_id; - u32 remote_session_id; - u64 local_cookie[2]; - u64 remote_cookie; - bool l2_sublayer_present; -}; - -define sw_if_l2tpv3_tunnel_dump -{ - u32 client_index; - u32 context; -}; - -autoreply define l2tpv3_interface_enable_disable -{ - u32 client_index; - u32 context; - bool enable_disable; - vl_api_interface_index_t sw_if_index; -}; - -enum l2t_lookup_key : u8 -{ - L2T_LOOKUP_KEY_API_SRC_ADDR = 0, - L2T_LOOKUP_KEY_API_DST_ADDR = 1, - L2T_LOOKUP_KEY_API_SESSION_ID = 2, -}; - -autoreply define l2tpv3_set_lookup_key -{ - u32 client_index; - u32 context; - vl_api_l2t_lookup_key_t key; -}; - -/* - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/l2tp.c b/src/vnet/l2tp/l2tp.c deleted file mode 100644 index fa112ee7986..00000000000 --- a/src/vnet/l2tp/l2tp.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * l2tp.c : L2TPv3 tunnel support - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vppinfra/error.h> -#include <vppinfra/hash.h> -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/l2/l2_input.h> -#include <vnet/ethernet/ethernet.h> -#include <vnet/l2tp/l2tp.h> - -l2t_main_t l2t_main; - -/* packet trace format function */ -u8 * -format_l2t_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 *); - l2t_trace_t *t = va_arg (*args, l2t_trace_t *); - - if (t->is_user_to_network) - s = format (s, "L2T: %U (client) -> %U (our) session %d", - format_ip6_address, &t->client_address, - format_ip6_address, &t->our_address, t->session_index); - else - s = format (s, "L2T: %U (our) -> %U (client) session %d)", - format_ip6_address, &t->our_address, - format_ip6_address, &t->client_address, t->session_index); - return s; -} - -u8 * -format_l2t_session (u8 * s, va_list * args) -{ - l2t_session_t *session = va_arg (*args, l2t_session_t *); - l2t_main_t *lm = &l2t_main; - u32 counter_index; - vlib_counter_t v; - - s = format (s, "[%d] %U (our) %U (client) %U (sw_if_index %d)\n", - session - lm->sessions, - format_ip6_address, &session->our_address, - format_ip6_address, &session->client_address, - format_vnet_sw_interface_name, lm->vnet_main, - vnet_get_sw_interface (lm->vnet_main, session->sw_if_index), - session->sw_if_index); - - s = format (s, " local cookies %016llx %016llx remote cookie %016llx\n", - clib_net_to_host_u64 (session->local_cookie[0]), - clib_net_to_host_u64 (session->local_cookie[1]), - clib_net_to_host_u64 (session->remote_cookie)); - - s = format (s, " local session-id %d remote session-id %d\n", - clib_net_to_host_u32 (session->local_session_id), - clib_net_to_host_u32 (session->remote_session_id)); - - s = format (s, " l2 specific sublayer %s\n", - session->l2_sublayer_present ? "preset" : "absent"); - - counter_index = - session_index_to_counter_index (session - lm->sessions, - SESSION_COUNTER_USER_TO_NETWORK); - - vlib_get_combined_counter (&lm->counter_main, counter_index, &v); - if (v.packets != 0) - s = format (s, " user-to-net: %llu pkts %llu bytes\n", - v.packets, v.bytes); - - vlib_get_combined_counter (&lm->counter_main, counter_index + 1, &v); - - if (v.packets != 0) - s = format (s, " net-to-user: %llu pkts %llu bytes\n", - v.packets, v.bytes); - return s; -} - -static clib_error_t * -show_l2tp_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - l2t_session_t *session; - l2t_main_t *lm = &l2t_main; - char *keystr = 0; - int verbose = 0; - - if (unformat (input, "verbose") || unformat (input, "v")) - verbose = 1; - - if (pool_elts (lm->sessions) == 0) - vlib_cli_output (vm, "No l2tp sessions..."); - else - vlib_cli_output (vm, "%u l2tp sessions...", pool_elts (lm->sessions)); - - if (verbose) - { - switch (lm->lookup_type) - { - case L2T_LOOKUP_SRC_ADDRESS: - keystr = "src address"; - break; - - case L2T_LOOKUP_DST_ADDRESS: - keystr = "dst address"; - break; - - case L2T_LOOKUP_SESSION_ID: - keystr = "session id"; - break; - - default: - keystr = "BOGUS!"; - break; - } - - vlib_cli_output (vm, "L2tp session lookup on %s", keystr); - - /* *INDENT-OFF* */ - pool_foreach (session, lm->sessions, - ({ - vlib_cli_output (vm, "%U", format_l2t_session, session); - })); - /* *INDENT-ON* */ - } - - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_session_detail_command, static) = { - .path = "show l2tpv3", - .short_help = "show l2tpv3 [verbose]", - .function = show_l2tp_command_fn, -}; -/* *INDENT-ON* */ - -static clib_error_t * -test_counters_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - l2t_session_t *session; - l2t_main_t *lm = &l2t_main; - u32 session_index; - u32 counter_index; - u32 nincr = 0; - u32 thread_index = vm->thread_index; - - /* *INDENT-OFF* */ - pool_foreach (session, lm->sessions, - ({ - session_index = session - lm->sessions; - counter_index = - session_index_to_counter_index (session_index, - SESSION_COUNTER_USER_TO_NETWORK); - vlib_increment_combined_counter (&lm->counter_main, - thread_index, - counter_index, - 1/*pkt*/, 1111 /*bytes*/); - vlib_increment_combined_counter (&lm->counter_main, - thread_index, - counter_index+1, - 1/*pkt*/, 2222 /*bytes*/); - nincr++; - - })); - /* *INDENT-ON* */ - vlib_cli_output (vm, "Incremented %d active counters\n", nincr); - - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (test_counters_command, static) = { - .path = "test lt2p counters", - .short_help = "increment all active counters", - .function = test_counters_command_fn, -}; -/* *INDENT-ON* */ - -static clib_error_t * -clear_counters_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - l2t_session_t *session; - l2t_main_t *lm = &l2t_main; - u32 session_index; - u32 counter_index; - u32 nincr = 0; - - /* *INDENT-OFF* */ - pool_foreach (session, lm->sessions, - ({ - session_index = session - lm->sessions; - counter_index = - session_index_to_counter_index (session_index, - SESSION_COUNTER_USER_TO_NETWORK); - vlib_zero_combined_counter (&lm->counter_main, counter_index); - vlib_zero_combined_counter (&lm->counter_main, counter_index+1); - nincr++; - })); - /* *INDENT-ON* */ - vlib_cli_output (vm, "Cleared %d active counters\n", nincr); - - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (clear_counters_command, static) = { - .path = "clear l2tp counters", - .short_help = "clear all active counters", - .function = clear_counters_command_fn, -}; -/* *INDENT-ON* */ - -static u8 * -format_l2tpv3_name (u8 * s, va_list * args) -{ - l2t_main_t *lm = &l2t_main; - u32 i = va_arg (*args, u32); - u32 show_dev_instance = ~0; - - if (i < vec_len (lm->dev_inst_by_real)) - show_dev_instance = lm->dev_inst_by_real[i]; - - if (show_dev_instance != ~0) - i = show_dev_instance; - - return format (s, "l2tpv3_tunnel%d", i); -} - -static int -l2tpv3_name_renumber (vnet_hw_interface_t * hi, u32 new_dev_instance) -{ - l2t_main_t *lm = &l2t_main; - - vec_validate_init_empty (lm->dev_inst_by_real, hi->dev_instance, ~0); - - lm->dev_inst_by_real[hi->dev_instance] = new_dev_instance; - - return 0; -} - -/* *INDENT-OFF* */ -VNET_DEVICE_CLASS (l2tpv3_device_class,static) = { - .name = "L2TPv3", - .format_device_name = format_l2tpv3_name, - .name_renumber = l2tpv3_name_renumber, -}; -/* *INDENT-ON* */ - -static u8 * -format_l2tp_header_with_length (u8 * s, va_list * args) -{ - u32 dev_instance = va_arg (*args, u32); - s = format (s, "unimplemented dev %u", dev_instance); - return s; -} - -/* *INDENT-OFF* */ -VNET_HW_INTERFACE_CLASS (l2tpv3_hw_class) = { - .name = "L2TPV3", - .format_header = format_l2tp_header_with_length, - .build_rewrite = default_build_rewrite, - .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P, -}; -/* *INDENT-ON* */ - -int -create_l2tpv3_ipv6_tunnel (l2t_main_t * lm, - ip6_address_t * client_address, - ip6_address_t * our_address, - u32 local_session_id, - u32 remote_session_id, - u64 local_cookie, - u64 remote_cookie, - int l2_sublayer_present, - u32 encap_fib_index, u32 * sw_if_index) -{ - l2t_session_t *s = 0; - vnet_main_t *vnm = lm->vnet_main; - vnet_hw_interface_t *hi; - uword *p = (uword *) ~ 0; - u32 hw_if_index; - l2tpv3_header_t l2tp_hdr; - ip6_address_t *dst_address_copy, *src_address_copy; - u32 counter_index; - - remote_session_id = clib_host_to_net_u32 (remote_session_id); - local_session_id = clib_host_to_net_u32 (local_session_id); - - switch (lm->lookup_type) - { - case L2T_LOOKUP_SRC_ADDRESS: - p = hash_get_mem (lm->session_by_src_address, client_address); - break; - - case L2T_LOOKUP_DST_ADDRESS: - p = hash_get_mem (lm->session_by_dst_address, our_address); - break; - - case L2T_LOOKUP_SESSION_ID: - p = hash_get (lm->session_by_session_id, local_session_id); - break; - - default: - ASSERT (0); - } - - /* adding a session: session must not already exist */ - if (p) - return VNET_API_ERROR_INVALID_VALUE; - - pool_get (lm->sessions, s); - clib_memset (s, 0, sizeof (*s)); - clib_memcpy (&s->our_address, our_address, sizeof (s->our_address)); - clib_memcpy (&s->client_address, client_address, - sizeof (s->client_address)); - s->local_cookie[0] = clib_host_to_net_u64 (local_cookie); - s->remote_cookie = clib_host_to_net_u64 (remote_cookie); - s->local_session_id = local_session_id; - s->remote_session_id = remote_session_id; - s->l2_sublayer_present = l2_sublayer_present; - /* precompute l2tp header size */ - s->l2tp_hdr_size = l2_sublayer_present ? - sizeof (l2tpv3_header_t) : - sizeof (l2tpv3_header_t) - sizeof (l2tp_hdr.l2_specific_sublayer); - s->admin_up = 0; - s->encap_fib_index = encap_fib_index; - - /* Setup hash table entries */ - switch (lm->lookup_type) - { - case L2T_LOOKUP_SRC_ADDRESS: - src_address_copy = clib_mem_alloc (sizeof (*src_address_copy)); - clib_memcpy (src_address_copy, client_address, - sizeof (*src_address_copy)); - hash_set_mem (lm->session_by_src_address, src_address_copy, - s - lm->sessions); - break; - case L2T_LOOKUP_DST_ADDRESS: - dst_address_copy = clib_mem_alloc (sizeof (*dst_address_copy)); - clib_memcpy (dst_address_copy, our_address, sizeof (*dst_address_copy)); - hash_set_mem (lm->session_by_dst_address, dst_address_copy, - s - lm->sessions); - break; - case L2T_LOOKUP_SESSION_ID: - hash_set (lm->session_by_session_id, local_session_id, - s - lm->sessions); - break; - - default: - ASSERT (0); - } - - /* validate counters */ - counter_index = - session_index_to_counter_index (s - lm->sessions, - SESSION_COUNTER_USER_TO_NETWORK); - vlib_validate_combined_counter (&lm->counter_main, counter_index); - vlib_validate_combined_counter (&lm->counter_main, counter_index + 1); - - if (vec_len (lm->free_l2tpv3_tunnel_hw_if_indices) > 0) - { - hw_if_index = lm->free_l2tpv3_tunnel_hw_if_indices - [vec_len (lm->free_l2tpv3_tunnel_hw_if_indices) - 1]; - _vec_len (lm->free_l2tpv3_tunnel_hw_if_indices) -= 1; - - hi = vnet_get_hw_interface (vnm, hw_if_index); - hi->dev_instance = s - lm->sessions; - hi->hw_instance = hi->dev_instance; - } - else - { - hw_if_index = vnet_register_interface - (vnm, l2tpv3_device_class.index, s - lm->sessions, - l2tpv3_hw_class.index, s - lm->sessions); - hi = vnet_get_hw_interface (vnm, hw_if_index); - hi->output_node_index = l2t_encap_node.index; - /* $$$$ initialize custom dispositions, if needed */ - } - - s->hw_if_index = hw_if_index; - s->sw_if_index = hi->sw_if_index; - - if (sw_if_index) - *sw_if_index = hi->sw_if_index; - - if (!lm->proto_registered) - { - ip6_register_protocol (IP_PROTOCOL_L2TP, l2t_decap_local_node.index); - lm->proto_registered = true; - } - - return 0; -} - -static clib_error_t * -create_l2tpv3_tunnel_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - ip6_address_t client_address, our_address; - unformat_input_t _line_input, *line_input = &_line_input; - l2t_main_t *lm = &l2t_main; - u64 local_cookie = (u64) ~ 0, remote_cookie = (u64) ~ 0; - u32 local_session_id = 1, remote_session_id = 1; - int our_address_set = 0, client_address_set = 0; - int l2_sublayer_present = 0; - int rv; - u32 sw_if_index; - u32 encap_fib_id = ~0; - u32 encap_fib_index = ~0; - clib_error_t *error = NULL; - - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "client %U", - unformat_ip6_address, &client_address)) - client_address_set = 1; - else if (unformat (line_input, "our %U", - unformat_ip6_address, &our_address)) - our_address_set = 1; - else if (unformat (line_input, "local-cookie %llx", &local_cookie)) - ; - else if (unformat (line_input, "remote-cookie %llx", &remote_cookie)) - ; - else if (unformat (line_input, "local-session-id %d", - &local_session_id)) - ; - else if (unformat (line_input, "remote-session-id %d", - &remote_session_id)) - ; - else if (unformat (line_input, "fib-id %d", &encap_fib_id)) - ; - else if (unformat (line_input, "l2-sublayer-present")) - l2_sublayer_present = 1; - else - { - error = clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - goto done; - } - } - - if (encap_fib_id != ~0) - { - uword *p; - ip6_main_t *im = &ip6_main; - if (!(p = hash_get (im->fib_index_by_table_id, encap_fib_id))) - { - error = clib_error_return (0, "No fib with id %d", encap_fib_id); - goto done; - } - encap_fib_index = p[0]; - } - else - { - encap_fib_index = ~0; - } - - if (our_address_set == 0) - { - error = clib_error_return (0, "our address not specified"); - goto done; - } - if (client_address_set == 0) - { - error = clib_error_return (0, "client address not specified"); - goto done; - } - - rv = create_l2tpv3_ipv6_tunnel (lm, &client_address, &our_address, - local_session_id, remote_session_id, - local_cookie, remote_cookie, - l2_sublayer_present, - encap_fib_index, &sw_if_index); - switch (rv) - { - case 0: - vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name, - vnet_get_main (), sw_if_index); - break; - case VNET_API_ERROR_INVALID_VALUE: - error = clib_error_return (0, "session already exists..."); - goto done; - - case VNET_API_ERROR_NO_SUCH_ENTRY: - error = clib_error_return (0, "session does not exist..."); - goto done; - - default: - error = clib_error_return (0, "l2tp_session_add_del returned %d", rv); - goto done; - } - -done: - unformat_free (line_input); - - return error; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (create_l2tpv3_tunnel_command, static) = -{ - .path = "create l2tpv3 tunnel", - .short_help = - "create l2tpv3 tunnel client <ip6> our <ip6> local-cookie <hex> remote-cookie <hex> local-session <dec> remote-session <dec>", - .function = create_l2tpv3_tunnel_command_fn, -}; -/* *INDENT-ON* */ - -int -l2tpv3_set_tunnel_cookies (l2t_main_t * lm, - u32 sw_if_index, - u64 new_local_cookie, u64 new_remote_cookie) -{ - l2t_session_t *s; - vnet_hw_interface_t *hi; - vnet_main_t *vnm = vnet_get_main (); - hi = vnet_get_sup_hw_interface (vnm, sw_if_index); - - if (pool_is_free_index (lm->sessions, hi->dev_instance)) - return VNET_API_ERROR_INVALID_VALUE; - - s = pool_elt_at_index (lm->sessions, hi->dev_instance); - - s->local_cookie[1] = s->local_cookie[0]; - s->local_cookie[0] = clib_host_to_net_u64 (new_local_cookie); - s->remote_cookie = clib_host_to_net_u64 (new_remote_cookie); - - return 0; -} - - -static clib_error_t * -set_l2tp_tunnel_cookie_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - l2t_main_t *lm = &l2t_main; - vnet_main_t *vnm = vnet_get_main (); - u32 sw_if_index = ~0; - u64 local_cookie = (u64) ~ 0, remote_cookie = (u64) ~ 0; - - int rv; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, - &sw_if_index)) - ; - else if (unformat (input, "local %llx", &local_cookie)) - ; - else if (unformat (input, "remote %llx", &remote_cookie)) - ; - else - break; - } - if (sw_if_index == ~0) - return clib_error_return (0, "unknown interface"); - if (local_cookie == ~0) - return clib_error_return (0, "local cookie required"); - if (remote_cookie == ~0) - return clib_error_return (0, "remote cookie required"); - - rv = l2tpv3_set_tunnel_cookies (lm, sw_if_index, - local_cookie, remote_cookie); - - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_INVALID_SW_IF_INDEX: - return clib_error_return (0, "invalid interface"); - - default: - return clib_error_return (0, "l2tp_session_set_cookies returned %d", - rv); - } - - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (set_l2tp_tunnel_cookie_command, static) = -{ - .path = "set l2tpv3 tunnel cookie", - .short_help = - "set l2tpv3 tunnel cookie <intfc> local <hex> remote <hex>", - .function = set_l2tp_tunnel_cookie_command_fn, -}; -/* *INDENT-ON* */ - -int -l2tpv3_interface_enable_disable (vnet_main_t * vnm, - u32 sw_if_index, int enable_disable) -{ - - if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) - return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - vnet_feature_enable_disable ("ip6-unicast", "l2tp-decap", sw_if_index, - enable_disable, 0, 0); - return 0; -} - -/* Enable/disable L2TPv3 intercept on IP6 forwarding path */ -static clib_error_t * -set_ip6_l2tpv3 (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - u32 sw_if_index = ~0; - int is_add = 1; - int rv; - vnet_main_t *vnm = vnet_get_main (); - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, - &sw_if_index)) - ; - else if (unformat (input, "del")) - is_add = 0; - else - break; - } - - if (sw_if_index == ~0) - return clib_error_return (0, "interface required"); - - rv = l2tpv3_interface_enable_disable (vnm, sw_if_index, is_add); - - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_INVALID_SW_IF_INDEX: - return clib_error_return (0, "invalid interface"); - - default: - return clib_error_return (0, - "l2tp_interface_enable_disable returned %d", - rv); - } - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (set_interface_ip6_l2tpv3, static) = -{ - .path = "set interface ip6 l2tpv3", - .function = set_ip6_l2tpv3, - .short_help = "set interface ip6 l2tpv3 <intfc> [del]", -}; -/* *INDENT-ON* */ - -static clib_error_t * -l2tp_config (vlib_main_t * vm, unformat_input_t * input) -{ - l2t_main_t *lm = &l2t_main; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "lookup-v6-src")) - lm->lookup_type = L2T_LOOKUP_SRC_ADDRESS; - else if (unformat (input, "lookup-v6-dst")) - lm->lookup_type = L2T_LOOKUP_DST_ADDRESS; - else if (unformat (input, "lookup-session-id")) - lm->lookup_type = L2T_LOOKUP_SESSION_ID; - else - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); - } - return 0; -} - -VLIB_CONFIG_FUNCTION (l2tp_config, "l2tp"); - - -clib_error_t * -l2tp_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags) -{ - l2t_main_t *lm = &l2t_main; - vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); - if (hi->hw_class_index != l2tpv3_hw_class.index) - return 0; - - u32 session_index = hi->dev_instance; - l2t_session_t *s = pool_elt_at_index (lm->sessions, session_index); - s->admin_up = ! !(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP); - return 0; -} - -VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (l2tp_sw_interface_up_down); - -clib_error_t * -l2tp_init (vlib_main_t * vm) -{ - l2t_main_t *lm = &l2t_main; - ip_main_t *im = &ip_main; - ip_protocol_info_t *pi; - - lm->vnet_main = vnet_get_main (); - lm->vlib_main = vm; - lm->lookup_type = L2T_LOOKUP_DST_ADDRESS; - - lm->session_by_src_address = hash_create_mem - (0, sizeof (ip6_address_t) /* key bytes */ , - sizeof (u32) /* value bytes */ ); - lm->session_by_dst_address = hash_create_mem - (0, sizeof (ip6_address_t) /* key bytes */ , - sizeof (u32) /* value bytes */ ); - lm->session_by_session_id = hash_create (0, sizeof (uword)); - - pi = ip_get_protocol_info (im, IP_PROTOCOL_L2TP); - pi->unformat_pg_edit = unformat_pg_l2tp_header; - - lm->proto_registered = false; - - /* insure these nodes are included in build */ - l2tp_encap_init (vm); - - return 0; -} - -VLIB_INIT_FUNCTION (l2tp_init); - -clib_error_t * -l2tp_worker_init (vlib_main_t * vm) -{ - l2tp_encap_init (vm); - - return 0; -} - -VLIB_WORKER_INIT_FUNCTION (l2tp_worker_init); - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/l2tp.h b/src/vnet/l2tp/l2tp.h deleted file mode 100644 index 49873380057..00000000000 --- a/src/vnet/l2tp/l2tp.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * l2tp.h : L2TPv3 tunnel support - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __included_l2tp_h__ -#define __included_l2tp_h__ - -#include <vlib/vlib.h> -#include <vnet/ip/ip.h> -#include <vnet/l2tp/packet.h> - -typedef struct -{ - /* ip6 addresses */ - ip6_address_t our_address; - ip6_address_t client_address; - - /* l2tpv3 header parameters */ - u64 local_cookie[2]; - u64 remote_cookie; - u32 local_session_id; - u32 remote_session_id; - - /* tunnel interface */ - u32 hw_if_index; - u32 sw_if_index; - - /* fib index used for outgoing encapsulated packets */ - u32 encap_fib_index; - - u8 l2tp_hdr_size; - u8 l2_sublayer_present; - u8 cookie_flags; /* in host byte order */ - - u8 admin_up; -} l2t_session_t; - -typedef enum -{ - L2T_LOOKUP_SRC_ADDRESS = 0, - L2T_LOOKUP_DST_ADDRESS, - L2T_LOOKUP_SESSION_ID, -} ip6_to_l2_lookup_t; - -typedef struct -{ - /* session pool */ - l2t_session_t *sessions; - - /* ip6 -> l2 hash tables. Make up your minds, people... */ - uword *session_by_src_address; - uword *session_by_dst_address; - uword *session_by_session_id; - - ip6_to_l2_lookup_t lookup_type; - - /* Counters */ - vlib_combined_counter_main_t counter_main; - - /* vector of free l2tpv3 tunnel interfaces */ - u32 *free_l2tpv3_tunnel_hw_if_indices; - - /* show device instance by real device instance */ - u32 *dev_inst_by_real; - - /* convenience */ - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; - - bool proto_registered; - -} l2t_main_t; - -/* Packet trace structure */ -typedef struct -{ - int is_user_to_network; - u32 session_index; - ip6_address_t our_address; - ip6_address_t client_address; -} l2t_trace_t; - -extern l2t_main_t l2t_main; -extern vlib_node_registration_t l2t_encap_node; -extern vlib_node_registration_t l2t_decap_node; -extern vlib_node_registration_t l2t_decap_local_node; - -enum -{ - SESSION_COUNTER_USER_TO_NETWORK = 0, - SESSION_COUNTER_NETWORK_TO_USER, -}; - -static inline u32 -session_index_to_counter_index (u32 session_index, u32 counter_id) -{ - return ((session_index << 1) + counter_id); -} - -u8 *format_l2t_trace (u8 * s, va_list * args); - -typedef struct -{ - /* Any per-interface config would go here */ -} ip6_l2tpv3_config_t; - -uword unformat_pg_l2tp_header (unformat_input_t * input, va_list * args); - -void l2tp_encap_init (vlib_main_t * vm); -int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm, - ip6_address_t * client_address, - ip6_address_t * our_address, - u32 local_session_id, - u32 remote_session_id, - u64 local_cookie, - u64 remote_cookie, - int l2_sublayer_present, - u32 encap_fib_index, u32 * sw_if_index); - -int l2tpv3_set_tunnel_cookies (l2t_main_t * lm, - u32 sw_if_index, - u64 new_local_cookie, u64 new_remote_cookie); - -int l2tpv3_interface_enable_disable (vnet_main_t * vnm, - u32 sw_if_index, int enable_disable); - -#endif /* __included_l2tp_h__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/l2tp_api.c b/src/vnet/l2tp/l2tp_api.c deleted file mode 100644 index 3a31372253f..00000000000 --- a/src/vnet/l2tp/l2tp_api.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - *------------------------------------------------------------------ - * l2tp_api.c - l2tpv3 api - * - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------ - */ - -#include <vnet/vnet.h> -#include <vlibmemory/api.h> - -#include <vnet/interface.h> -#include <vnet/api_errno.h> -#include <vnet/l2tp/l2tp.h> -#include <vnet/ip/ip_types_api.h> - -#include <vnet/vnet_msg_enum.h> - -#define vl_typedefs /* define message structures */ -#include <vnet/vnet_all_api_h.h> -#undef vl_typedefs - -#define vl_endianfun /* define message structures */ -#include <vnet/vnet_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define vl_printfun -#include <vnet/vnet_all_api_h.h> -#undef vl_printfun - -#include <vlibapi/api_helper_macros.h> - -#define foreach_vpe_api_msg \ -_(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel) \ -_(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies) \ -_(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable) \ -_(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key) \ -_(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump) - -static void -send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am, - vl_api_registration_t * reg, - l2t_session_t * s, - l2t_main_t * lm, u32 context) -{ - vl_api_sw_if_l2tpv3_tunnel_details_t *mp; - u8 *if_name = NULL; - vnet_sw_interface_t *si = NULL; - - si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index); - - if_name = format (if_name, "%U", - format_vnet_sw_interface_name, lm->vnet_main, si); - - mp = vl_msg_api_alloc (sizeof (*mp)); - clib_memset (mp, 0, sizeof (*mp)); - mp->_vl_msg_id = ntohs (VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS); - strncpy ((char *) mp->interface_name, - (char *) if_name, ARRAY_LEN (mp->interface_name) - 1); - mp->sw_if_index = ntohl (si->sw_if_index); - mp->local_session_id = s->local_session_id; - mp->remote_session_id = s->remote_session_id; - mp->local_cookie[0] = s->local_cookie[0]; - mp->local_cookie[1] = s->local_cookie[1]; - mp->remote_cookie = s->remote_cookie; - ip_address_encode ((ip46_address_t *) & s->client_address, IP46_TYPE_IP6, - &mp->client_address); - ip_address_encode ((ip46_address_t *) & s->our_address, IP46_TYPE_IP6, - &mp->our_address); - mp->l2_sublayer_present = s->l2_sublayer_present; - mp->context = context; - - vl_api_send_msg (reg, (u8 *) mp); -} - - -static void -vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (vl_api_sw_if_l2tpv3_tunnel_dump_t * - mp) -{ - vpe_api_main_t *am = &vpe_api_main; - l2t_main_t *lm = &l2t_main; - vl_api_registration_t *reg; - l2t_session_t *session; - - reg = vl_api_client_index_to_registration (mp->client_index); - if (!reg) - return; - - /* *INDENT-OFF* */ - pool_foreach (session, lm->sessions, - ({ - send_sw_if_l2tpv3_tunnel_details (am, reg, session, lm, mp->context); - })); - /* *INDENT-ON* */ -} - -static void vl_api_l2tpv3_create_tunnel_t_handler - (vl_api_l2tpv3_create_tunnel_t * mp) -{ - vl_api_l2tpv3_create_tunnel_reply_t *rmp; - l2t_main_t *lm = &l2t_main; - u32 sw_if_index = (u32) ~ 0; - int rv; - ip46_address_t client, our; - - if (mp->our_address.af == ADDRESS_IP4) - { - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - - u32 encap_fib_index; - - if (mp->encap_vrf_id != ~0) - { - uword *p; - ip6_main_t *im = &ip6_main; - if (! - (p = - hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id)))) - { - rv = VNET_API_ERROR_NO_SUCH_FIB; - goto out; - } - encap_fib_index = p[0]; - } - else - { - encap_fib_index = ~0; - } - - ip_address_decode (&mp->client_address, &client); - ip_address_decode (&mp->our_address, &our); - - rv = create_l2tpv3_ipv6_tunnel (lm, - &client.ip6, - &our.ip6, - ntohl (mp->local_session_id), - ntohl (mp->remote_session_id), - clib_net_to_host_u64 (mp->local_cookie), - clib_net_to_host_u64 (mp->remote_cookie), - mp->l2_sublayer_present, - encap_fib_index, &sw_if_index); - -out: - /* *INDENT-OFF* */ - REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY, - ({ - rmp->sw_if_index = ntohl (sw_if_index); - })); - /* *INDENT-ON* */ -} - -static void vl_api_l2tpv3_set_tunnel_cookies_t_handler - (vl_api_l2tpv3_set_tunnel_cookies_t * mp) -{ - vl_api_l2tpv3_set_tunnel_cookies_reply_t *rmp; - l2t_main_t *lm = &l2t_main; - int rv; - - VALIDATE_SW_IF_INDEX (mp); - - rv = l2tpv3_set_tunnel_cookies (lm, ntohl (mp->sw_if_index), - clib_net_to_host_u64 (mp->new_local_cookie), - clib_net_to_host_u64 - (mp->new_remote_cookie)); - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY); -} - -static void vl_api_l2tpv3_interface_enable_disable_t_handler - (vl_api_l2tpv3_interface_enable_disable_t * mp) -{ - int rv; - vnet_main_t *vnm = vnet_get_main (); - vl_api_l2tpv3_interface_enable_disable_reply_t *rmp; - - VALIDATE_SW_IF_INDEX (mp); - - rv = l2tpv3_interface_enable_disable - (vnm, ntohl (mp->sw_if_index), mp->enable_disable); - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY); -} - -static void vl_api_l2tpv3_set_lookup_key_t_handler - (vl_api_l2tpv3_set_lookup_key_t * mp) -{ - int rv = 0; - l2t_main_t *lm = &l2t_main; - vl_api_l2tpv3_set_lookup_key_reply_t *rmp; - - if (mp->key > L2T_LOOKUP_KEY_API_SESSION_ID) - { - rv = VNET_API_ERROR_INVALID_VALUE; - goto out; - } - - lm->lookup_type = (ip6_to_l2_lookup_t) mp->key; - -out: - REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY); -} - -/* - * l2tp_api_hookup - * Add vpe's API message handlers to the table. - * vlib has already mapped shared memory and - * added the client registration handlers. - * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() - */ -#define vl_msg_name_crc_list -#include <vnet/vnet_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (api_main_t * am) -{ -#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); - foreach_vl_msg_name_crc_l2tp; -#undef _ -} - -static clib_error_t * -l2tp_api_hookup (vlib_main_t * vm) -{ - api_main_t *am = vlibapi_get_main (); - -#define _(N,n) \ - vl_msg_api_set_handlers(VL_API_##N, #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); - foreach_vpe_api_msg; -#undef _ - - /* - * Set up the (msg_name, crc, message-id) table - */ - setup_message_id_table (am); - - return 0; -} - -VLIB_API_INIT_FUNCTION (l2tp_api_hookup); - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/packet.h b/src/vnet/l2tp/packet.h deleted file mode 100644 index 66dfea2194c..00000000000 --- a/src/vnet/l2tp/packet.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * packet.h : L2TPv3 packet header format - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __included_l2tp_packet_h__ -#define __included_l2tp_packet_h__ - -/* - * See RFC4719 for packet format. - * Note: the l2_specific_sublayer is present in current Linux l2tpv3 - * tunnels. It is not present in IOS XR l2tpv3 tunnels. - * The Linux implementation is almost certainly wrong. - */ -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct -{ - u32 session_id; - u64 cookie; u32 - l2_specific_sublayer; /* set to 0 (if present) */ -}) l2tpv3_header_t; -/* *INDENT-ON* */ - -#endif /* __included_l2tp_packet_h__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/l2tp/pg.c b/src/vnet/l2tp/pg.c deleted file mode 100644 index 1e523d3bbb0..00000000000 --- a/src/vnet/l2tp/pg.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * pg.c: packet generator for L2TPv3 header - * - * Copyright (c) 2013 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vlib/vlib.h> -#include <vnet/pg/pg.h> -#include <vnet/l2tp/l2tp.h> - -typedef struct -{ - pg_edit_t session_id; - pg_edit_t cookie; -} pg_l2tp_header_t; - -typedef struct -{ - pg_edit_t l2_sublayer; -} pg_l2tp_header_l2_sublayer_t; - -static inline void -pg_l2tp_header_init (pg_l2tp_header_t * e) -{ - pg_edit_init (&e->session_id, l2tpv3_header_t, session_id); - pg_edit_init (&e->cookie, l2tpv3_header_t, cookie); -} - -uword -unformat_pg_l2tp_header (unformat_input_t * input, va_list * args) -{ - pg_stream_t *s = va_arg (*args, pg_stream_t *); - pg_l2tp_header_t *h; - u32 group_index, error; - vlib_main_t *vm = vlib_get_main (); - - h = pg_create_edit_group (s, sizeof (h[0]), - sizeof (l2tpv3_header_t) - sizeof (u32), - &group_index); - pg_l2tp_header_init (h); - - error = 1; - - /* session id and cookie are required */ - if (!unformat (input, "L2TP: session_id %U cookie %U", - unformat_pg_edit, unformat_pg_number, &h->session_id, - unformat_pg_edit, unformat_pg_number, &h->cookie)) - { - goto done; - } - - /* "l2_sublayer <value>" is optional */ - if (unformat (input, "l2_sublayer")) - { - pg_l2tp_header_l2_sublayer_t *h2; - - h2 = pg_add_edits (s, sizeof (h2[0]), sizeof (u32), group_index); - pg_edit_init (&h2->l2_sublayer, l2tpv3_header_t, l2_specific_sublayer); - if (!unformat_user (input, unformat_pg_edit, - unformat_pg_number, &h2->l2_sublayer)) - { - goto done; - } - } - - /* Parse an ethernet header if it is present */ - { - pg_node_t *pg_node = 0; - vlib_node_t *eth_lookup_node; - - eth_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ethernet-input"); - ASSERT (eth_lookup_node); - - pg_node = pg_get_node (eth_lookup_node->index); - - if (pg_node && pg_node->unformat_edit - && unformat_user (input, pg_node->unformat_edit, s)) - ; - } - - error = 0; - -done: - if (error) - pg_free_edit_group (s); - return error == 0; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |