From 77a15e9d590871d4757a209aa17d8cda69e253a5 Mon Sep 17 00:00:00 2001 From: quarkysg Date: Thu, 25 Jun 2020 14:49:37 +0800 Subject: [PATCH] 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. --- .../fast-classifier/src/fast-classifier.c | 13 ++- package/lean/shortcut-fe/src/sfe_cm.c | 7 +- ...linux-kernel-to-support-shortcut-fe.patch} | 93 +++++++++--------- ...linux-kernel-to-support-shortcut-fe.patch} | 94 ++++++++++--------- 4 files changed, 118 insertions(+), 89 deletions(-) rename target/linux/generic/hack-4.14/{999-net-patch-linux-kernel-to-support-shortcut-fe.patch => 953-net-patch-linux-kernel-to-support-shortcut-fe.patch} (69%) rename target/linux/generic/hack-4.19/{999-net-patch-linux-kernel-to-support-shortcut-fe.patch => 953-net-patch-linux-kernel-to-support-shortcut-fe.patch} (69%) diff --git a/package/lean/fast-classifier/src/fast-classifier.c b/package/lean/fast-classifier/src/fast-classifier.c index 19e2e6fadd..62255733eb 100644 --- a/package/lean/fast-classifier/src/fast-classifier.c +++ b/package/lean/fast-classifier/src/fast-classifier.c @@ -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)); diff --git a/package/lean/shortcut-fe/src/sfe_cm.c b/package/lean/shortcut-fe/src/sfe_cm.c index 4e5a0c1841..18f3475e5b 100644 --- a/package/lean/shortcut-fe/src/sfe_cm.c +++ b/package/lean/shortcut-fe/src/sfe_cm.c @@ -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)); diff --git a/target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-4.14/953-net-patch-linux-kernel-to-support-shortcut-fe.patch similarity index 69% rename from target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch rename to target/linux/generic/hack-4.14/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index b0af6ea59a..500a0f5325 100644 --- a/target/linux/generic/hack-4.14/999-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-4.14/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -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) diff --git a/target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-4.19/953-net-patch-linux-kernel-to-support-shortcut-fe.patch similarity index 69% rename from target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch rename to target/linux/generic/hack-4.19/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index f2aed88545..bb1a2ebe8f 100644 --- a/target/linux/generic/hack-4.19/999-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-4.19/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -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)