L2TP: Add option for custom fib id for outgoing encapsulated packets
[vpp.git] / vnet / vnet / l2tp / l2tp.c
index 7dfbe15..ebf317f 100644 (file)
@@ -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;
@@ -345,6 +346,8 @@ int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm,
   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) {
@@ -402,9 +405,6 @@ int create_l2tpv3_ipv6_tunnel (l2t_main_t * lm,
   if (sw_if_index)
     *sw_if_index = hi->sw_if_index;
 
-  vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 
-                               VNET_SW_INTERFACE_FLAG_ADMIN_UP);
-
   return 0;
 }
 
@@ -422,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))
@@ -444,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 
@@ -453,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)
@@ -462,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)
     {
@@ -577,12 +593,12 @@ int l2tpv3_interface_enable_disable (vnet_main_t * vnm,
   ip_config_main_t * rx_cm = &lm->rx_config_mains[VNET_UNICAST];
   u32 ci;
   ip6_l2tpv3_config_t config;
-  ip6_rx_feature_type_t type;
+  u32 feature_index;
 
   if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
     return VNET_API_ERROR_INVALID_SW_IF_INDEX;
 
-  type = IP6_RX_FEATURE_L2TPV3;
+  feature_index = im->ip6_unicast_rx_feature_l2tp_decap;
 
   ci = rx_cm->config_index_by_sw_if_index[sw_if_index];
   ci = (enable_disable
@@ -590,7 +606,7 @@ int l2tpv3_interface_enable_disable (vnet_main_t * vnm,
         : vnet_config_del_feature)
     (vlib_get_main(), &rx_cm->config_main,
      ci,
-     type,
+     feature_index,
      &config,
      sizeof (config));
   rx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
@@ -665,6 +681,25 @@ l2tp_config (vlib_main_t * vm, unformat_input_t * input)
 
 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;