shortcut-fe: rework netfilter conntrack notification
The original patch from QCA over rode the nf_conntrack_un/register_notifier API, which will break other modules relying on the API. Reworked the notification APIs to play nice with others.
This commit is contained in:
parent
df12850680
commit
77a15e9d59
@ -1807,10 +1807,12 @@ static int __init fast_classifier_init(void)
|
||||
goto exit3;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
/*
|
||||
* Register a notifier hook to get fast notifications of expired connections.
|
||||
*/
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
result = nf_conntrack_register_chain_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#else
|
||||
result = nf_conntrack_register_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
if (result < 0) {
|
||||
DEBUG_ERROR("can't register nf notifier hook: %d\n", result);
|
||||
@ -1877,7 +1879,11 @@ exit6:
|
||||
|
||||
exit5:
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
nf_conntrack_unregister_chain_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#else
|
||||
nf_conntrack_unregister_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#endif
|
||||
|
||||
exit4:
|
||||
#endif
|
||||
@ -1945,8 +1951,11 @@ static void __exit fast_classifier_exit(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
nf_conntrack_unregister_chain_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
#else
|
||||
nf_conntrack_unregister_notifier(&init_net, &fast_classifier_conntrack_notifier);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
nf_unregister_net_hooks(&init_net, fast_classifier_ops_post_routing, ARRAY_SIZE(fast_classifier_ops_post_routing));
|
||||
|
||||
|
||||
@ -1049,7 +1049,7 @@ static int __init sfe_cm_init(void)
|
||||
*/
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
(void)nf_conntrack_register_notifier(&init_net, &sfe_cm_conntrack_notifier);
|
||||
(void)nf_conntrack_register_chain_notifier(&init_net, &sfe_cm_conntrack_notifier);
|
||||
#else
|
||||
result = nf_conntrack_register_notifier(&init_net, &sfe_cm_conntrack_notifier);
|
||||
if (result < 0) {
|
||||
@ -1123,8 +1123,11 @@ static void __exit sfe_cm_exit(void)
|
||||
sfe_ipv6_destroy_all_rules_for_dev(NULL);
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
nf_conntrack_unregister_chain_notifier(&init_net, &sfe_cm_conntrack_notifier);
|
||||
#else
|
||||
nf_conntrack_unregister_notifier(&init_net, &sfe_cm_conntrack_notifier);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
nf_unregister_net_hooks(&init_net, sfe_cm_ops_post_routing, ARRAY_SIZE(sfe_cm_ops_post_routing));
|
||||
|
||||
|
||||
@ -33,6 +33,17 @@
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
--- a/include/net/netfilter/nf_conntrack_ecache.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_ecache.h
|
||||
@@ -74,6 +74,8 @@ struct nf_ct_event {
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
|
||||
extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
#else
|
||||
struct nf_ct_event_notifier {
|
||||
int (*fcn)(unsigned int events, struct nf_ct_event *item);
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -463,3 +463,6 @@ config HAVE_CBPF_JIT
|
||||
@ -149,77 +160,49 @@
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -154,6 +154,14 @@ config NF_CONNTRACK_TIMEOUT
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
+config NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ bool "Register multiple callbacks to ct events"
|
||||
+ depends on NF_CONNTRACK_EVENTS
|
||||
+ help
|
||||
+ Support multiple registrations.
|
||||
+
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config NF_CONNTRACK_TIMESTAMP
|
||||
bool 'Connection tracking timestamping'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -157,13 +157,17 @@ int nf_conntrack_eventmask_report(unsign
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
@@ -162,7 +162,11 @@ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ if (!notify && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head))
|
||||
+#else
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
@@ -181,7 +185,12 @@ int nf_conntrack_eventmask_report(unsign
|
||||
@@ -181,7 +185,14 @@ int nf_conntrack_eventmask_report(unsign
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ eventmask | missed, &item);
|
||||
+ if (notify)
|
||||
+ ret = notify->fcn(eventmask | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
+#endif
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
@@ -256,15 +265,19 @@ void nf_ct_deliver_cached_events(struct
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
int ret;
|
||||
@@ -263,7 +274,11 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ if ((notify == NULL) && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head))
|
||||
+#else
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -287,7 +300,13 @@ void nf_ct_deliver_cached_events(struct
|
||||
@@ -287,7 +300,15 @@ void nf_ct_deliver_cached_events(struct
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
@ -227,9 +210,35 @@
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+ if (notify != NULL)
|
||||
+ ret = notify->fcn(events | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(events | missed, &item);
|
||||
+#endif
|
||||
|
||||
if (likely(ret == 0 && !missed))
|
||||
goto out_unlock;
|
||||
@@ -340,6 +363,11 @@ int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_register_chain_notifier);
|
||||
#else
|
||||
int nf_conntrack_register_notifier(struct net *net,
|
||||
struct nf_ct_event_notifier *new)
|
||||
@@ -369,6 +397,11 @@ int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_chain_notifier);
|
||||
#else
|
||||
void nf_conntrack_unregister_notifier(struct net *net,
|
||||
struct nf_ct_event_notifier *new)
|
||||
@ -33,6 +33,17 @@
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
struct lockdep_map lockdep_map;
|
||||
--- a/include/net/netfilter/nf_conntrack_ecache.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_ecache.h
|
||||
@@ -74,6 +74,8 @@ struct nf_ct_event {
|
||||
#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
|
||||
extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
+extern int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb);
|
||||
#else
|
||||
struct nf_ct_event_notifier {
|
||||
int (*fcn)(unsigned int events, struct nf_ct_event *item);
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
@@ -467,3 +467,6 @@ config HAVE_CBPF_JIT
|
||||
@ -149,77 +160,48 @@
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -165,6 +165,14 @@ config NF_CONNTRACK_TIMEOUT
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
+config NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ bool "Register multiple callbacks to ct events"
|
||||
+ depends on NF_CONNTRACK_EVENTS
|
||||
+ help
|
||||
+ Support multiple registrations.
|
||||
+
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config NF_CONNTRACK_TIMESTAMP
|
||||
bool 'Connection tracking timestamping'
|
||||
depends on NETFILTER_ADVANCED
|
||||
--- a/net/netfilter/nf_conntrack_ecache.c
|
||||
+++ b/net/netfilter/nf_conntrack_ecache.c
|
||||
@@ -159,13 +159,17 @@ int nf_conntrack_eventmask_report(unsign
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
@@ -164,7 +164,11 @@ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ if (!notify && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head))
|
||||
+#else
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
@@ -183,7 +187,12 @@ int nf_conntrack_eventmask_report(unsign
|
||||
@@ -183,7 +187,14 @@ int nf_conntrack_eventmask_report(unsign
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ eventmask | missed, &item);
|
||||
+ if (notify)
|
||||
+ ret = notify->fcn(eventmask | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
+#endif
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
@@ -258,15 +267,19 @@ void nf_ct_deliver_cached_events(struct
|
||||
{
|
||||
struct net *net = nf_ct_net(ct);
|
||||
unsigned long events, missed;
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
struct nf_ct_event_notifier *notify;
|
||||
+#endif
|
||||
struct nf_conntrack_ecache *e;
|
||||
struct nf_ct_event item;
|
||||
int ret;
|
||||
@@ -265,7 +276,11 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
|
||||
rcu_read_lock();
|
||||
+#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
+#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
|
||||
+ if ((notify == NULL) && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head))
|
||||
+#else
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
+#endif
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
@@ -289,7 +302,13 @@ void nf_ct_deliver_cached_events(struct
|
||||
@@ -289,7 +304,15 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
item.portid = 0;
|
||||
item.report = 0;
|
||||
|
||||
@ -227,9 +209,35 @@
|
||||
+ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
|
||||
+ events | missed,
|
||||
+ &item);
|
||||
+ if (notify != NULL)
|
||||
+ ret = notify->fcn(events | missed, &item);
|
||||
+#else
|
||||
ret = notify->fcn(events | missed, &item);
|
||||
+#endif
|
||||
|
||||
if (likely(ret == 0 && !missed))
|
||||
goto out_unlock;
|
||||
@@ -342,6 +365,11 @@ int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_register_chain_notifier);
|
||||
#else
|
||||
int nf_conntrack_register_notifier(struct net *net,
|
||||
struct nf_ct_event_notifier *new)
|
||||
@@ -371,6 +399,11 @@ int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
}
|
||||
+int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb)
|
||||
+{
|
||||
+ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_chain_notifier);
|
||||
#else
|
||||
void nf_conntrack_unregister_notifier(struct net *net,
|
||||
struct nf_ct_event_notifier *new)
|
||||
Loading…
Reference in New Issue
Block a user