/*
 * Copyright (c) 2016 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 <vnet/lisp-cp/packets.h>
#include <vnet/lisp-cp/lisp_cp_messages.h>
#include <vnet/udp/udp_packet.h>

/* Returns IP ID for the packet */
/* static u16 ip_id = 0;
static inline u16
get_IP_ID()
{
    ip_id++;
    return (ip_id);
} */

u16
udp_ip4_checksum (const void *b, u32 len, u8 * src, u8 * dst)
{
  const u16 *buf = b;
  u16 *ip_src = (u16 *) src;
  u16 *ip_dst = (u16 *) dst;
  u32 length = len;
  u32 sum = 0;

  while (len > 1)
    {
      sum += *buf++;
      if (sum & 0x80000000)
	sum = (sum & 0xFFFF) + (sum >> 16);
      len -= 2;
    }

  /* Add the padding if the packet length is odd */
  if (len & 1)
    sum += *((u8 *) buf);

  /* Add the pseudo-header */
  sum += *(ip_src++);
  sum += *ip_src;

  sum += *(ip_dst++);
  sum += *ip_dst;

  sum += clib_host_to_net_u16 (IP_PROTOCOL_UDP);
  sum += clib_host_to_net_u16 (length);

  /* Add the carries */
  while (sum >> 16)
    sum = (sum & 0xFFFF) + (sum >> 16);

  /* Return the one's complement of sum */
  return ((u16) (~sum));
}

u16
udp_ip6_checksum (ip6_header_t * ip6, udp_header_t * up, u32 len)
{
  size_t i;
  register const u16 *sp;
  u32 sum;
  union
  {
    struct
    {
      ip6_address_t ph_src;
      ip6_address_t ph_dst;
      u32 ph_len;
      u8 ph_zero[3];
      u8 ph_nxt;
    } ph;
    u16 pa[20];
  } phu;

  /* pseudo-header */
  memset (&phu, 0, sizeof (phu));
  phu.ph.ph_src = ip6->src_address;
  phu.ph.ph_dst = ip6->dst_address;
  phu.ph.ph_len = clib_host_to_net_u32 (len);
  phu.ph.ph_nxt = IP_PROTOCOL_UDP;

  sum = 0;
  for (i = 0; i < sizeof (phu.pa) / sizeof (phu.pa[0]); i++)
    sum += phu.pa[i];

  sp = (const u16 *) up;

  for (i = 0; i < (len & ~1); i += 2)
    sum += *sp++;

  if (len & 1)
    sum += clib_host_to_net_u16 ((*(const u8 *) sp) << 8);

  while (sum > 0xffff)
    sum = (sum & 0xffff) + (sum >> 16);
  sum = ~sum & 0xffff;

  return (sum);
}

u16
udp_checksum (udp_header_t * uh, u32 udp_len, void *ih, u8 version)
{
  switch (version)
    {
    case IP4:
      return (udp_ip4_checksum (uh, udp_len,
				((ip4_header_t *) ih)->src_address.as_u8,
				((ip4_header_t *) ih)->dst_address.as_u8));
    case IP6:
      return (udp_ip6_checksum (ih, uh, udp_len));
    default:
      return ~0;
    }
}

void *
pkt_push_udp (vlib_main_t * vm, vlib_buffer_t * b, u16 sp, u16 dp)
{
  udp_header_t *uh;
  u16 udp_len = sizeof (udp_header_t) + vlib_buffer_length_in_chain (vm, b);

  uh = vlib_buffer_push_uninit (b, sizeof (*uh));

  uh->src_port = clib_host_to_net_u16 (sp);
  uh->dst_port = clib_host_to_net_u16 (dp);
  uh->length = clib_host_to_net_u16 (udp_len);
  uh->checksum = 0;
  return uh;
}

void *
pkt_push_ip (vlib_main_t * vm, vlib_buffer_t * b, ip_address_t * src,
	     ip_address_t * dst, u32 proto, u8 csum_offload)
{
  if (ip_addr_version (src) != ip_addr_version (dst))
    {
      clib_warning ("src %U and dst %U IP have different AFI! Discarding!",
		    format_ip_address, src, format_ip_address, dst);
      return 0;
    }

  switch (ip_addr_version (src))
    {
    case IP4:
      return vlib_buffer_push_ip4 (vm, b, &ip_addr_v4 (src),
				   &ip_addr_v4 (dst), proto, csum_offload);
      break;
    case IP6:
      return vlib_buffer_push_ip6 (vm, b, &ip_addr_v6 (src),
				   &ip_addr_v6 (dst), proto);
      break;
    }

  return 0;
}

void *
pkt_push_udp_and_ip (vlib_main_t * vm, vlib_buffer_t * b, u16 sp, u16 dp,
		     ip_address_t * sip, ip_address_t * dip, u8 csum_offload)
{
  u16 udpsum;
  udp_header_t *uh;
  void *ih;

  uh = pkt_push_udp (vm, b, sp, dp);

  if (csum_offload)
    {
      ih = pkt_push_ip (vm, b, sip, dip, IP_PROTOCOL_UDP, 1);
      b->flags |= VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
      vnet_buffer (b)->l3_hdr_offset = (u8 *) ih - b->data;
      vnet_buffer (b)->l4_hdr_offset = (u8 *) uh - b->data;
      uh->checksum = 0;
    }
  else
    {
      ih = pkt_push_ip (vm, b, sip, dip, IP_PROTOCOL_UDP, 0);
      udpsum = udp_checksum (uh, clib_net_to_host_u16 (uh->length), ih,
			     ip_addr_version (sip));
      if (udpsum == (u16) ~ 0)
	{
	  clib_warning ("Failed UDP checksum! Discarding");
	  return 0;
	}
      /* clear flags used for csum since we're not offloading */
      b->flags &= ~(VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_IS_IP6);
      uh->checksum = udpsum;
    }
  return ih;
}

void *
pkt_push_ecm_hdr (vlib_buffer_t * b)
{
  ecm_hdr_t *h;
  h = vlib_buffer_push_uninit (b, sizeof (h[0]));

  memset (h, 0, sizeof (h[0]));
  h->type = LISP_ENCAP_CONTROL_TYPE;
  memset (h->reserved2, 0, sizeof (h->reserved2));

  return h;
}

/* *INDENT-ON* */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
