From 08e0312fe2ecb10e10acf334c71440df7be95cac Mon Sep 17 00:00:00 2001 From: Pierre Pfister Date: Fri, 15 Jul 2016 09:19:39 +0100 Subject: [PATCH] L2TP: Add option for custom fib id for outgoing encapsulated packets If a custom fib ID is used (different from ~0), the associated fib is used to forward outgoing encapsulated packets. Otherwise, the fib used is the same as for any packet received on the original RX interface (L2TP does not modify RX interface index). Change-Id: I4533d5f7fa432c78c937d3acdd802d0d1c92a0c7 Signed-off-by: Pierre Pfister --- vnet/vnet/l2tp/encap.c | 5 ++--- vnet/vnet/l2tp/l2tp.c | 20 +++++++++++++++++++- vnet/vnet/l2tp/l2tp.h | 7 ++++--- vpp/vpp-api/api.c | 15 +++++++++++++++ vpp/vpp-api/vpe.api | 2 ++ 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/vnet/vnet/l2tp/encap.c b/vnet/vnet/l2tp/encap.c index 49f5a15fb5c..08d7015da39 100644 --- a/vnet/vnet/l2tp/encap.c +++ b/vnet/vnet/l2tp/encap.c @@ -112,9 +112,6 @@ static inline u32 last_stage (vlib_main_t *vm, vlib_node_runtime_t *node, if (vnet_buffer(b)->l2t.next_index != L2T_ENCAP_NEXT_IP6_LOOKUP) return vnet_buffer(b)->l2t.next_index; - /* clear so it is not interpreted as fib_index */ - vnet_buffer(b)->sw_if_index[VLIB_TX] = (u32)~0; - em->counters[node_counter_base_index + L2T_ENCAP_ERROR_NETWORK_TO_USER] += 1; session_index = vnet_buffer(b)->l2t.session_index; @@ -132,6 +129,8 @@ static inline u32 last_stage (vlib_main_t *vm, vlib_node_runtime_t *node, 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); diff --git a/vnet/vnet/l2tp/l2tp.c b/vnet/vnet/l2tp/l2tp.c index 85f9c30ed11..ebf317fe6db 100644 --- a/vnet/vnet/l2tp/l2tp.c +++ b/vnet/vnet/l2tp/l2tp.c @@ -296,7 +296,8 @@ int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm, u32 remote_session_id, u64 local_cookie, u64 remote_cookie, - int l2_sublayer_present, + int l2_sublayer_present, + u32 encap_fib_index, u32 * sw_if_index) { l2t_session_t *s = 0; @@ -346,6 +347,7 @@ int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm, 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) { @@ -420,6 +422,8 @@ create_l2tpv3_tunnel_command_fn (vlib_main_t * vm, int l2_sublayer_present = 0; int rv; u32 sw_if_index; + u32 encap_fib_id = ~0; + u32 encap_fib_index = ~0; /* Get a line of input. */ if (! unformat_user (input, unformat_line_input, line_input)) @@ -442,6 +446,9 @@ create_l2tpv3_tunnel_command_fn (vlib_main_t * vm, 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 @@ -451,6 +458,16 @@ create_l2tpv3_tunnel_command_fn (vlib_main_t * vm, unformat_free (line_input); + 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))) + return clib_error_return (0, "No fib with id %d", encap_fib_id); + encap_fib_index = p[0]; + } else { + encap_fib_index = ~0; + } + if (our_address_set == 0) return clib_error_return (0, "our address not specified"); if (client_address_set == 0) @@ -460,6 +477,7 @@ create_l2tpv3_tunnel_command_fn (vlib_main_t * vm, local_session_id, remote_session_id, local_cookie, remote_cookie, l2_sublayer_present, + encap_fib_index, &sw_if_index); switch(rv) { diff --git a/vnet/vnet/l2tp/l2tp.h b/vnet/vnet/l2tp/l2tp.h index 6ca9d7b6a9f..733cb61fb63 100644 --- a/vnet/vnet/l2tp/l2tp.h +++ b/vnet/vnet/l2tp/l2tp.h @@ -27,8 +27,6 @@ typedef struct { ip6_address_t our_address; ip6_address_t client_address; - /* $$$$ maybe add encap-path lookup fib ID? */ - /* l2tpv3 header parameters */ u64 local_cookie[2]; u64 remote_cookie; @@ -39,6 +37,8 @@ typedef struct { u32 hw_if_index; u32 sw_if_index; + u32 encap_fib_index; //fib index used for outgoing encapsulated packets + u8 l2tp_hdr_size; u8 l2_sublayer_present; u8 cookie_flags; /* in host byte order */ @@ -119,7 +119,8 @@ int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm, u32 remote_session_id, u64 local_cookie, u64 remote_cookie, - int l2_sublayer_present, + int l2_sublayer_present, + u32 encap_fib_index, u32 * sw_if_index); int l2tpv3_set_tunnel_cookies (l2t_main_t * lm, diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index f6b1b739251..6a5a152ea56 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -4329,6 +4329,20 @@ static void vl_api_l2tpv3_create_tunnel_t_handler 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; + } + rv = create_l2tpv3_ipv6_tunnel (lm, (ip6_address_t *) mp->client_address, (ip6_address_t *) mp->our_address, @@ -4337,6 +4351,7 @@ static void vl_api_l2tpv3_create_tunnel_t_handler 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: diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 25e6ebaacc9..841f3088ba4 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -1694,6 +1694,7 @@ define dhcp_proxy_config_2_reply { @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; @@ -1706,6 +1707,7 @@ define l2tpv3_create_tunnel { u64 local_cookie; u64 remote_cookie; u8 l2_sublayer_present; + u32 encap_vrf_id; }; /** \brief l2tpv3 tunnel interface create response -- 2.16.6