// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/* gw.c - CAN frame Gateway/Router/Bridge with netlink interface
 *
 * Copyright (c) 2019 Volkswagen Group Electronic Research
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Volkswagen nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * Alternatively, provided that this notice is retained in full, this
 * software may be distributed under the terms of the GNU General
 * Public License ("GPL") version 2, in which case the provisions of the
 * GPL apply INSTEAD OF those given above.
 *
 * The provided data structures and external interfaces from this code
 * are not restricted to be used by modules with a GPL compatible license.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/rculist.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
#include <linux/can/core.h>
#include <linux/can/skb.h>
#include <linux/can/gw.h>
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>

#define CAN_GW_NAME "can-gw"

MODULE_DESCRIPTION("PF_CAN netlink gateway");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
MODULE_ALIAS(CAN_GW_NAME);

#define CGW_MIN_HOPS 1
#define CGW_MAX_HOPS 6
#define CGW_DEFAULT_HOPS 1

static unsigned int max_hops __read_mostly = CGW_DEFAULT_HOPS;
module_param(max_hops, uint, 0444);
MODULE_PARM_DESC(max_hops,
		 "maximum " CAN_GW_NAME " routing hops for CAN frames "
		 "(valid values: " __stringify(CGW_MIN_HOPS) "-"
		 __stringify(CGW_MAX_HOPS) " hops, "
		 "default: " __stringify(CGW_DEFAULT_HOPS) ")");

static struct notifier_block notifier;
static struct kmem_cache *cgw_cache __read_mostly;

/* structure that contains the (on-the-fly) CAN frame modifications */
struct cf_mod {
	struct {
		struct canfd_frame and;
		struct canfd_frame or;
		struct canfd_frame xor;
		struct canfd_frame set;
	} modframe;
	struct {
		u8 and;
		u8 or;
		u8 xor;
		u8 set;
	} modtype;
	void (*modfunc[MAX_MODFUNCTIONS])(struct canfd_frame *cf,
					  struct cf_mod *mod);

	/* CAN frame checksum calculation after CAN frame modifications */
	struct {
		struct cgw_csum_xor xor;
		struct cgw_csum_crc8 crc8;
	} csum;
	struct {
		void (*xor)(struct canfd_frame *cf,
			    struct cgw_csum_xor *xor);
		void (*crc8)(struct canfd_frame *cf,
			     struct cgw_csum_crc8 *crc8);
	} csumfunc;
	u32 uid;
};

/* So far we just support CAN -> CAN routing and frame modifications.
 *
 * The internal can_can_gw structure contains data and attributes for
 * a CAN -> CAN gateway job.
 */
struct can_can_gw {
	struct can_filter filter;
	int src_idx;
	int dst_idx;
};

/* list entry for CAN gateways jobs */
struct cgw_job {
	struct hlist_node list;
	struct rcu_head rcu;
	u32 handled_frames;
	u32 dropped_frames;
	u32 deleted_frames;
	struct cf_mod __rcu *cf_mod;
	union {
		/* CAN frame data source */
		struct net_device *dev;
	} src;
	union {
		/* CAN frame data destination */
		struct net_device *dev;
	} dst;
	union {
		struct can_can_gw ccgw;
		/* tbc */
	};
	u8 gwtype;
	u8 limit_hops;
	u16 flags;
};

/* modification functions that are invoked in the hot path in can_can_gw_rcv */

#define MODFUNC(func, op) static void func(struct canfd_frame *cf, \
					   struct cf_mod *mod) { op ; }

MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id)
MODFUNC(mod_and_len, cf->len &= mod->modframe.and.len)
MODFUNC(mod_and_flags, cf->flags &= mod->modframe.and.flags)
MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data)
MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id)
MODFUNC(mod_or_len, cf->len |= mod->modframe.or.len)
MODFUNC(mod_or_flags, cf->flags |= mod->modframe.or.flags)
MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data)
MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id)
MODFUNC(mod_xor_len, cf->len ^= mod->modframe.xor.len)
MODFUNC(mod_xor_flags, cf->flags ^= mod->modframe.xor.flags)
MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data)
MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id)
MODFUNC(mod_set_len, cf->len = mod->modframe.set.len)
MODFUNC(mod_set_flags, cf->flags = mod->modframe.set.flags)
MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data)

static void mod_and_fddata(struct canfd_frame *cf, struct cf_mod *mod)
{
	int i;

	for (i = 0; i < CANFD_MAX_DLEN; i += 8)
		*(u64 *)(cf->data + i) &= *(u64 *)(mod->modframe.and.data + i);
}

static void mod_or_fddata(struct canfd_frame *cf, struct cf_mod *mod)
{
	int i;

	for (i = 0; i < CANFD_MAX_DLEN; i += 8)
		*(u64 *)(cf->data + i) |= *(u64 *)(mod->modframe.or.data + i);
}

static void mod_xor_fddata(struct canfd_frame *cf, struct cf_mod *mod)
{
	int i;

	for (i = 0; i < CANFD_MAX_DLEN; i += 8)
		*(u64 *)(cf->data + i) ^= *(u64 *)(mod->modframe.xor.data + i);
}

static void mod_set_fddata(struct canfd_frame *cf, struct cf_mod *mod)
{
	memcpy(cf->data, mod->modframe.set.data, CANFD_MAX_DLEN);
}

/* retrieve valid CC DLC value and store it into 'len' */
static void mod_retrieve_ccdlc(struct canfd_frame *cf)
{
	struct can_frame *ccf = (struct can_frame *)cf;

	/* len8_dlc is only valid if len == CAN_MAX_DLEN */
	if (ccf->len != CAN_MAX_DLEN)
		return;

	/* do we have a valid len8_dlc value from 9 .. 15 ? */
	if (ccf->len8_dlc > CAN_MAX_DLEN && ccf->len8_dlc <= CAN_MAX_RAW_DLC)
		ccf->len = ccf->len8_dlc;
}

/* convert valid CC DLC value in 'len' into struct can_frame elements */
static void mod_store_ccdlc(struct canfd_frame *cf)
{
	struct can_frame *ccf = (struct can_frame *)cf;

	/* clear potential leftovers */
	ccf->len8_dlc = 0;

	/* plain data length 0 .. 8 - that was easy */
	if (ccf->len <= CAN_MAX_DLEN)
		return;

	/* potentially broken values are caught in can_can_gw_rcv() */
	if (ccf->len > CAN_MAX_RAW_DLC)
		return;

	/* we have a valid dlc value from 9 .. 15 in ccf->len */
	ccf->len8_dlc = ccf->len;
	ccf->len = CAN_MAX_DLEN;
}

static void mod_and_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
{
	mod_retrieve_ccdlc(cf);
	mod_and_len(cf, mod);
	mod_store_ccdlc(cf);
}

static void mod_or_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
{
	mod_retrieve_ccdlc(cf);
	mod_or_len(cf, mod);
	mod_store_ccdlc(cf);
}

static void mod_xor_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
{
	mod_retrieve_ccdlc(cf);
	mod_xor_len(cf, mod);
	mod_store_ccdlc(cf);
}

static void mod_set_ccdlc(struct canfd_frame *cf, struct cf_mod *mod)
{
	mod_set_len(cf, mod);
	mod_store_ccdlc(cf);
}

static void canframecpy(struct canfd_frame *dst, struct can_frame *src)
{
	/* Copy the struct members separately to ensure that no uninitialized
	 * data are copied in the 3 bytes hole of the struct. This is needed
	 * to make easy compares of the data in the struct cf_mod.
	 */

	dst->can_id = src->can_id;
	dst->len = src->len;
	*(u64 *)dst->data = *(u64 *)src->data;
}

static void canfdframecpy(struct canfd_frame *dst, struct canfd_frame *src)
{
	/* Copy the struct members separately to ensure that no uninitialized
	 * data are copied in the 2 bytes hole of the struct. This is needed
	 * to make easy compares of the data in the struct cf_mod.
	 */

	dst->can_id = src->can_id;
	dst->flags = src->flags;
	dst->len = src->len;
	memcpy(dst->data, src->data, CANFD_MAX_DLEN);
}

static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re, struct rtcanmsg *r)
{
	s8 dlen = CAN_MAX_DLEN;

	if (r->flags & CGW_FLAGS_CAN_FD)
		dlen = CANFD_MAX_DLEN;

	/* absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0]
	 * relative to received dlc -1 .. -8 :
	 * e.g. for received dlc = 8
	 * -1 => index = 7 (data[7])
	 * -3 => index = 5 (data[5])
	 * -8 => index = 0 (data[0])
	 */

	if (fr >= -dlen && fr < dlen &&
	    to >= -dlen && to < dlen &&
	    re >= -dlen && re < dlen)
		return 0;
	else
		return -EINVAL;
}

static inline int calc_idx(int idx, int rx_len)
{
	if (idx < 0)
		return rx_len + idx;
	else
		return idx;
}

static void cgw_csum_xor_rel(struct canfd_frame *cf, struct cgw_csum_xor *xor)
{
	int from = calc_idx(xor->from_idx, cf->len);
	int to = calc_idx(xor->to_idx, cf->len);
	int res = calc_idx(xor->result_idx, cf->len);
	u8 val = xor->init_xor_val;
	int i;

	if (from < 0 || to < 0 || res < 0)
		return;

	if (from <= to) {
		for (i = from; i <= to; i++)
			val ^= cf->data[i];
	} else {
		for (i = from; i >= to; i--)
			val ^= cf->data[i];
	}

	cf->data[res] = val;
}

static void cgw_csum_xor_pos(struct canfd_frame *cf, struct cgw_csum_xor *xor)
{
	u8 val = xor->init_xor_val;
	int i;

	for (i = xor->from_idx; i <= xor->to_idx; i++)
		val ^= cf->data[i];

	cf->data[xor->result_idx] = val;
}

static void cgw_csum_xor_neg(struct canfd_frame *cf, struct cgw_csum_xor *xor)
{
	u8 val = xor->init_xor_val;
	int i;

	for (i = xor->from_idx; i >= xor->to_idx; i--)
		val ^= cf->data[i];

	cf->data[xor->result_idx] = val;
}

static void cgw_csum_crc8_rel(struct canfd_frame *cf,
			      struct cgw_csum_crc8 *crc8)
{
	int from = calc_idx(crc8->from_idx, cf->len);
	int to = calc_idx(crc8->to_idx, cf->len);
	int res = calc_idx(crc8->result_idx, cf->len);
	u8 crc = crc8->init_crc_val;
	int i;

	if (from < 0 || to < 0 || res < 0)
		return;

	if (from <= to) {
		for (i = crc8->from_idx; i <= crc8->to_idx; i++)
			crc = crc8->crctab[crc ^ cf->data[i]];
	} else {
		for (i = crc8->from_idx; i >= crc8->to_idx; i--)
			crc = crc8->crctab[crc ^ cf->data[i]];
	}

	switch (crc8->profile) {
	case CGW_CRC8PRF_1U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[0]];
		break;

	case  CGW_CRC8PRF_16U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[cf->data[1] & 0xF]];
		break;

	case CGW_CRC8PRF_SFFID_XOR:
		crc = crc8->crctab[crc ^ (cf->can_id & 0xFF) ^
				   (cf->can_id >> 8 & 0xFF)];
		break;
	}

	cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
}

static void cgw_csum_crc8_pos(struct canfd_frame *cf,
			      struct cgw_csum_crc8 *crc8)
{
	u8 crc = crc8->init_crc_val;
	int i;

	for (i = crc8->from_idx; i <= crc8->to_idx; i++)
		crc = crc8->crctab[crc ^ cf->data[i]];

	switch (crc8->profile) {
	case CGW_CRC8PRF_1U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[0]];
		break;

	case  CGW_CRC8PRF_16U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[cf->data[1] & 0xF]];
		break;

	case CGW_CRC8PRF_SFFID_XOR:
		crc = crc8->crctab[crc ^ (cf->can_id & 0xFF) ^
				   (cf->can_id >> 8 & 0xFF)];
		break;
	}

	cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
}

static void cgw_csum_crc8_neg(struct canfd_frame *cf,
			      struct cgw_csum_crc8 *crc8)
{
	u8 crc = crc8->init_crc_val;
	int i;

	for (i = crc8->from_idx; i >= crc8->to_idx; i--)
		crc = crc8->crctab[crc ^ cf->data[i]];

	switch (crc8->profile) {
	case CGW_CRC8PRF_1U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[0]];
		break;

	case  CGW_CRC8PRF_16U8:
		crc = crc8->crctab[crc ^ crc8->profile_data[cf->data[1] & 0xF]];
		break;

	case CGW_CRC8PRF_SFFID_XOR:
		crc = crc8->crctab[crc ^ (cf->can_id & 0xFF) ^
				   (cf->can_id >> 8 & 0xFF)];
		break;
	}

	cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
}

/* the receive & process & send function */
static void can_can_gw_rcv(struct sk_buff *skb, void *data)
{
	struct cgw_job *gwj = (struct cgw_job *)data;
	struct canfd_frame *cf;
	struct sk_buff *nskb;
	struct cf_mod *mod;
	int modidx = 0;

	/* process strictly Classic CAN or CAN FD frames */
	if (gwj->flags & CGW_FLAGS_CAN_FD) {
		if (!can_is_canfd_skb(skb))
			return;
	} else {
		if (!can_is_can_skb(skb))
			return;
	}

	/* Do not handle CAN frames routed more than 'max_hops' times.
	 * In general we should never catch this delimiter which is intended
	 * to cover a misconfiguration protection (e.g. circular CAN routes).
	 *
	 * The Controller Area Network controllers only accept CAN frames with
	 * correct CRCs - which are not visible in the controller registers.
	 * According to skbuff.h documentation the csum_start element for IP
	 * checksums is undefined/unused when ip_summed == CHECKSUM_UNNECESSARY.
	 * Only CAN skbs can be processed here which already have this property.
	 */

#define cgw_hops(skb) ((skb)->csum_start)

	BUG_ON(skb->ip_summed != CHECKSUM_UNNECESSARY);

	if (cgw_hops(skb) >= max_hops) {
		/* indicate deleted frames due to misconfiguration */
		gwj->deleted_frames++;
		return;
	}

	if (!(gwj->dst.dev->flags & IFF_UP)) {
		gwj->dropped_frames++;
		return;
	}

	/* is sending the skb back to the incoming interface not allowed? */
	if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
	    can_skb_prv(skb)->ifindex == gwj->dst.dev->ifindex)
		return;

	/* clone the given skb, which has not been done in can_rcv()
	 *
	 * When there is at least one modification function activated,
	 * we need to copy the skb as we want to modify skb->data.
	 */
	mod = rcu_dereference(gwj->cf_mod);
	if (mod->modfunc[0])
		nskb = skb_copy(skb, GFP_ATOMIC);
	else
		nskb = skb_clone(skb, GFP_ATOMIC);

	if (!nskb) {
		gwj->dropped_frames++;
		return;
	}

	/* put the incremented hop counter in the cloned skb */
	cgw_hops(nskb) = cgw_hops(skb) + 1;

	/* first processing of this CAN frame -> adjust to private hop limit */
	if (gwj->limit_hops && cgw_hops(nskb) == 1)
		cgw_hops(nskb) = max_hops - gwj->limit_hops + 1;

	nskb->dev = gwj->dst.dev;

	/* pointer to modifiable CAN frame */
	cf = (struct canfd_frame *)nskb->data;

	/* perform preprocessed modification functions if there are any */
	while (modidx < MAX_MODFUNCTIONS && mod->modfunc[modidx])
		(*mod->modfunc[modidx++])(cf, mod);

	/* Has the CAN frame been modified? */
	if (modidx) {
		/* get available space for the processed CAN frame type */
		int max_len = nskb->len - offsetof(struct canfd_frame, data);

		/* dlc may have changed, make sure it fits to the CAN frame */
		if (cf->len > max_len) {
			/* delete frame due to misconfiguration */
			gwj->deleted_frames++;
			kfree_skb(nskb);
			return;
		}

		/* check for checksum updates */
		if (mod->csumfunc.crc8)
			(*mod->csumfunc.crc8)(cf, &mod->csum.crc8);

		if (mod->csumfunc.xor)
			(*mod->csumfunc.xor)(cf, &mod->csum.xor);
	}

	/* clear the skb timestamp if not configured the other way */
	if (!(gwj->flags & CGW_FLAGS_CAN_SRC_TSTAMP))
		nskb->tstamp = 0;

	/* send to netdevice */
	if (can_send(nskb, gwj->flags & CGW_FLAGS_CAN_ECHO))
		gwj->dropped_frames++;
	else
		gwj->handled_frames++;
}

static inline int cgw_register_filter(struct net *net, struct cgw_job *gwj)
{
	return can_rx_register(net, gwj->src.dev, gwj->ccgw.filter.can_id,
			       gwj->ccgw.filter.can_mask, can_can_gw_rcv,
			       gwj, "gw", NULL);
}

static inline void cgw_unregister_filter(struct net *net, struct cgw_job *gwj)
{
	can_rx_unregister(net, gwj->src.dev, gwj->ccgw.filter.can_id,
			  gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj);
}

static void cgw_job_free_rcu(struct rcu_head *rcu_head)
{
	struct cgw_job *gwj = container_of(rcu_head, struct cgw_job, rcu);

	/* cgw_job::cf_mod is always accessed from the same cgw_job object within
	 * the same RCU read section. Once cgw_job is scheduled for removal,
	 * cf_mod can also be removed without mandating an additional grace period.
	 */
	kfree(rcu_access_pointer(gwj->cf_mod));
	kmem_cache_free(cgw_cache, gwj);
}

/* Return cgw_job::cf_mod with RTNL protected section */
static struct cf_mod *cgw_job_cf_mod(struct cgw_job *gwj)
{
	return rcu_dereference_protected(gwj->cf_mod, rtnl_is_locked());
}

static int cgw_notifier(struct notifier_block *nb,
			unsigned long msg, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct net *net = dev_net(dev);

	if (dev->type != ARPHRD_CAN)
		return NOTIFY_DONE;

	if (msg == NETDEV_UNREGISTER) {
		struct cgw_job *gwj = NULL;
		struct hlist_node *nx;

		ASSERT_RTNL();

		hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
			if (gwj->src.dev == dev || gwj->dst.dev == dev) {
				hlist_del(&gwj->list);
				cgw_unregister_filter(net, gwj);
				call_rcu(&gwj->rcu, cgw_job_free_rcu);
			}
		}
	}

	return NOTIFY_DONE;
}

static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
		       u32 pid, u32 seq, int flags)
{
	struct rtcanmsg *rtcan;
	struct nlmsghdr *nlh;
	struct cf_mod *mod;

	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtcan), flags);
	if (!nlh)
		return -EMSGSIZE;

	rtcan = nlmsg_data(nlh);
	rtcan->can_family = AF_CAN;
	rtcan->gwtype = gwj->gwtype;
	rtcan->flags = gwj->flags;

	/* add statistics if available */

	if (gwj->handled_frames) {
		if (nla_put_u32(skb, CGW_HANDLED, gwj->handled_frames) < 0)
			goto cancel;
	}

	if (gwj->dropped_frames) {
		if (nla_put_u32(skb, CGW_DROPPED, gwj->dropped_frames) < 0)
			goto cancel;
	}

	if (gwj->deleted_frames) {
		if (nla_put_u32(skb, CGW_DELETED, gwj->deleted_frames) < 0)
			goto cancel;
	}

	/* check non default settings of attributes */

	if (gwj->limit_hops) {
		if (nla_put_u8(skb, CGW_LIM_HOPS, gwj->limit_hops) < 0)
			goto cancel;
	}

	mod = cgw_job_cf_mod(gwj);
	if (gwj->flags & CGW_FLAGS_CAN_FD) {
		struct cgw_fdframe_mod mb;

		if (mod->modtype.and) {
			memcpy(&mb.cf, &mod->modframe.and, sizeof(mb.cf));
			mb.modtype = mod->modtype.and;
			if (nla_put(skb, CGW_FDMOD_AND, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.or) {
			memcpy(&mb.cf, &mod->modframe.or, sizeof(mb.cf));
			mb.modtype = mod->modtype.or;
			if (nla_put(skb, CGW_FDMOD_OR, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.xor) {
			memcpy(&mb.cf, &mod->modframe.xor, sizeof(mb.cf));
			mb.modtype = mod->modtype.xor;
			if (nla_put(skb, CGW_FDMOD_XOR, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.set) {
			memcpy(&mb.cf, &mod->modframe.set, sizeof(mb.cf));
			mb.modtype = mod->modtype.set;
			if (nla_put(skb, CGW_FDMOD_SET, sizeof(mb), &mb) < 0)
				goto cancel;
		}
	} else {
		struct cgw_frame_mod mb;

		if (mod->modtype.and) {
			memcpy(&mb.cf, &mod->modframe.and, sizeof(mb.cf));
			mb.modtype = mod->modtype.and;
			if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.or) {
			memcpy(&mb.cf, &mod->modframe.or, sizeof(mb.cf));
			mb.modtype = mod->modtype.or;
			if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.xor) {
			memcpy(&mb.cf, &mod->modframe.xor, sizeof(mb.cf));
			mb.modtype = mod->modtype.xor;
			if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
				goto cancel;
		}

		if (mod->modtype.set) {
			memcpy(&mb.cf, &mod->modframe.set, sizeof(mb.cf));
			mb.modtype = mod->modtype.set;
			if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
				goto cancel;
		}
	}

	if (mod->uid) {
		if (nla_put_u32(skb, CGW_MOD_UID, mod->uid) < 0)
			goto cancel;
	}

	if (mod->csumfunc.crc8) {
		if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN,
			    &mod->csum.crc8) < 0)
			goto cancel;
	}

	if (mod->csumfunc.xor) {
		if (nla_put(skb, CGW_CS_XOR, CGW_CS_XOR_LEN,
			    &mod->csum.xor) < 0)
			goto cancel;
	}

	if (gwj->gwtype == CGW_TYPE_CAN_CAN) {
		if (gwj->ccgw.filter.can_id || gwj->ccgw.filter.can_mask) {
			if (nla_put(skb, CGW_FILTER, sizeof(struct can_filter),
				    &gwj->ccgw.filter) < 0)
				goto cancel;
		}

		if (nla_put_u32(skb, CGW_SRC_IF, gwj->ccgw.src_idx) < 0)
			goto cancel;

		if (nla_put_u32(skb, CGW_DST_IF, gwj->ccgw.dst_idx) < 0)
			goto cancel;
	}

	nlmsg_end(skb, nlh);
	return 0;

cancel:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}

/* Dump information about all CAN gateway jobs, in response to RTM_GETROUTE */
static int cgw_dump_jobs(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct net *net = sock_net(skb->sk);
	struct cgw_job *gwj = NULL;
	int idx = 0;
	int s_idx = cb->args[0];

	rcu_read_lock();
	hlist_for_each_entry_rcu(gwj, &net->can.cgw_list, list) {
		if (idx < s_idx)
			goto cont;

		if (cgw_put_job(skb, gwj, RTM_NEWROUTE,
				NETLINK_CB(cb->skb).portid,
				cb->nlh->nlmsg_seq, NLM_F_MULTI) < 0)
			break;
cont:
		idx++;
	}
	rcu_read_unlock();

	cb->args[0] = idx;

	return skb->len;
}

static const struct nla_policy cgw_policy[CGW_MAX + 1] = {
	[CGW_MOD_AND]	= { .len = sizeof(struct cgw_frame_mod) },
	[CGW_MOD_OR]	= { .len = sizeof(struct cgw_frame_mod) },
	[CGW_MOD_XOR]	= { .len = sizeof(struct cgw_frame_mod) },
	[CGW_MOD_SET]	= { .len = sizeof(struct cgw_frame_mod) },
	[CGW_CS_XOR]	= { .len = sizeof(struct cgw_csum_xor) },
	[CGW_CS_CRC8]	= { .len = sizeof(struct cgw_csum_crc8) },
	[CGW_SRC_IF]	= { .type = NLA_U32 },
	[CGW_DST_IF]	= { .type = NLA_U32 },
	[CGW_FILTER]	= { .len = sizeof(struct can_filter) },
	[CGW_LIM_HOPS]	= { .type = NLA_U8 },
	[CGW_MOD_UID]	= { .type = NLA_U32 },
	[CGW_FDMOD_AND]	= { .len = sizeof(struct cgw_fdframe_mod) },
	[CGW_FDMOD_OR]	= { .len = sizeof(struct cgw_fdframe_mod) },
	[CGW_FDMOD_XOR]	= { .len = sizeof(struct cgw_fdframe_mod) },
	[CGW_FDMOD_SET]	= { .len = sizeof(struct cgw_fdframe_mod) },
};

/* check for common and gwtype specific attributes */
static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
			  u8 gwtype, void *gwtypeattr, u8 *limhops)
{
	struct nlattr *tb[CGW_MAX + 1];
	struct rtcanmsg *r = nlmsg_data(nlh);
	int modidx = 0;
	int err = 0;

	/* initialize modification & checksum data space */
	memset(mod, 0, sizeof(*mod));

	err = nlmsg_parse_deprecated(nlh, sizeof(struct rtcanmsg), tb,
				     CGW_MAX, cgw_policy, NULL);
	if (err < 0)
		return err;

	if (tb[CGW_LIM_HOPS]) {
		*limhops = nla_get_u8(tb[CGW_LIM_HOPS]);

		if (*limhops < 1 || *limhops > max_hops)
			return -EINVAL;
	}

	/* check for AND/OR/XOR/SET modifications */
	if (r->flags & CGW_FLAGS_CAN_FD) {
		struct cgw_fdframe_mod mb;

		if (tb[CGW_FDMOD_AND]) {
			nla_memcpy(&mb, tb[CGW_FDMOD_AND], CGW_FDMODATTR_LEN);

			canfdframecpy(&mod->modframe.and, &mb.cf);
			mod->modtype.and = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_and_id;

			if (mb.modtype & CGW_MOD_LEN)
				mod->modfunc[modidx++] = mod_and_len;

			if (mb.modtype & CGW_MOD_FLAGS)
				mod->modfunc[modidx++] = mod_and_flags;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_and_fddata;
		}

		if (tb[CGW_FDMOD_OR]) {
			nla_memcpy(&mb, tb[CGW_FDMOD_OR], CGW_FDMODATTR_LEN);

			canfdframecpy(&mod->modframe.or, &mb.cf);
			mod->modtype.or = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_or_id;

			if (mb.modtype & CGW_MOD_LEN)
				mod->modfunc[modidx++] = mod_or_len;

			if (mb.modtype & CGW_MOD_FLAGS)
				mod->modfunc[modidx++] = mod_or_flags;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_or_fddata;
		}

		if (tb[CGW_FDMOD_XOR]) {
			nla_memcpy(&mb, tb[CGW_FDMOD_XOR], CGW_FDMODATTR_LEN);

			canfdframecpy(&mod->modframe.xor, &mb.cf);
			mod->modtype.xor = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_xor_id;

			if (mb.modtype & CGW_MOD_LEN)
				mod->modfunc[modidx++] = mod_xor_len;

			if (mb.modtype & CGW_MOD_FLAGS)
				mod->modfunc[modidx++] = mod_xor_flags;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_xor_fddata;
		}

		if (tb[CGW_FDMOD_SET]) {
			nla_memcpy(&mb, tb[CGW_FDMOD_SET], CGW_FDMODATTR_LEN);

			canfdframecpy(&mod->modframe.set, &mb.cf);
			mod->modtype.set = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_set_id;

			if (mb.modtype & CGW_MOD_LEN)
				mod->modfunc[modidx++] = mod_set_len;

			if (mb.modtype & CGW_MOD_FLAGS)
				mod->modfunc[modidx++] = mod_set_flags;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_set_fddata;
		}
	} else {
		struct cgw_frame_mod mb;

		if (tb[CGW_MOD_AND]) {
			nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);

			canframecpy(&mod->modframe.and, &mb.cf);
			mod->modtype.and = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_and_id;

			if (mb.modtype & CGW_MOD_DLC)
				mod->modfunc[modidx++] = mod_and_ccdlc;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_and_data;
		}

		if (tb[CGW_MOD_OR]) {
			nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);

			canframecpy(&mod->modframe.or, &mb.cf);
			mod->modtype.or = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_or_id;

			if (mb.modtype & CGW_MOD_DLC)
				mod->modfunc[modidx++] = mod_or_ccdlc;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_or_data;
		}

		if (tb[CGW_MOD_XOR]) {
			nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);

			canframecpy(&mod->modframe.xor, &mb.cf);
			mod->modtype.xor = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_xor_id;

			if (mb.modtype & CGW_MOD_DLC)
				mod->modfunc[modidx++] = mod_xor_ccdlc;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_xor_data;
		}

		if (tb[CGW_MOD_SET]) {
			nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);

			canframecpy(&mod->modframe.set, &mb.cf);
			mod->modtype.set = mb.modtype;

			if (mb.modtype & CGW_MOD_ID)
				mod->modfunc[modidx++] = mod_set_id;

			if (mb.modtype & CGW_MOD_DLC)
				mod->modfunc[modidx++] = mod_set_ccdlc;

			if (mb.modtype & CGW_MOD_DATA)
				mod->modfunc[modidx++] = mod_set_data;
		}
	}

	/* check for checksum operations after CAN frame modifications */
	if (modidx) {
		if (tb[CGW_CS_CRC8]) {
			struct cgw_csum_crc8 *c = nla_data(tb[CGW_CS_CRC8]);

			err = cgw_chk_csum_parms(c->from_idx, c->to_idx,
						 c->result_idx, r);
			if (err)
				return err;

			nla_memcpy(&mod->csum.crc8, tb[CGW_CS_CRC8],
				   CGW_CS_CRC8_LEN);

			/* select dedicated processing function to reduce
			 * runtime operations in receive hot path.
			 */
			if (c->from_idx < 0 || c->to_idx < 0 ||
			    c->result_idx < 0)
				mod->csumfunc.crc8 = cgw_csum_crc8_rel;
			else if (c->from_idx <= c->to_idx)
				mod->csumfunc.crc8 = cgw_csum_crc8_pos;
			else
				mod->csumfunc.crc8 = cgw_csum_crc8_neg;
		}

		if (tb[CGW_CS_XOR]) {
			struct cgw_csum_xor *c = nla_data(tb[CGW_CS_XOR]);

			err = cgw_chk_csum_parms(c->from_idx, c->to_idx,
						 c->result_idx, r);
			if (err)
				return err;

			nla_memcpy(&mod->csum.xor, tb[CGW_CS_XOR],
				   CGW_CS_XOR_LEN);

			/* select dedicated processing function to reduce
			 * runtime operations in receive hot path.
			 */
			if (c->from_idx < 0 || c->to_idx < 0 ||
			    c->result_idx < 0)
				mod->csumfunc.xor = cgw_csum_xor_rel;
			else if (c->from_idx <= c->to_idx)
				mod->csumfunc.xor = cgw_csum_xor_pos;
			else
				mod->csumfunc.xor = cgw_csum_xor_neg;
		}

		if (tb[CGW_MOD_UID])
			nla_memcpy(&mod->uid, tb[CGW_MOD_UID], sizeof(u32));
	}

	if (gwtype == CGW_TYPE_CAN_CAN) {
		/* check CGW_TYPE_CAN_CAN specific attributes */
		struct can_can_gw *ccgw = (struct can_can_gw *)gwtypeattr;

		memset(ccgw, 0, sizeof(*ccgw));

		/* check for can_filter in attributes */
		if (tb[CGW_FILTER])
			nla_memcpy(&ccgw->filter, tb[CGW_FILTER],
				   sizeof(struct can_filter));

		err = -ENODEV;

		/* specifying two interfaces is mandatory */
		if (!tb[CGW_SRC_IF] || !tb[CGW_DST_IF])
			return err;

		ccgw->src_idx = nla_get_u32(tb[CGW_SRC_IF]);
		ccgw->dst_idx = nla_get_u32(tb[CGW_DST_IF]);

		/* both indices set to 0 for flushing all routing entries */
		if (!ccgw->src_idx && !ccgw->dst_idx)
			return 0;

		/* only one index set to 0 is an error */
		if (!ccgw->src_idx || !ccgw->dst_idx)
			return err;
	}

	/* add the checks for other gwtypes here */

	return 0;
}

static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh,
			  struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct rtcanmsg *r;
	struct cgw_job *gwj;
	struct cf_mod *mod;
	struct can_can_gw ccgw;
	u8 limhops = 0;
	int err = 0;

	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (nlmsg_len(nlh) < sizeof(*r))
		return -EINVAL;

	r = nlmsg_data(nlh);
	if (r->can_family != AF_CAN)
		return -EPFNOSUPPORT;

	/* so far we only support CAN -> CAN routings */
	if (r->gwtype != CGW_TYPE_CAN_CAN)
		return -EINVAL;

	mod = kmalloc(sizeof(*mod), GFP_KERNEL);
	if (!mod)
		return -ENOMEM;

	err = cgw_parse_attr(nlh, mod, CGW_TYPE_CAN_CAN, &ccgw, &limhops);
	if (err < 0)
		goto out_free_cf;

	if (mod->uid) {
		ASSERT_RTNL();

		/* check for updating an existing job with identical uid */
		hlist_for_each_entry(gwj, &net->can.cgw_list, list) {
			struct cf_mod *old_cf;

			old_cf = cgw_job_cf_mod(gwj);
			if (old_cf->uid != mod->uid)
				continue;

			/* interfaces & filters must be identical */
			if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw))) {
				err = -EINVAL;
				goto out_free_cf;
			}

			rcu_assign_pointer(gwj->cf_mod, mod);
			kfree_rcu_mightsleep(old_cf);
			return 0;
		}
	}

	/* ifindex == 0 is not allowed for job creation */
	if (!ccgw.src_idx || !ccgw.dst_idx) {
		err = -ENODEV;
		goto out_free_cf;
	}

	gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL);
	if (!gwj) {
		err = -ENOMEM;
		goto out_free_cf;
	}

	gwj->handled_frames = 0;
	gwj->dropped_frames = 0;
	gwj->deleted_frames = 0;
	gwj->flags = r->flags;
	gwj->gwtype = r->gwtype;
	gwj->limit_hops = limhops;

	/* insert already parsed information */
	RCU_INIT_POINTER(gwj->cf_mod, mod);
	memcpy(&gwj->ccgw, &ccgw, sizeof(ccgw));

	err = -ENODEV;

	gwj->src.dev = __dev_get_by_index(net, gwj->ccgw.src_idx);

	if (!gwj->src.dev)
		goto out;

	if (gwj->src.dev->type != ARPHRD_CAN)
		goto out;

	gwj->dst.dev = __dev_get_by_index(net, gwj->ccgw.dst_idx);

	if (!gwj->dst.dev)
		goto out;

	if (gwj->dst.dev->type != ARPHRD_CAN)
		goto out;

	/* is sending the skb back to the incoming interface intended? */
	if (gwj->src.dev == gwj->dst.dev &&
	    !(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK)) {
		err = -EINVAL;
		goto out;
	}

	ASSERT_RTNL();

	err = cgw_register_filter(net, gwj);
	if (!err)
		hlist_add_head_rcu(&gwj->list, &net->can.cgw_list);
out:
	if (err) {
		kmem_cache_free(cgw_cache, gwj);
out_free_cf:
		kfree(mod);
	}
	return err;
}

static void cgw_remove_all_jobs(struct net *net)
{
	struct cgw_job *gwj = NULL;
	struct hlist_node *nx;

	ASSERT_RTNL();

	hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
		hlist_del(&gwj->list);
		cgw_unregister_filter(net, gwj);
		call_rcu(&gwj->rcu, cgw_job_free_rcu);
	}
}

static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh,
			  struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct cgw_job *gwj = NULL;
	struct hlist_node *nx;
	struct rtcanmsg *r;
	struct cf_mod mod;
	struct can_can_gw ccgw;
	u8 limhops = 0;
	int err = 0;

	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (nlmsg_len(nlh) < sizeof(*r))
		return -EINVAL;

	r = nlmsg_data(nlh);
	if (r->can_family != AF_CAN)
		return -EPFNOSUPPORT;

	/* so far we only support CAN -> CAN routings */
	if (r->gwtype != CGW_TYPE_CAN_CAN)
		return -EINVAL;

	err = cgw_parse_attr(nlh, &mod, CGW_TYPE_CAN_CAN, &ccgw, &limhops);
	if (err < 0)
		return err;

	/* two interface indices both set to 0 => remove all entries */
	if (!ccgw.src_idx && !ccgw.dst_idx) {
		cgw_remove_all_jobs(net);
		return 0;
	}

	err = -EINVAL;

	ASSERT_RTNL();

	/* remove only the first matching entry */
	hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
		struct cf_mod *cf_mod;

		if (gwj->flags != r->flags)
			continue;

		if (gwj->limit_hops != limhops)
			continue;

		cf_mod = cgw_job_cf_mod(gwj);
		/* we have a match when uid is enabled and identical */
		if (cf_mod->uid || mod.uid) {
			if (cf_mod->uid != mod.uid)
				continue;
		} else {
			/* no uid => check for identical modifications */
			if (memcmp(cf_mod, &mod, sizeof(mod)))
				continue;
		}

		/* if (r->gwtype == CGW_TYPE_CAN_CAN) - is made sure here */
		if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
			continue;

		hlist_del(&gwj->list);
		cgw_unregister_filter(net, gwj);
		call_rcu(&gwj->rcu, cgw_job_free_rcu);
		err = 0;
		break;
	}

	return err;
}

static int __net_init cangw_pernet_init(struct net *net)
{
	INIT_HLIST_HEAD(&net->can.cgw_list);
	return 0;
}

static void __net_exit cangw_pernet_exit_batch(struct list_head *net_list)
{
	struct net *net;

	rtnl_lock();
	list_for_each_entry(net, net_list, exit_list)
		cgw_remove_all_jobs(net);
	rtnl_unlock();
}

static struct pernet_operations cangw_pernet_ops = {
	.init = cangw_pernet_init,
	.exit_batch = cangw_pernet_exit_batch,
};

static __init int cgw_module_init(void)
{
	int ret;

	/* sanitize given module parameter */
	max_hops = clamp_t(unsigned int, max_hops, CGW_MIN_HOPS, CGW_MAX_HOPS);

	pr_info("can: netlink gateway - max_hops=%d\n",	max_hops);

	ret = register_pernet_subsys(&cangw_pernet_ops);
	if (ret)
		return ret;

	ret = -ENOMEM;
	cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job),
				      0, 0, NULL);
	if (!cgw_cache)
		goto out_cache_create;

	/* set notifier */
	notifier.notifier_call = cgw_notifier;
	ret = register_netdevice_notifier(&notifier);
	if (ret)
		goto out_register_notifier;

	ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_GETROUTE,
				   NULL, cgw_dump_jobs, 0);
	if (ret)
		goto out_rtnl_register1;

	ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_NEWROUTE,
				   cgw_create_job, NULL, 0);
	if (ret)
		goto out_rtnl_register2;
	ret = rtnl_register_module(THIS_MODULE, PF_CAN, RTM_DELROUTE,
				   cgw_remove_job, NULL, 0);
	if (ret)
		goto out_rtnl_register3;

	return 0;

out_rtnl_register3:
	rtnl_unregister(PF_CAN, RTM_NEWROUTE);
out_rtnl_register2:
	rtnl_unregister(PF_CAN, RTM_GETROUTE);
out_rtnl_register1:
	unregister_netdevice_notifier(&notifier);
out_register_notifier:
	kmem_cache_destroy(cgw_cache);
out_cache_create:
	unregister_pernet_subsys(&cangw_pernet_ops);

	return ret;
}

static __exit void cgw_module_exit(void)
{
	rtnl_unregister_all(PF_CAN);

	unregister_netdevice_notifier(&notifier);

	unregister_pernet_subsys(&cangw_pernet_ops);
	rcu_barrier(); /* Wait for completion of call_rcu()'s */

	kmem_cache_destroy(cgw_cache);
}

module_init(cgw_module_init);
module_exit(cgw_module_exit);
