ipq806x: NSS Hardware Offloading Chain Events Patch
This commit is contained in:
		| @@ -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 <linux/stddef.h> | ||||
|  #include <linux/err.h> | ||||
|  #include <linux/percpu.h> | ||||
| +#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS | ||||
| +#include <linux/notifier.h> | ||||
| +#endif | ||||
|  #include <linux/kernel.h> | ||||
|  #include <linux/netdevice.h> | ||||
|  #include <linux/slab.h> | ||||
| @@ -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) | ||||
|  { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 ACwifidude
					ACwifidude