Skip to content

Commit 615cc23

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
net: bridge: multicast: add vlan querier and query support
Add basic vlan context querier support, if the contexts passed to multicast_alloc_query are vlan then the query will be tagged. Also handle querier start/stop of vlan contexts. Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 4cdd0d1 commit 615cc23

File tree

1 file changed

+60
-8
lines changed

1 file changed

+60
-8
lines changed

net/bridge/br_multicast.c

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,28 @@ static void br_multicast_gc(struct hlist_head *head)
773773
}
774774
}
775775

776+
static void __br_multicast_query_handle_vlan(struct net_bridge_mcast *brmctx,
777+
struct net_bridge_mcast_port *pmctx,
778+
struct sk_buff *skb)
779+
{
780+
struct net_bridge_vlan *vlan = NULL;
781+
782+
if (pmctx && br_multicast_port_ctx_is_vlan(pmctx))
783+
vlan = pmctx->vlan;
784+
else if (br_multicast_ctx_is_vlan(brmctx))
785+
vlan = brmctx->vlan;
786+
787+
if (vlan && !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) {
788+
u16 vlan_proto;
789+
790+
if (br_vlan_get_proto(brmctx->br->dev, &vlan_proto) != 0)
791+
return;
792+
__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan->vid);
793+
}
794+
}
795+
776796
static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brmctx,
797+
struct net_bridge_mcast_port *pmctx,
777798
struct net_bridge_port_group *pg,
778799
__be32 ip_dst, __be32 group,
779800
bool with_srcs, bool over_lmqt,
@@ -822,6 +843,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brm
822843
if (!skb)
823844
goto out;
824845

846+
__br_multicast_query_handle_vlan(brmctx, pmctx, skb);
825847
skb->protocol = htons(ETH_P_IP);
826848

827849
skb_reset_mac_header(skb);
@@ -919,6 +941,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brm
919941

920942
#if IS_ENABLED(CONFIG_IPV6)
921943
static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brmctx,
944+
struct net_bridge_mcast_port *pmctx,
922945
struct net_bridge_port_group *pg,
923946
const struct in6_addr *ip6_dst,
924947
const struct in6_addr *group,
@@ -970,6 +993,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm
970993
if (!skb)
971994
goto out;
972995

996+
__br_multicast_query_handle_vlan(brmctx, pmctx, skb);
973997
skb->protocol = htons(ETH_P_IPV6);
974998

975999
/* Ethernet header */
@@ -1082,6 +1106,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm
10821106
#endif
10831107

10841108
static struct sk_buff *br_multicast_alloc_query(struct net_bridge_mcast *brmctx,
1109+
struct net_bridge_mcast_port *pmctx,
10851110
struct net_bridge_port_group *pg,
10861111
struct br_ip *ip_dst,
10871112
struct br_ip *group,
@@ -1094,7 +1119,7 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge_mcast *brmctx,
10941119
switch (group->proto) {
10951120
case htons(ETH_P_IP):
10961121
ip4_dst = ip_dst ? ip_dst->dst.ip4 : htonl(INADDR_ALLHOSTS_GROUP);
1097-
return br_ip4_multicast_alloc_query(brmctx, pg,
1122+
return br_ip4_multicast_alloc_query(brmctx, pmctx, pg,
10981123
ip4_dst, group->dst.ip4,
10991124
with_srcs, over_lmqt,
11001125
sflag, igmp_type,
@@ -1109,7 +1134,7 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge_mcast *brmctx,
11091134
ipv6_addr_set(&ip6_dst, htonl(0xff020000), 0, 0,
11101135
htonl(1));
11111136

1112-
return br_ip6_multicast_alloc_query(brmctx, pg,
1137+
return br_ip6_multicast_alloc_query(brmctx, pmctx, pg,
11131138
&ip6_dst, &group->dst.ip6,
11141139
with_srcs, over_lmqt,
11151140
sflag, igmp_type,
@@ -1603,9 +1628,12 @@ static void __br_multicast_send_query(struct net_bridge_mcast *brmctx,
16031628
struct sk_buff *skb;
16041629
u8 igmp_type;
16051630

1631+
if (!br_multicast_ctx_should_use(brmctx, pmctx))
1632+
return;
1633+
16061634
again_under_lmqt:
1607-
skb = br_multicast_alloc_query(brmctx, pg, ip_dst, group, with_srcs,
1608-
over_lmqt, sflag, &igmp_type,
1635+
skb = br_multicast_alloc_query(brmctx, pmctx, pg, ip_dst, group,
1636+
with_srcs, over_lmqt, sflag, &igmp_type,
16091637
need_rexmit);
16101638
if (!skb)
16111639
return;
@@ -1679,6 +1707,7 @@ br_multicast_port_query_expired(struct net_bridge_mcast_port *pmctx,
16791707
spin_lock(&br->multicast_lock);
16801708
if (br_multicast_port_ctx_state_stopped(pmctx))
16811709
goto out;
1710+
16821711
brmctx = br_multicast_port_ctx_get_global(pmctx);
16831712
if (query->startup_sent < brmctx->multicast_startup_query_count)
16841713
query->startup_sent++;
@@ -4129,15 +4158,38 @@ static void br_multicast_start_querier(struct net_bridge_mcast *brmctx,
41294158

41304159
rcu_read_lock();
41314160
list_for_each_entry_rcu(port, &brmctx->br->port_list, list) {
4132-
if (port->state == BR_STATE_DISABLED ||
4133-
port->state == BR_STATE_BLOCKING)
4161+
struct bridge_mcast_own_query *ip4_own_query;
4162+
#if IS_ENABLED(CONFIG_IPV6)
4163+
struct bridge_mcast_own_query *ip6_own_query;
4164+
#endif
4165+
4166+
if (br_multicast_port_ctx_state_stopped(&port->multicast_ctx))
41344167
continue;
41354168

4169+
if (br_multicast_ctx_is_vlan(brmctx)) {
4170+
struct net_bridge_vlan *vlan;
4171+
4172+
vlan = br_vlan_find(nbp_vlan_group(port), brmctx->vlan->vid);
4173+
if (!vlan ||
4174+
br_multicast_port_ctx_state_stopped(&vlan->port_mcast_ctx))
4175+
continue;
4176+
4177+
ip4_own_query = &vlan->port_mcast_ctx.ip4_own_query;
4178+
#if IS_ENABLED(CONFIG_IPV6)
4179+
ip6_own_query = &vlan->port_mcast_ctx.ip6_own_query;
4180+
#endif
4181+
} else {
4182+
ip4_own_query = &port->multicast_ctx.ip4_own_query;
4183+
#if IS_ENABLED(CONFIG_IPV6)
4184+
ip6_own_query = &port->multicast_ctx.ip6_own_query;
4185+
#endif
4186+
}
4187+
41364188
if (query == &brmctx->ip4_own_query)
4137-
br_multicast_enable(&port->multicast_ctx.ip4_own_query);
4189+
br_multicast_enable(ip4_own_query);
41384190
#if IS_ENABLED(CONFIG_IPV6)
41394191
else
4140-
br_multicast_enable(&port->multicast_ctx.ip6_own_query);
4192+
br_multicast_enable(ip6_own_query);
41414193
#endif
41424194
}
41434195
rcu_read_unlock();

0 commit comments

Comments
 (0)