|
@@ -104,12 +104,26 @@ static int masq_device_event(struct notifier_block *this,
|
|
|
return NOTIFY_DONE;
|
|
|
}
|
|
|
|
|
|
+static int inet_cmp(struct nf_conn *ct, void *ptr)
|
|
|
+{
|
|
|
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
|
|
|
+ struct net_device *dev = ifa->ifa_dev->dev;
|
|
|
+ struct nf_conntrack_tuple *tuple;
|
|
|
+
|
|
|
+ if (!device_cmp(ct, (void *)(long)dev->ifindex))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
|
|
+
|
|
|
+ return ifa->ifa_address == tuple->dst.u3.ip;
|
|
|
+}
|
|
|
+
|
|
|
static int masq_inet_event(struct notifier_block *this,
|
|
|
unsigned long event,
|
|
|
void *ptr)
|
|
|
{
|
|
|
struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
|
|
|
- struct netdev_notifier_info info;
|
|
|
+ struct net *net = dev_net(idev->dev);
|
|
|
|
|
|
/* The masq_dev_notifier will catch the case of the device going
|
|
|
* down. So if the inetdev is dead and being destroyed we have
|
|
@@ -119,8 +133,10 @@ static int masq_inet_event(struct notifier_block *this,
|
|
|
if (idev->dead)
|
|
|
return NOTIFY_DONE;
|
|
|
|
|
|
- netdev_notifier_info_init(&info, idev->dev);
|
|
|
- return masq_device_event(this, event, &info);
|
|
|
+ if (event == NETDEV_DOWN)
|
|
|
+ nf_ct_iterate_cleanup_net(net, inet_cmp, ptr, 0, 0);
|
|
|
+
|
|
|
+ return NOTIFY_DONE;
|
|
|
}
|
|
|
|
|
|
static struct notifier_block masq_dev_notifier = {
|