From b7afc848202d1c6847d9e97fc43ee3edcb019085 Mon Sep 17 00:00:00 2001 From: ACwifidude Date: Sun, 6 Feb 2022 10:48:10 -0600 Subject: [PATCH] ipq806x: NSS Hardware Offloading Chain Events Patch --- ...00a-qca-nss-add-chain-events-support.patch | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 target/linux/ipq806x/patches-5.10/999-00a-qca-nss-add-chain-events-support.patch diff --git a/target/linux/ipq806x/patches-5.10/999-00a-qca-nss-add-chain-events-support.patch b/target/linux/ipq806x/patches-5.10/999-00a-qca-nss-add-chain-events-support.patch new file mode 100644 index 0000000000..873cad577d --- /dev/null +++ b/target/linux/ipq806x/patches-5.10/999-00a-qca-nss-add-chain-events-support.patch @@ -0,0 +1,196 @@ +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -112,6 +112,9 @@ struct netns_ct { + + struct ct_pcpu __percpu *pcpu_lists; + struct ip_conntrack_stat __percpu *stat; ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct atomic_notifier_head nf_conntrack_chain; ++#endif + struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; + struct nf_exp_event_notifier __rcu *nf_expect_event_cb; + struct nf_ip_net nf_ct_proto; +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -72,6 +72,11 @@ struct nf_ct_event { + int report; + }; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++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); ++#endif ++ + struct nf_ct_event_notifier { + int (*fcn)(unsigned int events, struct nf_ct_event *item); + }; +@@ -105,11 +110,13 @@ static inline void + nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- struct net *net = nf_ct_net(ct); + struct nf_conntrack_ecache *e; ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return; ++#endif + + e = nf_ct_ecache_find(ct); + if (e == NULL) +@@ -124,10 +131,12 @@ nf_conntrack_event_report(enum ip_conntr + u32 portid, int report) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; ++#endif + + return nf_conntrack_eventmask_report(1 << event, ct, portid, report); + #else +@@ -139,10 +148,12 @@ static inline int + nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; ++#endif + + return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); + #else +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -146,6 +146,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_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2743,6 +2743,9 @@ int nf_conntrack_init_net(struct net *ne + nf_conntrack_ecache_pernet_init(net); + nf_conntrack_helper_pernet_init(net); + nf_conntrack_proto_pernet_init(net); ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain); ++#endif + + return 0; + +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -17,6 +17,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++#include ++#endif + #include + #include + #include +@@ -140,7 +143,11 @@ int nf_conntrack_eventmask_report(unsign + + rcu_read_lock(); + 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) ++#endif + goto out_unlock; + + e = nf_ct_ecache_find(ct); +@@ -159,7 +166,15 @@ 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) { +@@ -199,7 +214,11 @@ void nf_ct_deliver_cached_events(struct + + rcu_read_lock(); + 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) ++#endif + goto out_unlock; + + if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct)) +@@ -223,7 +242,16 @@ void nf_ct_deliver_cached_events(struct + item.portid = 0; + item.report = 0; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ 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; +@@ -270,6 +298,14 @@ out_unlock: + rcu_read_unlock(); + } + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++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); ++#endif ++ + int nf_conntrack_register_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +@@ -292,6 +328,14 @@ out_unlock: + } + EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++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); ++#endif ++ + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +