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