// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2023 Isovalent */

#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/filter.h>
#include <linux/netfilter_netdev.h>
#include <linux/bpf_mprog.h>
#include <linux/indirect_call_wrapper.h>

#include <net/netkit.h>
#include <net/dst.h>
#include <net/tcx.h>

#define DRV_NAME "netkit"

struct netkit {
	/* Needed in fast-path */
	struct net_device __rcu *peer;
	struct bpf_mprog_entry __rcu *active;
	enum netkit_action policy;
	struct bpf_mprog_bundle	bundle;

	/* Needed in slow-path */
	enum netkit_mode mode;
	bool primary;
	u32 headroom;
};

struct netkit_link {
	struct bpf_link link;
	struct net_device *dev;
	u32 location;
};

static __always_inline int
netkit_run(const struct bpf_mprog_entry *entry, struct sk_buff *skb,
	   enum netkit_action ret)
{
	const struct bpf_mprog_fp *fp;
	const struct bpf_prog *prog;

	bpf_mprog_foreach_prog(entry, fp, prog) {
		bpf_compute_data_pointers(skb);
		ret = bpf_prog_run(prog, skb);
		if (ret != NETKIT_NEXT)
			break;
	}
	return ret;
}

static void netkit_prep_forward(struct sk_buff *skb, bool xnet)
{
	skb_scrub_packet(skb, xnet);
	skb->priority = 0;
	nf_skip_egress(skb, true);
}

static struct netkit *netkit_priv(const struct net_device *dev)
{
	return netdev_priv(dev);
}

static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	enum netkit_action ret = READ_ONCE(nk->policy);
	netdev_tx_t ret_dev = NET_XMIT_SUCCESS;
	const struct bpf_mprog_entry *entry;
	struct net_device *peer;
	int len = skb->len;

	rcu_read_lock();
	peer = rcu_dereference(nk->peer);
	if (unlikely(!peer || !(peer->flags & IFF_UP) ||
		     !pskb_may_pull(skb, ETH_HLEN) ||
		     skb_orphan_frags(skb, GFP_ATOMIC)))
		goto drop;
	netkit_prep_forward(skb, !net_eq(dev_net(dev), dev_net(peer)));
	skb->dev = peer;
	entry = rcu_dereference(nk->active);
	if (entry)
		ret = netkit_run(entry, skb, ret);
	switch (ret) {
	case NETKIT_NEXT:
	case NETKIT_PASS:
		skb->protocol = eth_type_trans(skb, skb->dev);
		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
		if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
			dev_sw_netstats_tx_add(dev, 1, len);
			dev_sw_netstats_rx_add(peer, len);
		} else {
			goto drop_stats;
		}
		break;
	case NETKIT_REDIRECT:
		dev_sw_netstats_tx_add(dev, 1, len);
		skb_do_redirect(skb);
		break;
	case NETKIT_DROP:
	default:
drop:
		kfree_skb(skb);
drop_stats:
		dev_core_stats_tx_dropped_inc(dev);
		ret_dev = NET_XMIT_DROP;
		break;
	}
	rcu_read_unlock();
	return ret_dev;
}

static int netkit_open(struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);

	if (!peer)
		return -ENOTCONN;
	if (peer->flags & IFF_UP) {
		netif_carrier_on(dev);
		netif_carrier_on(peer);
	}
	return 0;
}

static int netkit_close(struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);

	netif_carrier_off(dev);
	if (peer)
		netif_carrier_off(peer);
	return 0;
}

static int netkit_get_iflink(const struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer;
	int iflink = 0;

	rcu_read_lock();
	peer = rcu_dereference(nk->peer);
	if (peer)
		iflink = peer->ifindex;
	rcu_read_unlock();
	return iflink;
}

static void netkit_set_multicast(struct net_device *dev)
{
	/* Nothing to do, we receive whatever gets pushed to us! */
}

static void netkit_set_headroom(struct net_device *dev, int headroom)
{
	struct netkit *nk = netkit_priv(dev), *nk2;
	struct net_device *peer;

	if (headroom < 0)
		headroom = NET_SKB_PAD;

	rcu_read_lock();
	peer = rcu_dereference(nk->peer);
	if (unlikely(!peer))
		goto out;

	nk2 = netkit_priv(peer);
	nk->headroom = headroom;
	headroom = max(nk->headroom, nk2->headroom);

	peer->needed_headroom = headroom;
	dev->needed_headroom = headroom;
out:
	rcu_read_unlock();
}

INDIRECT_CALLABLE_SCOPE struct net_device *netkit_peer_dev(struct net_device *dev)
{
	return rcu_dereference(netkit_priv(dev)->peer);
}

static void netkit_get_stats(struct net_device *dev,
			     struct rtnl_link_stats64 *stats)
{
	dev_fetch_sw_netstats(stats, dev->tstats);
	stats->tx_dropped = DEV_STATS_READ(dev, tx_dropped);
}

static void netkit_uninit(struct net_device *dev);

static const struct net_device_ops netkit_netdev_ops = {
	.ndo_open		= netkit_open,
	.ndo_stop		= netkit_close,
	.ndo_start_xmit		= netkit_xmit,
	.ndo_set_rx_mode	= netkit_set_multicast,
	.ndo_set_rx_headroom	= netkit_set_headroom,
	.ndo_get_iflink		= netkit_get_iflink,
	.ndo_get_peer_dev	= netkit_peer_dev,
	.ndo_get_stats64	= netkit_get_stats,
	.ndo_uninit		= netkit_uninit,
	.ndo_features_check	= passthru_features_check,
};

static void netkit_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
{
	strscpy(info->driver, DRV_NAME, sizeof(info->driver));
}

static const struct ethtool_ops netkit_ethtool_ops = {
	.get_drvinfo		= netkit_get_drvinfo,
};

static void netkit_setup(struct net_device *dev)
{
	static const netdev_features_t netkit_features_hw_vlan =
		NETIF_F_HW_VLAN_CTAG_TX |
		NETIF_F_HW_VLAN_CTAG_RX |
		NETIF_F_HW_VLAN_STAG_TX |
		NETIF_F_HW_VLAN_STAG_RX;
	static const netdev_features_t netkit_features =
		netkit_features_hw_vlan |
		NETIF_F_SG |
		NETIF_F_FRAGLIST |
		NETIF_F_HW_CSUM |
		NETIF_F_RXCSUM |
		NETIF_F_SCTP_CRC |
		NETIF_F_HIGHDMA |
		NETIF_F_GSO_SOFTWARE |
		NETIF_F_GSO_ENCAP_ALL;

	ether_setup(dev);
	dev->max_mtu = ETH_MAX_MTU;
	dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;

	dev->flags |= IFF_NOARP;
	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
	dev->priv_flags |= IFF_PHONY_HEADROOM;
	dev->priv_flags |= IFF_NO_QUEUE;

	dev->ethtool_ops = &netkit_ethtool_ops;
	dev->netdev_ops  = &netkit_netdev_ops;

	dev->features |= netkit_features | NETIF_F_LLTX;
	dev->hw_features = netkit_features;
	dev->hw_enc_features = netkit_features;
	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
	dev->vlan_features = dev->features & ~netkit_features_hw_vlan;

	dev->needs_free_netdev = true;

	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
}

static struct net *netkit_get_link_net(const struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);

	return peer ? dev_net(peer) : dev_net(dev);
}

static int netkit_check_policy(int policy, struct nlattr *tb,
			       struct netlink_ext_ack *extack)
{
	switch (policy) {
	case NETKIT_PASS:
	case NETKIT_DROP:
		return 0;
	default:
		NL_SET_ERR_MSG_ATTR(extack, tb,
				    "Provided default xmit policy not supported");
		return -EINVAL;
	}
}

static int netkit_check_mode(int mode, struct nlattr *tb,
			     struct netlink_ext_ack *extack)
{
	switch (mode) {
	case NETKIT_L2:
	case NETKIT_L3:
		return 0;
	default:
		NL_SET_ERR_MSG_ATTR(extack, tb,
				    "Provided device mode can only be L2 or L3");
		return -EINVAL;
	}
}

static int netkit_validate(struct nlattr *tb[], struct nlattr *data[],
			   struct netlink_ext_ack *extack)
{
	struct nlattr *attr = tb[IFLA_ADDRESS];

	if (!attr)
		return 0;
	NL_SET_ERR_MSG_ATTR(extack, attr,
			    "Setting Ethernet address is not supported");
	return -EOPNOTSUPP;
}

static struct rtnl_link_ops netkit_link_ops;

static int netkit_new_link(struct net *src_net, struct net_device *dev,
			   struct nlattr *tb[], struct nlattr *data[],
			   struct netlink_ext_ack *extack)
{
	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb, *attr;
	enum netkit_action default_prim = NETKIT_PASS;
	enum netkit_action default_peer = NETKIT_PASS;
	enum netkit_mode mode = NETKIT_L3;
	unsigned char ifname_assign_type;
	struct ifinfomsg *ifmp = NULL;
	struct net_device *peer;
	char ifname[IFNAMSIZ];
	struct netkit *nk;
	struct net *net;
	int err;

	if (data) {
		if (data[IFLA_NETKIT_MODE]) {
			attr = data[IFLA_NETKIT_MODE];
			mode = nla_get_u32(attr);
			err = netkit_check_mode(mode, attr, extack);
			if (err < 0)
				return err;
		}
		if (data[IFLA_NETKIT_PEER_INFO]) {
			attr = data[IFLA_NETKIT_PEER_INFO];
			ifmp = nla_data(attr);
			err = rtnl_nla_parse_ifinfomsg(peer_tb, attr, extack);
			if (err < 0)
				return err;
			err = netkit_validate(peer_tb, NULL, extack);
			if (err < 0)
				return err;
			tbp = peer_tb;
		}
		if (data[IFLA_NETKIT_POLICY]) {
			attr = data[IFLA_NETKIT_POLICY];
			default_prim = nla_get_u32(attr);
			err = netkit_check_policy(default_prim, attr, extack);
			if (err < 0)
				return err;
		}
		if (data[IFLA_NETKIT_PEER_POLICY]) {
			attr = data[IFLA_NETKIT_PEER_POLICY];
			default_peer = nla_get_u32(attr);
			err = netkit_check_policy(default_peer, attr, extack);
			if (err < 0)
				return err;
		}
	}

	if (ifmp && tbp[IFLA_IFNAME]) {
		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
		ifname_assign_type = NET_NAME_USER;
	} else {
		strscpy(ifname, "nk%d", IFNAMSIZ);
		ifname_assign_type = NET_NAME_ENUM;
	}

	net = rtnl_link_get_net(src_net, tbp);
	if (IS_ERR(net))
		return PTR_ERR(net);

	peer = rtnl_create_link(net, ifname, ifname_assign_type,
				&netkit_link_ops, tbp, extack);
	if (IS_ERR(peer)) {
		put_net(net);
		return PTR_ERR(peer);
	}

	netif_inherit_tso_max(peer, dev);

	if (mode == NETKIT_L2)
		eth_hw_addr_random(peer);
	if (ifmp && dev->ifindex)
		peer->ifindex = ifmp->ifi_index;

	nk = netkit_priv(peer);
	nk->primary = false;
	nk->policy = default_peer;
	nk->mode = mode;
	bpf_mprog_bundle_init(&nk->bundle);

	err = register_netdevice(peer);
	put_net(net);
	if (err < 0)
		goto err_register_peer;
	netif_carrier_off(peer);
	if (mode == NETKIT_L2)
		dev_change_flags(peer, peer->flags & ~IFF_NOARP, NULL);

	err = rtnl_configure_link(peer, NULL, 0, NULL);
	if (err < 0)
		goto err_configure_peer;

	if (mode == NETKIT_L2)
		eth_hw_addr_random(dev);
	if (tb[IFLA_IFNAME])
		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
	else
		strscpy(dev->name, "nk%d", IFNAMSIZ);

	nk = netkit_priv(dev);
	nk->primary = true;
	nk->policy = default_prim;
	nk->mode = mode;
	bpf_mprog_bundle_init(&nk->bundle);

	err = register_netdevice(dev);
	if (err < 0)
		goto err_configure_peer;
	netif_carrier_off(dev);
	if (mode == NETKIT_L2)
		dev_change_flags(dev, dev->flags & ~IFF_NOARP, NULL);

	rcu_assign_pointer(netkit_priv(dev)->peer, peer);
	rcu_assign_pointer(netkit_priv(peer)->peer, dev);
	return 0;
err_configure_peer:
	unregister_netdevice(peer);
	return err;
err_register_peer:
	free_netdev(peer);
	return err;
}

static struct bpf_mprog_entry *netkit_entry_fetch(struct net_device *dev,
						  bool bundle_fallback)
{
	struct netkit *nk = netkit_priv(dev);
	struct bpf_mprog_entry *entry;

	ASSERT_RTNL();
	entry = rcu_dereference_rtnl(nk->active);
	if (entry)
		return entry;
	if (bundle_fallback)
		return &nk->bundle.a;
	return NULL;
}

static void netkit_entry_update(struct net_device *dev,
				struct bpf_mprog_entry *entry)
{
	struct netkit *nk = netkit_priv(dev);

	ASSERT_RTNL();
	rcu_assign_pointer(nk->active, entry);
}

static void netkit_entry_sync(void)
{
	synchronize_rcu();
}

static struct net_device *netkit_dev_fetch(struct net *net, u32 ifindex, u32 which)
{
	struct net_device *dev;
	struct netkit *nk;

	ASSERT_RTNL();

	switch (which) {
	case BPF_NETKIT_PRIMARY:
	case BPF_NETKIT_PEER:
		break;
	default:
		return ERR_PTR(-EINVAL);
	}

	dev = __dev_get_by_index(net, ifindex);
	if (!dev)
		return ERR_PTR(-ENODEV);
	if (dev->netdev_ops != &netkit_netdev_ops)
		return ERR_PTR(-ENXIO);

	nk = netkit_priv(dev);
	if (!nk->primary)
		return ERR_PTR(-EACCES);
	if (which == BPF_NETKIT_PEER) {
		dev = rcu_dereference_rtnl(nk->peer);
		if (!dev)
			return ERR_PTR(-ENODEV);
	}
	return dev;
}

int netkit_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{
	struct bpf_mprog_entry *entry, *entry_new;
	struct bpf_prog *replace_prog = NULL;
	struct net_device *dev;
	int ret;

	rtnl_lock();
	dev = netkit_dev_fetch(current->nsproxy->net_ns, attr->target_ifindex,
			       attr->attach_type);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto out;
	}
	entry = netkit_entry_fetch(dev, true);
	if (attr->attach_flags & BPF_F_REPLACE) {
		replace_prog = bpf_prog_get_type(attr->replace_bpf_fd,
						 prog->type);
		if (IS_ERR(replace_prog)) {
			ret = PTR_ERR(replace_prog);
			replace_prog = NULL;
			goto out;
		}
	}
	ret = bpf_mprog_attach(entry, &entry_new, prog, NULL, replace_prog,
			       attr->attach_flags, attr->relative_fd,
			       attr->expected_revision);
	if (!ret) {
		if (entry != entry_new) {
			netkit_entry_update(dev, entry_new);
			netkit_entry_sync();
		}
		bpf_mprog_commit(entry);
	}
out:
	if (replace_prog)
		bpf_prog_put(replace_prog);
	rtnl_unlock();
	return ret;
}

int netkit_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog)
{
	struct bpf_mprog_entry *entry, *entry_new;
	struct net_device *dev;
	int ret;

	rtnl_lock();
	dev = netkit_dev_fetch(current->nsproxy->net_ns, attr->target_ifindex,
			       attr->attach_type);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto out;
	}
	entry = netkit_entry_fetch(dev, false);
	if (!entry) {
		ret = -ENOENT;
		goto out;
	}
	ret = bpf_mprog_detach(entry, &entry_new, prog, NULL, attr->attach_flags,
			       attr->relative_fd, attr->expected_revision);
	if (!ret) {
		if (!bpf_mprog_total(entry_new))
			entry_new = NULL;
		netkit_entry_update(dev, entry_new);
		netkit_entry_sync();
		bpf_mprog_commit(entry);
	}
out:
	rtnl_unlock();
	return ret;
}

int netkit_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
{
	struct net_device *dev;
	int ret;

	rtnl_lock();
	dev = netkit_dev_fetch(current->nsproxy->net_ns,
			       attr->query.target_ifindex,
			       attr->query.attach_type);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto out;
	}
	ret = bpf_mprog_query(attr, uattr, netkit_entry_fetch(dev, false));
out:
	rtnl_unlock();
	return ret;
}

static struct netkit_link *netkit_link(const struct bpf_link *link)
{
	return container_of(link, struct netkit_link, link);
}

static int netkit_link_prog_attach(struct bpf_link *link, u32 flags,
				   u32 id_or_fd, u64 revision)
{
	struct netkit_link *nkl = netkit_link(link);
	struct bpf_mprog_entry *entry, *entry_new;
	struct net_device *dev = nkl->dev;
	int ret;

	ASSERT_RTNL();
	entry = netkit_entry_fetch(dev, true);
	ret = bpf_mprog_attach(entry, &entry_new, link->prog, link, NULL, flags,
			       id_or_fd, revision);
	if (!ret) {
		if (entry != entry_new) {
			netkit_entry_update(dev, entry_new);
			netkit_entry_sync();
		}
		bpf_mprog_commit(entry);
	}
	return ret;
}

static void netkit_link_release(struct bpf_link *link)
{
	struct netkit_link *nkl = netkit_link(link);
	struct bpf_mprog_entry *entry, *entry_new;
	struct net_device *dev;
	int ret = 0;

	rtnl_lock();
	dev = nkl->dev;
	if (!dev)
		goto out;
	entry = netkit_entry_fetch(dev, false);
	if (!entry) {
		ret = -ENOENT;
		goto out;
	}
	ret = bpf_mprog_detach(entry, &entry_new, link->prog, link, 0, 0, 0);
	if (!ret) {
		if (!bpf_mprog_total(entry_new))
			entry_new = NULL;
		netkit_entry_update(dev, entry_new);
		netkit_entry_sync();
		bpf_mprog_commit(entry);
		nkl->dev = NULL;
	}
out:
	WARN_ON_ONCE(ret);
	rtnl_unlock();
}

static int netkit_link_update(struct bpf_link *link, struct bpf_prog *nprog,
			      struct bpf_prog *oprog)
{
	struct netkit_link *nkl = netkit_link(link);
	struct bpf_mprog_entry *entry, *entry_new;
	struct net_device *dev;
	int ret = 0;

	rtnl_lock();
	dev = nkl->dev;
	if (!dev) {
		ret = -ENOLINK;
		goto out;
	}
	if (oprog && link->prog != oprog) {
		ret = -EPERM;
		goto out;
	}
	oprog = link->prog;
	if (oprog == nprog) {
		bpf_prog_put(nprog);
		goto out;
	}
	entry = netkit_entry_fetch(dev, false);
	if (!entry) {
		ret = -ENOENT;
		goto out;
	}
	ret = bpf_mprog_attach(entry, &entry_new, nprog, link, oprog,
			       BPF_F_REPLACE | BPF_F_ID,
			       link->prog->aux->id, 0);
	if (!ret) {
		WARN_ON_ONCE(entry != entry_new);
		oprog = xchg(&link->prog, nprog);
		bpf_prog_put(oprog);
		bpf_mprog_commit(entry);
	}
out:
	rtnl_unlock();
	return ret;
}

static void netkit_link_dealloc(struct bpf_link *link)
{
	kfree(netkit_link(link));
}

static void netkit_link_fdinfo(const struct bpf_link *link, struct seq_file *seq)
{
	const struct netkit_link *nkl = netkit_link(link);
	u32 ifindex = 0;

	rtnl_lock();
	if (nkl->dev)
		ifindex = nkl->dev->ifindex;
	rtnl_unlock();

	seq_printf(seq, "ifindex:\t%u\n", ifindex);
	seq_printf(seq, "attach_type:\t%u (%s)\n",
		   nkl->location,
		   nkl->location == BPF_NETKIT_PRIMARY ? "primary" : "peer");
}

static int netkit_link_fill_info(const struct bpf_link *link,
				 struct bpf_link_info *info)
{
	const struct netkit_link *nkl = netkit_link(link);
	u32 ifindex = 0;

	rtnl_lock();
	if (nkl->dev)
		ifindex = nkl->dev->ifindex;
	rtnl_unlock();

	info->netkit.ifindex = ifindex;
	info->netkit.attach_type = nkl->location;
	return 0;
}

static int netkit_link_detach(struct bpf_link *link)
{
	netkit_link_release(link);
	return 0;
}

static const struct bpf_link_ops netkit_link_lops = {
	.release	= netkit_link_release,
	.detach		= netkit_link_detach,
	.dealloc	= netkit_link_dealloc,
	.update_prog	= netkit_link_update,
	.show_fdinfo	= netkit_link_fdinfo,
	.fill_link_info	= netkit_link_fill_info,
};

static int netkit_link_init(struct netkit_link *nkl,
			    struct bpf_link_primer *link_primer,
			    const union bpf_attr *attr,
			    struct net_device *dev,
			    struct bpf_prog *prog)
{
	bpf_link_init(&nkl->link, BPF_LINK_TYPE_NETKIT,
		      &netkit_link_lops, prog);
	nkl->location = attr->link_create.attach_type;
	nkl->dev = dev;
	return bpf_link_prime(&nkl->link, link_primer);
}

int netkit_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{
	struct bpf_link_primer link_primer;
	struct netkit_link *nkl;
	struct net_device *dev;
	int ret;

	rtnl_lock();
	dev = netkit_dev_fetch(current->nsproxy->net_ns,
			       attr->link_create.target_ifindex,
			       attr->link_create.attach_type);
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto out;
	}
	nkl = kzalloc(sizeof(*nkl), GFP_KERNEL_ACCOUNT);
	if (!nkl) {
		ret = -ENOMEM;
		goto out;
	}
	ret = netkit_link_init(nkl, &link_primer, attr, dev, prog);
	if (ret) {
		kfree(nkl);
		goto out;
	}
	ret = netkit_link_prog_attach(&nkl->link,
				      attr->link_create.flags,
				      attr->link_create.netkit.relative_fd,
				      attr->link_create.netkit.expected_revision);
	if (ret) {
		nkl->dev = NULL;
		bpf_link_cleanup(&link_primer);
		goto out;
	}
	ret = bpf_link_settle(&link_primer);
out:
	rtnl_unlock();
	return ret;
}

static void netkit_release_all(struct net_device *dev)
{
	struct bpf_mprog_entry *entry;
	struct bpf_tuple tuple = {};
	struct bpf_mprog_fp *fp;
	struct bpf_mprog_cp *cp;

	entry = netkit_entry_fetch(dev, false);
	if (!entry)
		return;
	netkit_entry_update(dev, NULL);
	netkit_entry_sync();
	bpf_mprog_foreach_tuple(entry, fp, cp, tuple) {
		if (tuple.link)
			netkit_link(tuple.link)->dev = NULL;
		else
			bpf_prog_put(tuple.prog);
	}
}

static void netkit_uninit(struct net_device *dev)
{
	netkit_release_all(dev);
}

static void netkit_del_link(struct net_device *dev, struct list_head *head)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);

	RCU_INIT_POINTER(nk->peer, NULL);
	unregister_netdevice_queue(dev, head);
	if (peer) {
		nk = netkit_priv(peer);
		RCU_INIT_POINTER(nk->peer, NULL);
		unregister_netdevice_queue(peer, head);
	}
}

static int netkit_change_link(struct net_device *dev, struct nlattr *tb[],
			      struct nlattr *data[],
			      struct netlink_ext_ack *extack)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);
	enum netkit_action policy;
	struct nlattr *attr;
	int err;

	if (!nk->primary) {
		NL_SET_ERR_MSG(extack,
			       "netkit link settings can be changed only through the primary device");
		return -EACCES;
	}

	if (data[IFLA_NETKIT_MODE]) {
		NL_SET_ERR_MSG_ATTR(extack, data[IFLA_NETKIT_MODE],
				    "netkit link operating mode cannot be changed after device creation");
		return -EACCES;
	}

	if (data[IFLA_NETKIT_PEER_INFO]) {
		NL_SET_ERR_MSG_ATTR(extack, data[IFLA_NETKIT_PEER_INFO],
				    "netkit peer info cannot be changed after device creation");
		return -EINVAL;
	}

	if (data[IFLA_NETKIT_POLICY]) {
		attr = data[IFLA_NETKIT_POLICY];
		policy = nla_get_u32(attr);
		err = netkit_check_policy(policy, attr, extack);
		if (err)
			return err;
		WRITE_ONCE(nk->policy, policy);
	}

	if (data[IFLA_NETKIT_PEER_POLICY]) {
		err = -EOPNOTSUPP;
		attr = data[IFLA_NETKIT_PEER_POLICY];
		policy = nla_get_u32(attr);
		if (peer)
			err = netkit_check_policy(policy, attr, extack);
		if (err)
			return err;
		nk = netkit_priv(peer);
		WRITE_ONCE(nk->policy, policy);
	}

	return 0;
}

static size_t netkit_get_size(const struct net_device *dev)
{
	return nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_POLICY */
	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_PEER_POLICY */
	       nla_total_size(sizeof(u8))  + /* IFLA_NETKIT_PRIMARY */
	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_MODE */
	       0;
}

static int netkit_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
	struct netkit *nk = netkit_priv(dev);
	struct net_device *peer = rtnl_dereference(nk->peer);

	if (nla_put_u8(skb, IFLA_NETKIT_PRIMARY, nk->primary))
		return -EMSGSIZE;
	if (nla_put_u32(skb, IFLA_NETKIT_POLICY, nk->policy))
		return -EMSGSIZE;
	if (nla_put_u32(skb, IFLA_NETKIT_MODE, nk->mode))
		return -EMSGSIZE;

	if (peer) {
		nk = netkit_priv(peer);
		if (nla_put_u32(skb, IFLA_NETKIT_PEER_POLICY, nk->policy))
			return -EMSGSIZE;
	}

	return 0;
}

static const struct nla_policy netkit_policy[IFLA_NETKIT_MAX + 1] = {
	[IFLA_NETKIT_PEER_INFO]		= { .len = sizeof(struct ifinfomsg) },
	[IFLA_NETKIT_POLICY]		= { .type = NLA_U32 },
	[IFLA_NETKIT_MODE]		= { .type = NLA_U32 },
	[IFLA_NETKIT_PEER_POLICY]	= { .type = NLA_U32 },
	[IFLA_NETKIT_PRIMARY]		= { .type = NLA_REJECT,
					    .reject_message = "Primary attribute is read-only" },
};

static struct rtnl_link_ops netkit_link_ops = {
	.kind		= DRV_NAME,
	.priv_size	= sizeof(struct netkit),
	.setup		= netkit_setup,
	.newlink	= netkit_new_link,
	.dellink	= netkit_del_link,
	.changelink	= netkit_change_link,
	.get_link_net	= netkit_get_link_net,
	.get_size	= netkit_get_size,
	.fill_info	= netkit_fill_info,
	.policy		= netkit_policy,
	.validate	= netkit_validate,
	.maxtype	= IFLA_NETKIT_MAX,
};

static __init int netkit_init(void)
{
	BUILD_BUG_ON((int)NETKIT_NEXT != (int)TCX_NEXT ||
		     (int)NETKIT_PASS != (int)TCX_PASS ||
		     (int)NETKIT_DROP != (int)TCX_DROP ||
		     (int)NETKIT_REDIRECT != (int)TCX_REDIRECT);

	return rtnl_link_register(&netkit_link_ops);
}

static __exit void netkit_exit(void)
{
	rtnl_link_unregister(&netkit_link_ops);
}

module_init(netkit_init);
module_exit(netkit_exit);

MODULE_DESCRIPTION("BPF-programmable network device");
MODULE_AUTHOR("Daniel Borkmann <daniel@iogearbox.net>");
MODULE_AUTHOR("Nikolay Aleksandrov <razor@blackwall.org>");
MODULE_LICENSE("GPL");
MODULE_ALIAS_RTNL_LINK(DRV_NAME);
