
/*
 * Copyright (c) 2015 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/vxlan/vxlan.h>
#include <vnet/qos/qos_types.h>
#include <vnet/adj/rewrite.h>

/* Statistics (not all errors) */
#define foreach_vxlan_encap_error    \
_(ENCAPSULATED, "good packets encapsulated")

static char * vxlan_encap_error_strings[] = {
#define _(sym,string) string,
  foreach_vxlan_encap_error
#undef _
};

typedef enum {
#define _(sym,str) VXLAN_ENCAP_ERROR_##sym,
    foreach_vxlan_encap_error
#undef _
    VXLAN_ENCAP_N_ERROR,
} vxlan_encap_error_t;

typedef enum {
    VXLAN_ENCAP_NEXT_DROP,
    VXLAN_ENCAP_N_NEXT,
} vxlan_encap_next_t;

typedef struct {
  u32 tunnel_index;
  u32 vni;
} vxlan_encap_trace_t;

#ifndef CLIB_MARCH_VARIANT
u8 * format_vxlan_encap_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 *);
  vxlan_encap_trace_t * t 
      = va_arg (*args, vxlan_encap_trace_t *);

  s = format (s, "VXLAN encap to vxlan_tunnel%d vni %d", 
	      t->tunnel_index, t->vni);
  return s;
}
#endif

always_inline uword
vxlan_encap_inline (vlib_main_t * vm,
		    vlib_node_runtime_t * node,
		    vlib_frame_t * from_frame,
		    u8 is_ip4, u8 csum_offload)
{
  u32 n_left_from, next_index, * from, * to_next;
  vxlan_main_t * vxm = &vxlan_main;
  vnet_main_t * vnm = vxm->vnet_main;
  vnet_interface_main_t * im = &vnm->interface_main;
  vlib_combined_counter_main_t * tx_counter = 
      im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX;
  u32 pkts_encapsulated = 0;
  u32 thread_index = vlib_get_thread_index();
  u32 sw_if_index0 = 0, sw_if_index1 = 0;
  u32 next0 = 0, next1 = 0;
  vxlan_tunnel_t * t0 = NULL, * t1 = NULL;
  index_t dpoi_idx0 = INDEX_INVALID, dpoi_idx1 = INDEX_INVALID;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  STATIC_ASSERT_SIZEOF(ip6_vxlan_header_t, 56);
  STATIC_ASSERT_SIZEOF(ip4_vxlan_header_t, 36);

  u8 const underlay_hdr_len = is_ip4 ?
    sizeof(ip4_vxlan_header_t) : sizeof(ip6_vxlan_header_t);
  u16 const l3_len = is_ip4 ? sizeof(ip4_header_t) : sizeof(ip6_header_t);
  u32 const csum_flags = is_ip4 ?
    VNET_BUFFER_F_OFFLOAD_IP_CKSUM | VNET_BUFFER_F_IS_IP4 |
    VNET_BUFFER_F_OFFLOAD_UDP_CKSUM :
    VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index,
			   to_next, n_left_to_next);

      while (n_left_from >= 4 && n_left_to_next >= 2)
	{
	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t * p2, * p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);

	    CLIB_PREFETCH (p2->data - CLIB_CACHE_LINE_BYTES, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	    CLIB_PREFETCH (p3->data - CLIB_CACHE_LINE_BYTES, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	  }

	  u32 bi0 = to_next[0] = from[0];
	  u32 bi1 = to_next[1] = from[1];
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;

	  vlib_buffer_t * b0 = vlib_get_buffer (vm, bi0);
	  vlib_buffer_t * b1 = vlib_get_buffer (vm, bi1);
          u32 flow_hash0 = vnet_l2_compute_flow_hash (b0);
          u32 flow_hash1 = vnet_l2_compute_flow_hash (b1);

	  /* Get next node index and adj index from tunnel next_dpo */
	  if (sw_if_index0 != vnet_buffer(b0)->sw_if_index[VLIB_TX])
	    {
	      sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX];
	      vnet_hw_interface_t *hi0 = 
		  vnet_get_sup_hw_interface (vnm, sw_if_index0);
	      t0 = &vxm->tunnels[hi0->dev_instance];
	      /* Note: change to always set next0 if it may set to drop */
	      next0 = t0->next_dpo.dpoi_next_node;
	      dpoi_idx0 = t0->next_dpo.dpoi_index;
	    }

	  /* Get next node index and adj index from tunnel next_dpo */
	  if (sw_if_index1 != vnet_buffer(b1)->sw_if_index[VLIB_TX])
	    {
	      if (sw_if_index0 == vnet_buffer(b1)->sw_if_index[VLIB_TX])
	        {
		  sw_if_index1 = sw_if_index0;
		  t1 = t0;
		  next1 = next0;
		  dpoi_idx1 = dpoi_idx0;
	        }
	      else
	        {
		  sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_TX];
		  vnet_hw_interface_t *hi1 = 
		      vnet_get_sup_hw_interface (vnm, sw_if_index1);
		  t1 = &vxm->tunnels[hi1->dev_instance];
		  /* Note: change to always set next1 if it may set to drop */
		  next1 = t1->next_dpo.dpoi_next_node;
		  dpoi_idx1 = t1->next_dpo.dpoi_index;
	        }
	    }

          vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpoi_idx0;
          vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpoi_idx1;

          ASSERT(t0->rewrite_header.data_bytes == underlay_hdr_len);
          ASSERT(t1->rewrite_header.data_bytes == underlay_hdr_len);
          vnet_rewrite_two_headers(*t0, *t1, vlib_buffer_get_current(b0), vlib_buffer_get_current(b1), underlay_hdr_len);

          vlib_buffer_advance (b0, -underlay_hdr_len);
          vlib_buffer_advance (b1, -underlay_hdr_len);

 	  u32 len0 = vlib_buffer_length_in_chain (vm, b0);
 	  u32 len1 = vlib_buffer_length_in_chain (vm, b1);
          u16 payload_l0 = clib_host_to_net_u16 (len0 - l3_len);
          u16 payload_l1 = clib_host_to_net_u16 (len1 - l3_len);

          void * underlay0 = vlib_buffer_get_current(b0);
          void * underlay1 = vlib_buffer_get_current(b1);

          ip4_header_t * ip4_0, * ip4_1;
	  qos_bits_t ip4_0_tos = 0, ip4_1_tos = 0;
          ip6_header_t * ip6_0, * ip6_1;
          udp_header_t * udp0, * udp1;
          u8 * l3_0, * l3_1;
	  if (is_ip4)
	    {
              ip4_vxlan_header_t * hdr0 = underlay0;
              ip4_vxlan_header_t * hdr1 = underlay1;

	      /* Fix the IP4 checksum and length */
	      ip4_0 = &hdr0->ip4;
	      ip4_1 = &hdr1->ip4;
              ip4_0->length = clib_host_to_net_u16 (len0);
              ip4_1->length = clib_host_to_net_u16 (len1);

	      if (PREDICT_FALSE (b0->flags & VNET_BUFFER_F_QOS_DATA_VALID))
	        {
		  ip4_0_tos = vnet_buffer2 (b0)->qos.bits;
		  ip4_0->tos = ip4_0_tos;
		}
	      if (PREDICT_FALSE (b1->flags & VNET_BUFFER_F_QOS_DATA_VALID))
	        {
		  ip4_1_tos = vnet_buffer2 (b1)->qos.bits;
		  ip4_1->tos = ip4_1_tos;
		}

              l3_0 = (u8 *)ip4_0;
              l3_1 = (u8 *)ip4_1;
	      udp0 = &hdr0->udp;
	      udp1 = &hdr1->udp;
	    }
	  else /* ipv6 */
	    {
              ip6_vxlan_header_t * hdr0 = underlay0;
              ip6_vxlan_header_t * hdr1 = underlay1;

	      /* Fix IP6 payload length */
              ip6_0 = &hdr0->ip6;
              ip6_1 = &hdr1->ip6;
	      ip6_0->payload_length = payload_l0;
	      ip6_1->payload_length = payload_l1;

              l3_0 = (u8 *)ip6_0;
              l3_1 = (u8 *)ip6_1;
              udp0 = &hdr0->udp;
              udp1 = &hdr1->udp;
	    }

          /* Fix UDP length  and set source port */
          udp0->length = payload_l0;
          udp0->src_port = flow_hash0;
          udp1->length = payload_l1;
          udp1->src_port = flow_hash1;

          if (csum_offload)
            {
              b0->flags |= csum_flags;
              vnet_buffer (b0)->l3_hdr_offset = l3_0 - b0->data;
              vnet_buffer (b0)->l4_hdr_offset = (u8 *) udp0 - b0->data;
              b1->flags |= csum_flags;
              vnet_buffer (b1)->l3_hdr_offset = l3_1 - b1->data;
              vnet_buffer (b1)->l4_hdr_offset = (u8 *) udp1 - b1->data;
            }
          /* IPv4 UDP checksum only if checksum offload is used */
          else if (is_ip4)
            {
              ip_csum_t sum0 = ip4_0->checksum;
              sum0 = ip_csum_update (sum0, 0, ip4_0->length, ip4_header_t,
                  length /* changed member */);
	      if (PREDICT_FALSE (ip4_0_tos))
	        {
		  sum0 = ip_csum_update (sum0, 0, ip4_0_tos, ip4_header_t,
		      tos /* changed member */);
		}
              ip4_0->checksum = ip_csum_fold (sum0);
              ip_csum_t sum1 = ip4_1->checksum;
              sum1 = ip_csum_update (sum1, 0, ip4_1->length, ip4_header_t,
                  length /* changed member */);
	      if (PREDICT_FALSE (ip4_1_tos))
	        {
		  sum1 = ip_csum_update (sum1, 0, ip4_1_tos, ip4_header_t,
		      tos /* changed member */);
		}
              ip4_1->checksum = ip_csum_fold (sum1);
            }
          /* IPv6 UDP checksum is mandatory */
          else
            {
              int bogus = 0;

              udp0->checksum = ip6_tcp_udp_icmp_compute_checksum
                (vm, b0, ip6_0, &bogus);
              ASSERT(bogus == 0);
              if (udp0->checksum == 0)
                udp0->checksum = 0xffff;
              udp1->checksum = ip6_tcp_udp_icmp_compute_checksum
                (vm, b1, ip6_1, &bogus);
              ASSERT(bogus == 0);
              if (udp1->checksum == 0)
                udp1->checksum = 0xffff;
            }

	if (sw_if_index0 == sw_if_index1)
	{
          vlib_increment_combined_counter (tx_counter, thread_index,
              sw_if_index0, 2, len0 + len1);
	}
	else
	{
          vlib_increment_combined_counter (tx_counter, thread_index,
              sw_if_index0, 1, len0);
          vlib_increment_combined_counter (tx_counter, thread_index,
              sw_if_index1, 1, len1);
	}
          pkts_encapsulated += 2;

	  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
            {
              vxlan_encap_trace_t *tr = 
                vlib_add_trace (vm, node, b0, sizeof (*tr));
              tr->tunnel_index = t0 - vxm->tunnels;
              tr->vni = t0->vni;
           }

          if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED)) 
            {
              vxlan_encap_trace_t *tr = 
                vlib_add_trace (vm, node, b1, sizeof (*tr));
              tr->tunnel_index = t1 - vxm->tunnels;
              tr->vni = t1->vni;
            }

	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0 = to_next[0] = from[0];
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  vlib_buffer_t * b0 = vlib_get_buffer (vm, bi0);
          u32 flow_hash0 = vnet_l2_compute_flow_hash(b0);

	  /* Get next node index and adj index from tunnel next_dpo */
	  if (sw_if_index0 != vnet_buffer(b0)->sw_if_index[VLIB_TX])
	    {
	      sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX];
	      vnet_hw_interface_t *hi0 = 
		  vnet_get_sup_hw_interface (vnm, sw_if_index0);
	      t0 = &vxm->tunnels[hi0->dev_instance];
	      /* Note: change to always set next0 if it may be set to drop */
	      next0 = t0->next_dpo.dpoi_next_node;
	      dpoi_idx0 = t0->next_dpo.dpoi_index;
	    }
	  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpoi_idx0;

          ASSERT(t0->rewrite_header.data_bytes == underlay_hdr_len);
          vnet_rewrite_one_header(*t0, vlib_buffer_get_current(b0), underlay_hdr_len);

          vlib_buffer_advance (b0, -underlay_hdr_len);
          void * underlay0 = vlib_buffer_get_current(b0);

 	  u32 len0 = vlib_buffer_length_in_chain (vm, b0);
          u16 payload_l0 = clib_host_to_net_u16 (len0 - l3_len);

          udp_header_t * udp0;
          ip4_header_t * ip4_0;
	  qos_bits_t ip4_0_tos = 0;
          ip6_header_t * ip6_0;
          u8 * l3_0;
	  if (is_ip4)
	    {
              ip4_vxlan_header_t * hdr = underlay0;

	      /* Fix the IP4 checksum and length */
              ip4_0 = &hdr->ip4;
              ip4_0->length = clib_host_to_net_u16 (len0);

	      if (PREDICT_FALSE (b0->flags & VNET_BUFFER_F_QOS_DATA_VALID))
	        {
		  ip4_0_tos = vnet_buffer2 (b0)->qos.bits;
		  ip4_0->tos = ip4_0_tos;
		}

              l3_0 = (u8*)ip4_0;
	      udp0 = &hdr->udp;
	    }
	  else /* ip6 path */
	    {
              ip6_vxlan_header_t * hdr = underlay0;

	      /* Fix IP6 payload length */
              ip6_0 = &hdr->ip6;
	      ip6_0->payload_length = payload_l0;

              l3_0 = (u8 *)ip6_0;
              udp0 = &hdr->udp;
	    }

          /* Fix UDP length  and set source port */
          udp0->length = payload_l0;
          udp0->src_port = flow_hash0;

          if (csum_offload)
            {
              b0->flags |= csum_flags;
              vnet_buffer (b0)->l3_hdr_offset = l3_0 - b0->data;
              vnet_buffer (b0)->l4_hdr_offset = (u8 *) udp0 - b0->data;
            }
          /* IPv4 UDP checksum only if checksum offload is used */
          else if (is_ip4)
            {
              ip_csum_t sum0 = ip4_0->checksum;
              sum0 = ip_csum_update (sum0, 0, ip4_0->length, ip4_header_t,
                  length /* changed member */);
	      if (PREDICT_FALSE (ip4_0_tos))
	        {
		  sum0 = ip_csum_update (sum0, 0, ip4_0_tos, ip4_header_t,
		      tos /* changed member */);
		}
              ip4_0->checksum = ip_csum_fold (sum0);
            }
          /* IPv6 UDP checksum is mandatory */
          else
            {
              int bogus = 0;

              udp0->checksum = ip6_tcp_udp_icmp_compute_checksum
                (vm, b0, ip6_0, &bogus);
              ASSERT(bogus == 0);
              if (udp0->checksum == 0)
                udp0->checksum = 0xffff;
            }

          vlib_increment_combined_counter (tx_counter, thread_index,
              sw_if_index0, 1, len0);
          pkts_encapsulated ++;

          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
            {
              vxlan_encap_trace_t *tr = 
                vlib_add_trace (vm, node, b0, sizeof (*tr));
              tr->tunnel_index = t0 - vxm->tunnels;
              tr->vni = t0->vni;
            }
	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  /* Do we still need this now that tunnel tx stats is kept? */
  vlib_node_increment_counter (vm, node->node_index, 
                               VXLAN_ENCAP_ERROR_ENCAPSULATED, 
                               pkts_encapsulated);

  return from_frame->n_vectors;
}

VLIB_NODE_FN (vxlan4_encap_node) (vlib_main_t * vm,
	      vlib_node_runtime_t * node,
	      vlib_frame_t * from_frame)
{
  /* Disable chksum offload as setup overhead in tx node is not worthwhile
     for ip4 header checksum only, unless udp checksum is also required */
  return vxlan_encap_inline (vm, node, from_frame, /* is_ip4 */ 1, 
			     /* csum_offload */ 0);
}

VLIB_NODE_FN (vxlan6_encap_node) (vlib_main_t * vm,
	      vlib_node_runtime_t * node,
	      vlib_frame_t * from_frame)
{
  /* Enable checksum offload for ip6 as udp checksum is mandatory, */
  return vxlan_encap_inline (vm, node, from_frame, /* is_ip4 */ 0, 
			     /* csum_offload */ 1);
}

VLIB_REGISTER_NODE (vxlan4_encap_node) = {
  .name = "vxlan4-encap",
  .vector_size = sizeof (u32),
  .format_trace = format_vxlan_encap_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,
  .n_errors = ARRAY_LEN(vxlan_encap_error_strings),
  .error_strings = vxlan_encap_error_strings,
  .n_next_nodes = VXLAN_ENCAP_N_NEXT,
  .next_nodes = {
        [VXLAN_ENCAP_NEXT_DROP] = "error-drop",
  },
};

VLIB_REGISTER_NODE (vxlan6_encap_node) = {
  .name = "vxlan6-encap",
  .vector_size = sizeof (u32),
  .format_trace = format_vxlan_encap_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,
  .n_errors = ARRAY_LEN(vxlan_encap_error_strings),
  .error_strings = vxlan_encap_error_strings,
  .n_next_nodes = VXLAN_ENCAP_N_NEXT,
  .next_nodes = {
        [VXLAN_ENCAP_NEXT_DROP] = "error-drop",
  },
};

