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

Commit 46e38bdd authored by Tyler Wear's avatar Tyler Wear Committed by Ravinder Konka
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.

CRs-FIXED: 490813
Change-Id: Ibb225d7b91070ca9948c7a11f0b5925a8435915c
Signed-off-by: default avatarTyler Wear <twear@codeaurora.org>
parent eb30eb83
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ struct ipt_nattype_info {
	u_int16_t type;
};

extern bool nattype_refresh_timer(unsigned long nattype);
extern bool nattype_refresh_timer(unsigned long nattype,
unsigned long timeout_value);

#endif /*_IPT_NATTYPE_H_target*/
+43 −27
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ static const char * const modes[] = {"MODE_DNAT", "MODE_FORWARD_IN",
struct ipt_nattype {
	struct list_head list;
	struct timer_list timeout;
	unsigned long timeout_value;
	unsigned char is_valid;
	unsigned short proto;		/* Protocol: TCP or UDP */
	struct nf_nat_ipv4_range range;	/* LAN side src info*/
@@ -97,7 +98,7 @@ static void nattype_free(struct ipt_nattype *nte)
/* netfilter NATTYPE nattype_refresh_timer()
 * Refresh the timer for this object.
 */
bool nattype_refresh_timer(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;

@@ -109,7 +110,8 @@ bool nattype_refresh_timer(unsigned long nat_type)
		return false;
	}
	if (del_timer(&nte->timeout)) {
		nte->timeout.expires = jiffies + NATTYPE_TIMEOUT * HZ;
		nte->timeout_value = timeout_value - jiffies;
		nte->timeout.expires = timeout_value;
		add_timer(&nte->timeout);
		spin_unlock_bh(&nattype_lock);
		return true;
@@ -213,7 +215,8 @@ static bool nattype_packet_in_match(const struct ipt_nattype *nte,
/* netfilter NATTYPE nattype_compare
 * 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
	 * compare.
@@ -250,20 +253,16 @@ static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2)
		return false;
	}

	/* netfilter NATTYPE
	 * Destination compare
	/* netfilter NATTYPE 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",
		       &n1->dest_addr, &n2->dest_addr);
		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;
}

@@ -303,8 +302,17 @@ static unsigned int nattype_nat(struct sk_buff *skb,
			return XT_CONTINUE;
		}

		/* Expand the ingress conntrack
		 * to include the reply as source
		/* netfilter
		 * 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",
			ct, ctinfo, &newrange.min_ip, ntohs(newrange.min.all));
@@ -331,12 +339,22 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	enum ip_conntrack_info ctinfo;
	const struct ipt_nattype_info *info = par->targinfo;
	uint16_t nat_port;
	enum ip_conntrack_dir dir;


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

	/* Ingress packet,
	 * refresh the timer if we find an entry.
	/* 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;

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

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

	/* netfilter NATTYPE
	 * 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;
	dir = CTINFO2DIR(ctinfo);

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

	/* netfilter NATTYPE
	 * Allocate a new entry
@@ -429,7 +442,7 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	 */
	spin_lock_bh(&nattype_lock);
	list_for_each_entry(nte2, &nattype_list, list) {
		if (!nattype_compare(nte, nte2))
		if (!nattype_compare(nte, nte2, info))
			continue;
		spin_unlock_bh(&nattype_lock);
		/* netfilter NATTYPE
@@ -437,7 +450,9 @@ static unsigned int nattype_forward(struct sk_buff *skb,
		 * entry as this one is timed out and will be removed
		 * from the list shortly.
		 */
		if (!nattype_refresh_timer((unsigned long)nte2))
		nte2->timeout_value = ct->timeout.expires - jiffies;
		if (!nattype_refresh_timer((unsigned long)nte2,
					   ct->timeout.expires))
			break;

		/* netfilter NATTYPE
@@ -454,7 +469,8 @@ static unsigned int nattype_forward(struct sk_buff *skb,
	/* netfilter NATTYPE
	 * Add the new entry to the list.
	 */
	nte->timeout.expires = jiffies + (NATTYPE_TIMEOUT  * HZ);
	nte->timeout_value = ct->timeout.expires - jiffies;
	nte->timeout.expires = ct->timeout.expires;
	add_timer(&nte->timeout);
	list_add(&nte->list, &nattype_list);
	ct->nattype_entry = (unsigned long)nte;
+1 −1
Original line number Diff line number Diff line
@@ -1236,7 +1236,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,

/* Refresh the NAT type entry. */
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	(void)nattype_refresh_timer(ct->nattype_entry);
	(void)nattype_refresh_timer(ct->nattype_entry, ct->timeout.expires);
#endif

acct:
+5 −0
Original line number Diff line number Diff line
@@ -1428,6 +1428,11 @@ ctnetlink_change_timeout(struct nf_conn *ct, const struct nlattr * const cda[])
	ct->timeout.expires = jiffies + timeout * HZ;
	add_timer(&ct->timeout);

/* Refresh the NAT type entry. */
#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
	(void)nattype_refresh_timer(ct->nattype_entry, ct->timeout.expires);
#endif

	return 0;
}