diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index ef66365b7354..93067ecdb9a2 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1127,9 +1127,10 @@ static void br_multicast_query_received(struct net_bridge *br, | |||
1127 | struct net_bridge_port *port, | 1127 | struct net_bridge_port *port, |
1128 | struct bridge_mcast_querier *querier, | 1128 | struct bridge_mcast_querier *querier, |
1129 | int saddr, | 1129 | int saddr, |
1130 | bool is_general_query, | ||
1130 | unsigned long max_delay) | 1131 | unsigned long max_delay) |
1131 | { | 1132 | { |
1132 | if (saddr) | 1133 | if (saddr && is_general_query) |
1133 | br_multicast_update_querier_timer(br, querier, max_delay); | 1134 | br_multicast_update_querier_timer(br, querier, max_delay); |
1134 | else if (timer_pending(&querier->timer)) | 1135 | else if (timer_pending(&querier->timer)) |
1135 | return; | 1136 | return; |
@@ -1181,8 +1182,16 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
1181 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; | 1182 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; |
1182 | } | 1183 | } |
1183 | 1184 | ||
1185 | /* RFC2236+RFC3376 (IGMPv2+IGMPv3) require the multicast link layer | ||
1186 | * all-systems destination addresses (224.0.0.1) for general queries | ||
1187 | */ | ||
1188 | if (!group && iph->daddr != htonl(INADDR_ALLHOSTS_GROUP)) { | ||
1189 | err = -EINVAL; | ||
1190 | goto out; | ||
1191 | } | ||
1192 | |||
1184 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, | 1193 | br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr, |
1185 | max_delay); | 1194 | !group, max_delay); |
1186 | 1195 | ||
1187 | if (!group) | 1196 | if (!group) |
1188 | goto out; | 1197 | goto out; |
@@ -1228,6 +1237,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1228 | unsigned long max_delay; | 1237 | unsigned long max_delay; |
1229 | unsigned long now = jiffies; | 1238 | unsigned long now = jiffies; |
1230 | const struct in6_addr *group = NULL; | 1239 | const struct in6_addr *group = NULL; |
1240 | bool is_general_query; | ||
1231 | int err = 0; | 1241 | int err = 0; |
1232 | 1242 | ||
1233 | spin_lock(&br->multicast_lock); | 1243 | spin_lock(&br->multicast_lock); |
@@ -1235,6 +1245,12 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1235 | (port && port->state == BR_STATE_DISABLED)) | 1245 | (port && port->state == BR_STATE_DISABLED)) |
1236 | goto out; | 1246 | goto out; |
1237 | 1247 | ||
1248 | /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */ | ||
1249 | if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) { | ||
1250 | err = -EINVAL; | ||
1251 | goto out; | ||
1252 | } | ||
1253 | |||
1238 | if (skb->len == sizeof(*mld)) { | 1254 | if (skb->len == sizeof(*mld)) { |
1239 | if (!pskb_may_pull(skb, sizeof(*mld))) { | 1255 | if (!pskb_may_pull(skb, sizeof(*mld))) { |
1240 | err = -EINVAL; | 1256 | err = -EINVAL; |
@@ -1256,8 +1272,19 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1256 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); | 1272 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); |
1257 | } | 1273 | } |
1258 | 1274 | ||
1275 | is_general_query = group && ipv6_addr_any(group); | ||
1276 | |||
1277 | /* RFC2710+RFC3810 (MLDv1+MLDv2) require the multicast link layer | ||
1278 | * all-nodes destination address (ff02::1) for general queries | ||
1279 | */ | ||
1280 | if (is_general_query && !ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) { | ||
1281 | err = -EINVAL; | ||
1282 | goto out; | ||
1283 | } | ||
1284 | |||
1259 | br_multicast_query_received(br, port, &br->ip6_querier, | 1285 | br_multicast_query_received(br, port, &br->ip6_querier, |
1260 | !ipv6_addr_any(&ip6h->saddr), max_delay); | 1286 | !ipv6_addr_any(&ip6h->saddr), |
1287 | is_general_query, max_delay); | ||
1261 | 1288 | ||
1262 | if (!group) | 1289 | if (!group) |
1263 | goto out; | 1290 | goto out; |