]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
net/ipv6: Add l3mdev check to ipv6_chk_addr_and_flags
authorDavid Ahern <dsahern@gmail.com>
Tue, 13 Mar 2018 15:29:38 +0000 (08:29 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 16 Mar 2018 15:28:38 +0000 (11:28 -0400)
Lookup the L3 master device for the passed in device. Only consider
addresses on netdev's with the same master device. If the device is
not enslaved or is NULL, then the l3mdev is NULL which means only
devices not enslaved (ie, in the default domain) are considered.

Signed-off-by: David Ahern <dsahern@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/addrconf.c

index 0677b9732d5619b38633af6f1fb2ca116e0cc822..6fd4bbdc444f3c6c3fe118b8f652f8772371bf9e 100644 (file)
@@ -1856,22 +1856,37 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
 }
 EXPORT_SYMBOL(ipv6_chk_addr);
 
+/* device argument is used to find the L3 domain of interest. If
+ * skip_dev_check is set, then the ifp device is not checked against
+ * the passed in dev argument. So the 2 cases for addresses checks are:
+ *   1. does the address exist in the L3 domain that dev is part of
+ *      (skip_dev_check = true), or
+ *
+ *   2. does the address exist on the specific device
+ *      (skip_dev_check = false)
+ */
 int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
                            const struct net_device *dev, bool skip_dev_check,
                            int strict, u32 banned_flags)
 {
        unsigned int hash = inet6_addr_hash(net, addr);
+       const struct net_device *l3mdev;
        struct inet6_ifaddr *ifp;
        u32 ifp_flags;
 
        rcu_read_lock();
 
+       l3mdev = l3mdev_master_dev_rcu(dev);
        if (skip_dev_check)
                dev = NULL;
 
        hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
                if (!net_eq(dev_net(ifp->idev->dev), net))
                        continue;
+
+               if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
+                       continue;
+
                /* Decouple optimistic from tentative for evaluation here.
                 * Ban optimistic addresses explicitly, when required.
                 */