tun: Multicast handling in tun_chr_ioctl() needs proper locking.
Since these operations don't go through the normal device calls, we have to ensure we synchronize with those paths. Noticed by Alan Cox. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5e659e4cb0
commit
9edb74cc6c
|
@ -741,7 +741,12 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
|
||||||
case SIOCADDMULTI:
|
case SIOCADDMULTI:
|
||||||
/** Add the specified group to the character device's multicast filter
|
/** Add the specified group to the character device's multicast filter
|
||||||
* list. */
|
* list. */
|
||||||
|
rtnl_lock();
|
||||||
|
netif_tx_lock_bh(tun->dev);
|
||||||
add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
|
add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
|
||||||
|
netif_tx_unlock_bh(tun->dev);
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
DBG(KERN_DEBUG "%s: add multi: %s\n",
|
DBG(KERN_DEBUG "%s: add multi: %s\n",
|
||||||
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
|
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -749,7 +754,12 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
|
||||||
case SIOCDELMULTI:
|
case SIOCDELMULTI:
|
||||||
/** Remove the specified group from the character device's multicast
|
/** Remove the specified group from the character device's multicast
|
||||||
* filter list. */
|
* filter list. */
|
||||||
|
rtnl_lock();
|
||||||
|
netif_tx_lock_bh(tun->dev);
|
||||||
del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
|
del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
|
||||||
|
netif_tx_unlock_bh(tun->dev);
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
DBG(KERN_DEBUG "%s: del multi: %s\n",
|
DBG(KERN_DEBUG "%s: del multi: %s\n",
|
||||||
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
|
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue