diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 44 |
1 files changed, 19 insertions, 25 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 0513ef3ce667..4c214b2b88ef 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -947,7 +947,8 @@ void br_multicast_disable_port(struct net_bridge_port *port) | |||
947 | 947 | ||
948 | static int br_ip4_multicast_igmp3_report(struct net_bridge *br, | 948 | static int br_ip4_multicast_igmp3_report(struct net_bridge *br, |
949 | struct net_bridge_port *port, | 949 | struct net_bridge_port *port, |
950 | struct sk_buff *skb) | 950 | struct sk_buff *skb, |
951 | u16 vid) | ||
951 | { | 952 | { |
952 | struct igmpv3_report *ih; | 953 | struct igmpv3_report *ih; |
953 | struct igmpv3_grec *grec; | 954 | struct igmpv3_grec *grec; |
@@ -957,12 +958,10 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, | |||
957 | int type; | 958 | int type; |
958 | int err = 0; | 959 | int err = 0; |
959 | __be32 group; | 960 | __be32 group; |
960 | u16 vid = 0; | ||
961 | 961 | ||
962 | if (!pskb_may_pull(skb, sizeof(*ih))) | 962 | if (!pskb_may_pull(skb, sizeof(*ih))) |
963 | return -EINVAL; | 963 | return -EINVAL; |
964 | 964 | ||
965 | br_vlan_get_tag(skb, &vid); | ||
966 | ih = igmpv3_report_hdr(skb); | 965 | ih = igmpv3_report_hdr(skb); |
967 | num = ntohs(ih->ngrec); | 966 | num = ntohs(ih->ngrec); |
968 | len = sizeof(*ih); | 967 | len = sizeof(*ih); |
@@ -1005,7 +1004,8 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, | |||
1005 | #if IS_ENABLED(CONFIG_IPV6) | 1004 | #if IS_ENABLED(CONFIG_IPV6) |
1006 | static int br_ip6_multicast_mld2_report(struct net_bridge *br, | 1005 | static int br_ip6_multicast_mld2_report(struct net_bridge *br, |
1007 | struct net_bridge_port *port, | 1006 | struct net_bridge_port *port, |
1008 | struct sk_buff *skb) | 1007 | struct sk_buff *skb, |
1008 | u16 vid) | ||
1009 | { | 1009 | { |
1010 | struct icmp6hdr *icmp6h; | 1010 | struct icmp6hdr *icmp6h; |
1011 | struct mld2_grec *grec; | 1011 | struct mld2_grec *grec; |
@@ -1013,12 +1013,10 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, | |||
1013 | int len; | 1013 | int len; |
1014 | int num; | 1014 | int num; |
1015 | int err = 0; | 1015 | int err = 0; |
1016 | u16 vid = 0; | ||
1017 | 1016 | ||
1018 | if (!pskb_may_pull(skb, sizeof(*icmp6h))) | 1017 | if (!pskb_may_pull(skb, sizeof(*icmp6h))) |
1019 | return -EINVAL; | 1018 | return -EINVAL; |
1020 | 1019 | ||
1021 | br_vlan_get_tag(skb, &vid); | ||
1022 | icmp6h = icmp6_hdr(skb); | 1020 | icmp6h = icmp6_hdr(skb); |
1023 | num = ntohs(icmp6h->icmp6_dataun.un_data16[1]); | 1021 | num = ntohs(icmp6h->icmp6_dataun.un_data16[1]); |
1024 | len = sizeof(*icmp6h); | 1022 | len = sizeof(*icmp6h); |
@@ -1141,7 +1139,8 @@ static void br_multicast_query_received(struct net_bridge *br, | |||
1141 | 1139 | ||
1142 | static int br_ip4_multicast_query(struct net_bridge *br, | 1140 | static int br_ip4_multicast_query(struct net_bridge *br, |
1143 | struct net_bridge_port *port, | 1141 | struct net_bridge_port *port, |
1144 | struct sk_buff *skb) | 1142 | struct sk_buff *skb, |
1143 | u16 vid) | ||
1145 | { | 1144 | { |
1146 | const struct iphdr *iph = ip_hdr(skb); | 1145 | const struct iphdr *iph = ip_hdr(skb); |
1147 | struct igmphdr *ih = igmp_hdr(skb); | 1146 | struct igmphdr *ih = igmp_hdr(skb); |
@@ -1153,7 +1152,6 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
1153 | unsigned long now = jiffies; | 1152 | unsigned long now = jiffies; |
1154 | __be32 group; | 1153 | __be32 group; |
1155 | int err = 0; | 1154 | int err = 0; |
1156 | u16 vid = 0; | ||
1157 | 1155 | ||
1158 | spin_lock(&br->multicast_lock); | 1156 | spin_lock(&br->multicast_lock); |
1159 | if (!netif_running(br->dev) || | 1157 | if (!netif_running(br->dev) || |
@@ -1189,7 +1187,6 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
1189 | if (!group) | 1187 | if (!group) |
1190 | goto out; | 1188 | goto out; |
1191 | 1189 | ||
1192 | br_vlan_get_tag(skb, &vid); | ||
1193 | mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid); | 1190 | mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid); |
1194 | if (!mp) | 1191 | if (!mp) |
1195 | goto out; | 1192 | goto out; |
@@ -1219,7 +1216,8 @@ out: | |||
1219 | #if IS_ENABLED(CONFIG_IPV6) | 1216 | #if IS_ENABLED(CONFIG_IPV6) |
1220 | static int br_ip6_multicast_query(struct net_bridge *br, | 1217 | static int br_ip6_multicast_query(struct net_bridge *br, |
1221 | struct net_bridge_port *port, | 1218 | struct net_bridge_port *port, |
1222 | struct sk_buff *skb) | 1219 | struct sk_buff *skb, |
1220 | u16 vid) | ||
1223 | { | 1221 | { |
1224 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); | 1222 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
1225 | struct mld_msg *mld; | 1223 | struct mld_msg *mld; |
@@ -1231,7 +1229,6 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1231 | unsigned long now = jiffies; | 1229 | unsigned long now = jiffies; |
1232 | const struct in6_addr *group = NULL; | 1230 | const struct in6_addr *group = NULL; |
1233 | int err = 0; | 1231 | int err = 0; |
1234 | u16 vid = 0; | ||
1235 | 1232 | ||
1236 | spin_lock(&br->multicast_lock); | 1233 | spin_lock(&br->multicast_lock); |
1237 | if (!netif_running(br->dev) || | 1234 | if (!netif_running(br->dev) || |
@@ -1265,7 +1262,6 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1265 | if (!group) | 1262 | if (!group) |
1266 | goto out; | 1263 | goto out; |
1267 | 1264 | ||
1268 | br_vlan_get_tag(skb, &vid); | ||
1269 | mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid); | 1265 | mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid); |
1270 | if (!mp) | 1266 | if (!mp) |
1271 | goto out; | 1267 | goto out; |
@@ -1439,7 +1435,8 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, | |||
1439 | 1435 | ||
1440 | static int br_multicast_ipv4_rcv(struct net_bridge *br, | 1436 | static int br_multicast_ipv4_rcv(struct net_bridge *br, |
1441 | struct net_bridge_port *port, | 1437 | struct net_bridge_port *port, |
1442 | struct sk_buff *skb) | 1438 | struct sk_buff *skb, |
1439 | u16 vid) | ||
1443 | { | 1440 | { |
1444 | struct sk_buff *skb2 = skb; | 1441 | struct sk_buff *skb2 = skb; |
1445 | const struct iphdr *iph; | 1442 | const struct iphdr *iph; |
@@ -1447,7 +1444,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1447 | unsigned int len; | 1444 | unsigned int len; |
1448 | unsigned int offset; | 1445 | unsigned int offset; |
1449 | int err; | 1446 | int err; |
1450 | u16 vid = 0; | ||
1451 | 1447 | ||
1452 | /* We treat OOM as packet loss for now. */ | 1448 | /* We treat OOM as packet loss for now. */ |
1453 | if (!pskb_may_pull(skb, sizeof(*iph))) | 1449 | if (!pskb_may_pull(skb, sizeof(*iph))) |
@@ -1508,7 +1504,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1508 | 1504 | ||
1509 | err = 0; | 1505 | err = 0; |
1510 | 1506 | ||
1511 | br_vlan_get_tag(skb2, &vid); | ||
1512 | BR_INPUT_SKB_CB(skb)->igmp = 1; | 1507 | BR_INPUT_SKB_CB(skb)->igmp = 1; |
1513 | ih = igmp_hdr(skb2); | 1508 | ih = igmp_hdr(skb2); |
1514 | 1509 | ||
@@ -1519,10 +1514,10 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1519 | err = br_ip4_multicast_add_group(br, port, ih->group, vid); | 1514 | err = br_ip4_multicast_add_group(br, port, ih->group, vid); |
1520 | break; | 1515 | break; |
1521 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 1516 | 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); |
1523 | break; | 1518 | break; |
1524 | case IGMP_HOST_MEMBERSHIP_QUERY: | 1519 | case IGMP_HOST_MEMBERSHIP_QUERY: |
1525 | err = br_ip4_multicast_query(br, port, skb2); | 1520 | err = br_ip4_multicast_query(br, port, skb2, vid); |
1526 | break; | 1521 | break; |
1527 | case IGMP_HOST_LEAVE_MESSAGE: | 1522 | case IGMP_HOST_LEAVE_MESSAGE: |
1528 | br_ip4_multicast_leave_group(br, port, ih->group, vid); | 1523 | br_ip4_multicast_leave_group(br, port, ih->group, vid); |
@@ -1540,7 +1535,8 @@ err_out: | |||
1540 | #if IS_ENABLED(CONFIG_IPV6) | 1535 | #if IS_ENABLED(CONFIG_IPV6) |
1541 | static int br_multicast_ipv6_rcv(struct net_bridge *br, | 1536 | static int br_multicast_ipv6_rcv(struct net_bridge *br, |
1542 | struct net_bridge_port *port, | 1537 | struct net_bridge_port *port, |
1543 | struct sk_buff *skb) | 1538 | struct sk_buff *skb, |
1539 | u16 vid) | ||
1544 | { | 1540 | { |
1545 | struct sk_buff *skb2; | 1541 | struct sk_buff *skb2; |
1546 | const struct ipv6hdr *ip6h; | 1542 | const struct ipv6hdr *ip6h; |
@@ -1550,7 +1546,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1550 | unsigned int len; | 1546 | unsigned int len; |
1551 | int offset; | 1547 | int offset; |
1552 | int err; | 1548 | int err; |
1553 | u16 vid = 0; | ||
1554 | 1549 | ||
1555 | if (!pskb_may_pull(skb, sizeof(*ip6h))) | 1550 | if (!pskb_may_pull(skb, sizeof(*ip6h))) |
1556 | return -EINVAL; | 1551 | return -EINVAL; |
@@ -1640,7 +1635,6 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1640 | 1635 | ||
1641 | err = 0; | 1636 | err = 0; |
1642 | 1637 | ||
1643 | br_vlan_get_tag(skb, &vid); | ||
1644 | BR_INPUT_SKB_CB(skb)->igmp = 1; | 1638 | BR_INPUT_SKB_CB(skb)->igmp = 1; |
1645 | 1639 | ||
1646 | switch (icmp6_type) { | 1640 | switch (icmp6_type) { |
@@ -1657,10 +1651,10 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1657 | break; | 1651 | break; |
1658 | } | 1652 | } |
1659 | case ICMPV6_MLD2_REPORT: | 1653 | 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); |
1661 | break; | 1655 | break; |
1662 | case ICMPV6_MGM_QUERY: | 1656 | case ICMPV6_MGM_QUERY: |
1663 | err = br_ip6_multicast_query(br, port, skb2); | 1657 | err = br_ip6_multicast_query(br, port, skb2, vid); |
1664 | break; | 1658 | break; |
1665 | case ICMPV6_MGM_REDUCTION: | 1659 | case ICMPV6_MGM_REDUCTION: |
1666 | { | 1660 | { |
@@ -1681,7 +1675,7 @@ out: | |||
1681 | #endif | 1675 | #endif |
1682 | 1676 | ||
1683 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, | 1677 | 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) |
1685 | { | 1679 | { |
1686 | BR_INPUT_SKB_CB(skb)->igmp = 0; | 1680 | BR_INPUT_SKB_CB(skb)->igmp = 0; |
1687 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | 1681 | 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, | |||
1691 | 1685 | ||
1692 | switch (skb->protocol) { | 1686 | switch (skb->protocol) { |
1693 | case htons(ETH_P_IP): | 1687 | case htons(ETH_P_IP): |
1694 | return br_multicast_ipv4_rcv(br, port, skb); | 1688 | return br_multicast_ipv4_rcv(br, port, skb, vid); |
1695 | #if IS_ENABLED(CONFIG_IPV6) | 1689 | #if IS_ENABLED(CONFIG_IPV6) |
1696 | case htons(ETH_P_IPV6): | 1690 | case htons(ETH_P_IPV6): |
1697 | return br_multicast_ipv6_rcv(br, port, skb); | 1691 | return br_multicast_ipv6_rcv(br, port, skb, vid); |
1698 | #endif | 1692 | #endif |
1699 | } | 1693 | } |
1700 | 1694 | ||