diff options
| -rw-r--r-- | net/bridge/br_multicast.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index fb0e36fac668..e56bae4f59ce 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1181,6 +1181,14 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
| 1181 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; | 1181 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; |
| 1182 | } | 1182 | } |
| 1183 | 1183 | ||
| 1184 | /* RFC2236+RFC3376 (IGMPv2+IGMPv3) require the multicast link layer | ||
| 1185 | * all-systems destination addresses (224.0.0.1) for general queries | ||
| 1186 | */ | ||
| 1187 | if (!group && iph->daddr != htonl(INADDR_ALLHOSTS_GROUP)) { | ||
| 1188 | err = -EINVAL; | ||
| 1189 | goto out; | ||
| 1190 | } | ||
| 1191 | |||
| 1184 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, | 1192 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, |
| 1185 | max_delay); | 1193 | max_delay); |
| 1186 | 1194 | ||
| @@ -1228,6 +1236,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1228 | unsigned long max_delay; | 1236 | unsigned long max_delay; |
| 1229 | unsigned long now = jiffies; | 1237 | unsigned long now = jiffies; |
| 1230 | const struct in6_addr *group = NULL; | 1238 | const struct in6_addr *group = NULL; |
| 1239 | bool is_general_query; | ||
| 1231 | int err = 0; | 1240 | int err = 0; |
| 1232 | 1241 | ||
| 1233 | spin_lock(&br->multicast_lock); | 1242 | spin_lock(&br->multicast_lock); |
| @@ -1262,6 +1271,16 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1262 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); | 1271 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); |
| 1263 | } | 1272 | } |
| 1264 | 1273 | ||
| 1274 | is_general_query = group && ipv6_addr_any(group); | ||
| 1275 | |||
| 1276 | /* RFC2710+RFC3810 (MLDv1+MLDv2) require the multicast link layer | ||
| 1277 | * all-nodes destination address (ff02::1) for general queries | ||
| 1278 | */ | ||
| 1279 | if (is_general_query && !ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) { | ||
| 1280 | err = -EINVAL; | ||
| 1281 | goto out; | ||
| 1282 | } | ||
| 1283 | |||
| 1265 | br_multicast_query_received(br, port, &br->ip6_querier, | 1284 | br_multicast_query_received(br, port, &br->ip6_querier, |
| 1266 | !ipv6_addr_any(&ip6h->saddr), max_delay); | 1285 | !ipv6_addr_any(&ip6h->saddr), max_delay); |
| 1267 | 1286 | ||
