OSDN Git Service

net/smc: determine vlan_id of stacked net_device
authorUrsula Braun <ubraun@linux.ibm.com>
Wed, 2 May 2018 14:56:47 +0000 (16:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 May 2018 17:29:12 +0000 (13:29 -0400)
An SMC link group is bound to a specific vlan_id. Its link uses
the RoCE-GIDs established for the specific vlan_id. This patch makes
sure the appropriate vlan_id is determined for stacked scenarios like
for instance a master bonding device with vlan devices enslaved.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_core.c

index d924776..1f3ea62 100644 (file)
@@ -360,7 +360,8 @@ void smc_lgr_terminate(struct smc_link_group *lgr)
 static int smc_vlan_by_tcpsk(struct socket *clcsock, unsigned short *vlan_id)
 {
        struct dst_entry *dst = sk_dst_get(clcsock->sk);
-       int rc = 0;
+       struct net_device *ndev;
+       int i, nest_lvl, rc = 0;
 
        *vlan_id = 0;
        if (!dst) {
@@ -372,8 +373,27 @@ static int smc_vlan_by_tcpsk(struct socket *clcsock, unsigned short *vlan_id)
                goto out_rel;
        }
 
-       if (is_vlan_dev(dst->dev))
-               *vlan_id = vlan_dev_vlan_id(dst->dev);
+       ndev = dst->dev;
+       if (is_vlan_dev(ndev)) {
+               *vlan_id = vlan_dev_vlan_id(ndev);
+               goto out_rel;
+       }
+
+       rtnl_lock();
+       nest_lvl = dev_get_nest_level(ndev);
+       for (i = 0; i < nest_lvl; i++) {
+               struct list_head *lower = &ndev->adj_list.lower;
+
+               if (list_empty(lower))
+                       break;
+               lower = lower->next;
+               ndev = (struct net_device *)netdev_lower_get_next(ndev, &lower);
+               if (is_vlan_dev(ndev)) {
+                       *vlan_id = vlan_dev_vlan_id(ndev);
+                       break;
+               }
+       }
+       rtnl_unlock();
 
 out_rel:
        dst_release(dst);