Commit 82f17091 authored by Francesco Ruggeri's avatar Francesco Ruggeri Committed by David S. Miller

net: delete stale packet_mclist entries

When an interface is deleted from a net namespace the ifindex in the
corresponding entries in PF_PACKET sockets' mclists becomes stale.
This can create inconsistencies if later an interface with the same ifindex
is moved from a different namespace (not that unlikely since ifindexes are
per-namespace).
In particular we saw problems with dev->promiscuity, resulting
in "promiscuity touches roof, set promiscuity failed. promiscuity
feature of device might be broken" warnings and EOVERFLOW failures of
setsockopt(PACKET_ADD_MEMBERSHIP).
This patch deletes the mclist entries for interfaces that are deleted.
Since this now causes setsockopt(PACKET_DROP_MEMBERSHIP) to fail with
EADDRNOTAVAIL if called after the interface is deleted, also make
packet_mc_drop not fail.
Signed-off-by: default avatarFrancesco Ruggeri <fruggeri@arista.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0b2eb3e9
...@@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, ...@@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
return 0; return 0;
} }
static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) static void packet_dev_mclist_delete(struct net_device *dev,
struct packet_mclist **mlp)
{ {
for ( ; i; i = i->next) { struct packet_mclist *ml;
if (i->ifindex == dev->ifindex)
packet_dev_mc(dev, i, what); while ((ml = *mlp) != NULL) {
if (ml->ifindex == dev->ifindex) {
packet_dev_mc(dev, ml, -1);
*mlp = ml->next;
kfree(ml);
} else
mlp = &ml->next;
} }
} }
...@@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) ...@@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
packet_dev_mc(dev, ml, -1); packet_dev_mc(dev, ml, -1);
kfree(ml); kfree(ml);
} }
rtnl_unlock(); break;
return 0;
} }
} }
rtnl_unlock(); rtnl_unlock();
return -EADDRNOTAVAIL; return 0;
} }
static void packet_flush_mclist(struct sock *sk) static void packet_flush_mclist(struct sock *sk)
...@@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this, ...@@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this,
switch (msg) { switch (msg) {
case NETDEV_UNREGISTER: case NETDEV_UNREGISTER:
if (po->mclist) if (po->mclist)
packet_dev_mclist(dev, po->mclist, -1); packet_dev_mclist_delete(dev, &po->mclist);
/* fallthrough */ /* fallthrough */
case NETDEV_DOWN: case NETDEV_DOWN:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment