/*
 * Copyright (c) 2019 Alexander Wachter.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(net_l2_canbus, CONFIG_NET_L2_CANBUS_LOG_LEVEL);

#include <net/net_core.h>
#include <net/net_l2.h>
#include <net/net_if.h>
#include <net/net_pkt.h>
#include <net/can.h>
#include "canbus_internal.h"
#include <6lo.h>
#include <timeout_q.h>
#include <string.h>
#include <sys/byteorder.h>
#include <net/ethernet.h>
#include <net/net_ip.h>
#include <string.h>

#define NET_CAN_WFTMAX 2
#define NET_CAN_ALLOC_TIMEOUT K_MSEC(100)

/* Minimal separation time betwee frames */
#define NET_CAN_STMIN CONFIG_NET_L2_CANBUS_STMIN
#define NET_CAN_BS CONFIG_NET_L2_CANBUS_BS

#define NET_CAN_DAD_SEND_RETRY 5
#define NET_CAN_DAD_TIMEOUT K_MSEC(100)

extern u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto);

static struct canbus_l2_ctx l2_ctx;

static struct k_work_q net_canbus_workq;
K_THREAD_STACK_DEFINE(net_canbus_stack, 512);

char *net_sprint_addr(sa_family_t af, const void *addr);

#if CONFIG_NET_L2_CANBUS_LOG_LEVEL >= LOG_LEVEL_DBG
static void canbus_print_ip_hdr(struct net_ipv6_hdr *ip_hdr)
{
	u8_t version = (ip_hdr->vtc >> 4);
	u8_t tc = ((ip_hdr->vtc & 0x0F) << 4) | ((ip_hdr->tcflow & 0xF0 >> 4));
	u32_t flow = ((ip_hdr->tcflow & 0x0F) << 16) | ip_hdr->flow;

	NET_DBG("IP header: Version: 0x%x, TC: 0x%x, Flow Label: 0x%x, "
		"Payload Length: %u, Next Header: 0x%x, Hop Limit: %u, "
		"Src: %s, Dest: %s",
		version, tc, flow, ntohs(ip_hdr->len), ip_hdr->nexthdr,
		ip_hdr->hop_limit,
		log_strdup(net_sprint_addr(AF_INET6, &ip_hdr->src)),
		log_strdup(net_sprint_addr(AF_INET6, &ip_hdr->dst)));
}
#else
#define canbus_print_ip_hdr(...)
#endif

static void canbus_free_tx_ctx(struct canbus_isotp_tx_ctx *ctx)
{
	k_mutex_lock(&l2_ctx.tx_ctx_mtx, K_FOREVER);
	ctx->state = NET_CAN_TX_STATE_UNUSED;
	k_mutex_unlock(&l2_ctx.tx_ctx_mtx);
}

static void canbus_free_rx_ctx(struct canbus_isotp_rx_ctx *ctx)
{
	k_mutex_lock(&l2_ctx.rx_ctx_mtx, K_FOREVER);
	ctx->state = NET_CAN_RX_STATE_UNUSED;
	k_mutex_unlock(&l2_ctx.rx_ctx_mtx);
}

static void canbus_tx_finish(struct net_pkt *pkt)
{
	struct canbus_isotp_tx_ctx *ctx = pkt->canbus_tx_ctx;

	if (ctx->state != NET_CAN_TX_STATE_RESET) {
		z_abort_timeout(&ctx->timeout);
	}

	canbus_free_tx_ctx(ctx);
	net_pkt_unref(pkt);
	k_sem_give(&l2_ctx.tx_sem);
}

static void canbus_rx_finish(struct net_pkt *pkt)
{
	struct canbus_isotp_rx_ctx *ctx = pkt->canbus_rx_ctx;

	canbus_free_rx_ctx(ctx);
}

static void canbus_tx_report_err(struct net_pkt *pkt)
{
	canbus_tx_finish(pkt);
}

static void canbus_rx_report_err(struct net_pkt *pkt)
{
	canbus_rx_finish(pkt);
	net_pkt_unref(pkt);
}

static void rx_err_work_handler(struct k_work *item)
{
	struct net_pkt *pkt = CONTAINER_OF(item, struct net_pkt, work);

	canbus_rx_report_err(pkt);
}

static void canbus_rx_report_err_from_isr(struct net_pkt *pkt)
{
	k_work_init(&pkt->work, rx_err_work_handler);
	k_work_submit_to_queue(&net_canbus_workq, &pkt->work);
}

static void canbus_tx_timeout(struct _timeout *t)
{
	struct canbus_isotp_tx_ctx *ctx =
		CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);

	NET_ERR("TX Timeout. CTX: %p", ctx);
	ctx->state = NET_CAN_TX_STATE_ERR;
	k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
}

static void canbus_rx_timeout(struct _timeout *t)
{
	struct canbus_isotp_rx_ctx *ctx =
		CONTAINER_OF(t, struct canbus_isotp_rx_ctx, timeout);

	NET_ERR("RX Timeout. CTX: %p", ctx);
	ctx->state = NET_CAN_RX_STATE_TIMEOUT;
	canbus_rx_report_err_from_isr(ctx->pkt);
}

static void canbus_st_min_timeout(struct _timeout *t)
{
	struct canbus_isotp_tx_ctx *ctx =
		CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);

	k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
}

static s32_t canbus_stmin_to_ticks(u8_t stmin)
{
	s32_t time_ms;

	/* According to ISO 15765-2 stmin should be 127ms if value is corrupt */
	if (stmin > NET_CAN_STMIN_MAX ||
	    (stmin > NET_CAN_STMIN_MS_MAX && stmin < NET_CAN_STMIN_US_BEGIN)) {
		time_ms = K_MSEC(NET_CAN_STMIN_MS_MAX);
	} else if (stmin >= NET_CAN_STMIN_US_BEGIN) {
		/* This should be 100us-900us but zephyr can't handle that */
		time_ms = K_MSEC(1);
	} else {
		time_ms = stmin;
	}

	return k_ms_to_ticks_ceil32(time_ms);
}

static u16_t canbus_get_lladdr(struct net_linkaddr *net_lladdr)
{
	NET_ASSERT(net_lladdr->len == sizeof(u16_t));

	return sys_be16_to_cpu(UNALIGNED_GET((u16_t *)net_lladdr->addr));
}

static u16_t canbus_get_src_lladdr(struct net_pkt *pkt)
{
	return net_pkt_lladdr_src(pkt)->type == NET_LINK_CANBUS ?
	       canbus_get_lladdr(net_pkt_lladdr_src(pkt)) :
	       NET_CAN_ETH_TRANSLATOR_ADDR;
}

static u16_t canbus_get_dest_lladdr(struct net_pkt *pkt)
{
	return net_pkt_lladdr_dst(pkt)->type == NET_LINK_CANBUS &&
	       net_pkt_lladdr_dst(pkt)->len == sizeof(struct net_canbus_lladdr) ?
	       canbus_get_lladdr(net_pkt_lladdr_dst(pkt)) :
	       NET_CAN_ETH_TRANSLATOR_ADDR;
}

static inline bool canbus_dest_is_mcast(struct net_pkt *pkt)
{
	u16_t lladdr_be = UNALIGNED_GET((u16_t *)net_pkt_lladdr_dst(pkt)->addr);

	return (sys_be16_to_cpu(lladdr_be) & CAN_NET_IF_IS_MCAST_BIT);
}

static bool canbus_src_is_translator(struct net_pkt *pkt)
{
	return ((canbus_get_src_lladdr(pkt) & CAN_NET_IF_ADDR_MASK) ==
		NET_CAN_ETH_TRANSLATOR_ADDR);
}

static bool canbus_dest_is_translator(struct net_pkt *pkt)
{
	return (net_pkt_lladdr_dst(pkt)->type == NET_LINK_ETHERNET ||
		net_pkt_lladdr_dst(pkt)->len == sizeof(struct net_eth_addr));
}

#if defined(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR)
static bool canbus_is_for_translator(struct net_pkt *pkt)
{
	return ((net_pkt_lladdr_dst(pkt)->type == NET_LINK_CANBUS) &&
		(canbus_get_lladdr(net_pkt_lladdr_dst(pkt)) ==
		 NET_CAN_ETH_TRANSLATOR_ADDR));
}
#else
#define canbus_is_for_translator(...) false
#endif /* CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR */

static size_t canbus_total_lladdr_len(struct net_pkt *pkt)
{
	/* This pkt will be farowarded to Ethernet
	 * Destination MAC is carried inline, source is going to be extended
	 */
	if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
	    canbus_is_for_translator(pkt)) {
		return sizeof(struct net_eth_addr) +
		       sizeof(struct net_canbus_lladdr);
	}

	return 2U * sizeof(struct net_canbus_lladdr);
}

static inline void canbus_cpy_lladdr(struct net_pkt *dst, struct net_pkt *src)
{
	struct net_linkaddr *lladdr;

	lladdr = net_pkt_lladdr_dst(dst);
	lladdr->addr = net_pkt_cursor_get_pos(dst);
	net_pkt_write(dst, net_pkt_lladdr_dst(src)->addr,
		      sizeof(struct net_canbus_lladdr));
	lladdr->len = sizeof(struct net_canbus_lladdr);
	lladdr->type = NET_LINK_CANBUS;

	if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
	    canbus_is_for_translator(src)) {
		/* Make room for address extension */
		net_pkt_skip(dst, sizeof(struct net_eth_addr) -
			     sizeof(struct net_canbus_lladdr));
	}

	lladdr = net_pkt_lladdr_src(dst);
	lladdr->addr = net_pkt_cursor_get_pos(dst);

	if (canbus_src_is_translator(src)) {
		net_pkt_copy(dst, src, sizeof(struct net_eth_addr));
		lladdr->len = sizeof(struct net_eth_addr);
		lladdr->type = NET_LINK_ETHERNET;
		NET_DBG("Inline MAC: %02x:%02x:%02x:%02x:%02x:%02x",
			lladdr->addr[0], lladdr->addr[1], lladdr->addr[2],
			lladdr->addr[3], lladdr->addr[4], lladdr->addr[5]);
	} else {
		net_pkt_write(dst, net_pkt_lladdr_src(src)->addr,
			      sizeof(struct net_canbus_lladdr));
		lladdr->len = sizeof(struct net_canbus_lladdr);
		lladdr->type = NET_LINK_CANBUS;
	}
}


static struct canbus_isotp_rx_ctx *canbus_get_rx_ctx(u8_t state,
						     u16_t src_addr)
{
	int i;
	struct canbus_isotp_rx_ctx *ret = NULL;

	k_mutex_lock(&l2_ctx.rx_ctx_mtx, K_FOREVER);
	for (i = 0; i < ARRAY_SIZE(l2_ctx.rx_ctx); i++) {
		struct canbus_isotp_rx_ctx *ctx = &l2_ctx.rx_ctx[i];

		if (ctx->state == state) {
			if (state == NET_CAN_RX_STATE_UNUSED) {
				ctx->state = NET_CAN_RX_STATE_RESET;
				z_init_timeout(&ctx->timeout);
				ret = ctx;
				break;
			}

			if (canbus_get_src_lladdr(ctx->pkt) == src_addr) {
				ret = ctx;
				break;
			}
		}
	}

	k_mutex_unlock(&l2_ctx.rx_ctx_mtx);
	return ret;
}

static struct canbus_isotp_tx_ctx *canbus_get_tx_ctx(u8_t state,
						     u16_t dest_addr)
{
	int i;
	struct canbus_isotp_tx_ctx *ret = NULL;

	k_mutex_lock(&l2_ctx.tx_ctx_mtx, K_FOREVER);
	for (i = 0; i < ARRAY_SIZE(l2_ctx.tx_ctx); i++) {
		struct canbus_isotp_tx_ctx *ctx = &l2_ctx.tx_ctx[i];

		if (ctx->state == state) {
			if (state == NET_CAN_TX_STATE_UNUSED) {
				ctx->state = NET_CAN_TX_STATE_RESET;
				z_init_timeout(&ctx->timeout);
				ret = ctx;
				break;
			}

			if (ctx->dest_addr.addr == dest_addr) {
				ret = ctx;
				break;
			}
		}
	}

	k_mutex_unlock(&l2_ctx.tx_ctx_mtx);
	return ret;
}

static inline u16_t canbus_receive_get_ff_length(struct net_pkt *pkt)
{
	u16_t len;
	int ret;

	ret = net_pkt_read_be16(pkt, &len);
	if (ret < 0) {
		NET_ERR("Can't read length");
	}

	return len & 0x0FFF;
}

static inline size_t canbus_get_sf_length(struct net_pkt *pkt)
{
	size_t len;

	net_buf_pull_u8(pkt->frags);
	len = net_buf_pull_u8(pkt->frags);

	return len;
}

static inline void canbus_set_frame_datalength(struct zcan_frame *frame,
					       u8_t length)
{
	/* TODO: Needs update when CAN FD support is added */
	NET_ASSERT(length <= NET_CAN_DL);
	frame->dlc = length;
}

static enum net_verdict canbus_finish_pkt(struct net_pkt *pkt)
{
	/* Pull the ll addresses to ignore them in upper layers */
	net_buf_pull(pkt->buffer, net_pkt_lladdr_dst(pkt)->len +
		     net_pkt_lladdr_src(pkt)->len);

	if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
	    canbus_is_for_translator(pkt)) {
		/* Pull room for address extension */
		net_buf_pull(pkt->buffer, sizeof(struct net_eth_addr) -
			     net_pkt_lladdr_src(pkt)->len);
		/* Set the destination address to the inline MAC and pull it */
		net_pkt_cursor_init(pkt);
		net_pkt_lladdr_dst(pkt)->addr = net_pkt_cursor_get_pos(pkt);
		net_pkt_lladdr_dst(pkt)->type = NET_LINK_ETHERNET;
		net_pkt_lladdr_dst(pkt)->len = sizeof(struct net_eth_addr);
		net_buf_pull(pkt->buffer, sizeof(struct net_eth_addr));
	}

	net_pkt_cursor_init(pkt);
	if (!net_6lo_uncompress(pkt)) {
		NET_ERR("6lo uncompression failed");
		return NET_DROP;
	}

	net_pkt_cursor_init(pkt);

	return NET_CONTINUE;
}

static inline u32_t canbus_addr_to_id(u16_t dest, u16_t src)
{
	return (dest << CAN_NET_IF_ADDR_DEST_POS) |
	       (src << CAN_NET_IF_ADDR_SRC_POS);
}

static void canbus_set_frame_addr(struct zcan_frame *frame,
				  const struct net_canbus_lladdr *dest,
				  const struct net_canbus_lladdr *src,
				  bool mcast)
{
	frame->id_type = CAN_EXTENDED_IDENTIFIER;
	frame->rtr = CAN_DATAFRAME;

	frame->ext_id = canbus_addr_to_id(dest->addr, src->addr);

	if (mcast) {
		frame->ext_id |= CAN_NET_IF_ADDR_MCAST_MASK;
	}
}

static void canbus_set_frame_addr_pkt(struct zcan_frame *frame,
				      struct net_pkt *pkt,
				      struct net_canbus_lladdr *dest_addr,
				      bool mcast)
{
	struct net_canbus_lladdr src_addr;

	if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
	    net_pkt_lladdr_src(pkt)->type == NET_LINK_ETHERNET) {
		src_addr.addr = NET_CAN_ETH_TRANSLATOR_ADDR;
	} else {
		src_addr.addr = canbus_get_lladdr(net_if_get_link_addr(pkt->iface));
	}

	canbus_set_frame_addr(frame, dest_addr, &src_addr, mcast);
}

static void canbus_fc_send_cb(u32_t err_flags, void *arg)
{
	if (err_flags) {
		NET_ERR("Sending FC frame failed: %d", err_flags);
	}
}

static int canbus_send_fc(struct device *net_can_dev,
			  struct net_canbus_lladdr *dest,
			  struct net_canbus_lladdr *src, u8_t fs)
{
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_frame frame = {
		.id_type = CAN_EXTENDED_IDENTIFIER,
		.rtr = CAN_DATAFRAME,
	};

	NET_ASSERT(!(fs & NET_CAN_PCI_TYPE_MASK));

	canbus_set_frame_addr(&frame, dest, src, false);

	frame.data[0] = NET_CAN_PCI_TYPE_FC | fs;
	/* BS (Block Size) */
	frame.data[1] = NET_CAN_BS;
	/* STmin (minimum Seperation Time) */
	frame.data[2] = NET_CAN_STMIN;
	canbus_set_frame_datalength(&frame, 3);

	NET_DBG("Sending FC to ID: 0x%08x", frame.ext_id);
	return api->send(net_can_dev, &frame, canbus_fc_send_cb, NULL,
			 K_FOREVER);
}

static int canbus_process_cf_data(struct net_pkt *frag_pkt,
				  struct canbus_isotp_rx_ctx *ctx)
{
	struct net_pkt *pkt = ctx->pkt;
	size_t data_len = net_pkt_get_len(frag_pkt) - 1;
	u8_t pci;
	int ret;

	pci = net_buf_pull_u8(frag_pkt->frags);

	if ((pci & NET_CAN_PCI_SN_MASK) != ctx->sn) {
		NET_ERR("Sequence number missmatch. Expect %u, got %u",
			ctx->sn, pci & NET_CAN_PCI_SN_MASK);
		goto err;
	}

	ctx->sn++;

	if (data_len > ctx->rem_len) {
		NET_DBG("Remove padding of %d bytes", data_len - ctx->rem_len);
		data_len = ctx->rem_len;
	}

	net_pkt_cursor_init(frag_pkt);
	NET_DBG("Appending CF data to pkt (%d bytes)", data_len);
	ret = net_pkt_copy(pkt, frag_pkt, data_len);
	if (ret < 0) {
		NET_ERR("Failed to write data to pkt [%d]", ret);
		goto err;
	}

	ctx->rem_len -= data_len;

	NET_DBG("%u bytes remaining", ctx->rem_len);

	return 0;
err:
	canbus_rx_report_err(pkt);
	return -1;
}

static enum net_verdict canbus_process_cf(struct net_pkt *pkt)
{
	struct canbus_isotp_rx_ctx *rx_ctx;
	enum net_verdict ret;
	struct device *net_can_dev;
	struct net_canbus_lladdr src, dest;
	bool mcast;

	mcast = canbus_dest_is_mcast(pkt);

	rx_ctx = canbus_get_rx_ctx(NET_CAN_RX_STATE_CF,
				   canbus_get_src_lladdr(pkt));
	if (!rx_ctx) {
		NET_INFO("Got CF but can't find a CTX that is waiting for it. "
			 "Src: 0x%04x", canbus_get_src_lladdr(pkt));
		return NET_DROP;
	}

	z_abort_timeout(&rx_ctx->timeout);

	ret = canbus_process_cf_data(pkt, rx_ctx);
	if (ret < 0) {
		return NET_DROP;
	}

	net_pkt_unref(pkt);

	if (rx_ctx->rem_len == 0) {
		rx_ctx->state = NET_CAN_RX_STATE_FIN;
		ret = net_recv_data(pkt->iface, rx_ctx->pkt);
		if (ret < 0) {
			NET_ERR("Packet dropped by NET stack");
			net_pkt_unref(pkt);
		}
	} else {
		z_add_timeout(&rx_ctx->timeout, canbus_rx_timeout,
			      k_ms_to_ticks_ceil32(NET_CAN_BS_TIME));

		if (NET_CAN_BS != 0 && !mcast) {
			rx_ctx->act_block_nr++;
			if (rx_ctx->act_block_nr >= NET_CAN_BS) {
				NET_DBG("BS reached. Send FC");
				src.addr = canbus_get_src_lladdr(pkt);
				dest.addr = canbus_get_dest_lladdr(pkt);
				net_can_dev = net_if_get_device(pkt->iface);
				ret = canbus_send_fc(net_can_dev, &src, &dest,
						     NET_CAN_PCI_FS_CTS);
				if (ret) {
					NET_ERR("Failed to send FC CTS. BS: %d",
						NET_CAN_BS);
					canbus_rx_report_err(rx_ctx->pkt);
					return NET_OK;
				}

				rx_ctx->act_block_nr = 0;
			}
		}
	}

	return NET_OK;
}

static enum net_verdict canbus_process_ff(struct net_pkt *pkt)
{
	struct device *net_can_dev = net_if_get_device(pkt->iface);
	struct canbus_isotp_rx_ctx *rx_ctx = NULL;
	struct net_pkt *new_pkt = NULL;
	int ret;
	struct net_canbus_lladdr src, dest;
	u16_t msg_len;
	size_t new_pkt_len;
	u8_t data_len;
	bool mcast;

	mcast = canbus_dest_is_mcast(pkt);
	src.addr = canbus_get_src_lladdr(pkt);
	dest.addr = canbus_get_dest_lladdr(pkt);
	net_pkt_cursor_init(pkt);

	msg_len = canbus_receive_get_ff_length(pkt);

	new_pkt_len = msg_len + canbus_total_lladdr_len(pkt);

	new_pkt = net_pkt_rx_alloc_with_buffer(pkt->iface, new_pkt_len,
					       AF_INET6, 0,
					       NET_CAN_ALLOC_TIMEOUT);
	if (!new_pkt) {
		NET_ERR("Failed to obtain net_pkt with size of %d", new_pkt_len);

		if (!mcast) {
			canbus_send_fc(net_can_dev, &src, &dest,
				       NET_CAN_PCI_FS_OVFLW);
		}

		goto err;
	}

	rx_ctx = canbus_get_rx_ctx(NET_CAN_RX_STATE_UNUSED, 0);
	if (!rx_ctx) {
		NET_ERR("No rx context left");

		if (!mcast) {
			canbus_send_fc(net_can_dev, &src, &dest,
				       NET_CAN_PCI_FS_OVFLW);
		}

		goto err;
	}

	rx_ctx->act_block_nr = 0;
	rx_ctx->pkt = new_pkt;
	new_pkt->canbus_rx_ctx = rx_ctx;

	net_pkt_cursor_init(new_pkt);
	data_len = net_pkt_remaining_data(pkt);
	canbus_cpy_lladdr(new_pkt, pkt);
	rx_ctx->sn = 1;

	ret = net_pkt_copy(new_pkt, pkt, net_pkt_remaining_data(pkt));
	if (ret) {
		NET_ERR("Failed to write to pkt [%d]", ret);
		goto err;
	}

	rx_ctx->rem_len = msg_len - data_len;
	net_pkt_unref(pkt);

	if (!mcast) {
		/* switch src and dest because we are answering */
		ret = canbus_send_fc(net_can_dev, &src, &dest,
				     NET_CAN_PCI_FS_CTS);
		if (ret) {
			NET_ERR("Failed to send FC CTS");
			canbus_rx_report_err(new_pkt);
			return NET_OK;
		}
	}

	/* At this point we expect to get Consecutive frames directly */
	z_add_timeout(&rx_ctx->timeout, canbus_rx_timeout,
		      k_ms_to_ticks_ceil32(NET_CAN_BS_TIME));

	rx_ctx->state = NET_CAN_RX_STATE_CF;

	NET_DBG("Processed FF from 0x%04x (%scast)"
		"Msg length: %u CTX: %p",
		src.addr, mcast ? "m" : "uni", msg_len, rx_ctx);

	return NET_OK;

err:
	if (new_pkt) {
		net_pkt_unref(new_pkt);
	}

	if (rx_ctx) {
		canbus_free_rx_ctx(rx_ctx);
	}

	return NET_DROP;
}

static enum net_verdict canbus_process_sf(struct net_pkt *pkt)
{
	size_t data_len;
	size_t pkt_len;

	net_pkt_set_family(pkt, AF_INET6);

	data_len = canbus_get_sf_length(pkt);
	pkt_len = net_pkt_get_len(pkt);

	if (data_len > pkt_len) {
		NET_ERR("SF datalen > pkt size");
		return NET_DROP;
	}

	if (pkt_len != data_len) {
		NET_DBG("Remove padding (%d byte)", pkt_len - data_len);
		net_pkt_update_length(pkt, data_len);
	}

	return canbus_finish_pkt(pkt);
}

static void canbus_tx_frame_isr(u32_t err_flags, void *arg)
{
	struct net_pkt *pkt = (struct net_pkt *)arg;
	struct canbus_isotp_tx_ctx *ctx = pkt->canbus_tx_ctx;

	ctx->tx_backlog--;

	if (ctx->state == NET_CAN_TX_STATE_WAIT_TX_BACKLOG) {
		if (ctx->tx_backlog > 0) {
			return;
		}

		ctx->state = NET_CAN_TX_STATE_FIN;
	}

	k_work_submit_to_queue(&net_canbus_workq, &pkt->work);
}

static inline int canbus_send_cf(struct net_pkt *pkt)
{
	struct canbus_isotp_tx_ctx *ctx = pkt->canbus_tx_ctx;
	struct device *net_can_dev = net_if_get_device(pkt->iface);
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_frame frame;
	struct net_pkt_cursor cursor_backup;
	int ret, len;

	canbus_set_frame_addr_pkt(&frame, pkt, &ctx->dest_addr, ctx->is_mcast);

	/* sn wraps around at 0xF automatically because it has a 4 bit size */
	frame.data[0] = NET_CAN_PCI_TYPE_CF | ctx->sn;

	len = MIN(ctx->rem_len, NET_CAN_DL - 1);

	canbus_set_frame_datalength(&frame, len + 1);

	net_pkt_cursor_backup(pkt, &cursor_backup);
	net_pkt_read(pkt, &frame.data[1], len);
	ret = api->send(net_can_dev, &frame, canbus_tx_frame_isr,
			pkt, K_NO_WAIT);
	if (ret == CAN_TX_OK) {
		ctx->sn++;
		ctx->rem_len -= len;
		ctx->act_block_nr--;
		ctx->tx_backlog++;
	} else {
		net_pkt_cursor_restore(pkt, &cursor_backup);
	}

	NET_DBG("CF sent. %d bytes left. CTX: %p", ctx->rem_len, ctx);

	return ret ? ret : ctx->rem_len;
}

static void canbus_tx_work(struct net_pkt *pkt)
{
	int ret;
	struct canbus_isotp_tx_ctx *ctx = pkt->canbus_tx_ctx;

	NET_ASSERT(ctx);

	switch (ctx->state) {
	case NET_CAN_TX_STATE_SEND_CF:
		do {
			ret = canbus_send_cf(ctx->pkt);
			if (!ret) {
				ctx->state = NET_CAN_TX_STATE_WAIT_TX_BACKLOG;
				break;
			}

			if (ret < 0 && ret != CAN_TIMEOUT) {
				NET_ERR("Failed to send CF. CTX: %p", ctx);
				canbus_tx_report_err(pkt);
				break;
			}

			if (ctx->opts.bs && !ctx->is_mcast &&
			    !ctx->act_block_nr) {
				NET_DBG("BS reached. Wait for FC again. CTX: %p",
					ctx);
				ctx->state = NET_CAN_TX_STATE_WAIT_FC;
				z_add_timeout(&ctx->timeout, canbus_tx_timeout,
					      k_ms_to_ticks_ceil32(NET_CAN_BS_TIME));
				break;
			} else if (ctx->opts.stmin) {
				ctx->state = NET_CAN_TX_STATE_WAIT_ST;
				break;
			}
		} while (ret > 0);

		break;

	case NET_CAN_TX_STATE_WAIT_ST:
		NET_DBG("SM wait ST. CTX: %p", ctx);
		z_add_timeout(&ctx->timeout, canbus_st_min_timeout,
			      k_ms_to_ticks_ceil32(canbus_stmin_to_ticks(ctx->opts.stmin)));
		ctx->state = NET_CAN_TX_STATE_SEND_CF;
		break;

	case NET_CAN_TX_STATE_ERR:
		NET_DBG("SM handle error. CTX: %p", ctx);
		canbus_tx_report_err(pkt);
		break;

	case NET_CAN_TX_STATE_FIN:
		canbus_tx_finish(ctx->pkt);
		NET_DBG("SM finish. CTX: %p", ctx);
		break;

	default:
		break;
	}
}

static void canbus_tx_work_handler(struct k_work *item)
{
	struct net_pkt *pkt = CONTAINER_OF(item, struct net_pkt, work);

	canbus_tx_work(pkt);
}

static enum net_verdict canbus_process_fc_data(struct canbus_isotp_tx_ctx *ctx,
					       struct net_pkt *pkt)
{
	struct net_buf *buf = pkt->frags;
	u8_t pci;

	pci = net_buf_pull_u8(buf);

	switch (pci & NET_CAN_PCI_FS_MASK) {
	case NET_CAN_PCI_FS_CTS:
		if (net_buf_frags_len(buf) != 2) {
			NET_ERR("Frame length error for CTS");
			canbus_tx_report_err(pkt);
			return NET_DROP;
		}

		ctx->state = NET_CAN_TX_STATE_SEND_CF;
		ctx->wft = 0;
		ctx->opts.bs = net_buf_pull_u8(buf);
		ctx->opts.stmin = net_buf_pull_u8(buf);
		ctx->act_block_nr = ctx->opts.bs;
		z_abort_timeout(&ctx->timeout);
		NET_DBG("Got CTS. BS: %d, STmin: %d. CTX: %p",
			ctx->opts.bs, ctx->opts.stmin, ctx);
		net_pkt_unref(pkt);
		return NET_OK;
	case NET_CAN_PCI_FS_WAIT:
		NET_DBG("Got WAIT frame. CTX: %p", ctx);
		z_abort_timeout(&ctx->timeout);
		z_add_timeout(&ctx->timeout, canbus_tx_timeout,
			      k_ms_to_ticks_ceil32(NET_CAN_BS_TIME));
		if (ctx->wft >= NET_CAN_WFTMAX) {
			NET_INFO("Got to many wait frames. CTX: %p", ctx);
			ctx->state = NET_CAN_TX_STATE_ERR;
		}

		ctx->wft++;
		return NET_OK;
	case NET_CAN_PCI_FS_OVFLW:
		NET_ERR("Got overflow FC frame. CTX: %p", ctx);
		ctx->state = NET_CAN_TX_STATE_ERR;
		return NET_OK;
	default:
		NET_ERR("Invalid Frame Status. CTX: %p", ctx);
		ctx->state = NET_CAN_TX_STATE_ERR;
		break;
	}

	return NET_DROP;
}

static enum net_verdict canbus_process_fc(struct net_pkt *pkt)
{
	struct canbus_isotp_tx_ctx *tx_ctx;
	u16_t src_addr = canbus_get_src_lladdr(pkt);
	enum net_verdict ret;

	tx_ctx = canbus_get_tx_ctx(NET_CAN_TX_STATE_WAIT_FC, src_addr);
	if (!tx_ctx) {
		NET_WARN("Got FC frame from 0x%04x but can't find any "
			 "CTX waiting for it", src_addr);
		return NET_DROP;
	}

	ret = canbus_process_fc_data(tx_ctx, pkt);
	if (ret == NET_OK) {
		k_work_submit_to_queue(&net_canbus_workq, &tx_ctx->pkt->work);
	}

	return ret;
}

static inline int canbus_send_ff(struct net_pkt *pkt, size_t len, bool mcast,
				 struct net_canbus_lladdr *dest_addr)
{
	struct device *net_can_dev = net_if_get_device(pkt->iface);
	const struct net_can_api *api = net_can_dev->driver_api;
	struct net_linkaddr *lladdr_inline;
	struct zcan_frame frame;
	int ret, index = 0;

	canbus_set_frame_addr_pkt(&frame, pkt, dest_addr, mcast);
	canbus_set_frame_datalength(&frame, NET_CAN_DL);

	if (mcast) {
		NET_DBG("Sending FF (multicast). ID: 0x%08x. PKT len: %zu"
			" CTX: %p",
			frame.ext_id, len, pkt->canbus_tx_ctx);
	} else {
		NET_DBG("Sending FF (unicast). ID: 0x%08x. PKT len: %zu"
			" CTX: %p",
			frame.ext_id, len, pkt->canbus_tx_ctx);
	}

#if defined(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR)
	NET_ASSERT(mcast || !(canbus_dest_is_translator(pkt) &&
			      canbus_src_is_translator(pkt)));

	if (canbus_src_is_translator(pkt)) {
		len += net_pkt_lladdr_src(pkt)->len;
	}
#endif
	if (!mcast && canbus_dest_is_translator(pkt)) {
		len += net_pkt_lladdr_dst(pkt)->len;
	}

	frame.data[index++] = NET_CAN_PCI_TYPE_FF | (len >> 8);
	frame.data[index++] = len & 0xFF;

	/* According to ISO, FF has sn 0 and is incremented to one
	 * alltough it's not part of the FF frame
	 */
	pkt->canbus_tx_ctx->sn = 1;

	if (!mcast && canbus_dest_is_translator(pkt)) {
		lladdr_inline = net_pkt_lladdr_dst(pkt);
		memcpy(&frame.data[index], lladdr_inline->addr,
		       lladdr_inline->len);
		index += lladdr_inline->len;
	}

	if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
	    net_pkt_lladdr_src(pkt)->type == NET_LINK_ETHERNET) {
		lladdr_inline = net_pkt_lladdr_src(pkt);
		memcpy(&frame.data[index], lladdr_inline->addr,
		       lladdr_inline->len);
		index += lladdr_inline->len;
	}

	net_pkt_read(pkt, &frame.data[index], NET_CAN_DL - index);
	pkt->canbus_tx_ctx->rem_len -= NET_CAN_DL - index;

	ret = api->send(net_can_dev, &frame, NULL, NULL, K_FOREVER);
	if (ret != CAN_TX_OK) {
		NET_ERR("Sending FF failed [%d]. CTX: %p",
			ret, pkt->canbus_tx_ctx);
	}

	return ret;
}

static inline int canbus_send_single_frame(struct net_pkt *pkt, size_t len,
					   bool mcast,
					   struct net_canbus_lladdr *dest_addr)
{
	struct device *net_can_dev = net_if_get_device(pkt->iface);
	const struct net_can_api *api = net_can_dev->driver_api;
	int index = 0;
	struct zcan_frame frame;
	struct net_linkaddr *lladdr_dest;
	int ret;

	canbus_set_frame_addr_pkt(&frame, pkt, dest_addr, mcast);

	frame.data[index++] = NET_CAN_PCI_TYPE_SF;
	frame.data[index++] = len;

	NET_ASSERT((len + (!mcast && canbus_dest_is_translator(pkt)) ?
		    net_pkt_lladdr_dst(pkt)->len : 0) <= NET_CAN_DL - 1);

	if (!mcast && canbus_dest_is_translator(pkt)) {
		lladdr_dest = net_pkt_lladdr_dst(pkt);
		memcpy(&frame.data[index], lladdr_dest->addr, lladdr_dest->len);
		index += lladdr_dest->len;
	}

	net_pkt_read(pkt, &frame.data[index], len);

	canbus_set_frame_datalength(&frame, len + index);

	ret = api->send(net_can_dev, &frame, NULL, NULL, K_FOREVER);
	if (ret != CAN_TX_OK) {
		NET_ERR("Sending SF failed [%d]", ret);
		return -EIO;
	}

	return 0;
}

static void canbus_start_sending_cf(struct _timeout *t)
{
	struct canbus_isotp_tx_ctx *ctx =
		CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);

	k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
}

static int canbus_send_multiple_frames(struct net_pkt *pkt, size_t len,
				       bool mcast,
				       struct net_canbus_lladdr *dest_addr)
{
	struct canbus_isotp_tx_ctx *tx_ctx = NULL;
	int ret;

	tx_ctx = canbus_get_tx_ctx(NET_CAN_TX_STATE_UNUSED, 0);

	if (!tx_ctx) {
		NET_ERR("No tx context left");
		k_sem_give(&l2_ctx.tx_sem);
		return -EAGAIN;
	}

	tx_ctx->pkt = pkt;
	pkt->canbus_tx_ctx = tx_ctx;
	tx_ctx->is_mcast = mcast;
	tx_ctx->dest_addr = *dest_addr;
	tx_ctx->rem_len = net_pkt_get_len(pkt);
	tx_ctx->tx_backlog = 0;

	k_work_init(&pkt->work, canbus_tx_work_handler);

	ret = canbus_send_ff(pkt, len, mcast, dest_addr);
	if (ret != CAN_TX_OK) {
		NET_ERR("Failed to send FF [%d]", ret);
		canbus_tx_report_err(pkt);
		return -EIO;
	}

	if (!mcast) {
		z_add_timeout(&tx_ctx->timeout, canbus_tx_timeout,
			      k_ms_to_ticks_ceil32(NET_CAN_BS_TIME));
		tx_ctx->state = NET_CAN_TX_STATE_WAIT_FC;
	} else {
		tx_ctx->state = NET_CAN_TX_STATE_SEND_CF;
		z_add_timeout(&tx_ctx->timeout, canbus_start_sending_cf,
			      k_ms_to_ticks_ceil32(NET_CAN_FF_CF_TIME));
	}

	return 0;
}

static void canbus_ipv6_mcast_to_dest(struct net_pkt *pkt,
				      struct net_canbus_lladdr *dest_addr)
{
	dest_addr->addr =
		sys_be16_to_cpu(UNALIGNED_GET(&NET_IPV6_HDR(pkt)->dst.s6_addr16[7]));
}

static inline u16_t canbus_eth_to_can_addr(struct net_linkaddr *lladdr)
{
	return (sys_be16_to_cpu(UNALIGNED_GET((u16_t *)&lladdr->addr[4])) &
		CAN_NET_IF_ADDR_MASK);
}

static int canbus_send(struct net_if *iface, struct net_pkt *pkt)
{
	int ret = 0;
	int comp_len;
	size_t pkt_len, inline_lladdr_len;
	struct net_canbus_lladdr dest_addr;
	bool mcast;

	if (net_pkt_family(pkt) != AF_INET6) {
		return -EINVAL;
	}

	mcast = net_ipv6_is_addr_mcast(&NET_IPV6_HDR(pkt)->dst);
	if (mcast || canbus_dest_is_mcast(pkt)) {
		canbus_ipv6_mcast_to_dest(pkt, &dest_addr);
	} else if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR) &&
		   net_pkt_lladdr_dst(pkt)->type == NET_LINK_ETHERNET) {
		struct net_linkaddr *lladdr = net_pkt_lladdr_dst(pkt);

		lladdr->type = NET_LINK_CANBUS;
		lladdr->len = sizeof(struct net_canbus_lladdr);
		dest_addr.addr = canbus_eth_to_can_addr(net_pkt_lladdr_dst(pkt));
		NET_DBG("Translated %02x:%02x:%02x:%02x:%02x:%02x to 0x%04x",
			lladdr->addr[0], lladdr->addr[1], lladdr->addr[2],
			lladdr->addr[3], lladdr->addr[4], lladdr->addr[5],
			dest_addr.addr);
	} else {
		dest_addr.addr = canbus_get_dest_lladdr(pkt);
	}

	net_pkt_cursor_init(pkt);
	canbus_print_ip_hdr((struct net_ipv6_hdr *)net_pkt_cursor_get_pos(pkt));
	comp_len = net_6lo_compress(pkt, true);
	if (comp_len < 0) {
		NET_ERR("IPHC failed [%d]", comp_len);
		return comp_len;
	}

	NET_DBG("IPv6 hdr compressed by %d bytes", comp_len);
	net_pkt_cursor_init(pkt);
	pkt_len = net_pkt_get_len(pkt);

	NET_DBG("Send CAN frame to 0x%04x%s", dest_addr.addr,
		mcast ? " (mcast)" : "");

	inline_lladdr_len = (!mcast && canbus_dest_is_translator(pkt)) ?
			    net_pkt_lladdr_dst(pkt)->len : 0;

	if ((pkt_len + inline_lladdr_len) > (NET_CAN_DL - 1)) {
		k_sem_take(&l2_ctx.tx_sem, K_FOREVER);
		ret = canbus_send_multiple_frames(pkt, pkt_len, mcast,
						  &dest_addr);
	} else {
		ret = canbus_send_single_frame(pkt, pkt_len, mcast, &dest_addr);
		canbus_tx_finish(pkt);
	}

	return ret;
}

static enum net_verdict canbus_process_frame(struct net_pkt *pkt)
{
	enum net_verdict ret = NET_DROP;
	u8_t pci_type;

	net_pkt_cursor_init(pkt);
	ret = net_pkt_read_u8(pkt, &pci_type);
	if (ret < 0) {
		NET_ERR("Can't read PCI");
	}
	pci_type = (pci_type & NET_CAN_PCI_TYPE_MASK) >> NET_CAN_PCI_TYPE_POS;

	switch (pci_type) {
	case NET_CAN_PCI_SF:
		ret = canbus_process_sf(pkt);
		break;
	case NET_CAN_PCI_FF:
		ret = canbus_process_ff(pkt);
		break;
	case NET_CAN_PCI_CF:
		ret = canbus_process_cf(pkt);
		break;
	case NET_CAN_PCI_FC:
		ret = canbus_process_fc(pkt);
		break;
	default:
		NET_ERR("Unknown PCI number %u", pci_type);
		break;
	}

	return ret;
}

#if defined(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR)
static void forward_eth_frame(struct net_pkt *pkt, struct net_if *canbus_iface)
{
	pkt->iface = canbus_iface;
	net_if_queue_tx(canbus_iface, pkt);
}

static struct net_ipv6_hdr *get_ip_hdr_from_eth_frame(struct net_pkt *pkt)
{
	return (struct net_ipv6_hdr *)((u8_t *)net_pkt_data(pkt) +
				       sizeof(struct net_eth_hdr));
}

enum net_verdict net_canbus_translate_eth_frame(struct net_if *iface,
						struct net_pkt *pkt)
{
	struct net_linkaddr *lladdr = net_pkt_lladdr_dst(pkt);
	struct net_pkt *clone_pkt;
	struct net_if *canbus_iface;

	/* Forward only IPv6 frames */
	if ((get_ip_hdr_from_eth_frame(pkt)->vtc & 0xf0) != 0x60) {
		return NET_CONTINUE;
	}

	/* This frame is for the Ethernet interface itself */
	if (net_linkaddr_cmp(net_if_get_link_addr(iface), lladdr)) {
		NET_DBG("Frame is for Ethernet only %02x:%02x:%02x:%02x:%02x:%02x",
			lladdr->addr[0], lladdr->addr[1], lladdr->addr[2],
			lladdr->addr[3], lladdr->addr[4], lladdr->addr[5]);
		return NET_CONTINUE;
	}

	canbus_iface = net_if_get_first_by_type(&NET_L2_GET_NAME(CANBUS));

	net_pkt_cursor_init(pkt);
	/* Forward all broadcasts */
	if (net_eth_is_addr_broadcast((struct net_eth_addr *)lladdr->addr) ||
	    net_eth_is_addr_multicast((struct net_eth_addr *)lladdr->addr)) {
		if (!canbus_iface || !net_if_is_up(canbus_iface)) {
			NET_ERR("No canbus iface");
			return NET_CONTINUE;
		}

		clone_pkt = net_pkt_shallow_clone(pkt, NET_CAN_ALLOC_TIMEOUT);
		if (clone_pkt) {
			NET_DBG("Frame is %scast %02x:%02x:%02x:%02x:%02x:%02x,",
				net_eth_is_addr_broadcast(
					(struct net_eth_addr *)lladdr->addr) ? "broad" :
				"multi",
				lladdr->addr[0], lladdr->addr[1], lladdr->addr[2],
				lladdr->addr[3], lladdr->addr[4], lladdr->addr[5]);
			net_pkt_set_family(clone_pkt, AF_INET6);
			forward_eth_frame(clone_pkt, canbus_iface);
		} else {
			NET_ERR("PKT forwarding: cloning failed");
		}

		return NET_CONTINUE;
	}

	if (!canbus_iface || !net_if_is_up(canbus_iface)) {
		NET_ERR("No canbus iface");
		return NET_DROP;
	}

	/* This frame is for 6LoCAN only */
	net_pkt_set_family(pkt, AF_INET6);
	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
	forward_eth_frame(pkt, canbus_iface);
	NET_DBG("Frame is for CANBUS: 0x%04x", canbus_get_dest_lladdr(pkt));

	return NET_OK;
}

static void forward_can_frame(struct net_pkt *pkt, struct net_if *eth_iface)
{
	net_pkt_set_iface(pkt, eth_iface);
	net_if_queue_tx(eth_iface, pkt);
}

static void rewrite_icmp_hdr(struct net_pkt *pkt, struct net_icmp_hdr *icmp_hdr)
{
	int ret;

	net_pkt_cursor_init(pkt);
	net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr));
	ret = net_icmpv6_create(pkt, icmp_hdr->type, icmp_hdr->code);
	if (ret) {
		NET_ERR("Can't create ICMP HDR");
		return;
	}

	net_pkt_cursor_init(pkt);
	net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr));
	ret = net_icmpv6_finalize(pkt);
	if (ret) {
		NET_ERR("Can't finalize ICMP HDR");
	}
}

static void extend_llao(struct net_pkt *pkt, struct net_linkaddr *mac_addr)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access, struct net_icmp_hdr);
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_opt_access,
					      struct net_icmpv6_nd_opt_hdr);
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(llao_access,
					      struct net_eth_addr);
	struct net_pkt_cursor cursor_backup;
	struct net_icmp_hdr *icmp_hdr;
	struct net_icmpv6_nd_opt_hdr *icmp_opt_hdr;
	u8_t *llao, llao_backup[2];
	int ret;

	net_pkt_cursor_backup(pkt, &cursor_backup);
	net_pkt_cursor_init(pkt);
	net_pkt_set_overwrite(pkt, true);
	net_pkt_skip(pkt, sizeof(struct net_ipv6_hdr));

	if (net_calc_chksum(pkt, IPPROTO_ICMPV6) != 0U) {
		NET_ERR("Invalid checksum");
		return;
	}

	icmp_hdr = (struct net_icmp_hdr *)net_pkt_get_data(pkt, &icmp_access);
	if (!icmp_hdr) {
		NET_ERR("No ICMP6 HDR");
		goto done;
	}

	switch (icmp_hdr->type) {

	case NET_ICMPV6_NS:
		net_pkt_skip(pkt, sizeof(struct net_icmpv6_ns_hdr));
		NET_DBG("Extend NS SLLAO");
		break;

	case NET_ICMPV6_NA:
		net_pkt_skip(pkt, sizeof(struct net_icmpv6_na_hdr));
		NET_DBG("Extend NA TLLAO");
		break;

	case NET_ICMPV6_RS:
		net_pkt_skip(pkt, sizeof(struct net_icmpv6_rs_hdr));
		NET_DBG("Extend RS SLLAO");
		break;

	case NET_ICMPV6_RA:
		net_pkt_skip(pkt, sizeof(struct net_icmpv6_ra_hdr));
		NET_DBG("Extend RA SLLAO");
		break;

	default:
		goto done;
	}

	net_pkt_acknowledge_data(pkt, &icmp_access);

	icmp_opt_hdr = (struct net_icmpv6_nd_opt_hdr *)
		       net_pkt_get_data(pkt, &icmp_opt_access);
	if (!icmp_opt_hdr) {
		NET_DBG("No LLAO opt to extend");
		goto done;
	}

	net_pkt_acknowledge_data(pkt, &icmp_opt_access);

	if (icmp_opt_hdr->type != NET_ICMPV6_ND_OPT_SLLAO &&
	    (icmp_hdr->type == NET_ICMPV6_NA &&
	     icmp_opt_hdr->type != NET_ICMPV6_ND_OPT_TLLAO)) {
		NET_DBG("opt was not LLAO");
		goto done;
	}

	if (icmp_opt_hdr->len != 1) {
		NET_ERR("LLAO len is %u. This should be 1 for 6LoCAN",
			icmp_opt_hdr->len);
		goto done;
	}

	llao = (u8_t *)net_pkt_get_data(pkt, &llao_access);
	if (!llao) {
		NET_ERR("Can't read LLAO");
		goto done;
	}

	memcpy(llao_backup, llao, sizeof(struct net_canbus_lladdr));
	memcpy(llao, mac_addr->addr, mac_addr->len);

	llao[4] = (llao[4] & 0xC0) | llao_backup[0];
	llao[5] = llao_backup[1];

	ret = net_pkt_set_data(pkt, &llao_access);
	if (ret < 0) {
		NET_ERR("Failed to write MAC to LLAO [%d]", ret);
		goto done;
	}

	rewrite_icmp_hdr(pkt, icmp_hdr);

	NET_DBG("LLAO extended to %02x:%02x:%02x:%02x:%02x:%02x",
		llao[0], llao[1], llao[2], llao[3], llao[4], llao[5]);

done:
	net_pkt_cursor_restore(pkt, &cursor_backup);
}

static bool pkt_is_icmp(struct net_pkt *pkt)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
	struct net_ipv6_hdr *ipv6_hdr =
		(struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);

	if (!ipv6_hdr) {
		NET_ERR("No IPv6 HDR");
		return false;
	}

	return (ipv6_hdr->nexthdr == IPPROTO_ICMPV6);
}

static void swap_scr_lladdr(struct net_pkt *pkt, struct net_pkt *pkt_clone)
{
	struct net_linkaddr *lladdr_origin = net_pkt_lladdr_src(pkt);
	struct net_linkaddr *lladdr_clone = net_pkt_lladdr_src(pkt_clone);
	size_t offset;

	offset = lladdr_origin->addr - pkt->buffer->data;
	lladdr_clone->addr = pkt_clone->buffer->data + offset;
}

static void can_to_eth_lladdr(struct net_pkt *pkt, struct net_if *eth_iface,
			      bool bcast)
{
	u16_t src_can_addr = canbus_get_src_lladdr(pkt);
	struct net_linkaddr *lladdr_src = net_pkt_lladdr_src(pkt);
	struct net_linkaddr *lladdr_dst;

	if (bcast) {
		lladdr_dst = net_pkt_lladdr_dst(pkt);
		lladdr_dst->len = sizeof(struct net_eth_addr);
		lladdr_dst->type = NET_LINK_ETHERNET;
		lladdr_dst->addr = (u8_t *)net_eth_broadcast_addr()->addr;
	}

	lladdr_src->addr = net_pkt_lladdr_src(pkt)->addr -
			   (sizeof(struct net_eth_addr) - lladdr_src->len);
	memcpy(lladdr_src->addr, net_if_get_link_addr(eth_iface)->addr,
	       sizeof(struct net_eth_addr));
	lladdr_src->addr[4] = (lladdr_src->addr[4] & 0xC0) | (src_can_addr >> 8U);
	lladdr_src->addr[5] = src_can_addr & 0xFF;
	lladdr_src->len = sizeof(struct net_eth_addr);
	lladdr_src->type = NET_LINK_ETHERNET;
}

void translate_to_eth_frame(struct net_pkt *pkt, bool is_bcast,
			    struct net_if *eth_iface)
{
	struct net_linkaddr *dest_addr = net_pkt_lladdr_dst(pkt);
	struct net_linkaddr *src_addr = net_pkt_lladdr_src(pkt);
	bool is_icmp;

	is_icmp = pkt_is_icmp(pkt);

	can_to_eth_lladdr(pkt, eth_iface, is_bcast);
	canbus_print_ip_hdr((struct net_ipv6_hdr *)net_pkt_cursor_get_pos(pkt));
	NET_DBG("Forward frame to %02x:%02x:%02x:%02x:%02x:%02x. "
		"Src: %02x:%02x:%02x:%02x:%02x:%02x",
		dest_addr->addr[0], dest_addr->addr[1], dest_addr->addr[2],
		dest_addr->addr[3], dest_addr->addr[4], dest_addr->addr[5],
		src_addr->addr[0], src_addr->addr[1], src_addr->addr[2],
		src_addr->addr[3], src_addr->addr[4], src_addr->addr[5]);

	if (is_icmp) {
		extend_llao(pkt, net_if_get_link_addr(eth_iface));
	}
}

static enum net_verdict canbus_forward_to_eth(struct net_pkt *pkt)
{
	struct net_pkt *pkt_clone;
	struct net_if *eth_iface;

	eth_iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
	if (!eth_iface || !net_if_is_up(eth_iface)) {
		NET_ERR("No Ethernet iface available");
		if (canbus_is_for_translator(pkt)) {
			return NET_DROP;
		} else {
			return NET_CONTINUE;
		}
	}

	if (canbus_dest_is_mcast(pkt)) {
		/* net_pkt_clone can't be called on a pkt where
		 * net_buf_pull was called on. We need to clone
		 * first and then finish the pkt.
		 */
		pkt_clone = net_pkt_clone(pkt, NET_CAN_ALLOC_TIMEOUT);
		if (pkt_clone) {
			swap_scr_lladdr(pkt, pkt_clone);
			canbus_finish_pkt(pkt_clone);
			translate_to_eth_frame(pkt_clone, true, eth_iface);
			forward_can_frame(pkt_clone, eth_iface);
			NET_DBG("Len: %zu", net_pkt_get_len(pkt_clone));
		} else {
			NET_ERR("Failed to clone pkt");
		}
	}

	canbus_finish_pkt(pkt);

	if (net_pkt_lladdr_dst(pkt)->type == NET_LINK_ETHERNET) {
		translate_to_eth_frame(pkt, false, eth_iface);
		forward_can_frame(pkt, eth_iface);
		return NET_OK;
	}

	return NET_CONTINUE;
}
#else
#define canbus_forward_to_eth(...) 0
#endif /*CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR*/

static enum net_verdict canbus_recv(struct net_if *iface,
				    struct net_pkt *pkt)
{
	struct net_linkaddr *lladdr = net_pkt_lladdr_src(pkt);
	enum net_verdict ret = NET_DROP;

	if (pkt->canbus_rx_ctx) {
		if (lladdr->len == sizeof(struct net_canbus_lladdr)) {
			NET_DBG("Push reassembled packet from 0x%04x trough "
				"stack again", canbus_get_src_lladdr(pkt));
		} else {
			NET_DBG("Push reassembled packet from "
				"%02x:%02x:%02x:%02x:%02x:%02x trough stack again",
				lladdr->addr[0], lladdr->addr[1], lladdr->addr[2],
				lladdr->addr[3], lladdr->addr[4], lladdr->addr[5]);
		}

		if (pkt->canbus_rx_ctx->state == NET_CAN_RX_STATE_FIN) {
			canbus_rx_finish(pkt);

			if (IS_ENABLED(CONFIG_NET_L2_CANBUS_ETH_TRANSLATOR)) {
				ret = canbus_forward_to_eth(pkt);
			} else {
				canbus_finish_pkt(pkt);
				canbus_print_ip_hdr(NET_IPV6_HDR(pkt));
				ret = NET_CONTINUE;
			}
		} else {
			NET_ERR("Expected pkt in FIN state");
		}
	} else {
		ret = canbus_process_frame(pkt);
	}

	return ret;
}

static inline int canbus_send_dad_request(struct device *net_can_dev,
					  struct net_canbus_lladdr *ll_addr)
{
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_frame frame;
	int ret;

	canbus_set_frame_datalength(&frame, 0);
	frame.rtr = CAN_REMOTEREQUEST;
	frame.id_type = CAN_EXTENDED_IDENTIFIER;
	frame.ext_id = canbus_addr_to_id(ll_addr->addr,
					 sys_rand32_get() & CAN_NET_IF_ADDR_MASK);

	ret = api->send(net_can_dev, &frame, NULL, NULL, K_FOREVER);
	if (ret != CAN_TX_OK) {
		NET_ERR("Sending DAD request failed [%d]", ret);
		return -EIO;
	}

	return 0;
}

static void canbus_send_dad_resp_cb(u32_t err_flags, void *cb_arg)
{
	static u8_t fail_cnt;
	struct k_work *work = (struct k_work *)cb_arg;

	if (err_flags) {
		NET_ERR("Failed to send dad response [%u]", err_flags);
		if (err_flags != CAN_TX_BUS_OFF &&
		    fail_cnt < NET_CAN_DAD_SEND_RETRY) {
			k_work_submit_to_queue(&net_canbus_workq, work);
		}

		fail_cnt++;
	} else {
		fail_cnt = 0;
	}
}

static inline void canbus_send_dad_response(struct k_work *item)
{
	struct canbus_net_ctx *ctx = CONTAINER_OF(item, struct canbus_net_ctx,
						  dad_work);
	struct net_if *iface = ctx->iface;
	struct net_linkaddr *ll_addr = net_if_get_link_addr(iface);
	struct device *net_can_dev = net_if_get_device(iface);
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_frame frame;
	int ret;

	canbus_set_frame_datalength(&frame, 0);
	frame.rtr = CAN_DATAFRAME;
	frame.id_type = CAN_EXTENDED_IDENTIFIER;
	frame.ext_id = canbus_addr_to_id(NET_CAN_DAD_ADDR,
					 ntohs(UNALIGNED_GET((u16_t *) ll_addr->addr)));

	ret = api->send(net_can_dev, &frame, canbus_send_dad_resp_cb, item,
			K_FOREVER);
	if (ret != CAN_TX_OK) {
		NET_ERR("Sending SF failed [%d]", ret);
	} else {
		NET_INFO("DAD response sent");
	}
}

static inline void canbus_detach_filter(struct device *net_can_dev,
					int filter_id)
{
	const struct net_can_api *api = net_can_dev->driver_api;

	api->detach_filter(net_can_dev, filter_id);
}

static void canbus_dad_resp_cb(struct zcan_frame *frame, void *arg)
{
	struct k_sem *dad_sem = (struct k_sem *)arg;

	k_sem_give(dad_sem);
}

static inline
int canbus_attach_dad_resp_filter(struct device *net_can_dev,
				  struct net_canbus_lladdr *ll_addr,
				  struct k_sem *dad_sem)
{
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_filter filter = {
		.id_type = CAN_EXTENDED_IDENTIFIER,
		.rtr = CAN_DATAFRAME,
		.rtr_mask = 1,
		.ext_id_mask = CAN_EXT_ID_MASK
	};
	int filter_id;

	filter.ext_id = canbus_addr_to_id(NET_CAN_DAD_ADDR, ll_addr->addr);

	filter_id = api->attach_filter(net_can_dev, canbus_dad_resp_cb,
				       dad_sem, &filter);
	if (filter_id == CAN_NO_FREE_FILTER) {
		NET_ERR("Can't attach dad response filter");
	}

	return filter_id;
}

static void canbus_dad_request_cb(struct zcan_frame *frame, void *arg)
{
	struct k_work *work = (struct k_work *)arg;

	k_work_submit_to_queue(&net_canbus_workq, work);
}

static inline int canbus_attach_dad_filter(struct device *net_can_dev,
					   struct net_canbus_lladdr *ll_addr,
					   struct k_work *dad_work)
{
	const struct net_can_api *api = net_can_dev->driver_api;
	struct zcan_filter filter = {
		.id_type = CAN_EXTENDED_IDENTIFIER,
		.rtr = CAN_REMOTEREQUEST,
		.rtr_mask = 1,
		.ext_id_mask = (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_DEST_POS)
	};
	int filter_id;

	filter.ext_id = canbus_addr_to_id(ll_addr->addr, 0);

	filter_id = api->attach_filter(net_can_dev, canbus_dad_request_cb,
				       dad_work, &filter);
	if (filter_id == CAN_NO_FREE_FILTER) {
		NET_ERR("Can't attach dad filter");
	}

	return filter_id;
}

static inline int canbus_init_ll_addr(struct net_if *iface)
{
	struct canbus_net_ctx *ctx = net_if_l2_data(iface);
	struct device *net_can_dev = net_if_get_device(iface);
	int dad_resp_filter_id = CAN_NET_FILTER_NOT_SET;
	struct net_canbus_lladdr ll_addr;
	int ret;
	struct k_sem dad_sem;

#if defined(CONFIG_NET_L2_CANBUS_USE_FIXED_ADDR)
	ll_addr.addr = CONFIG_NET_L2_CANBUS_FIXED_ADDR;
#else
	do {
		ll_addr.addr = sys_rand32_get() % (NET_CAN_MAX_ADDR + 1);
	} while (ll_addr.addr < NET_CAN_MIN_ADDR);
#endif

	/* Add address early for DAD response */
	ctx->ll_addr = sys_cpu_to_be16(ll_addr.addr);
	net_if_set_link_addr(iface, (u8_t *)&ctx->ll_addr, sizeof(ll_addr),
			     NET_LINK_CANBUS);

	dad_resp_filter_id = canbus_attach_dad_resp_filter(net_can_dev, &ll_addr,
							   &dad_sem);
	if (dad_resp_filter_id < 0) {
		return -EIO;
	}
	/*
	 * Attach this filter now to defend this address instantly.
	 * This filter is not called for own DAD because loopback is not
	 * enabled.
	 */
	ctx->dad_filter_id = canbus_attach_dad_filter(net_can_dev, &ll_addr,
						      &ctx->dad_work);
	if (ctx->dad_filter_id < 0) {
		ret = -EIO;
		goto dad_err;
	}

	k_sem_init(&dad_sem, 0, 1);
	ret = canbus_send_dad_request(net_can_dev, &ll_addr);
	if (ret) {
		ret = -EIO;
		goto dad_err;
	}

	ret = k_sem_take(&dad_sem, NET_CAN_DAD_TIMEOUT);
	canbus_detach_filter(net_can_dev, dad_resp_filter_id);
	dad_resp_filter_id = CAN_NET_FILTER_NOT_SET;

	if (ret != -EAGAIN) {
		NET_INFO("DAD failed");
		ret = -EAGAIN;
		goto dad_err;
	}

	return 0;

dad_err:
	net_if_set_link_addr(iface, NULL, 0, NET_LINK_CANBUS);
	if (ctx->dad_filter_id != CAN_NET_FILTER_NOT_SET) {
		canbus_detach_filter(net_can_dev, ctx->dad_filter_id);
		ctx->dad_filter_id = CAN_NET_FILTER_NOT_SET;
	}

	if (dad_resp_filter_id != CAN_NET_FILTER_NOT_SET) {
		canbus_detach_filter(net_can_dev, dad_resp_filter_id);
	}

	return ret;
}

void net_6locan_init(struct net_if *iface)
{
	struct canbus_net_ctx *ctx = net_if_l2_data(iface);
	u8_t thread_priority;
	int i;

	NET_DBG("Init CAN net interface");

	for (i = 0; i < ARRAY_SIZE(l2_ctx.tx_ctx); i++) {
		l2_ctx.tx_ctx[i].state = NET_CAN_TX_STATE_UNUSED;
	}

	for (i = 0; i < ARRAY_SIZE(l2_ctx.rx_ctx); i++) {
		l2_ctx.rx_ctx[i].state = NET_CAN_RX_STATE_UNUSED;
	}

	ctx->dad_filter_id = CAN_NET_FILTER_NOT_SET;
	ctx->iface = iface;
	k_work_init(&ctx->dad_work, canbus_send_dad_response);

	k_mutex_init(&l2_ctx.tx_ctx_mtx);
	k_mutex_init(&l2_ctx.rx_ctx_mtx);
	k_sem_init(&l2_ctx.tx_sem, 1, INT_MAX);

	/* This work queue should have precedence over the tx stream
	 * TODO thread_priority = tx_tc2thread(NET_TC_TX_COUNT -1) - 1;
	 */
	thread_priority = 6;

	k_work_q_start(&net_canbus_workq, net_canbus_stack,
		       K_THREAD_STACK_SIZEOF(net_canbus_stack),
		       K_PRIO_COOP(thread_priority));
	k_thread_name_set(&net_canbus_workq.thread, "isotp_work");
	NET_DBG("Workq started. Thread ID: %p", &net_canbus_workq.thread);
}

static int canbus_enable(struct net_if *iface, bool state)
{
	struct device *net_can_dev = net_if_get_device(iface);
	const struct net_can_api *api = net_can_dev->driver_api;
	struct canbus_net_ctx *ctx = net_if_l2_data(iface);
	int dad_retry_cnt, ret;

	NET_DBG("start to bring iface %p %s", iface, state ? "up" : "down");

	if (state) {
		for (dad_retry_cnt = CONFIG_NET_L2_CANBUS_DAD_RETRIES;
		     dad_retry_cnt; dad_retry_cnt--) {
			ret = canbus_init_ll_addr(iface);
			if (ret == 0) {
				break;
			} else if (ret == -EIO) {
				return -EIO;
			}
		}

		if (ret != 0) {
			return ret;
		}

	} else {
		if (ctx->dad_filter_id != CAN_NET_FILTER_NOT_SET) {
			canbus_detach_filter(net_can_dev, ctx->dad_filter_id);
		}
	}

	ret = api->enable(net_can_dev, state);
	if (!ret) {
		NET_DBG("Iface %p is up", iface);
	}

	return ret;
}

static enum net_l2_flags canbus_net_flags(struct net_if *iface)
{
	return NET_L2_MULTICAST;
}

NET_L2_INIT(CANBUS_L2, canbus_recv, canbus_send, canbus_enable,
	    canbus_net_flags);
