Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6d2be8e authored by Mohammed Javid's avatar Mohammed Javid Committed by Gerrit - the friendly Code Review server
Browse files

msm: netfilter: NATTYPE Refresh Timer Changes



NATTYPE entry timeout will not be updated when packets
start flowing through IPA and eventually can timeout.
Make changes to refresh the NATTYPE entry timeout from
the connection tracking netlink module which is used by
IPANAT to update conntrack timeout. Also make the timeout
dynamic by taking the expiry timeout value from connection
tracking entry. Otherwise NATTYPE entry will not timeout
even when all the corresponding conntrack entries expire.

Also, This change take care of porting of below changes
1) netfilter: Add of NATTYPE COOKIE Check
I1a53fa0dc6961dd3e53d382642b413d4ee781ed6
2)ipt_NATTYPE: Fix for changes in
I31e4c4acae30378f37bd4b8e4d7d617957a0545d
3)netfilter: Move NATTYPE forward mode to POSTROUTING chain.
Ic03436339e2b0a6c4277146942f518e6c7d49574

CRs-FIXED: 490813
Change-Id: Ibb225d7b91070ca9948c7a11f0b5925a8435915c
Acked-by: default avatarSuraj Jaiswal <c_surajj@qti.qualcomm.com>
Signed-off-by: default avatarTyler Wear <twear@codeaurora.org>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent a8118139
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -51,7 +51,9 @@ bool nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
			const struct nf_conntrack_l3proto *l3proto,
			const struct nf_conntrack_l3proto *l3proto,
			const struct nf_conntrack_l4proto *l4proto);
			const struct nf_conntrack_l4proto *l4proto);
extern void (*delete_sfe_entry)(struct nf_conn *ct);
extern void (*delete_sfe_entry)(struct nf_conn *ct);
extern bool (*nattype_refresh_timer)(unsigned long nattype);
extern bool (*nattype_refresh_timer)
			(unsigned long nattype,
			unsigned long timeout_value);


/* Find a connection corresponding to a tuple. */
/* Find a connection corresponding to a tuple. */
struct nf_conntrack_tuple_hash *
struct nf_conntrack_tuple_hash *
+75 −56
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
 * Ubicom32 implementation derived from
 * Ubicom32 implementation derived from
 * Cameo's implementation(with many thanks):
 * Cameo's implementation(with many thanks):
 */
 */

#include <linux/types.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/udp.h>
@@ -36,21 +37,17 @@
#include <linux/tcp.h>
#include <linux/tcp.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_nat_rule.h>
#include <net/netfilter/nf_nat.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ipt_NATTYPE.h>
#include <linux/netfilter_ipv4/ipt_NATTYPE.h>
#include <linux/atomic.h>
#include <linux/atomic.h>


#if !defined(NATTYPE_DEBUG)
#define DEBUGP(type, args...)
#else
static const char * const types[] = {"TYPE_PORT_ADDRESS_RESTRICTED",
static const char * const types[] = {"TYPE_PORT_ADDRESS_RESTRICTED",
			"TYPE_ENDPOINT_INDEPENDENT",
			"TYPE_ENDPOINT_INDEPENDENT",
			"TYPE_ADDRESS_RESTRICTED"};
			"TYPE_ADDRESS_RESTRICTED"};
static const char * const modes[] = {"MODE_DNAT", "MODE_FORWARD_IN",
static const char * const modes[] = {"MODE_DNAT", "MODE_FORWARD_IN",
			"MODE_FORWARD_OUT"};
			"MODE_FORWARD_OUT"};
#define DEBUGP(args...) pr_debug(args)
#define DEBUGP(args...) pr_debug(args)
#endif


/* netfilter NATTYPE TODO:
/* netfilter NATTYPE TODO:
 * Add magic value checks to data structure.
 * Add magic value checks to data structure.
@@ -58,14 +55,17 @@ static const char * const modes[] = {"MODE_DNAT", "MODE_FORWARD_IN",
struct ipt_nattype {
struct ipt_nattype {
	struct list_head list;
	struct list_head list;
	struct timer_list timeout;
	struct timer_list timeout;
	unsigned char is_valid;
	unsigned long timeout_value;
	unsigned int nattype_cookie;
	unsigned short proto;		/* Protocol: TCP or UDP */
	unsigned short proto;		/* Protocol: TCP or UDP */
	struct nf_nat_ipv4_range range;	/* LAN side src info*/
	struct nf_nat_range range;	/* LAN side source information */
	unsigned short nat_port;	/* Routed NAT port */
	unsigned short nat_port;	/* Routed NAT port */
	unsigned int dest_addr;	/* Original egress packets dst addr */
	unsigned int dest_addr;	/* Original egress packets dst addr */
	unsigned short dest_port;/* Original egress packets destination port */
	unsigned short dest_port;/* Original egress packets destination port */
};
};


#define NATTYPE_COOKIE 0x11abcdef

/* TODO: It might be better to use a hash table for performance in
/* TODO: It might be better to use a hash table for performance in
 * heavy traffic.
 * heavy traffic.
 */
 */
@@ -78,11 +78,13 @@ static DEFINE_SPINLOCK(nattype_lock);
static void nattype_nte_debug_print(const struct ipt_nattype *nte,
static void nattype_nte_debug_print(const struct ipt_nattype *nte,
				    const char *s)
				    const char *s)
{
{
	DEBUGP("%p: %s - proto[%d], src[%pI4:%d], nat[<x>:%d], dest[%pI4:%d]\n",
	DEBUGP("%p:%s-proto[%d],src[%pI4:%d],nat[%d],dest[%pI4:%d]\n",
	       nte, s, nte->proto,
	       nte, s, nte->proto,
		&nte->range.min_ip, ntohs(nte->range.min.all),
	       &nte->range.min_addr.ip, ntohs(nte->range.min_proto.all),
		ntohs(nte->nat_port),
		ntohs(nte->nat_port),
		&nte->dest_addr, ntohs(nte->dest_port));
		&nte->dest_addr, ntohs(nte->dest_port));
	DEBUGP("Timeout[%lx], Expires[%lx]\n", nte->timeout_value,
	       nte->timeout.expires);
}
}


/* netfilter NATTYPE nattype_free()
/* netfilter NATTYPE nattype_free()
@@ -90,28 +92,28 @@ static void nattype_nte_debug_print(const struct ipt_nattype *nte,
 */
 */
static void nattype_free(struct ipt_nattype *nte)
static void nattype_free(struct ipt_nattype *nte)
{
{
	nattype_nte_debug_print(nte, "free");
	kfree(nte);
	kfree(nte);
}
}


/* netfilter NATTYPE nattype_refresh_timer()
/* netfilter NATTYPE nattype_refresh_timer()
 * Refresh the timer for this object.
 * Refresh the timer for this object.
 */
 */
bool nattype_refresh_timer_impl(unsigned long nat_type)
bool nattype_refresh_timer(unsigned long nat_type, unsigned long timeout_value)
{
{
	struct ipt_nattype *nte = (struct ipt_nattype *)nat_type;
	struct ipt_nattype *nte = (struct ipt_nattype *)nat_type;


	if (!nte)
	if (!nte)
		return false;
		return false;
	spin_lock_bh(&nattype_lock);
	spin_lock_bh(&nattype_lock);
	if (!nte->is_valid) {
	if (nte->nattype_cookie != NATTYPE_COOKIE) {
		spin_unlock_bh(&nattype_lock);
		spin_unlock_bh(&nattype_lock);
		return false;
		return false;
	}
	}
	if (del_timer(&nte->timeout)) {
	if (del_timer(&nte->timeout)) {
		nte->timeout.expires = jiffies + NATTYPE_TIMEOUT * HZ;
		nte->timeout.expires = timeout_value;
		add_timer(&nte->timeout);
		add_timer(&nte->timeout);
		spin_unlock_bh(&nattype_lock);
		spin_unlock_bh(&nattype_lock);
		nattype_nte_debug_print(nte, "refresh");
		return true;
		return true;
	}
	}
	spin_unlock_bh(&nattype_lock);
	spin_unlock_bh(&nattype_lock);
@@ -213,7 +215,8 @@ static bool nattype_packet_in_match(const struct ipt_nattype *nte,
/* netfilter NATTYPE nattype_compare
/* netfilter NATTYPE nattype_compare
 * Compare two entries, return true if relevant fields are the same.
 * Compare two entries, return true if relevant fields are the same.
 */
 */
static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2)
static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2,
			    const struct ipt_nattype_info *info)
{
{
	/* netfilter NATTYPE Protocol
	/* netfilter NATTYPE Protocol
	 * compare.
	 * compare.
@@ -228,16 +231,16 @@ static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2)
	  * Since we always keep min/max values the same,
	  * Since we always keep min/max values the same,
	  * just compare the min values.
	  * just compare the min values.
	  */
	  */
	if (n1->range.min_ip != n2->range.min_ip) {
	if (n1->range.min_addr.ip != n2->range.min_addr.ip) {
		DEBUGP("nattype_compare: r.min_ip mismatch: %pI4:%pI4\n",
		DEBUGP("nattype_compare: r.min_addr.ip mismatch: %pI4:%pI4\n",
		       &n1->range.min_ip, &n2->range.min_ip);
		       &n1->range.min_addr.ip, &n2->range.min_addr.ip);
		return false;
		return false;
	}
	}


	if (n1->range.min.all != n2->range.min.all) {
	if (n1->range.min_proto.all != n2->range.min_proto.all) {
		DEBUGP("nattype_compare: r.min mismatch: %d:%d\n",
		DEBUGP("nattype_compare: r.min mismatch: %d:%d\n",
		       ntohs(n1->range.min.all),
				ntohs(n1->range.min_proto.all),
		       ntohs(n2->range.min.all));
				ntohs(n2->range.min_proto.all));
		return false;
		return false;
	}
	}


@@ -250,20 +253,16 @@ static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2)
		return false;
		return false;
	}
	}


	/* netfilter NATTYPE
	/* netfilter NATTYPE Destination compare
	 * Destination compare
	 * Destination Comapre for Address Restricted Cone NAT.
	 */
	 */
	if (n1->dest_addr != n2->dest_addr) {
	if ((info->type == TYPE_ADDRESS_RESTRICTED) &&
	    (n1->dest_addr != n2->dest_addr)) {
		DEBUGP("nattype_compare: dest_addr mismatch: %pI4:%pI4\n",
		DEBUGP("nattype_compare: dest_addr mismatch: %pI4:%pI4\n",
		       &n1->dest_addr, &n2->dest_addr);
		       &n1->dest_addr, &n2->dest_addr);
		return false;
		return false;
	}
	}


	if (n1->dest_port != n2->dest_port) {
		DEBUGP("nattype_compare: dest_port mismatch: %d:%d\n",
		       ntohs(n1->dest_port), ntohs(n2->dest_port));
		return false;
	}
	return true;
	return true;
}
}


@@ -283,7 +282,7 @@ static unsigned int nattype_nat(struct sk_buff *skb,
	list_for_each_entry(nte, &nattype_list, list) {
	list_for_each_entry(nte, &nattype_list, list) {
		struct nf_conn *ct;
		struct nf_conn *ct;
		enum ip_conntrack_info ctinfo;
		enum ip_conntrack_info ctinfo;
		struct nf_nat_ipv4_range newrange;
		struct nf_nat_range newrange;
		unsigned int ret;
		unsigned int ret;


		if (!nattype_packet_in_match(nte, skb, par->targinfo))
		if (!nattype_packet_in_match(nte, skb, par->targinfo))
@@ -304,11 +303,21 @@ static unsigned int nattype_nat(struct sk_buff *skb,
			return XT_CONTINUE;
			return XT_CONTINUE;
		}
		}


		/* Expand the ingress conntrack
		/* netfilter
		 * to include the reply as source
		 * Refresh the timer, if we fail, break
		 * out and forward fail as though we never
		 * found the entry.
		 */
		if (!nattype_refresh_timer((unsigned long)nte,
					   jiffies + nte->timeout_value))
			break;

		/* netfilter
		 * Expand the ingress conntrack to include the reply as source
		 */
		 */
		DEBUGP("Expand ingress conntrack=%p, type=%d, src[%pI4:%d]\n",
		DEBUGP("Expand ingress conntrack=%p, type=%d, src[%pI4:%d]\n",
			ct, ctinfo, &newrange.min_ip, ntohs(newrange.min.all));
			ct, ctinfo, &newrange.min_addr.ip,
			ntohs(newrange.min_proto.all));
		ct->nattype_entry = (unsigned long)nte;
		ct->nattype_entry = (unsigned long)nte;
		ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
		ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
		DEBUGP("Expand returned: %d\n", ret);
		DEBUGP("Expand returned: %d\n", ret);
@@ -332,12 +341,22 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	enum ip_conntrack_info ctinfo;
	enum ip_conntrack_info ctinfo;
	const struct ipt_nattype_info *info = par->targinfo;
	const struct ipt_nattype_info *info = par->targinfo;
	u16 nat_port;
	u16 nat_port;
	enum ip_conntrack_dir dir;


	if (par->hooknum != NF_INET_FORWARD)

	if (par->hooknum != NF_INET_POST_ROUTING)
		return XT_CONTINUE;

	/* netfilter
	 * Egress packet, create a new rule in our list.  If conntrack does
	 * not have an entry, skip this packet.
	 */
	ct = nf_ct_get(skb, &ctinfo);
	if (!ct)
		return XT_CONTINUE;
		return XT_CONTINUE;


	/* Ingress packet,
	/* netfilter
	 * refresh the timer if we find an entry.
	 * Ingress packet, refresh the timer if we find an entry.
	 */
	 */
	if (info->mode == MODE_FORWARD_IN) {
	if (info->mode == MODE_FORWARD_IN) {
		spin_lock_bh(&nattype_lock);
		spin_lock_bh(&nattype_lock);
@@ -355,7 +374,8 @@ static unsigned int nattype_forward(struct sk_buff *skb,
			 * out and forward fail as though we never
			 * out and forward fail as though we never
			 * found the entry.
			 * found the entry.
			 */
			 */
			if (!nattype_refresh_timer((unsigned long)nte))
			if (!nattype_refresh_timer((unsigned long)nte,
						   ct->timeout.expires))
				break;
				break;


			/* netfilter NATTYPE
			/* netfilter NATTYPE
@@ -372,15 +392,9 @@ static unsigned int nattype_forward(struct sk_buff *skb,
		return XT_CONTINUE;
		return XT_CONTINUE;
	}
	}


	/* netfilter NATTYPE
	dir = CTINFO2DIR(ctinfo);
	 * Egress packet, create a new rule in our list.  If conntrack does
	 * not have an entry, skip this packet.
	 */
	ct = nf_ct_get(skb, &ctinfo);
	if (!ct || (ctinfo == IP_CT_NEW && ctinfo == IP_CT_RELATED))
		return XT_CONTINUE;


	nat_port = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all;
	nat_port = ct->tuplehash[!dir].tuple.dst.u.all;


	/* netfilter NATTYPE
	/* netfilter NATTYPE
	 * Allocate a new entry
	 * Allocate a new entry
@@ -396,20 +410,22 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	nte->proto = iph->protocol;
	nte->proto = iph->protocol;
	nte->nat_port = nat_port;
	nte->nat_port = nat_port;
	nte->dest_addr = iph->daddr;
	nte->dest_addr = iph->daddr;
	nte->range.min_ip = iph->saddr;
	nte->range.min_addr.ip = iph->saddr;
	nte->range.max_ip = nte->range.min_ip;
	nte->range.max_addr.ip = nte->range.min_addr.ip;


	/* netfilter NATTYPE
	/* netfilter NATTYPE
	 * TOOD: Would it be better to get this information from the
	 * TOOD: Would it be better to get this information from the
	 * conntrack instead of the headers.
	 * conntrack instead of the headers.
	 */
	 */
	if (iph->protocol == IPPROTO_TCP) {
	if (iph->protocol == IPPROTO_TCP) {
		nte->range.min.tcp.port = ((struct tcphdr *)protoh)->source;
		nte->range.min_proto.tcp.port =
		nte->range.max.tcp.port = nte->range.min.tcp.port;
					((struct tcphdr *)protoh)->source;
		nte->range.max_proto.tcp.port = nte->range.min_proto.tcp.port;
		nte->dest_port = ((struct tcphdr *)protoh)->dest;
		nte->dest_port = ((struct tcphdr *)protoh)->dest;
	} else if (iph->protocol == IPPROTO_UDP) {
	} else if (iph->protocol == IPPROTO_UDP) {
		nte->range.min.udp.port = ((struct udphdr *)protoh)->source;
		nte->range.min_proto.udp.port =
		nte->range.max.udp.port = nte->range.min.udp.port;
					((struct udphdr *)protoh)->source;
		nte->range.max_proto.udp.port = nte->range.min_proto.udp.port;
		nte->dest_port = ((struct udphdr *)protoh)->dest;
		nte->dest_port = ((struct udphdr *)protoh)->dest;
	}
	}
	nte->range.flags = (NF_NAT_RANGE_MAP_IPS |
	nte->range.flags = (NF_NAT_RANGE_MAP_IPS |
@@ -430,7 +446,7 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	 */
	 */
	spin_lock_bh(&nattype_lock);
	spin_lock_bh(&nattype_lock);
	list_for_each_entry(nte2, &nattype_list, list) {
	list_for_each_entry(nte2, &nattype_list, list) {
		if (!nattype_compare(nte, nte2))
		if (!nattype_compare(nte, nte2, info))
			continue;
			continue;
		spin_unlock_bh(&nattype_lock);
		spin_unlock_bh(&nattype_lock);
		/* netfilter NATTYPE
		/* netfilter NATTYPE
@@ -438,7 +454,9 @@ static unsigned int nattype_forward(struct sk_buff *skb,
		 * entry as this one is timed out and will be removed
		 * entry as this one is timed out and will be removed
		 * from the list shortly.
		 * from the list shortly.
		 */
		 */
		if (!nattype_refresh_timer((unsigned long)nte2))
		if (!nattype_refresh_timer(
			(unsigned long)nte2,
			jiffies + nte2->timeout_value))
			break;
			break;


		/* netfilter NATTYPE
		/* netfilter NATTYPE
@@ -455,11 +473,12 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	/* netfilter NATTYPE
	/* netfilter NATTYPE
	 * Add the new entry to the list.
	 * Add the new entry to the list.
	 */
	 */
	nte->timeout.expires = jiffies + (NATTYPE_TIMEOUT  * HZ);
	nte->timeout_value = ct->timeout.expires;
	nte->timeout.expires = ct->timeout.expires + jiffies;
	add_timer(&nte->timeout);
	add_timer(&nte->timeout);
	list_add(&nte->list, &nattype_list);
	list_add(&nte->list, &nattype_list);
	ct->nattype_entry = (unsigned long)nte;
	ct->nattype_entry = (unsigned long)nte;
	nte->is_valid = 1;
	nte->nattype_cookie = NATTYPE_COOKIE;
	spin_unlock_bh(&nattype_lock);
	spin_unlock_bh(&nattype_lock);
	nattype_nte_debug_print(nte, "ADD");
	nattype_nte_debug_print(nte, "ADD");
	return XT_CONTINUE;
	return XT_CONTINUE;
@@ -549,7 +568,7 @@ static int nattype_check(const struct xt_tgchk_param *par)
	       types[info->type], modes[info->mode]);
	       types[info->type], modes[info->mode]);


	if (par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) |
	if (par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) |
		(1 << NF_INET_FORWARD))) {
		(1 << NF_INET_POST_ROUTING))) {
		DEBUGP("nattype_check: bad hooks %x.\n", par->hook_mask);
		DEBUGP("nattype_check: bad hooks %x.\n", par->hook_mask);
		return -EINVAL;
		return -EINVAL;
	}
	}
@@ -590,7 +609,7 @@ static struct xt_target nattype = {
	.checkentry	= nattype_check,
	.checkentry	= nattype_check,
	.targetsize	= sizeof(struct ipt_nattype_info),
	.targetsize	= sizeof(struct ipt_nattype_info),
	.hooks		= ((1 << NF_INET_PRE_ROUTING) |
	.hooks		= ((1 << NF_INET_PRE_ROUTING) |
				(1 << NF_INET_FORWARD)),
				(1 << NF_INET_POST_ROUTING)),
	.me		= THIS_MODULE,
	.me		= THIS_MODULE,
};
};


+6 −0
Original line number Original line Diff line number Diff line
@@ -68,7 +68,13 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
	newrange.max_proto   = range->max_proto;
	newrange.max_proto   = range->max_proto;


	/* Hand modified range to generic setup. */
	/* Hand modified range to generic setup. */
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
	return XT_CONTINUE;
#else
	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
#endif

}
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4);
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4);


+11 −3
Original line number Original line Diff line number Diff line
@@ -72,7 +72,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
struct hlist_nulls_head *nf_conntrack_hash __read_mostly;
struct hlist_nulls_head *nf_conntrack_hash __read_mostly;
EXPORT_SYMBOL_GPL(nf_conntrack_hash);
EXPORT_SYMBOL_GPL(nf_conntrack_hash);


bool (*nattype_refresh_timer)(unsigned long nattype) __rcu __read_mostly;
bool (*nattype_refresh_timer)
	(unsigned long nattype,
	unsigned long timeout_value)
	__rcu __read_mostly;
EXPORT_SYMBOL(nattype_refresh_timer);
EXPORT_SYMBOL(nattype_refresh_timer);


struct conntrack_gc_work {
struct conntrack_gc_work {
@@ -1097,6 +1100,9 @@ __nf_conntrack_alloc(struct net *net,


	nf_ct_zone_add(ct, zone);
	nf_ct_zone_add(ct, zone);


#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	ct->nattype_entry = 0;
#endif
	/* Because we use RCU lookups, we set ct_general.use to zero before
	/* Because we use RCU lookups, we set ct_general.use to zero before
	 * this is inserted in any list.
	 * this is inserted in any list.
	 */
	 */
@@ -1468,7 +1474,9 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
	struct nf_conn_acct *acct;
	struct nf_conn_acct *acct;
	u64 pkts;
	u64 pkts;
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	bool (*nattype_ref_timer)(unsigned long nattype);
	bool (*nattype_ref_timer)
		(unsigned long nattype,
		unsigned long timeout_value);
#endif
#endif


	NF_CT_ASSERT(skb);
	NF_CT_ASSERT(skb);
@@ -1486,7 +1494,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	nattype_ref_timer = rcu_dereference(nattype_refresh_timer);
	nattype_ref_timer = rcu_dereference(nattype_refresh_timer);
	if (nattype_ref_timer)
	if (nattype_ref_timer)
		nattype_ref_timer(ct->nattype_entry);
		nattype_ref_timer(ct->nattype_entry, ct->timeout.expires);
#endif
#endif


acct:
acct:
+11 −0
Original line number Original line Diff line number Diff line
@@ -1540,12 +1540,23 @@ static int ctnetlink_change_timeout(struct nf_conn *ct,
				    const struct nlattr * const cda[])
				    const struct nlattr * const cda[])
{
{
	u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
	u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	bool (*nattype_ref_timer)
		(unsigned long nattype,
		unsigned long timeout_value);
#endif


	ct->timeout = nfct_time_stamp + timeout * HZ;
	ct->timeout = nfct_time_stamp + timeout * HZ;


	if (test_bit(IPS_DYING_BIT, &ct->status))
	if (test_bit(IPS_DYING_BIT, &ct->status))
		return -ETIME;
		return -ETIME;


/* Refresh the NAT type entry. */
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	nattype_ref_timer = rcu_dereference(nattype_refresh_timer);
	if (nattype_ref_timer)
		nattype_ref_timer(ct->nattype_entry, ct->timeout.expires);
#endif
	return 0;
	return 0;
}
}