/** @file
 * @brief IPv6 related functions
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/* By default this prints too much data, set the value to 1 to see
 * neighbor cache contents.
 */
#define NET_DEBUG_NBR 0

#include <logging/log.h>
LOG_MODULE_REGISTER(net_ipv6, CONFIG_NET_IPV6_LOG_LEVEL);

#include <errno.h>
#include <stdlib.h>
#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/net_stats.h>
#include <net/net_context.h>
#include <net/net_mgmt.h>
#include "net_private.h"
#include "connection.h"
#include "icmpv6.h"
#include "udp_internal.h"
#include "tcp_internal.h"
#include "ipv6.h"
#include "nbr.h"
#include "6lo.h"
#include "route.h"
#include "net_stats.h"

/* Timeout value to be used when allocating net buffer during various
 * neighbor discovery procedures.
 */
#define ND_NET_BUF_TIMEOUT K_MSEC(100)

/* Timeout for various buffer allocations in this file. */
#define NET_BUF_TIMEOUT K_MSEC(50)

/* Maximum reachable time value specified in RFC 4861 section
 * 6.2.1. Router Configuration Variables, AdvReachableTime
 */
#define MAX_REACHABLE_TIME 3600000

/* IPv6 wildcard and loopback address defined by RFC2553 */
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;

const struct in6_addr *net_ipv6_unspecified_address(void)
{
	return &in6addr_any;
}

int net_ipv6_create(struct net_pkt *pkt,
		    const struct in6_addr *src,
		    const struct in6_addr *dst)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
	struct net_ipv6_hdr *ipv6_hdr;

	ipv6_hdr = (struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);
	if (!ipv6_hdr) {
		return -ENOBUFS;
	}

	ipv6_hdr->vtc     = 0x60;
	ipv6_hdr->tcflow  = 0;
	ipv6_hdr->flow    = 0;
	ipv6_hdr->len     = 0;
	ipv6_hdr->nexthdr = 0;

	/* User can tweak the default hop limit if needed */
	ipv6_hdr->hop_limit = net_pkt_ipv6_hop_limit(pkt);
	if (ipv6_hdr->hop_limit == 0) {
		ipv6_hdr->hop_limit =
			net_if_ipv6_get_hop_limit(net_pkt_iface(pkt));
	}

	net_ipaddr_copy(&ipv6_hdr->dst, dst);
	net_ipaddr_copy(&ipv6_hdr->src, src);

	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr));
	net_pkt_set_ipv6_ext_len(pkt, 0);

	return net_pkt_set_data(pkt, &ipv6_access);
}

int net_ipv6_finalize(struct net_pkt *pkt, u8_t next_header_proto)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
	struct net_ipv6_hdr *ipv6_hdr;

	net_pkt_set_overwrite(pkt, true);

	ipv6_hdr = (struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);
	if (!ipv6_hdr) {
		return -ENOBUFS;
	}

	ipv6_hdr->len = htons(net_pkt_get_len(pkt) -
			      sizeof(struct net_ipv6_hdr));

	if (net_pkt_ipv6_next_hdr(pkt) != 255) {
		ipv6_hdr->nexthdr = net_pkt_ipv6_next_hdr(pkt);
	} else {
		ipv6_hdr->nexthdr = next_header_proto;
	}

	net_pkt_set_data(pkt, &ipv6_access);

	if (net_pkt_ipv6_next_hdr(pkt) != 255 &&
	    net_pkt_skip(pkt, net_pkt_ipv6_ext_len(pkt))) {
		return -ENOBUFS;
	}

	if (IS_ENABLED(CONFIG_NET_UDP) &&
	    next_header_proto == IPPROTO_UDP) {
		return net_udp_finalize(pkt);
	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
		   next_header_proto == IPPROTO_TCP) {
		return net_tcp_finalize(pkt);
	} else if (next_header_proto == IPPROTO_ICMPV6) {
		return net_icmpv6_finalize(pkt);
	}

	return 0;
}

static inline bool ipv6_drop_on_unknown_option(struct net_pkt *pkt,
					       struct net_ipv6_hdr *hdr,
					       u8_t opt_type,
					       u16_t length)
{
	/* RFC 2460 chapter 4.2 tells how to handle the unknown
	 * options by the two highest order bits of the option:
	 *
	 * 00: Skip over this option and continue processing the header.
	 * 01: Discard the packet.
	 * 10: Discard the packet and, regardless of whether or not the
	 *     packet's Destination Address was a multicast address,
	 *     send an ICMP Parameter Problem, Code 2, message to the packet's
	 *     Source Address, pointing to the unrecognized Option Type.
	 * 11: Discard the packet and, only if the packet's Destination
	 *     Address was not a multicast address, send an ICMP Parameter
	 *     Problem, Code 2, message to the packet's Source Address,
	 *     pointing to the unrecognized Option Type.
	 */
	NET_DBG("Unknown option %d (0x%02x) MSB %d - 0x%02x",
		opt_type, opt_type, opt_type >> 6, opt_type & 0xc0);

	switch (opt_type & 0xc0) {
	case 0x00:
		return false;
	case 0x40:
		break;
	case 0xc0:
		if (net_ipv6_is_addr_mcast(&hdr->dst)) {
			break;
		}

		/* passthrough */
	case 0x80:
		net_icmpv6_send_error(pkt, NET_ICMPV6_PARAM_PROBLEM,
				      NET_ICMPV6_PARAM_PROB_OPTION,
				      (u32_t)length);
		break;
	}

	return true;
}

static inline int ipv6_handle_ext_hdr_options(struct net_pkt *pkt,
					      struct net_ipv6_hdr *hdr,
					      u16_t pkt_len)
{
	u16_t exthdr_len = 0U;
	u16_t length = 0U;

	if (net_pkt_read_u8(pkt, (u8_t *)&exthdr_len)) {
		return -ENOBUFS;
	}

	exthdr_len = exthdr_len * 8 + 8;
	if (exthdr_len > pkt_len) {
		NET_DBG("Corrupted packet, extension header %d too long "
			"(max %d bytes)", exthdr_len, pkt_len);
		return -EINVAL;
	}

	length += 2;

	while (length < exthdr_len) {
		u8_t opt_type, opt_len;

		/* Each extension option has type and length */
		if (net_pkt_read_u8(pkt, &opt_type)) {
			return -ENOBUFS;
		}

		if (opt_type != NET_IPV6_EXT_HDR_OPT_PAD1) {
			if (net_pkt_read_u8(pkt, &opt_len)) {
				return -ENOBUFS;
			}
		}

		switch (opt_type) {
		case NET_IPV6_EXT_HDR_OPT_PAD1:
			length++;
			break;
		case NET_IPV6_EXT_HDR_OPT_PADN:
			NET_DBG("PADN option");
			length += opt_len + 2;

			break;
		default:
			if (ipv6_drop_on_unknown_option(pkt, hdr,
							opt_type, length)) {
				return -ENOTSUP;
			}

			if (net_pkt_skip(pkt, opt_len)) {
				return -ENOBUFS;
			}

			length += opt_len + 2;

			break;
		}
	}

	return exthdr_len;
}

#if defined(CONFIG_NET_ROUTE)
static struct net_route_entry *add_route(struct net_if *iface,
					 struct in6_addr *addr,
					 u8_t prefix_len)
{
	struct net_route_entry *route;

	route = net_route_lookup(iface, addr);
	if (route) {
		return route;
	}

	route = net_route_add(iface, addr, prefix_len, addr);

	NET_DBG("%s route to %s/%d iface %p", route ? "Add" : "Cannot add",
		log_strdup(net_sprint_ipv6_addr(addr)), prefix_len, iface);

	return route;
}
#endif /* CONFIG_NET_ROUTE */

static void ipv6_no_route_info(struct net_pkt *pkt,
			       struct in6_addr *src,
			       struct in6_addr *dst)
{
	NET_DBG("Will not route pkt %p ll src %s to dst %s between interfaces",
		pkt, log_strdup(net_sprint_ipv6_addr(src)),
		log_strdup(net_sprint_ipv6_addr(dst)));
}

#if defined(CONFIG_NET_ROUTE)
static enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
					  struct net_ipv6_hdr *hdr)
{
	struct net_route_entry *route;
	struct in6_addr *nexthop;
	bool found;

	/* Check if the packet can be routed */
	if (IS_ENABLED(CONFIG_NET_ROUTING)) {
		found = net_route_get_info(NULL, &hdr->dst, &route,
					   &nexthop);
	} else {
		found = net_route_get_info(net_pkt_iface(pkt),
					   &hdr->dst, &route, &nexthop);
	}

	if (found) {
		int ret;

		if (IS_ENABLED(CONFIG_NET_ROUTING) &&
		    (net_ipv6_is_ll_addr(&hdr->src) ||
		     net_ipv6_is_ll_addr(&hdr->dst))) {
			/* RFC 4291 ch 2.5.6 */
			ipv6_no_route_info(pkt, &hdr->src, &hdr->dst);
			goto drop;
		}

		/* Used when detecting if the original link
		 * layer address length is changed or not.
		 */
		net_pkt_set_orig_iface(pkt, net_pkt_iface(pkt));

		if (route) {
			net_pkt_set_iface(pkt, route->iface);
		}

		if (IS_ENABLED(CONFIG_NET_ROUTING) &&
		    net_pkt_orig_iface(pkt) != net_pkt_iface(pkt)) {
			/* If the route interface to destination is
			 * different than the original route, then add
			 * route to original source.
			 */
			NET_DBG("Route pkt %p from %p to %p",
				pkt, net_pkt_orig_iface(pkt),
				net_pkt_iface(pkt));

			add_route(net_pkt_orig_iface(pkt), &hdr->src, 128);
		}

		ret = net_route_packet(pkt, nexthop);
		if (ret < 0) {
			NET_DBG("Cannot re-route pkt %p via %s "
				"at iface %p (%d)",
				pkt, log_strdup(net_sprint_ipv6_addr(nexthop)),
				net_pkt_iface(pkt), ret);
		} else {
			return NET_OK;
		}
	} else {
		NET_DBG("No route to %s pkt %p dropped",
			log_strdup(net_sprint_ipv6_addr(&hdr->dst)), pkt);
	}

drop:
	return NET_DROP;
}
#else
static inline enum net_verdict ipv6_route_packet(struct net_pkt *pkt,
						 struct net_ipv6_hdr *hdr)
{
	ARG_UNUSED(pkt);
	ARG_UNUSED(hdr);

	NET_DBG("DROP: Packet %p not for me", pkt);

	return NET_DROP;
}

#endif /* CONFIG_NET_ROUTE */

enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct net_tcp_hdr);
	enum net_verdict verdict = NET_DROP;
	int real_len = net_pkt_get_len(pkt);
	u8_t ext_bitmap = 0U;
	u16_t ext_len = 0U;
	u8_t nexthdr, next_nexthdr;
	union net_proto_header proto_hdr;
	struct net_ipv6_hdr *hdr;
	union net_ip_header ip;
	int pkt_len;

	net_stats_update_ipv6_recv(net_pkt_iface(pkt));

	hdr = (struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);
	if (!hdr) {
		NET_DBG("DROP: no buffer");
		goto drop;
	}

	pkt_len = ntohs(hdr->len) + sizeof(struct net_ipv6_hdr);
	if (real_len < pkt_len) {
		NET_DBG("DROP: pkt len per hdr %d != pkt real len %d",
			pkt_len, real_len);
		goto drop;
	} else if (real_len > pkt_len) {
		net_pkt_update_length(pkt, pkt_len);
	}

	NET_DBG("IPv6 packet len %d received from %s to %s", pkt_len,
		log_strdup(net_sprint_ipv6_addr(&hdr->src)),
		log_strdup(net_sprint_ipv6_addr(&hdr->dst)));

	if (net_ipv6_is_addr_mcast(&hdr->src) ||
	    net_ipv6_is_addr_mcast_scope(&hdr->dst, 0)) {
		NET_DBG("DROP: multicast packet");
		goto drop;
	}

	if (!is_loopback) {
		if (net_ipv6_is_addr_loopback(&hdr->dst) ||
		    net_ipv6_is_addr_loopback(&hdr->src)) {
			NET_DBG("DROP: ::1 packet");
			goto drop;
		}

		if (net_ipv6_is_addr_mcast_iface(&hdr->dst) ||
		    (net_ipv6_is_addr_mcast_group(
			    &hdr->dst, net_ipv6_unspecified_address()) &&
		     (net_ipv6_is_addr_mcast_site(&hdr->dst) ||
		      net_ipv6_is_addr_mcast_org(&hdr->dst)))) {
			NET_DBG("DROP: invalid scope multicast packet");
			goto drop;
		}
	}

	/* Check extension headers */
	net_pkt_set_ipv6_next_hdr(pkt, hdr->nexthdr);
	net_pkt_set_ipv6_ext_len(pkt, 0);
	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr));
	net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_HDR(pkt)->hop_limit);

	if (!net_ipv6_is_my_addr(&hdr->dst) &&
	    !net_ipv6_is_my_maddr(&hdr->dst) &&
	    !net_ipv6_is_addr_mcast(&hdr->dst)) {
		if (ipv6_route_packet(pkt, hdr) == NET_OK) {
			return NET_OK;
		}

		goto drop;
	}

	/* If we receive a packet with ll source address fe80: and destination
	 * address is one of ours, and if the packet would cross interface
	 * boundary, then drop the packet. RFC 4291 ch 2.5.6
	 */
	if (IS_ENABLED(CONFIG_NET_ROUTING) &&
	    net_ipv6_is_ll_addr(&hdr->src) &&
	    !net_ipv6_is_addr_mcast(&hdr->dst) &&
	    !net_if_ipv6_addr_lookup_by_iface(net_pkt_iface(pkt),
					      &hdr->dst)) {
		ipv6_no_route_info(pkt, &hdr->src, &hdr->dst);
		goto drop;
	}

	net_pkt_acknowledge_data(pkt, &ipv6_access);

	nexthdr = hdr->nexthdr;
	while (!net_ipv6_is_nexthdr_upper_layer(nexthdr)) {
		int exthdr_len;

		NET_DBG("IPv6 next header %d", nexthdr);

		if (net_pkt_read_u8(pkt, &next_nexthdr)) {
			goto drop;
		}

		switch (nexthdr) {
		case NET_IPV6_NEXTHDR_HBHO:
			if (ext_bitmap & NET_IPV6_EXT_HDR_BITMAP_HBHO) {
				NET_ERR("DROP: multiple hop-by-hop");
				goto drop;
			}

			/* HBH option needs to be the first one */
			if (nexthdr != hdr->nexthdr) {
				goto bad_hdr;
			}

			ext_bitmap |= NET_IPV6_EXT_HDR_BITMAP_HBHO;

			break;

		case NET_IPV6_NEXTHDR_DESTO:
			if (ext_bitmap & NET_IPV6_EXT_HDR_BITMAP_DESTO2) {
				/* DESTO option cannot appear more than twice */
				goto bad_hdr;
			}

			if (ext_bitmap & NET_IPV6_EXT_HDR_BITMAP_DESTO1) {
				ext_bitmap |= NET_IPV6_EXT_HDR_BITMAP_DESTO2;
			} else {
				ext_bitmap |= NET_IPV6_EXT_HDR_BITMAP_DESTO1;
			}

			break;

		case NET_IPV6_NEXTHDR_FRAG:
			if (IS_ENABLED(CONFIG_NET_IPV6_FRAGMENT)) {
				net_pkt_set_ipv6_fragment_start(
					pkt, net_pkt_get_current_offset(pkt));
				return net_ipv6_handle_fragment_hdr(pkt, hdr,
								    nexthdr);
			}

			goto bad_hdr;

		case NET_IPV6_NEXTHDR_NONE:
			/* There is nothing after this header (see RFC 2460,
			 * ch 4.7), so we can drop the packet now.
			 * This is not an error case so do not update drop
			 * statistics.
			 */
			return NET_DROP;

		default:
			goto bad_hdr;
		}

		exthdr_len = ipv6_handle_ext_hdr_options(pkt, hdr, pkt_len);
		if (exthdr_len < 0) {
			goto drop;
		}

		ext_len += exthdr_len;
		nexthdr = next_nexthdr;
	}

	net_pkt_set_ipv6_ext_len(pkt, ext_len);
	net_pkt_set_family(pkt, PF_INET6);

	switch (nexthdr) {
	case IPPROTO_ICMPV6:
		verdict = net_icmpv6_input(pkt, hdr);
		break;
	case IPPROTO_TCP:
		proto_hdr.tcp = net_tcp_input(pkt, &tcp_access);
		if (proto_hdr.tcp) {
			verdict = NET_OK;
		}
		break;
	case IPPROTO_UDP:
		proto_hdr.udp = net_udp_input(pkt, &udp_access);
		if (proto_hdr.udp) {
			verdict = NET_OK;
		}
		break;
	}

	if (verdict == NET_DROP) {
		goto drop;
	} else if (nexthdr == IPPROTO_ICMPV6) {
		return verdict;
	}

	ip.ipv6 = hdr;

	verdict = net_conn_input(pkt, &ip, nexthdr, &proto_hdr);
	if (verdict != NET_DROP) {
		return verdict;
	}

drop:
	net_stats_update_ipv6_drop(net_pkt_iface(pkt));
	return NET_DROP;

bad_hdr:
	/* Send error message about parameter problem (RFC 2460) */
	net_icmpv6_send_error(pkt, NET_ICMPV6_PARAM_PROBLEM,
			      NET_ICMPV6_PARAM_PROB_NEXTHEADER,
			      net_pkt_get_current_offset(pkt) - 1);

	NET_DBG("DROP: Unknown/wrong nexthdr type");
	net_stats_update_ip_errors_protoerr(net_pkt_iface(pkt));

	return NET_DROP;
}

void net_ipv6_init(void)
{
	net_ipv6_nbr_init();

#if defined(CONFIG_NET_IPV6_MLD)
	net_ipv6_mld_init();
#endif
}
