Commit 9abddac5 authored by Daniel Xu's avatar Daniel Xu Committed by Alexei Starovoitov

netfilter: defrag: Add glue hooks for enabling/disabling defrag

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: default avatarDaniel Xu <dxu@dxuuu.xyz>
Reviewed-by: default avatarFlorian Westphal <fw@strlen.de>
Link: https://lore.kernel.org/r/f6a8824052441b72afe5285acedbd634bd3384c1.1689970773.git.dxu@dxuuu.xyzSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ee932bf9
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/static_key.h> #include <linux/static_key.h>
#include <linux/module.h>
#include <linux/netfilter_defs.h> #include <linux/netfilter_defs.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/sockptr.h> #include <linux/sockptr.h>
...@@ -481,6 +482,15 @@ struct nfnl_ct_hook { ...@@ -481,6 +482,15 @@ struct nfnl_ct_hook {
}; };
extern const struct nfnl_ct_hook __rcu *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 * nf_skb_duplicated - TEE target has sent a packet
* *
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/netns/generic.h> #include <net/netns/generic.h>
#include <net/route.h> #include <net/route.h>
...@@ -113,17 +114,31 @@ static void __net_exit defrag4_net_exit(struct net *net) ...@@ -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 = { static struct pernet_operations defrag4_net_ops = {
.exit = defrag4_net_exit, .exit = defrag4_net_exit,
}; };
static int __init nf_defrag_init(void) 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) static void __exit nf_defrag_fini(void)
{ {
rcu_assign_pointer(nf_defrag_v4_hook, NULL);
unregister_pernet_subsys(&defrag4_net_ops); unregister_pernet_subsys(&defrag4_net_ops);
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/icmp.h> #include <linux/icmp.h>
#include <linux/rcupdate.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <net/ipv6_frag.h> #include <net/ipv6_frag.h>
...@@ -96,6 +97,12 @@ static void __net_exit defrag6_net_exit(struct net *net) ...@@ -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 = { static struct pernet_operations defrag6_net_ops = {
.exit = defrag6_net_exit, .exit = defrag6_net_exit,
}; };
...@@ -114,6 +121,9 @@ static int __init nf_defrag_init(void) ...@@ -114,6 +121,9 @@ static int __init nf_defrag_init(void)
pr_err("nf_defrag_ipv6: can't register pernet ops\n"); pr_err("nf_defrag_ipv6: can't register pernet ops\n");
goto cleanup_frag6; goto cleanup_frag6;
} }
rcu_assign_pointer(nf_defrag_v6_hook, &defrag_hook);
return ret; return ret;
cleanup_frag6: cleanup_frag6:
...@@ -124,6 +134,7 @@ static int __init nf_defrag_init(void) ...@@ -124,6 +134,7 @@ static int __init nf_defrag_init(void)
static void __exit nf_defrag_fini(void) static void __exit nf_defrag_fini(void)
{ {
rcu_assign_pointer(nf_defrag_v6_hook, NULL);
unregister_pernet_subsys(&defrag6_net_ops); unregister_pernet_subsys(&defrag6_net_ops);
nf_ct_frag6_cleanup(); nf_ct_frag6_cleanup();
} }
......
...@@ -680,6 +680,12 @@ EXPORT_SYMBOL_GPL(nfnl_ct_hook); ...@@ -680,6 +680,12 @@ EXPORT_SYMBOL_GPL(nfnl_ct_hook);
const struct nf_ct_hook __rcu *nf_ct_hook __read_mostly; const struct nf_ct_hook __rcu *nf_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_hook); 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) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
u8 nf_ctnetlink_has_listener; u8 nf_ctnetlink_has_listener;
EXPORT_SYMBOL_GPL(nf_ctnetlink_has_listener); EXPORT_SYMBOL_GPL(nf_ctnetlink_has_listener);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment