patch-2.4.25 linux-2.4.25/net/ipv4/netfilter/ipt_MASQUERADE.c

Next file: linux-2.4.25/net/ipv4/netfilter/ipt_conntrack.c
Previous file: linux-2.4.25/net/ipv4/netfilter/ip_tables.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.24/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.4.25/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -124,63 +124,37 @@
 }
 
 static inline int
-device_cmp(const struct ip_conntrack *i, void *ifindex)
+device_cmp(const struct ip_conntrack *i, void *_ina)
 {
-	int ret;
+	int ret = 0;
+	struct in_ifaddr *ina = _ina;
 
 	READ_LOCK(&masq_lock);
-	ret = (i->nat.masq_index == (int)(long)ifindex);
+	/* If it's masquerading out this interface with a different address,
+	 * or we don't know the new address of this interface. */
+	if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
+	    && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
+		ret = 1;
 	READ_UNLOCK(&masq_lock);
 
 	return ret;
 }
 
-static int masq_device_event(struct notifier_block *this,
-			     unsigned long event,
-			     void *ptr)
-{
-	struct net_device *dev = ptr;
-
-	if (event == NETDEV_DOWN) {
-		/* Device was downed.  Search entire table for
-		   conntracks which were associated with that device,
-		   and forget them. */
-		IP_NF_ASSERT(dev->ifindex != 0);
-
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
-	}
-
-	return NOTIFY_DONE;
-}
-
 static int masq_inet_event(struct notifier_block *this,
 			   unsigned long event,
 			   void *ptr)
 {
-	struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
-
-	if (event == NETDEV_DOWN) {
-		/* IP address was deleted.  Search entire table for
-		   conntracks which were associated with that device,
-		   and forget them. */
-		IP_NF_ASSERT(dev->ifindex != 0);
-
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
-	}
+	/* For some configurations, interfaces often come back with
+	 * the same address.  If not, clean up old conntrack
+	 * entries. */
+	if (event == NETDEV_UP)
+		ip_ct_selective_cleanup(device_cmp, ptr);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block masq_dev_notifier = {
-	masq_device_event,
-	NULL,
-	0
-};
-
 static struct notifier_block masq_inet_notifier = {
-	masq_inet_event,
-	NULL,
-	0
+	.notifier_call = masq_inet_event
 };
 
 static struct ipt_target masquerade
@@ -193,12 +167,9 @@
 
 	ret = ipt_register_target(&masquerade);
 
-	if (ret == 0) {
-		/* Register for device down reports */
-		register_netdevice_notifier(&masq_dev_notifier);
+	if (ret == 0)
 		/* Register IP address change reports */
 		register_inetaddr_notifier(&masq_inet_notifier);
-	}
 
 	return ret;
 }
@@ -206,7 +177,6 @@
 static void __exit fini(void)
 {
 	ipt_unregister_target(&masquerade);
-	unregister_netdevice_notifier(&masq_dev_notifier);
 	unregister_inetaddr_notifier(&masq_inet_notifier);	
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)