/** @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/virtual.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"

BUILD_ASSERT(sizeof(struct in6_addr) == NET_IPV6_ADDR_SIZE);

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

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  = 0U;
	ipv6_hdr->flow    = 0U;
	ipv6_hdr->len     = 0U;
	ipv6_hdr->nexthdr = 0U;

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

	net_ipv6_addr_copy_raw(ipv6_hdr->dst, (uint8_t *)dst);
	net_ipv6_addr_copy_raw(ipv6_hdr->src, (uint8_t *)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, uint8_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) != 255U) {
		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) != 255U &&
	    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,
					       uint8_t opt_type,
					       uint16_t opt_type_offset)
{
	/* 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((struct in6_addr *)hdr->dst)) {
			break;
		}

		__fallthrough;
	case 0x80:
		net_icmpv6_send_error(pkt, NET_ICMPV6_PARAM_PROBLEM,
				      NET_ICMPV6_PARAM_PROB_OPTION,
				      (uint32_t)opt_type_offset);
		break;
	}

	return true;
}

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

	{
		uint8_t val = 0U;

		if (net_pkt_read_u8(pkt, &val)) {
			return -ENOBUFS;
		}
		exthdr_len = val * 8U + 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 += 2U;

	while (length < exthdr_len) {
		uint16_t opt_type_offset;
		uint8_t opt_type, opt_len;

		opt_type_offset = net_pkt_get_current_offset(pkt);

		/* Each extension option has type and length - except
		 * Pad1 which has only a type without any 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:
			NET_DBG("PAD1 option");
			length++;
			break;
		case NET_IPV6_EXT_HDR_OPT_PADN:
			NET_DBG("PADN option");
			length += opt_len + 2;
			net_pkt_skip(pkt, opt_len);
			break;
		default:
			/* Make sure that the option length is not too large.
			 * The former 1 + 1 is the length of extension type +
			 * length fields.
			 * The latter 1 + 1 is the length of the sub-option
			 * type and length fields.
			 */
			if (opt_len > (exthdr_len - (1 + 1 + 1 + 1))) {
				return -EINVAL;
			}

			if (ipv6_drop_on_unknown_option(pkt, hdr,
							opt_type, opt_type_offset)) {
				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,
					 uint8_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_IPV6_ND_INFINITE_LIFETIME,
			      NET_ROUTE_PREFERENCE_LOW);

	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, (struct in6_addr *)hdr->dst,
					   &route, &nexthop);
	} else {
		found = net_route_get_info(net_pkt_iface(pkt),
					   (struct in6_addr *)hdr->dst,
					   &route, &nexthop);
	}

	if (found) {
		int ret;

		if (IS_ENABLED(CONFIG_NET_ROUTING) &&
		    (net_ipv6_is_ll_addr((struct in6_addr *)hdr->src) ||
		     net_ipv6_is_ll_addr((struct in6_addr *)hdr->dst))) {
			/* RFC 4291 ch 2.5.6 */
			ipv6_no_route_info(pkt, (struct in6_addr *)hdr->src,
					   (struct in6_addr *)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),
				  (struct in6_addr *)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 {
		struct net_if *iface = NULL;
		int ret;

		if (net_if_ipv6_addr_onlink(&iface, (struct in6_addr *)hdr->dst)) {
			ret = net_route_packet_if(pkt, iface);
			if (ret < 0) {
				NET_DBG("Cannot re-route pkt %p "
					"at iface %p (%d)",
					pkt, net_pkt_iface(pkt), ret);
			} else {
				return NET_OK;
			}
		}

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


static enum net_verdict ipv6_forward_mcast_packet(struct net_pkt *pkt,
						 struct net_ipv6_hdr *hdr)
{
#if defined(CONFIG_NET_ROUTE_MCAST)
	int routed;

	/* check if routing loop could be created or if the destination is of
	 * interface local scope or if from link local source
	 */
	if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->src)  ||
	      net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) ||
	       net_ipv6_is_ll_addr((struct in6_addr *)hdr->src)) {
		return NET_CONTINUE;
	}

	routed = net_route_mcast_forward_packet(pkt, hdr);

	if (routed < 0) {
		return NET_DROP;
	}
#endif /*CONFIG_NET_ROUTE_MCAST*/
	return NET_CONTINUE;
}

static uint8_t extension_to_bitmap(uint8_t header, uint8_t ext_bitmap)
{
	switch (header) {
	case NET_IPV6_NEXTHDR_HBHO:
		return NET_IPV6_EXT_HDR_BITMAP_HBHO;
	case NET_IPV6_NEXTHDR_DESTO:
		/* Destination header can appears twice */
		if (ext_bitmap & NET_IPV6_EXT_HDR_BITMAP_DESTO1) {
			return NET_IPV6_EXT_HDR_BITMAP_DESTO2;
		}
		return NET_IPV6_EXT_HDR_BITMAP_DESTO1;
	case NET_IPV6_NEXTHDR_ROUTING:
		return NET_IPV6_EXT_HDR_BITMAP_ROUTING;
	case NET_IPV6_NEXTHDR_FRAG:
		return NET_IPV6_EXT_HDR_BITMAP_FRAG;
	default:
		return 0;
	}
}

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);
	struct net_if *pkt_iface = net_pkt_iface(pkt);
	enum net_verdict verdict = NET_DROP;
	int real_len = net_pkt_get_len(pkt);
	uint8_t ext_bitmap = 0U;
	uint16_t ext_len = 0U;
	uint8_t current_hdr, nexthdr, prev_hdr_offset;
	union net_proto_header proto_hdr;
	struct net_ipv6_hdr *hdr;
	struct net_if_mcast_addr *if_mcast_addr;
	union net_ip_header ip;
	int pkt_len;

#if defined(CONFIG_NET_L2_VIRTUAL)
	struct net_pkt_cursor hdr_start;

	net_pkt_cursor_backup(pkt, &hdr_start);
#endif

	net_stats_update_ipv6_recv(pkt_iface);

	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_unspecified((struct in6_addr *)hdr->src)) {
		NET_DBG("DROP: src addr is %s", "unspecified");
		goto drop;
	}

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

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

		if (net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) ||
		    (net_ipv6_is_addr_mcast_group(
			    (struct in6_addr *)hdr->dst,
			    net_ipv6_unspecified_address()) &&
		     (net_ipv6_is_addr_mcast_site((struct in6_addr *)hdr->dst) ||
		      net_ipv6_is_addr_mcast_org((struct in6_addr *)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);
	net_pkt_set_family(pkt, PF_INET6);

	if (IS_ENABLED(CONFIG_NET_ROUTE_MCAST) &&
		net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst)) {
		/* If the packet is a multicast packet and multicast routing
		 * is activated, we give the packet to the routing engine.
		 *
		 * But we only drop the packet if an error occurs, otherwise
		 * it might be eminent to respond on the packet on application
		 * layer.
		 */
		if (ipv6_forward_mcast_packet(pkt, hdr) == NET_DROP) {
			goto drop;
		}
	}

	if (!net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst)) {
		if (!net_ipv6_is_my_addr((struct in6_addr *)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((struct in6_addr *)hdr->src) &&
		    !net_if_ipv6_addr_lookup_by_iface(
				pkt_iface, (struct in6_addr *)hdr->dst)) {
			ipv6_no_route_info(pkt, (struct in6_addr *)hdr->src,
					   (struct in6_addr *)hdr->dst);
			goto drop;
		}
	}

	if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst) &&
	    !(net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) ||
	      net_ipv6_is_addr_mcast_link_all_nodes((struct in6_addr *)hdr->dst))) {
		/* If we receive a packet with a interface-local or
		 * link-local all-nodes multicast destination address we
		 * always have to pass it to the upper layer.
		 *
		 * For all other destination multicast addresses we have to
		 * check if one of the joined multicast groups on the
		 * originating interface of the packet matches. Otherwise the
		 * packet will be dropped.
		 * RFC4291 ch 2.7.1, ch 2.8
		 */
		if_mcast_addr = net_if_ipv6_maddr_lookup(
				    (struct in6_addr *)hdr->dst, &pkt_iface);

		if (!if_mcast_addr ||
		    !net_if_ipv6_maddr_is_joined(if_mcast_addr)) {
			NET_DBG("DROP: packet for unjoined multicast address");
			goto drop;
		}
	}

	net_pkt_acknowledge_data(pkt, &ipv6_access);

	current_hdr = hdr->nexthdr;
	ext_bitmap = extension_to_bitmap(current_hdr, ext_bitmap);
	/* Offset of "nexthdr" in the IPv6 header */
	prev_hdr_offset = (uint8_t *)&hdr->nexthdr - (uint8_t *)hdr;
	net_pkt_set_ipv6_hdr_prev(pkt, prev_hdr_offset);

	while (!net_ipv6_is_nexthdr_upper_layer(current_hdr)) {
		int exthdr_len;
		uint8_t ext_bit;

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

		if (current_hdr == 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;
		}

		/* Offset of "nexthdr" in the Extension Header */
		prev_hdr_offset = net_pkt_get_current_offset(pkt);

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

		/* Detect duplicated Extension headers */
		ext_bit = extension_to_bitmap(nexthdr, ext_bitmap);
		if (ext_bit & ext_bitmap) {
			goto bad_hdr;
		}
		ext_bitmap |= ext_bit;

		/* Make sure that nexthdr is valid, reject the Extension Header early otherwise.
		 * This is also important so that the "pointer" field in the ICMPv6 error
		 * message points to the "nexthdr" field.
		 */
		switch (nexthdr) {
		case NET_IPV6_NEXTHDR_HBHO:
			/* Hop-by-hop header can appear only once and must appear right after
			 * the IPv6 header. Consequently the "nexthdr" field of an Extension
			 * Header can never be an HBH option.
			 */
			goto bad_hdr;

		case NET_IPV6_NEXTHDR_DESTO:
		case NET_IPV6_NEXTHDR_FRAG:
		case NET_IPV6_NEXTHDR_NONE:
			/* Valid values */
			break;

		default:
			if (net_ipv6_is_nexthdr_upper_layer(nexthdr)) {
				break;
			}
			goto bad_hdr;
		}

		/* Process the current Extension Header */
		switch (current_hdr) {
		case NET_IPV6_NEXTHDR_HBHO:
		case NET_IPV6_NEXTHDR_DESTO:
			/* Process options below */
			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) - 1);
				return net_ipv6_handle_fragment_hdr(pkt, hdr,
								    current_hdr);
			}

			goto bad_hdr;

		default:
			/* Unsupported */
			goto bad_hdr;
		}

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

		ext_len += exthdr_len;
		current_hdr = nexthdr;
		/* Save the offset to "nexthdr" in case we need to overwrite it
		 * when processing a fragment header
		 */
		net_pkt_set_ipv6_hdr_prev(pkt, prev_hdr_offset);
	}

	net_pkt_set_ipv6_ext_len(pkt, ext_len);

	switch (current_hdr) {
	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 defined(CONFIG_NET_L2_VIRTUAL)
	case IPPROTO_IPV6:
	case IPPROTO_IPIP: {
		struct net_addr remote_addr;

		remote_addr.family = AF_INET6;
		net_ipv6_addr_copy_raw((uint8_t *)&remote_addr.in6_addr, hdr->src);

		/* Get rid of the old IP header */
		net_pkt_cursor_restore(pkt, &hdr_start);
		net_pkt_pull(pkt, net_pkt_ip_hdr_len(pkt) +
			     net_pkt_ipv6_ext_len(pkt));

		return net_virtual_input(pkt_iface, &remote_addr, pkt);
	}
#endif
	}

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

	ip.ipv6 = hdr;

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

drop:
	net_stats_update_ipv6_drop(pkt_iface);
	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(pkt_iface);

	return NET_DROP;
}

void net_ipv6_init(void)
{
	net_ipv6_nbr_init();

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