* [PATCH bpf-next v6 1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag
2023-07-21 20:22 [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF Daniel Xu
@ 2023-07-21 20:22 ` Daniel Xu
2023-07-28 9:16 ` Florian Westphal
2023-07-21 20:22 ` [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link Daniel Xu
2023-07-29 0:00 ` [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF patchwork-bot+netdevbpf
2 siblings, 1 reply; 8+ messages in thread
From: Daniel Xu @ 2023-07-21 20:22 UTC (permalink / raw)
To: kadlec, edumazet, fw, kuba, pabeni, pablo, dsahern, davem,
alexei.starovoitov, daniel
Cc: netfilter-devel, coreteam, linux-kernel, netdev, bpf
We want to be able to enable/disable IP packet defrag from core
bpf/netfilter code. In other words, execute code from core that could
possibly be built as a module.
To help avoid symbol resolution errors, use glue hooks that the modules
will register callbacks with during module init.
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
---
include/linux/netfilter.h | 10 ++++++++++
net/ipv4/netfilter/nf_defrag_ipv4.c | 17 ++++++++++++++++-
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 11 +++++++++++
net/netfilter/core.c | 6 ++++++
4 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index d4fed4c508ca..d68644b7c299 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -11,6 +11,7 @@
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/static_key.h>
+#include <linux/module.h>
#include <linux/netfilter_defs.h>
#include <linux/netdevice.h>
#include <linux/sockptr.h>
@@ -481,6 +482,15 @@ struct nfnl_ct_hook {
};
extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;
+struct nf_defrag_hook {
+ struct module *owner;
+ int (*enable)(struct net *net);
+ void (*disable)(struct net *net);
+};
+
+extern const struct nf_defrag_hook __rcu *nf_defrag_v4_hook;
+extern const struct nf_defrag_hook __rcu *nf_defrag_v6_hook;
+
/*
* nf_skb_duplicated - TEE target has sent a packet
*
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index e61ea428ea18..a9ba7de092c4 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -7,6 +7,7 @@
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/module.h>
+#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <net/netns/generic.h>
#include <net/route.h>
@@ -113,17 +114,31 @@ static void __net_exit defrag4_net_exit(struct net *net)
}
}
+static const struct nf_defrag_hook defrag_hook = {
+ .owner = THIS_MODULE,
+ .enable = nf_defrag_ipv4_enable,
+ .disable = nf_defrag_ipv4_disable,
+};
+
static struct pernet_operations defrag4_net_ops = {
.exit = defrag4_net_exit,
};
static int __init nf_defrag_init(void)
{
- return register_pernet_subsys(&defrag4_net_ops);
+ int err;
+
+ err = register_pernet_subsys(&defrag4_net_ops);
+ if (err)
+ return err;
+
+ rcu_assign_pointer(nf_defrag_v4_hook, &defrag_hook);
+ return err;
}
static void __exit nf_defrag_fini(void)
{
+ rcu_assign_pointer(nf_defrag_v4_hook, NULL);
unregister_pernet_subsys(&defrag4_net_ops);
}
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index cb4eb1d2c620..d59b296b4f51 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmp.h>
+#include <linux/rcupdate.h>
#include <linux/sysctl.h>
#include <net/ipv6_frag.h>
@@ -96,6 +97,12 @@ static void __net_exit defrag6_net_exit(struct net *net)
}
}
+static const struct nf_defrag_hook defrag_hook = {
+ .owner = THIS_MODULE,
+ .enable = nf_defrag_ipv6_enable,
+ .disable = nf_defrag_ipv6_disable,
+};
+
static struct pernet_operations defrag6_net_ops = {
.exit = defrag6_net_exit,
};
@@ -114,6 +121,9 @@ static int __init nf_defrag_init(void)
pr_err("nf_defrag_ipv6: can't register pernet ops\n");
goto cleanup_frag6;
}
+
+ rcu_assign_pointer(nf_defrag_v6_hook, &defrag_hook);
+
return ret;
cleanup_frag6:
@@ -124,6 +134,7 @@ static int __init nf_defrag_init(void)
static void __exit nf_defrag_fini(void)
{
+ rcu_assign_pointer(nf_defrag_v6_hook, NULL);
unregister_pernet_subsys(&defrag6_net_ops);
nf_ct_frag6_cleanup();
}
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 5f76ae86a656..ef4e76e5aef9 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -680,6 +680,12 @@ EXPORT_SYMBOL_GPL(nfnl_ct_hook);
const struct nf_ct_hook __rcu *nf_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_hook);
+const struct nf_defrag_hook __rcu *nf_defrag_v4_hook __read_mostly;
+EXPORT_SYMBOL_GPL(nf_defrag_v4_hook);
+
+const struct nf_defrag_hook __rcu *nf_defrag_v6_hook __read_mostly;
+EXPORT_SYMBOL_GPL(nf_defrag_v6_hook);
+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
u8 nf_ctnetlink_has_listener;
EXPORT_SYMBOL_GPL(nf_ctnetlink_has_listener);
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH bpf-next v6 1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag
2023-07-21 20:22 ` [PATCH bpf-next v6 1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag Daniel Xu
@ 2023-07-28 9:16 ` Florian Westphal
0 siblings, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2023-07-28 9:16 UTC (permalink / raw)
To: Daniel Xu
Cc: kadlec, edumazet, fw, kuba, pabeni, pablo, dsahern, davem,
alexei.starovoitov, daniel, netfilter-devel, coreteam,
linux-kernel, netdev, bpf
Daniel Xu <dxu@dxuuu.xyz> wrote:
> We want to be able to enable/disable IP packet defrag from core
> bpf/netfilter code. In other words, execute code from core that could
> possibly be built as a module.
>
> To help avoid symbol resolution errors, use glue hooks that the modules
> will register callbacks with during module init.
Reviewed-by: Florian Westphal <fw@strlen.de>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link
2023-07-21 20:22 [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF Daniel Xu
2023-07-21 20:22 ` [PATCH bpf-next v6 1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag Daniel Xu
@ 2023-07-21 20:22 ` Daniel Xu
2023-07-28 1:16 ` Alexei Starovoitov
2023-07-28 9:52 ` Florian Westphal
2023-07-29 0:00 ` [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF patchwork-bot+netdevbpf
2 siblings, 2 replies; 8+ messages in thread
From: Daniel Xu @ 2023-07-21 20:22 UTC (permalink / raw)
To: daniel, kadlec, edumazet, ast, fw, kuba, pabeni, pablo, andrii,
davem, alexei.starovoitov
Cc: martin.lau, song, yhs, john.fastabend, kpsingh, sdf, haoluo,
jolsa, bpf, linux-kernel, netfilter-devel, coreteam, netdev,
dsahern
This commit adds support for enabling IP defrag using pre-existing
netfilter defrag support. Basically all the flag does is bump a refcnt
while the link the active. Checks are also added to ensure the prog
requesting defrag support is run _after_ netfilter defrag hooks.
We also take care to avoid any issues w.r.t. module unloading -- while
defrag is active on a link, the module is prevented from unloading.
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
---
include/uapi/linux/bpf.h | 5 ++
net/netfilter/nf_bpf_link.c | 123 +++++++++++++++++++++++++++++----
tools/include/uapi/linux/bpf.h | 5 ++
3 files changed, 118 insertions(+), 15 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 739c15906a65..12a5480314a2 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1187,6 +1187,11 @@ enum bpf_perf_event_type {
*/
#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
+/* link_create.netfilter.flags used in LINK_CREATE command for
+ * BPF_PROG_TYPE_NETFILTER to enable IP packet defragmentation.
+ */
+#define BPF_F_NETFILTER_IP_DEFRAG (1U << 0)
+
/* When BPF ldimm64's insn[0].src_reg != 0 then this can have
* the following extensions:
*
diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c
index c36da56d756f..8fe594bbc7e2 100644
--- a/net/netfilter/nf_bpf_link.c
+++ b/net/netfilter/nf_bpf_link.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include <linux/filter.h>
+#include <linux/kmod.h>
+#include <linux/module.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_bpf_link.h>
@@ -23,8 +25,88 @@ struct bpf_nf_link {
struct nf_hook_ops hook_ops;
struct net *net;
u32 dead;
+ const struct nf_defrag_hook *defrag_hook;
};
+static const struct nf_defrag_hook *
+get_proto_defrag_hook(struct bpf_nf_link *link,
+ const struct nf_defrag_hook __rcu *global_hook,
+ const char *mod)
+{
+ const struct nf_defrag_hook *hook;
+ int err;
+
+ /* RCU protects us from races against module unloading */
+ rcu_read_lock();
+ hook = rcu_dereference(global_hook);
+ if (!hook) {
+ rcu_read_unlock();
+ err = request_module(mod);
+ if (err)
+ return ERR_PTR(err < 0 ? err : -EINVAL);
+
+ rcu_read_lock();
+ hook = rcu_dereference(global_hook);
+ }
+
+ if (hook && try_module_get(hook->owner)) {
+ /* Once we have a refcnt on the module, we no longer need RCU */
+ hook = rcu_pointer_handoff(hook);
+ } else {
+ WARN_ONCE(!hook, "%s has bad registration", mod);
+ hook = ERR_PTR(-ENOENT);
+ }
+ rcu_read_unlock();
+
+ if (!IS_ERR(hook)) {
+ err = hook->enable(link->net);
+ if (err) {
+ module_put(hook->owner);
+ hook = ERR_PTR(err);
+ }
+ }
+
+ return hook;
+}
+
+static int bpf_nf_enable_defrag(struct bpf_nf_link *link)
+{
+ const struct nf_defrag_hook __maybe_unused *hook;
+
+ switch (link->hook_ops.pf) {
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+ case NFPROTO_IPV4:
+ hook = get_proto_defrag_hook(link, nf_defrag_v4_hook, "nf_defrag_ipv4");
+ if (IS_ERR(hook))
+ return PTR_ERR(hook);
+
+ link->defrag_hook = hook;
+ return 0;
+#endif
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+ case NFPROTO_IPV6:
+ hook = get_proto_defrag_hook(link, nf_defrag_v6_hook, "nf_defrag_ipv6");
+ if (IS_ERR(hook))
+ return PTR_ERR(hook);
+
+ link->defrag_hook = hook;
+ return 0;
+#endif
+ default:
+ return -EAFNOSUPPORT;
+ }
+}
+
+static void bpf_nf_disable_defrag(struct bpf_nf_link *link)
+{
+ const struct nf_defrag_hook *hook = link->defrag_hook;
+
+ if (!hook)
+ return;
+ hook->disable(link->net);
+ module_put(hook->owner);
+}
+
static void bpf_nf_link_release(struct bpf_link *link)
{
struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
@@ -32,11 +114,11 @@ static void bpf_nf_link_release(struct bpf_link *link)
if (nf_link->dead)
return;
- /* prevent hook-not-found warning splat from netfilter core when
- * .detach was already called
- */
- if (!cmpxchg(&nf_link->dead, 0, 1))
+ /* do not double release in case .detach was already called */
+ if (!cmpxchg(&nf_link->dead, 0, 1)) {
nf_unregister_net_hook(nf_link->net, &nf_link->hook_ops);
+ bpf_nf_disable_defrag(nf_link);
+ }
}
static void bpf_nf_link_dealloc(struct bpf_link *link)
@@ -92,6 +174,8 @@ static const struct bpf_link_ops bpf_nf_link_lops = {
static int bpf_nf_check_pf_and_hooks(const union bpf_attr *attr)
{
+ int prio;
+
switch (attr->link_create.netfilter.pf) {
case NFPROTO_IPV4:
case NFPROTO_IPV6:
@@ -102,19 +186,18 @@ static int bpf_nf_check_pf_and_hooks(const union bpf_attr *attr)
return -EAFNOSUPPORT;
}
- if (attr->link_create.netfilter.flags)
+ if (attr->link_create.netfilter.flags & ~BPF_F_NETFILTER_IP_DEFRAG)
return -EOPNOTSUPP;
- /* make sure conntrack confirm is always last.
- *
- * In the future, if userspace can e.g. request defrag, then
- * "defrag_requested && prio before NF_IP_PRI_CONNTRACK_DEFRAG"
- * should fail.
- */
- switch (attr->link_create.netfilter.priority) {
- case NF_IP_PRI_FIRST: return -ERANGE; /* sabotage_in and other warts */
- case NF_IP_PRI_LAST: return -ERANGE; /* e.g. conntrack confirm */
- }
+ /* make sure conntrack confirm is always last */
+ prio = attr->link_create.netfilter.priority;
+ if (prio == NF_IP_PRI_FIRST)
+ return -ERANGE; /* sabotage_in and other warts */
+ else if (prio == NF_IP_PRI_LAST)
+ return -ERANGE; /* e.g. conntrack confirm */
+ else if ((attr->link_create.netfilter.flags & BPF_F_NETFILTER_IP_DEFRAG) &&
+ prio <= NF_IP_PRI_CONNTRACK_DEFRAG)
+ return -ERANGE; /* cannot use defrag if prog runs before nf_defrag */
return 0;
}
@@ -149,6 +232,7 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
link->net = net;
link->dead = false;
+ link->defrag_hook = NULL;
err = bpf_link_prime(&link->link, &link_primer);
if (err) {
@@ -156,8 +240,17 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
return err;
}
+ if (attr->link_create.netfilter.flags & BPF_F_NETFILTER_IP_DEFRAG) {
+ err = bpf_nf_enable_defrag(link);
+ if (err) {
+ bpf_link_cleanup(&link_primer);
+ return err;
+ }
+ }
+
err = nf_register_net_hook(net, &link->hook_ops);
if (err) {
+ bpf_nf_disable_defrag(link);
bpf_link_cleanup(&link_primer);
return err;
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 739c15906a65..12a5480314a2 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1187,6 +1187,11 @@ enum bpf_perf_event_type {
*/
#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
+/* link_create.netfilter.flags used in LINK_CREATE command for
+ * BPF_PROG_TYPE_NETFILTER to enable IP packet defragmentation.
+ */
+#define BPF_F_NETFILTER_IP_DEFRAG (1U << 0)
+
/* When BPF ldimm64's insn[0].src_reg != 0 then this can have
* the following extensions:
*
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link
2023-07-21 20:22 ` [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link Daniel Xu
@ 2023-07-28 1:16 ` Alexei Starovoitov
2023-07-28 4:37 ` Daniel Xu
2023-07-28 9:52 ` Florian Westphal
1 sibling, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2023-07-28 1:16 UTC (permalink / raw)
To: Daniel Xu
Cc: daniel, kadlec, edumazet, ast, fw, kuba, pabeni, pablo, andrii,
davem, martin.lau, song, yhs, john.fastabend, kpsingh, sdf,
haoluo, jolsa, bpf, linux-kernel, netfilter-devel, coreteam,
netdev, dsahern
On Fri, Jul 21, 2023 at 02:22:46PM -0600, Daniel Xu wrote:
> This commit adds support for enabling IP defrag using pre-existing
> netfilter defrag support. Basically all the flag does is bump a refcnt
> while the link the active. Checks are also added to ensure the prog
> requesting defrag support is run _after_ netfilter defrag hooks.
>
> We also take care to avoid any issues w.r.t. module unloading -- while
> defrag is active on a link, the module is prevented from unloading.
>
> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> ---
> include/uapi/linux/bpf.h | 5 ++
> net/netfilter/nf_bpf_link.c | 123 +++++++++++++++++++++++++++++----
> tools/include/uapi/linux/bpf.h | 5 ++
> 3 files changed, 118 insertions(+), 15 deletions(-)
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 739c15906a65..12a5480314a2 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -1187,6 +1187,11 @@ enum bpf_perf_event_type {
> */
> #define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
>
> +/* link_create.netfilter.flags used in LINK_CREATE command for
> + * BPF_PROG_TYPE_NETFILTER to enable IP packet defragmentation.
> + */
> +#define BPF_F_NETFILTER_IP_DEFRAG (1U << 0)
> +
> /* When BPF ldimm64's insn[0].src_reg != 0 then this can have
> * the following extensions:
> *
> diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c
> index c36da56d756f..8fe594bbc7e2 100644
> --- a/net/netfilter/nf_bpf_link.c
> +++ b/net/netfilter/nf_bpf_link.c
> @@ -1,6 +1,8 @@
> // SPDX-License-Identifier: GPL-2.0
> #include <linux/bpf.h>
> #include <linux/filter.h>
> +#include <linux/kmod.h>
> +#include <linux/module.h>
> #include <linux/netfilter.h>
>
> #include <net/netfilter/nf_bpf_link.h>
> @@ -23,8 +25,88 @@ struct bpf_nf_link {
> struct nf_hook_ops hook_ops;
> struct net *net;
> u32 dead;
> + const struct nf_defrag_hook *defrag_hook;
> };
>
> +static const struct nf_defrag_hook *
> +get_proto_defrag_hook(struct bpf_nf_link *link,
> + const struct nf_defrag_hook __rcu *global_hook,
> + const char *mod)
> +{
> + const struct nf_defrag_hook *hook;
> + int err;
> +
> + /* RCU protects us from races against module unloading */
> + rcu_read_lock();
> + hook = rcu_dereference(global_hook);
> + if (!hook) {
> + rcu_read_unlock();
> + err = request_module(mod);
> + if (err)
> + return ERR_PTR(err < 0 ? err : -EINVAL);
> +
> + rcu_read_lock();
> + hook = rcu_dereference(global_hook);
> + }
> +
> + if (hook && try_module_get(hook->owner)) {
> + /* Once we have a refcnt on the module, we no longer need RCU */
> + hook = rcu_pointer_handoff(hook);
> + } else {
> + WARN_ONCE(!hook, "%s has bad registration", mod);
> + hook = ERR_PTR(-ENOENT);
> + }
> + rcu_read_unlock();
> +
> + if (!IS_ERR(hook)) {
> + err = hook->enable(link->net);
> + if (err) {
> + module_put(hook->owner);
> + hook = ERR_PTR(err);
> + }
> + }
> +
> + return hook;
The rcu + module_get logic looks correct to me, but you've dropped all Florian's acks.
What's going on?
We need explicit acks to merge this through bpf-next.
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link
2023-07-28 1:16 ` Alexei Starovoitov
@ 2023-07-28 4:37 ` Daniel Xu
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Xu @ 2023-07-28 4:37 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: daniel, kadlec, edumazet, ast, fw, kuba, pabeni, pablo, andrii,
davem, martin.lau, song, yhs, john.fastabend, kpsingh, sdf,
haoluo, jolsa, bpf, linux-kernel, netfilter-devel, coreteam,
netdev, dsahern
Hi Alexei,
On Thu, Jul 27, 2023 at 06:16:20PM -0700, Alexei Starovoitov wrote:
> On Fri, Jul 21, 2023 at 02:22:46PM -0600, Daniel Xu wrote:
> > This commit adds support for enabling IP defrag using pre-existing
> > netfilter defrag support. Basically all the flag does is bump a refcnt
> > while the link the active. Checks are also added to ensure the prog
> > requesting defrag support is run _after_ netfilter defrag hooks.
> >
> > We also take care to avoid any issues w.r.t. module unloading -- while
> > defrag is active on a link, the module is prevented from unloading.
> >
> > Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> > ---
> > include/uapi/linux/bpf.h | 5 ++
> > net/netfilter/nf_bpf_link.c | 123 +++++++++++++++++++++++++++++----
> > tools/include/uapi/linux/bpf.h | 5 ++
> > 3 files changed, 118 insertions(+), 15 deletions(-)
> >
> > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> > index 739c15906a65..12a5480314a2 100644
> > --- a/include/uapi/linux/bpf.h
> > +++ b/include/uapi/linux/bpf.h
> > @@ -1187,6 +1187,11 @@ enum bpf_perf_event_type {
> > */
> > #define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
> >
> > +/* link_create.netfilter.flags used in LINK_CREATE command for
> > + * BPF_PROG_TYPE_NETFILTER to enable IP packet defragmentation.
> > + */
> > +#define BPF_F_NETFILTER_IP_DEFRAG (1U << 0)
> > +
> > /* When BPF ldimm64's insn[0].src_reg != 0 then this can have
> > * the following extensions:
> > *
> > diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c
> > index c36da56d756f..8fe594bbc7e2 100644
> > --- a/net/netfilter/nf_bpf_link.c
> > +++ b/net/netfilter/nf_bpf_link.c
> > @@ -1,6 +1,8 @@
> > // SPDX-License-Identifier: GPL-2.0
> > #include <linux/bpf.h>
> > #include <linux/filter.h>
> > +#include <linux/kmod.h>
> > +#include <linux/module.h>
> > #include <linux/netfilter.h>
> >
> > #include <net/netfilter/nf_bpf_link.h>
> > @@ -23,8 +25,88 @@ struct bpf_nf_link {
> > struct nf_hook_ops hook_ops;
> > struct net *net;
> > u32 dead;
> > + const struct nf_defrag_hook *defrag_hook;
> > };
> >
> > +static const struct nf_defrag_hook *
> > +get_proto_defrag_hook(struct bpf_nf_link *link,
> > + const struct nf_defrag_hook __rcu *global_hook,
> > + const char *mod)
> > +{
> > + const struct nf_defrag_hook *hook;
> > + int err;
> > +
> > + /* RCU protects us from races against module unloading */
> > + rcu_read_lock();
> > + hook = rcu_dereference(global_hook);
> > + if (!hook) {
> > + rcu_read_unlock();
> > + err = request_module(mod);
> > + if (err)
> > + return ERR_PTR(err < 0 ? err : -EINVAL);
> > +
> > + rcu_read_lock();
> > + hook = rcu_dereference(global_hook);
> > + }
> > +
> > + if (hook && try_module_get(hook->owner)) {
> > + /* Once we have a refcnt on the module, we no longer need RCU */
> > + hook = rcu_pointer_handoff(hook);
> > + } else {
> > + WARN_ONCE(!hook, "%s has bad registration", mod);
> > + hook = ERR_PTR(-ENOENT);
> > + }
> > + rcu_read_unlock();
> > +
> > + if (!IS_ERR(hook)) {
> > + err = hook->enable(link->net);
> > + if (err) {
> > + module_put(hook->owner);
> > + hook = ERR_PTR(err);
> > + }
> > + }
> > +
> > + return hook;
>
> The rcu + module_get logic looks correct to me, but you've dropped all Florian's acks.
> What's going on?
>
> We need explicit acks to merge this through bpf-next.
I understood acked-by tags to be a lighter form of reviewed-by tag. So
b/c the patches changed so much I dropped the tag. It sounds like maybe
I misunderstand -- I'll keep it in mind the next time around.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link
2023-07-21 20:22 ` [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link Daniel Xu
2023-07-28 1:16 ` Alexei Starovoitov
@ 2023-07-28 9:52 ` Florian Westphal
1 sibling, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2023-07-28 9:52 UTC (permalink / raw)
To: Daniel Xu
Cc: daniel, kadlec, edumazet, ast, fw, kuba, pabeni, pablo, andrii,
davem, alexei.starovoitov, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, bpf, linux-kernel, netfilter-devel,
coreteam, netdev, dsahern
Daniel Xu <dxu@dxuuu.xyz> wrote:
> This commit adds support for enabling IP defrag using pre-existing
> netfilter defrag support. Basically all the flag does is bump a refcnt
> while the link the active. Checks are also added to ensure the prog
> requesting defrag support is run _after_ netfilter defrag hooks.
>
> We also take care to avoid any issues w.r.t. module unloading -- while
> defrag is active on a link, the module is prevented from unloading.
Reviewed-by: Florian Westphal <fw@strlen.de>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF
2023-07-21 20:22 [PATCH bpf-next v6 0/5] Support defragmenting IPv(4|6) packets in BPF Daniel Xu
2023-07-21 20:22 ` [PATCH bpf-next v6 1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag Daniel Xu
2023-07-21 20:22 ` [PATCH bpf-next v6 2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link Daniel Xu
@ 2023-07-29 0:00 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-07-29 0:00 UTC (permalink / raw)
To: Daniel Xu
Cc: linux-kernel, coreteam, netfilter-devel, linux-kselftest, bpf,
netdev, alexei.starovoitov, fw, daniel, dsahern
Hello:
This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Fri, 21 Jul 2023 14:22:44 -0600 you wrote:
> === Context ===
>
> In the context of a middlebox, fragmented packets are tricky to handle.
> The full 5-tuple of a packet is often only available in the first
> fragment which makes enforcing consistent policy difficult. There are
> really only two stateless options, neither of which are very nice:
>
> [...]
Here is the summary with links:
- [bpf-next,v6,1/5] netfilter: defrag: Add glue hooks for enabling/disabling defrag
https://git.kernel.org/bpf/bpf-next/c/9abddac583d6
- [bpf-next,v6,2/5] netfilter: bpf: Support BPF_F_NETFILTER_IP_DEFRAG in netfilter link
https://git.kernel.org/bpf/bpf-next/c/91721c2d02d3
- [bpf-next,v6,3/5] bpf: selftests: Support not connecting client socket
https://git.kernel.org/bpf/bpf-next/c/3495e89cdc3a
- [bpf-next,v6,4/5] bpf: selftests: Support custom type and proto for client sockets
https://git.kernel.org/bpf/bpf-next/c/e15a22095608
- [bpf-next,v6,5/5] bpf: selftests: Add defrag selftests
https://git.kernel.org/bpf/bpf-next/c/c313eae739b9
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread