Skip to content

Commit 0649909

Browse files
Vlad Yasevichdavem330
Vlad Yasevich
authored andcommitted
bridge: pass correct vlan id to multicast code
Currently multicast code attempts to extrace the vlan id from the skb even when vlan filtering is disabled. This can lead to mdb entries being created with the wrong vlan id. Pass the already extracted vlan id to the multicast filtering code to make the correct id is used in creation as well as lookup. Signed-off-by: Vlad Yasevich <[email protected]> Acked-by: Toshiaki Makita <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 911aeb1 commit 0649909

File tree

4 files changed

+25
-29
lines changed

4 files changed

+25
-29
lines changed

net/bridge/br_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
6464
br_flood_deliver(br, skb, false);
6565
goto out;
6666
}
67-
if (br_multicast_rcv(br, NULL, skb)) {
67+
if (br_multicast_rcv(br, NULL, skb, vid)) {
6868
kfree_skb(skb);
6969
goto out;
7070
}

net/bridge/br_input.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
8080
br_fdb_update(br, p, eth_hdr(skb)->h_source, vid);
8181

8282
if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) &&
83-
br_multicast_rcv(br, p, skb))
83+
br_multicast_rcv(br, p, skb, vid))
8484
goto drop;
8585

8686
if (p->state == BR_STATE_LEARNING)

net/bridge/br_multicast.c

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,8 @@ void br_multicast_disable_port(struct net_bridge_port *port)
947947

948948
static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
949949
struct net_bridge_port *port,
950-
struct sk_buff *skb)
950+
struct sk_buff *skb,
951+
u16 vid)
951952
{
952953
struct igmpv3_report *ih;
953954
struct igmpv3_grec *grec;
@@ -957,12 +958,10 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
957958
int type;
958959
int err = 0;
959960
__be32 group;
960-
u16 vid = 0;
961961

962962
if (!pskb_may_pull(skb, sizeof(*ih)))
963963
return -EINVAL;
964964

965-
br_vlan_get_tag(skb, &vid);
966965
ih = igmpv3_report_hdr(skb);
967966
num = ntohs(ih->ngrec);
968967
len = sizeof(*ih);
@@ -1005,20 +1004,19 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
10051004
#if IS_ENABLED(CONFIG_IPV6)
10061005
static int br_ip6_multicast_mld2_report(struct net_bridge *br,
10071006
struct net_bridge_port *port,
1008-
struct sk_buff *skb)
1007+
struct sk_buff *skb,
1008+
u16 vid)
10091009
{
10101010
struct icmp6hdr *icmp6h;
10111011
struct mld2_grec *grec;
10121012
int i;
10131013
int len;
10141014
int num;
10151015
int err = 0;
1016-
u16 vid = 0;
10171016

10181017
if (!pskb_may_pull(skb, sizeof(*icmp6h)))
10191018
return -EINVAL;
10201019

1021-
br_vlan_get_tag(skb, &vid);
10221020
icmp6h = icmp6_hdr(skb);
10231021
num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
10241022
len = sizeof(*icmp6h);
@@ -1141,7 +1139,8 @@ static void br_multicast_query_received(struct net_bridge *br,
11411139

11421140
static int br_ip4_multicast_query(struct net_bridge *br,
11431141
struct net_bridge_port *port,
1144-
struct sk_buff *skb)
1142+
struct sk_buff *skb,
1143+
u16 vid)
11451144
{
11461145
const struct iphdr *iph = ip_hdr(skb);
11471146
struct igmphdr *ih = igmp_hdr(skb);
@@ -1153,7 +1152,6 @@ static int br_ip4_multicast_query(struct net_bridge *br,
11531152
unsigned long now = jiffies;
11541153
__be32 group;
11551154
int err = 0;
1156-
u16 vid = 0;
11571155

11581156
spin_lock(&br->multicast_lock);
11591157
if (!netif_running(br->dev) ||
@@ -1189,7 +1187,6 @@ static int br_ip4_multicast_query(struct net_bridge *br,
11891187
if (!group)
11901188
goto out;
11911189

1192-
br_vlan_get_tag(skb, &vid);
11931190
mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid);
11941191
if (!mp)
11951192
goto out;
@@ -1219,7 +1216,8 @@ static int br_ip4_multicast_query(struct net_bridge *br,
12191216
#if IS_ENABLED(CONFIG_IPV6)
12201217
static int br_ip6_multicast_query(struct net_bridge *br,
12211218
struct net_bridge_port *port,
1222-
struct sk_buff *skb)
1219+
struct sk_buff *skb,
1220+
u16 vid)
12231221
{
12241222
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
12251223
struct mld_msg *mld;
@@ -1231,7 +1229,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
12311229
unsigned long now = jiffies;
12321230
const struct in6_addr *group = NULL;
12331231
int err = 0;
1234-
u16 vid = 0;
12351232

12361233
spin_lock(&br->multicast_lock);
12371234
if (!netif_running(br->dev) ||
@@ -1265,7 +1262,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
12651262
if (!group)
12661263
goto out;
12671264

1268-
br_vlan_get_tag(skb, &vid);
12691265
mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid);
12701266
if (!mp)
12711267
goto out;
@@ -1439,15 +1435,15 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
14391435

14401436
static int br_multicast_ipv4_rcv(struct net_bridge *br,
14411437
struct net_bridge_port *port,
1442-
struct sk_buff *skb)
1438+
struct sk_buff *skb,
1439+
u16 vid)
14431440
{
14441441
struct sk_buff *skb2 = skb;
14451442
const struct iphdr *iph;
14461443
struct igmphdr *ih;
14471444
unsigned int len;
14481445
unsigned int offset;
14491446
int err;
1450-
u16 vid = 0;
14511447

14521448
/* We treat OOM as packet loss for now. */
14531449
if (!pskb_may_pull(skb, sizeof(*iph)))
@@ -1508,7 +1504,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
15081504

15091505
err = 0;
15101506

1511-
br_vlan_get_tag(skb2, &vid);
15121507
BR_INPUT_SKB_CB(skb)->igmp = 1;
15131508
ih = igmp_hdr(skb2);
15141509

@@ -1519,10 +1514,10 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
15191514
err = br_ip4_multicast_add_group(br, port, ih->group, vid);
15201515
break;
15211516
case IGMPV3_HOST_MEMBERSHIP_REPORT:
1522-
err = br_ip4_multicast_igmp3_report(br, port, skb2);
1517+
err = br_ip4_multicast_igmp3_report(br, port, skb2, vid);
15231518
break;
15241519
case IGMP_HOST_MEMBERSHIP_QUERY:
1525-
err = br_ip4_multicast_query(br, port, skb2);
1520+
err = br_ip4_multicast_query(br, port, skb2, vid);
15261521
break;
15271522
case IGMP_HOST_LEAVE_MESSAGE:
15281523
br_ip4_multicast_leave_group(br, port, ih->group, vid);
@@ -1540,7 +1535,8 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
15401535
#if IS_ENABLED(CONFIG_IPV6)
15411536
static int br_multicast_ipv6_rcv(struct net_bridge *br,
15421537
struct net_bridge_port *port,
1543-
struct sk_buff *skb)
1538+
struct sk_buff *skb,
1539+
u16 vid)
15441540
{
15451541
struct sk_buff *skb2;
15461542
const struct ipv6hdr *ip6h;
@@ -1550,7 +1546,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
15501546
unsigned int len;
15511547
int offset;
15521548
int err;
1553-
u16 vid = 0;
15541549

15551550
if (!pskb_may_pull(skb, sizeof(*ip6h)))
15561551
return -EINVAL;
@@ -1640,7 +1635,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
16401635

16411636
err = 0;
16421637

1643-
br_vlan_get_tag(skb, &vid);
16441638
BR_INPUT_SKB_CB(skb)->igmp = 1;
16451639

16461640
switch (icmp6_type) {
@@ -1657,10 +1651,10 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
16571651
break;
16581652
}
16591653
case ICMPV6_MLD2_REPORT:
1660-
err = br_ip6_multicast_mld2_report(br, port, skb2);
1654+
err = br_ip6_multicast_mld2_report(br, port, skb2, vid);
16611655
break;
16621656
case ICMPV6_MGM_QUERY:
1663-
err = br_ip6_multicast_query(br, port, skb2);
1657+
err = br_ip6_multicast_query(br, port, skb2, vid);
16641658
break;
16651659
case ICMPV6_MGM_REDUCTION:
16661660
{
@@ -1681,7 +1675,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
16811675
#endif
16821676

16831677
int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
1684-
struct sk_buff *skb)
1678+
struct sk_buff *skb, u16 vid)
16851679
{
16861680
BR_INPUT_SKB_CB(skb)->igmp = 0;
16871681
BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
@@ -1691,10 +1685,10 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
16911685

16921686
switch (skb->protocol) {
16931687
case htons(ETH_P_IP):
1694-
return br_multicast_ipv4_rcv(br, port, skb);
1688+
return br_multicast_ipv4_rcv(br, port, skb, vid);
16951689
#if IS_ENABLED(CONFIG_IPV6)
16961690
case htons(ETH_P_IPV6):
1697-
return br_multicast_ipv6_rcv(br, port, skb);
1691+
return br_multicast_ipv6_rcv(br, port, skb, vid);
16981692
#endif
16991693
}
17001694

net/bridge/br_private.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,8 @@ extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __us
451451
extern unsigned int br_mdb_rehash_seq;
452452
extern int br_multicast_rcv(struct net_bridge *br,
453453
struct net_bridge_port *port,
454-
struct sk_buff *skb);
454+
struct sk_buff *skb,
455+
u16 vid);
455456
extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
456457
struct sk_buff *skb, u16 vid);
457458
extern void br_multicast_add_port(struct net_bridge_port *port);
@@ -522,7 +523,8 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
522523
#else
523524
static inline int br_multicast_rcv(struct net_bridge *br,
524525
struct net_bridge_port *port,
525-
struct sk_buff *skb)
526+
struct sk_buff *skb,
527+
u16 vid)
526528
{
527529
return 0;
528530
}

0 commit comments

Comments
 (0)