/*
 * 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 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 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;
}

static uword
dummy_interface_tx (vlib_main_t * vm,
		    vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  clib_warning ("you shouldn't be here, leaking buffers...");
  return frame->n_vectors;
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (l2tpv3_device_class,static) = {
  .name = "L2TPv3",
  .format_device_name = format_l2tpv3_name,
  .name_renumber = l2tpv3_name_renumber,
  .tx_function = dummy_interface_tx,
};
/* *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);
  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;

  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;

  /* insure these nodes are included in build */
  l2tp_encap_init (vm);
  l2tp_decap_init ();

  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:
 */
