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

Commit 87581bec authored by Paras Singh Jain's avatar Paras Singh Jain
Browse files

msm: netfilter: NATTYPE Refresh Timer Changes



When IPA is present, all the data packets go through IPA
and as a result NATTYPE entry timeout will not be refreshed
and eventually it times out. IPA periodically refreshes
the connection tracking entry timeout. So making changes to refresh
the NATTYPE entry timeout from the connection tracking module.

Change-Id: I5861427990af4bfd6046d21809a778409d0d8d5f
Signed-off-by: default avatarParas Singh Jain <parassin@codeaurora.org>
parent 989de097
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -55,6 +55,11 @@ struct nf_conntrack_net {
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>

/* Handle NATTYPE Stuff,only if NATTYPE module was defined */
#ifdef CONFIG_IP_NF_TARGET_NATTYPE_MODULE
#include <linux/netfilter_ipv4/ipt_NATTYPE.h>
#endif

struct nf_conn {
	/* Usage count in here is 1 for hash table, 1 per skb,
	 * plus 1 for any connection(s) we are `master' for
@@ -103,6 +108,10 @@ struct nf_conn {
	/* Extensions */
	struct nf_ct_ext *ext;

#ifdef CONFIG_IP_NF_TARGET_NATTYPE_MODULE
	unsigned long nattype_entry;
#endif

	/* Storage reserved for other modules, must be the last member */
	union nf_conntrack_proto proto;
};
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ void nf_conntrack_cleanup_end(void);

bool nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
			const struct nf_conntrack_tuple *orig);
extern bool (*nattype_refresh_timer)(unsigned long nattype) __rcu __read_mostly;

/* Find a connection corresponding to a tuple. */
struct nf_conntrack_tuple_hash *
+24 −7
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ static const char * const modes[] = {"MODE_DNAT", "MODE_FORWARD_IN",
struct ipt_nattype {
	struct list_head list;
	struct timer_list timeout;
	unsigned char is_valid;
	unsigned short proto;		/* Protocol: TCP or UDP */
	struct nf_nat_ipv4_range range;	/* LAN side src info*/
	unsigned short nat_port;	/* Routed NAT port */
@@ -67,13 +68,24 @@ static void nattype_free(struct ipt_nattype *nte)
/* netfilter NATTYPE nattype_refresh_timer()
 * Refresh the timer for this object.
 */
static bool nattype_refresh_timer(struct ipt_nattype *nte)
bool nattype_refresh_timer_impl(unsigned long nat_type)
{
	struct ipt_nattype *nte = (struct ipt_nattype *)nat_type;

	if (!nte)
		return false;
	spin_lock_bh(&nattype_lock);
	if (!nte->is_valid) {
		spin_unlock_bh(&nattype_lock);
		return false;
	}
	if (del_timer(&nte->timeout)) {
		nte->timeout.expires = jiffies + NATTYPE_TIMEOUT * HZ;
		add_timer(&nte->timeout);
		spin_unlock_bh(&nattype_lock);
		return true;
	}
	spin_unlock_bh(&nattype_lock);
	return false;
}

@@ -92,6 +104,7 @@ static void nattype_timer_timeout(unsigned long in_nattype)
	nattype_nte_debug_print(nte, "timeout");
	spin_lock_bh(&nattype_lock);
	list_del(&nte->list);
	memset(nte, 0, sizeof(struct ipt_nattype));
	spin_unlock_bh(&nattype_lock);
	nattype_free(nte);
}
@@ -268,6 +281,7 @@ static unsigned int nattype_nat(struct sk_buff *skb,
		 */
		DEBUGP("Expand ingress conntrack=%p, type=%d, src[%pI4:%d]\n",
			ct, ctinfo, &newrange.min_ip, ntohs(newrange.min.all));
		ct->nattype_entry = (unsigned long)nte;
		ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
		DEBUGP("Expand returned: %d\n", ret);
		return ret;
@@ -307,12 +321,13 @@ static unsigned int nattype_forward(struct sk_buff *skb,
			if (!nattype_packet_in_match(nte, skb, info))
				continue;

			spin_unlock_bh(&nattype_lock);
			/* netfilter NATTYPE
			 * Refresh the timer, if we fail, break
			 * out and forward fail as though we never
			 * found the entry.
			 */
			if (!nattype_refresh_timer(nte))
			if (!nattype_refresh_timer((unsigned long)nte))
				break;

			/* netfilter NATTYPE
@@ -320,7 +335,6 @@ static unsigned int nattype_forward(struct sk_buff *skb,
			 * entry values should not change so print
			 * them outside the lock.
			 */
			spin_unlock_bh(&nattype_lock);
			nattype_nte_debug_print(nte, "refresh");
			DEBUGP("FORWARD_IN_ACCEPT\n");
			return NF_ACCEPT;
@@ -386,13 +400,13 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	list_for_each_entry(nte2, &nattype_list, list) {
		if (!nattype_compare(nte, nte2))
			continue;

		spin_unlock_bh(&nattype_lock);
		/* netfilter NATTYPE
		 * If we can not refresh this entry, insert our new
		 * entry as this one is timed out and will be removed
		 * from the list shortly.
		 */
		if (!nattype_refresh_timer(nte2))
		if (!nattype_refresh_timer((unsigned long)nte2))
			break;

		/* netfilter NATTYPE
@@ -401,7 +415,6 @@ static unsigned int nattype_forward(struct sk_buff *skb,
		 *
		 * Free up the new entry.
		 */
		spin_unlock_bh(&nattype_lock);
		nattype_nte_debug_print(nte2, "refresh");
		nattype_free(nte);
		return XT_CONTINUE;
@@ -413,6 +426,8 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	nte->timeout.expires = jiffies + (NATTYPE_TIMEOUT  * HZ);
	add_timer(&nte->timeout);
	list_add(&nte->list, &nattype_list);
	ct->nattype_entry = (unsigned long)nte;
	nte->is_valid = 1;
	spin_unlock_bh(&nattype_lock);
	nattype_nte_debug_print(nte, "ADD");
	return XT_CONTINUE;
@@ -545,6 +560,8 @@ static struct xt_target nattype = {

static int __init init(void)
{
	WARN_ON(nattype_refresh_timer);
	RCU_INIT_POINTER(nattype_refresh_timer, nattype_refresh_timer_impl);
	return xt_register_target(&nattype);
}

+19 −0
Original line number Diff line number Diff line
@@ -64,6 +64,9 @@ EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
struct hlist_nulls_head *nf_conntrack_hash __read_mostly;
EXPORT_SYMBOL_GPL(nf_conntrack_hash);

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

struct conntrack_gc_work {
	struct delayed_work	dwork;
	u32			last_bucket;
@@ -1495,6 +1498,10 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
			ct->secmark = exp->master->secmark;
#endif
/* Initialize the NAT type entry. */
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
		ct->nattype_entry = 0;
#endif
			NF_CT_STAT_INC(net, expect_new);
		}
@@ -1784,6 +1791,10 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
			  u32 extra_jiffies,
			  bool do_acct)
{
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	bool (*nattype_ref_timer)(unsigned long nattype);
#endif

	/* Only update if this is not a fixed timeout */
	if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
		goto acct;
@@ -1794,6 +1805,14 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,

	if (READ_ONCE(ct->timeout) != extra_jiffies)
		WRITE_ONCE(ct->timeout, extra_jiffies);

/* 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);
#endif

acct:
	if (do_acct)
		nf_ct_acct_update(ct, ctinfo, skb->len);