From e639e204373827cd0588448dcfef97b6b887108e 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 | 73 ++++++++++++------- 3 files changed, 64 insertions(+), 29 deletions(-) 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-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index 74b2959a2f..09a4c1d57b 100644 --- a/target/linux/generic/hack-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -36,6 +36,17 @@ #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -75,6 +75,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/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -746,6 +746,28 @@ void br_port_flags_change(struct net_bri @@ -161,57 +172,45 @@ static int nf_ct_tcp_loose __read_mostly = 1; --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c -@@ -153,13 +153,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(unsign 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) -@@ -177,7 +181,12 @@ int nf_conntrack_eventmask_report(unsign +@@ -177,7 +181,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) { -@@ -252,15 +261,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 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) @@ -283,7 +296,13 @@ void nf_ct_deliver_cached_events(struct item.portid = 0; item.report = 0; @@ -226,3 +225,27 @@ 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)