Re: [PATCH bpf-next 01/10] bpf: Add initial fd-based API to attach tc BPF programs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/4/22 4:11 PM, Daniel Borkmann wrote:
diff --git a/kernel/bpf/net.c b/kernel/bpf/net.c
new file mode 100644
index 000000000000..ab9a9dee615b
--- /dev/null
+++ b/kernel/bpf/net.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2022 Isovalent */
+
+#include <linux/bpf.h>
+#include <linux/filter.h>
+#include <linux/netdevice.h>
+
+#include <net/xtc.h>
+
+static int __xtc_prog_attach(struct net_device *dev, bool ingress, u32 limit,
+			     struct bpf_prog *nprog, u32 prio, u32 flags)
+{
+	struct bpf_prog_array_item *item, *tmp;
+	struct xtc_entry *entry, *peer;
+	struct bpf_prog *oprog;
+	bool created;
+	int i, j;
+
+	ASSERT_RTNL();
+
+	entry = dev_xtc_entry_fetch(dev, ingress, &created);
+	if (!entry)
+		return -ENOMEM;
+	for (i = 0; i < limit; i++) {
+		item = &entry->items[i];
+		oprog = item->prog;
+		if (!oprog)
+			break;
+		if (item->bpf_priority == prio) {
+			if (flags & BPF_F_REPLACE) {
+				/* Pairs with READ_ONCE() in xtc_run_progs(). */
+				WRITE_ONCE(item->prog, nprog);
+				bpf_prog_put(oprog);
+				dev_xtc_entry_prio_set(entry, prio, nprog);
+				return prio;
+			}
+			return -EBUSY;
+		}
+	}
+	if (dev_xtc_entry_total(entry) >= limit)
+		return -ENOSPC;
+	prio = dev_xtc_entry_prio_new(entry, prio, nprog);
+	if (prio < 0) {
+		if (created)
+			dev_xtc_entry_free(entry);
+		return -ENOMEM;
+	}
+	peer = dev_xtc_entry_peer(entry);
+	dev_xtc_entry_clear(peer);
+	for (i = 0, j = 0; i < limit; i++, j++) {
+		item = &entry->items[i];
+		tmp = &peer->items[j];
+		oprog = item->prog;
+		if (!oprog) {
+			if (i == j) {
+				tmp->prog = nprog;
+				tmp->bpf_priority = prio;
+			}
+			break;
+		} else if (item->bpf_priority < prio) {
+			tmp->prog = oprog;
+			tmp->bpf_priority = item->bpf_priority;
+		} else if (item->bpf_priority > prio) {
+			if (i == j) {
+				tmp->prog = nprog;
+				tmp->bpf_priority = prio;
+				tmp = &peer->items[++j];
+			}
+			tmp->prog = oprog;
+			tmp->bpf_priority = item->bpf_priority;
+		}
+	}
+	dev_xtc_entry_update(dev, peer, ingress);
+	if (ingress)
+		net_inc_ingress_queue();
+	else
+		net_inc_egress_queue();
+	xtc_inc();
+	return prio;
+}
+
+int xtc_prog_attach(const union bpf_attr *attr, struct bpf_prog *nprog)
+{
+	struct net *net = current->nsproxy->net_ns;
+	bool ingress = attr->attach_type == BPF_NET_INGRESS;
+	struct net_device *dev;
+	int ret;
+
+	if (attr->attach_flags & ~BPF_F_REPLACE)
+		return -EINVAL;

After looking at patch 3, I think it needs to check the attach_priority is non zero when BPF_F_REPLACE is set.

Then the __xtc_prog_attach() should return -ENOENT for BPF_F_REPLACE when prio is not found instead of continuing to dev_xtc_entry_prio_new().

However, all these probably could go away if the decision on the prio discussion is to avoid it.


+	rtnl_lock();
+	dev = __dev_get_by_index(net, attr->target_ifindex);
+	if (!dev) {
+		rtnl_unlock();
+		return -EINVAL;
+	}
+	ret = __xtc_prog_attach(dev, ingress, XTC_MAX_ENTRIES, nprog,
+				attr->attach_priority, attr->attach_flags);
+	rtnl_unlock();
+	return ret;
+}
+




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux