Skip to content

Commit 4d4fd36

Browse files
pmachatadavem330
authored andcommitted
net: bridge: Publish bridge accessor functions
Add a couple new functions to allow querying FDB and vlan settings of a bridge. Signed-off-by: Petr Machata <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6df9346 commit 4d4fd36

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

include/linux/if_bridge.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,39 @@ static inline bool br_multicast_router(const struct net_device *dev)
9393

9494
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING)
9595
bool br_vlan_enabled(const struct net_device *dev);
96+
int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid);
97+
int br_vlan_get_info(const struct net_device *dev, u16 vid,
98+
struct bridge_vlan_info *p_vinfo);
9699
#else
97100
static inline bool br_vlan_enabled(const struct net_device *dev)
98101
{
99102
return false;
100103
}
104+
105+
static inline int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
106+
{
107+
return -1;
108+
}
109+
110+
static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
111+
struct bridge_vlan_info *p_vinfo)
112+
{
113+
return -1;
114+
}
115+
#endif
116+
117+
#if IS_ENABLED(CONFIG_BRIDGE)
118+
struct net_device *br_fdb_find_port(const struct net_device *br_dev,
119+
const unsigned char *addr,
120+
__u16 vid);
121+
#else
122+
static inline struct net_device *
123+
br_fdb_find_port(const struct net_device *br_dev,
124+
const unsigned char *addr,
125+
__u16 vid)
126+
{
127+
return NULL;
128+
}
101129
#endif
102130

103131
#endif

net/bridge/br_fdb.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,28 @@ static struct net_bridge_fdb_entry *br_fdb_find(struct net_bridge *br,
121121
return fdb;
122122
}
123123

124+
struct net_device *br_fdb_find_port(const struct net_device *br_dev,
125+
const unsigned char *addr,
126+
__u16 vid)
127+
{
128+
struct net_bridge_fdb_entry *f;
129+
struct net_device *dev = NULL;
130+
struct net_bridge *br;
131+
132+
ASSERT_RTNL();
133+
134+
if (!netif_is_bridge_master(br_dev))
135+
return NULL;
136+
137+
br = netdev_priv(br_dev);
138+
f = br_fdb_find(br, addr, vid);
139+
if (f && f->dst)
140+
dev = f->dst->dev;
141+
142+
return dev;
143+
}
144+
EXPORT_SYMBOL_GPL(br_fdb_find_port);
145+
124146
struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
125147
const unsigned char *addr,
126148
__u16 vid)

net/bridge/br_private.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,11 +594,22 @@ static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
594594
return rcu_dereference(dev->rx_handler) == br_handle_frame;
595595
}
596596

597+
static inline bool br_rx_handler_check_rtnl(const struct net_device *dev)
598+
{
599+
return rcu_dereference_rtnl(dev->rx_handler) == br_handle_frame;
600+
}
601+
597602
static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
598603
{
599604
return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
600605
}
601606

607+
static inline struct net_bridge_port *
608+
br_port_get_check_rtnl(const struct net_device *dev)
609+
{
610+
return br_rx_handler_check_rtnl(dev) ? br_port_get_rtnl_rcu(dev) : NULL;
611+
}
612+
602613
/* br_ioctl.c */
603614
int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
604615
int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd,

net/bridge/br_vlan.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,3 +1149,42 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
11491149
stats->tx_packets += txpackets;
11501150
}
11511151
}
1152+
1153+
int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
1154+
{
1155+
struct net_bridge_vlan_group *vg;
1156+
1157+
ASSERT_RTNL();
1158+
if (netif_is_bridge_master(dev))
1159+
vg = br_vlan_group(netdev_priv(dev));
1160+
else
1161+
return -EINVAL;
1162+
1163+
*p_pvid = br_get_pvid(vg);
1164+
return 0;
1165+
}
1166+
EXPORT_SYMBOL_GPL(br_vlan_get_pvid);
1167+
1168+
int br_vlan_get_info(const struct net_device *dev, u16 vid,
1169+
struct bridge_vlan_info *p_vinfo)
1170+
{
1171+
struct net_bridge_vlan_group *vg;
1172+
struct net_bridge_vlan *v;
1173+
struct net_bridge_port *p;
1174+
1175+
ASSERT_RTNL();
1176+
p = br_port_get_check_rtnl(dev);
1177+
if (p)
1178+
vg = nbp_vlan_group(p);
1179+
else
1180+
return -EINVAL;
1181+
1182+
v = br_vlan_find(vg, vid);
1183+
if (!v)
1184+
return -ENOENT;
1185+
1186+
p_vinfo->vid = vid;
1187+
p_vinfo->flags = v->flags;
1188+
return 0;
1189+
}
1190+
EXPORT_SYMBOL_GPL(br_vlan_get_info);

0 commit comments

Comments
 (0)