lkml.org 
[lkml]   [2020]   [Mar]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 08/89] ipvlan: do not add hardware address of master to its unicast filter list
    Date
    From: Jiri Wiesner <jwiesner@suse.com>

    [ Upstream commit 63aae7b17344d4b08a7d05cb07044de4c0f9dcc6 ]

    There is a problem when ipvlan slaves are created on a master device that
    is a vmxnet3 device (ipvlan in VMware guests). The vmxnet3 driver does not
    support unicast address filtering. When an ipvlan device is brought up in
    ipvlan_open(), the ipvlan driver calls dev_uc_add() to add the hardware
    address of the vmxnet3 master device to the unicast address list of the
    master device, phy_dev->uc. This inevitably leads to the vmxnet3 master
    device being forced into promiscuous mode by __dev_set_rx_mode().

    Promiscuous mode is switched on the master despite the fact that there is
    still only one hardware address that the master device should use for
    filtering in order for the ipvlan device to be able to receive packets.
    The comment above struct net_device describes the uc_promisc member as a
    "counter, that indicates, that promiscuous mode has been enabled due to
    the need to listen to additional unicast addresses in a device that does
    not implement ndo_set_rx_mode()". Moreover, the design of ipvlan
    guarantees that only the hardware address of a master device,
    phy_dev->dev_addr, will be used to transmit and receive all packets from
    its ipvlan slaves. Thus, the unicast address list of the master device
    should not be modified by ipvlan_open() and ipvlan_stop() in order to make
    ipvlan a workable option on masters that do not support unicast address
    filtering.

    Fixes: 2ad7bf3638411 ("ipvlan: Initial check-in of the IPVLAN driver")
    Reported-by: Per Sundstrom <per.sundstrom@redqube.se>
    Signed-off-by: Jiri Wiesner <jwiesner@suse.com>
    Reviewed-by: Eric Dumazet <edumazet@google.com>
    Acked-by: Mahesh Bandewar <maheshb@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ipvlan/ipvlan_main.c | 5 +----
    1 file changed, 1 insertion(+), 4 deletions(-)

    --- a/drivers/net/ipvlan/ipvlan_main.c
    +++ b/drivers/net/ipvlan/ipvlan_main.c
    @@ -236,7 +236,6 @@ static void ipvlan_uninit(struct net_dev
    static int ipvlan_open(struct net_device *dev)
    {
    struct ipvl_dev *ipvlan = netdev_priv(dev);
    - struct net_device *phy_dev = ipvlan->phy_dev;
    struct ipvl_addr *addr;

    if (ipvlan->port->mode == IPVLAN_MODE_L3 ||
    @@ -250,7 +249,7 @@ static int ipvlan_open(struct net_device
    ipvlan_ht_addr_add(ipvlan, addr);
    rcu_read_unlock();

    - return dev_uc_add(phy_dev, phy_dev->dev_addr);
    + return 0;
    }

    static int ipvlan_stop(struct net_device *dev)
    @@ -262,8 +261,6 @@ static int ipvlan_stop(struct net_device
    dev_uc_unsync(phy_dev, dev);
    dev_mc_unsync(phy_dev, dev);

    - dev_uc_del(phy_dev, phy_dev->dev_addr);
    -
    rcu_read_lock();
    list_for_each_entry_rcu(addr, &ipvlan->addrs, anode)
    ipvlan_ht_addr_del(addr);

    \
     
     \ /
      Last update: 2020-03-17 12:22    [W:4.371 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site