]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ipv4: ipmr: Add the parent ID field to VIF struct
authorYotam Gigi <yotamg@mellanox.com>
Tue, 3 Oct 2017 07:58:07 +0000 (09:58 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Oct 2017 17:06:30 +0000 (10:06 -0700)
In order to allow the ipmr module to do partial multicast forwarding
according to the device parent ID, add the device parent ID field to the
VIF struct. This way, the forwarding path can use the parent ID field
without invoking switchdev calls, which requires the RTNL lock.

When a new VIF is added, set the device parent ID field in it by invoking
the switchdev_port_attr_get call.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/mroute.h
net/ipv4/ipmr.c

index b072a84fbe1c78993a971bfdea94383c1708e7a7..8242d05df35e1c5dffdb8cf4c16b5eefcff12533 100644 (file)
@@ -57,6 +57,7 @@ static inline bool ipmr_rule_default(const struct fib_rule *rule)
 
 struct vif_device {
        struct net_device       *dev;                   /* Device we are using */
+       struct netdev_phys_item_id dev_parent_id;       /* Device parent ID    */
        unsigned long   bytes_in,bytes_out;
        unsigned long   pkt_in,pkt_out;         /* Statistics                   */
        unsigned long   rate_limit;             /* Traffic shaping (NI)         */
index a844738b38bd4ebd33a7797fd2e6df0d1184efce..1b161ada7ae65e0da4e3f1f9d5ebfb4d53e94e88 100644 (file)
@@ -67,6 +67,7 @@
 #include <net/fib_rules.h>
 #include <linux/netconf.h>
 #include <net/nexthop.h>
+#include <net/switchdev.h>
 
 struct ipmr_rule {
        struct fib_rule         common;
@@ -868,6 +869,9 @@ static int vif_add(struct net *net, struct mr_table *mrt,
                   struct vifctl *vifc, int mrtsock)
 {
        int vifi = vifc->vifc_vifi;
+       struct switchdev_attr attr = {
+               .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+       };
        struct vif_device *v = &mrt->vif_table[vifi];
        struct net_device *dev;
        struct in_device *in_dev;
@@ -942,6 +946,13 @@ static int vif_add(struct net *net, struct mr_table *mrt,
 
        /* Fill in the VIF structures */
 
+       attr.orig_dev = dev;
+       if (!switchdev_port_attr_get(dev, &attr)) {
+               memcpy(v->dev_parent_id.id, attr.u.ppid.id, attr.u.ppid.id_len);
+               v->dev_parent_id.id_len = attr.u.ppid.id_len;
+       } else {
+               v->dev_parent_id.id_len = 0;
+       }
        v->rate_limit = vifc->vifc_rate_limit;
        v->local = vifc->vifc_lcl_addr.s_addr;
        v->remote = vifc->vifc_rmt_addr.s_addr;