From: wenxu <we...@ucloud.cn>

This new function allows you to fetch vlan info from packet path.

Signed-off-by: wenxu <we...@ucloud.cn>
Signed-off-by: Nikolay Aleksandrov <niko...@cumulusnetworks.com>
---
 include/linux/if_bridge.h |  7 +++++++
 net/bridge/br_vlan.c      | 25 +++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 9e57c44..5c85608 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -92,6 +92,8 @@ static inline bool br_multicast_router(const struct 
net_device *dev)
 int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto);
 int br_vlan_get_info(const struct net_device *dev, u16 vid,
                     struct bridge_vlan_info *p_vinfo);
+int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid,
+                        struct bridge_vlan_info *p_vinfo);
 #else
 static inline bool br_vlan_enabled(const struct net_device *dev)
 {
@@ -118,6 +120,11 @@ static inline int br_vlan_get_info(const struct net_device 
*dev, u16 vid,
 {
        return -EINVAL;
 }
+static inline int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid,
+                                      struct bridge_vlan_info *p_vinfo)
+{
+       return -EINVAL;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_BRIDGE)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 021cc9f66..8a9a26e 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1293,6 +1293,31 @@ int br_vlan_get_info(const struct net_device *dev, u16 
vid,
 }
 EXPORT_SYMBOL_GPL(br_vlan_get_info);
 
+int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid,
+                        struct bridge_vlan_info *p_vinfo)
+{
+       struct net_bridge_vlan_group *vg;
+       struct net_bridge_vlan *v;
+       struct net_bridge_port *p;
+
+       p = br_port_get_check_rcu(dev);
+       if (p)
+               vg = nbp_vlan_group_rcu(p);
+       else if (netif_is_bridge_master(dev))
+               vg = br_vlan_group_rcu(netdev_priv(dev));
+       else
+               return -EINVAL;
+
+       v = br_vlan_find(vg, vid);
+       if (!v)
+               return -ENOENT;
+
+       p_vinfo->vid = vid;
+       p_vinfo->flags = v->flags;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(br_vlan_get_info_rcu);
+
 static int br_vlan_is_bind_vlan_dev(const struct net_device *dev)
 {
        return is_vlan_dev(dev) &&
-- 
1.8.3.1

Reply via email to