/*
 * Copyright (c) 2017 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/ip/ip.h>
#include <vnet/fib/fib_table.h>

u32 ip_flow_hash_router_id;

ethernet_type_t
ip_address_family_to_ether_type (ip_address_family_t af)
{
  switch (af)
    {
    case AF_IP4:
      return (ETHERNET_TYPE_IP4);
    case AF_IP6:
      return (ETHERNET_TYPE_IP6);
    }
  ASSERT (0);
  return (ETHERNET_TYPE_IP4);
}

u8
ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
{
  if (is_ip4)
    return (ip46_address->ip4.as_u32 == 0);
  else
    return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
}

u8
ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
{
  if (is_ip4)
    return (ip46_address->ip4.as_u8[0] == 127);
  else
    return (ip46_address->as_u64[0] == 0 &&
	    clib_net_to_host_u64 (ip46_address->as_u64[1]) == 1);
}

u8
ip4_is_local_host (ip4_address_t * ip4_address)
{
  return (ip4_address->as_u8[0] == 127);
}

u8
ip6_is_local_host (ip6_address_t * ip6_address)
{
  return (ip6_address->as_u64[0] == 0 &&
	  clib_net_to_host_u64 (ip6_address->as_u64[1]) == 1);
}

/**
 * Checks that an ip is local to the requested fib
 */
u8
ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
{
  fib_node_index_t fei;
  fib_entry_flag_t flags;
  fib_prefix_t prefix;

  /* Check if requester is local */
  if (is_ip4)
    {
      prefix.fp_len = 32;
      prefix.fp_proto = FIB_PROTOCOL_IP4;
    }
  else
    {
      prefix.fp_len = 128;
      prefix.fp_proto = FIB_PROTOCOL_IP6;
    }

  clib_memcpy_fast (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
  fei = fib_table_lookup (fib_index, &prefix);
  flags = fib_entry_get_flags (fei);

  return (flags & FIB_ENTRY_FLAG_LOCAL);
}

void
ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
{
  if (is_ip4)
    {
      ip46_address_mask_ip4 (dst);
      dst->ip4.as_u32 = src->ip4.as_u32;
    }
  else
    clib_memcpy_fast (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
}

void
ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
{
  if (is_ip4)
    {
      ip46_address_mask_ip4 (dst);
      dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
    }
  else
    clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
		      sizeof (ip6_address_t));
}

static const char *ip_arc_names[N_IP_FEATURE_LOCATIONS][N_AF][N_SAFI] = {
  [IP_FEATURE_INPUT] = {
    [AF_IP4] = {
      [SAFI_UNICAST] = "ip4-unicast",
      [SAFI_MULTICAST] = "ip4-multicast",
    },
    [AF_IP6] = {
      [SAFI_UNICAST] = "ip6-unicast",
      [SAFI_MULTICAST] = "ip6-multicast",
    },
  },
  [IP_FEATURE_OUTPUT] = {
    [AF_IP4] = {
      [SAFI_UNICAST] = "ip4-output",
      [SAFI_MULTICAST] = "ip4-output",
    },
    [AF_IP6] = {
      [SAFI_UNICAST] = "ip6-output",
      [SAFI_MULTICAST] = "ip6-output",
    },
  },
  [IP_FEATURE_LOCAL] = {
    [AF_IP4] = {
      [SAFI_UNICAST] = "ip4-local",
      [SAFI_MULTICAST] = "ip4-local",
    },
    [AF_IP6] = {
      [SAFI_UNICAST] = "ip6-local",
      [SAFI_MULTICAST] = "ip6-local",
    },
  },
  [IP_FEATURE_PUNT] = {
    [AF_IP4] = {
      [SAFI_UNICAST] = "ip4-punt",
      [SAFI_MULTICAST] = "ip4-punt",
    },
    [AF_IP6] = {
      [SAFI_UNICAST] = "ip6-punt",
      [SAFI_MULTICAST] = "ip6-punt",
    },
  },
  [IP_FEATURE_DROP] = {
    [AF_IP4] = {
      [SAFI_UNICAST] = "ip4-drop",
      [SAFI_MULTICAST] = "ip4-drop",
    },
    [AF_IP6] = {
      [SAFI_UNICAST] = "ip6-drop",
      [SAFI_MULTICAST] = "ip6-drop",
    },
  },
};

void
ip_feature_enable_disable (ip_address_family_t af,
			   ip_sub_address_family_t safi,
			   ip_feature_location_t loc,
			   const char *feature_name,
			   u32 sw_if_index, int enable,
			   void *feature_config, u32 n_feature_config_bytes)
{
  if (IP_FEATURE_INPUT == loc)
    {
      if (N_SAFI == safi)
	FOR_EACH_IP_ADDRESS_SUB_FAMILY (safi)
	  vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
				       feature_name, sw_if_index,
				       enable, feature_config,
				       n_feature_config_bytes);
      else
	vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
				     feature_name, sw_if_index,
				     enable, feature_config,
				     n_feature_config_bytes);
    }
  else
    vnet_feature_enable_disable (ip_arc_names[loc][af][SAFI_UNICAST],
				 feature_name, sw_if_index,
				 enable, feature_config,
				 n_feature_config_bytes);
}

int
ip_flow_hash_set (ip_address_family_t af, u32 table_id,
		  flow_hash_config_t flow_hash_config)
{
  fib_protocol_t fproto;
  u32 fib_index;

  fproto = ip_address_family_to_fib_proto (af);
  fib_index = fib_table_find (fproto, table_id);

  if (~0 == fib_index)
    return VNET_API_ERROR_NO_SUCH_FIB;

  fib_table_set_flow_hash_config (fib_index, fproto, flow_hash_config);

  return 0;
}

void
ip_flow_hash_router_id_set (u32 router_id)
{
  ip_flow_hash_router_id = router_id;
}

u8 *
format_ip_address_family (u8 * s, va_list * args)
{
  ip_address_family_t af = va_arg (*args, int);	// int promo ip_address_family_t);

  switch (af)
    {
    case AF_IP4:
      return (format (s, "ip4"));
    case AF_IP6:
      return (format (s, "ip6"));
    }

  return (format (s, "unknown"));
}

uword
unformat_ip_address_family (unformat_input_t * input, va_list * args)
{
  ip_address_family_t *af = va_arg (*args, ip_address_family_t *);

  if (unformat (input, "ip4") || unformat (input, "ipv4") ||
      unformat (input, "IP4") || unformat (input, "IPv4"))
    {
      *af = AF_IP4;
      return (1);
    }
  else if (unformat (input, "ip6") || unformat (input, "ipv6") ||
	   unformat (input, "IP6") || unformat (input, "IPv6"))
    {
      *af = AF_IP6;
      return (1);
    }
  return (0);
}

u8 *
format_ip_sub_address_family (u8 * s, va_list * args)
{
  ip_sub_address_family_t safi = va_arg (*args, int);	// int promo ip_sub_address_family_t);

  switch (safi)
    {
    case SAFI_UNICAST:
      return (format (s, "unicast"));
    case SAFI_MULTICAST:
      return (format (s, "multicast"));
    }

  return (format (s, "unknown"));
}

uword
unformat_ip_sub_address_family (unformat_input_t * input, va_list * args)
{
  ip_sub_address_family_t *safi = va_arg (*args, ip_sub_address_family_t *);

  if (unformat (input, "unicast") || unformat (input, "uni"))
    {
      *safi = SAFI_UNICAST;
      return (1);
    }
  else if (unformat (input, "multicast") || unformat (input, "multi"))
    {
      *safi = SAFI_MULTICAST;
      return (1);
    }
  return (0);
}

u8 *
format_ip_dscp (u8 * s, va_list * va)
{
  ip_dscp_t dscp = va_arg (*va, u32);	// int promotion of u8

  switch (dscp)
    {
#define _(n,v)                                                  \
    case IP_DSCP_##v:                                           \
      return (format (s, "%s", #v));
      foreach_ip_dscp
#undef _
    }

  return (format (s, "unknown"));
}

uword
unformat_ip_dscp (unformat_input_t * input, va_list * args)
{
  ip_dscp_t *dscp = va_arg (*args, ip_dscp_t *);

  if (0)
    ;
#define _(n,v)                                                  \
  else if (unformat (input, #v))                                \
    *dscp = IP_DSCP_##v;
  foreach_ip_dscp
#undef _
    else
    return 0;

  return 1;
}

u8 *
format_ip_ecn (u8 * s, va_list * va)
{
  ip_ecn_t ecn = va_arg (*va, u32);	// int promotion of u8

  switch (ecn)
    {
#define _(n,v)                                                  \
    case IP_ECN_##v:                                           \
      return (format (s, "%s", #v));
      foreach_ip_ecn
#undef _
    }

  return (format (s, "unknown"));
}

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