br_multicast.c (8f8cb77e0b22d9044d8d57ab3bb18ea8d0474752) | br_multicast.c (085b53c8beabf9b379762f73aaac562d6c428923) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Bridge multicast support. 4 * 5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 6 */ 7 8#include <linux/err.h> --- 27 unchanged lines hidden (view full) --- 36 37static const struct rhashtable_params br_mdb_rht_params = { 38 .head_offset = offsetof(struct net_bridge_mdb_entry, rhnode), 39 .key_offset = offsetof(struct net_bridge_mdb_entry, addr), 40 .key_len = sizeof(struct br_ip), 41 .automatic_shrinking = true, 42}; 43 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Bridge multicast support. 4 * 5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 6 */ 7 8#include <linux/err.h> --- 27 unchanged lines hidden (view full) --- 36 37static const struct rhashtable_params br_mdb_rht_params = { 38 .head_offset = offsetof(struct net_bridge_mdb_entry, rhnode), 39 .key_offset = offsetof(struct net_bridge_mdb_entry, addr), 40 .key_len = sizeof(struct br_ip), 41 .automatic_shrinking = true, 42}; 43 |
44static const struct rhashtable_params br_sg_port_rht_params = { 45 .head_offset = offsetof(struct net_bridge_port_group, rhnode), 46 .key_offset = offsetof(struct net_bridge_port_group, key), 47 .key_len = sizeof(struct net_bridge_port_group_sg_key), 48 .automatic_shrinking = true, 49}; 50 |
|
44static void br_multicast_start_querier(struct net_bridge *br, 45 struct bridge_mcast_own_query *query); 46static void br_multicast_add_router(struct net_bridge *br, 47 struct net_bridge_port *port); 48static void br_ip4_multicast_leave_group(struct net_bridge *br, 49 struct net_bridge_port *port, 50 __be32 group, 51 __u16 vid, 52 const unsigned char *src); 53static void br_multicast_port_group_rexmit(struct timer_list *t); 54 55static void __del_port_router(struct net_bridge_port *p); 56#if IS_ENABLED(CONFIG_IPV6) 57static void br_ip6_multicast_leave_group(struct net_bridge *br, 58 struct net_bridge_port *port, 59 const struct in6_addr *group, 60 __u16 vid, const unsigned char *src); 61#endif 62 | 51static void br_multicast_start_querier(struct net_bridge *br, 52 struct bridge_mcast_own_query *query); 53static void br_multicast_add_router(struct net_bridge *br, 54 struct net_bridge_port *port); 55static void br_ip4_multicast_leave_group(struct net_bridge *br, 56 struct net_bridge_port *port, 57 __be32 group, 58 __u16 vid, 59 const unsigned char *src); 60static void br_multicast_port_group_rexmit(struct timer_list *t); 61 62static void __del_port_router(struct net_bridge_port *p); 63#if IS_ENABLED(CONFIG_IPV6) 64static void br_ip6_multicast_leave_group(struct net_bridge *br, 65 struct net_bridge_port *port, 66 const struct in6_addr *group, 67 __u16 vid, const unsigned char *src); 68#endif 69 |
70static struct net_bridge_port_group * 71br_sg_port_find(struct net_bridge *br, 72 struct net_bridge_port_group_sg_key *sg_p) 73{ 74 lockdep_assert_held_once(&br->multicast_lock); 75 76 return rhashtable_lookup_fast(&br->sg_port_tbl, sg_p, 77 br_sg_port_rht_params); 78} 79 |
|
63static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br, 64 struct br_ip *dst) 65{ 66 return rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params); 67} 68 69struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br, 70 struct br_ip *dst) --- 136 unchanged lines hidden (view full) --- 207 WARN_ON(!hlist_unhashed(&src->node)); 208 209 del_timer_sync(&src->timer); 210 kfree_rcu(src, rcu); 211} 212 213static void br_multicast_del_group_src(struct net_bridge_group_src *src) 214{ | 80static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br, 81 struct br_ip *dst) 82{ 83 return rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params); 84} 85 86struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br, 87 struct br_ip *dst) --- 136 unchanged lines hidden (view full) --- 224 WARN_ON(!hlist_unhashed(&src->node)); 225 226 del_timer_sync(&src->timer); 227 kfree_rcu(src, rcu); 228} 229 230static void br_multicast_del_group_src(struct net_bridge_group_src *src) 231{ |
215 struct net_bridge *br = src->pg->port->br; | 232 struct net_bridge *br = src->pg->key.port->br; |
216 217 hlist_del_init_rcu(&src->node); 218 src->pg->src_ents--; 219 hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list); 220 queue_work(system_long_wq, &br->mcast_gc_work); 221} 222 223static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc) --- 8 unchanged lines hidden (view full) --- 232 del_timer_sync(&pg->timer); 233 kfree_rcu(pg, rcu); 234} 235 236void br_multicast_del_pg(struct net_bridge_mdb_entry *mp, 237 struct net_bridge_port_group *pg, 238 struct net_bridge_port_group __rcu **pp) 239{ | 233 234 hlist_del_init_rcu(&src->node); 235 src->pg->src_ents--; 236 hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list); 237 queue_work(system_long_wq, &br->mcast_gc_work); 238} 239 240static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc) --- 8 unchanged lines hidden (view full) --- 249 del_timer_sync(&pg->timer); 250 kfree_rcu(pg, rcu); 251} 252 253void br_multicast_del_pg(struct net_bridge_mdb_entry *mp, 254 struct net_bridge_port_group *pg, 255 struct net_bridge_port_group __rcu **pp) 256{ |
240 struct net_bridge *br = pg->port->br; | 257 struct net_bridge *br = pg->key.port->br; |
241 struct net_bridge_group_src *ent; 242 struct hlist_node *tmp; 243 | 258 struct net_bridge_group_src *ent; 259 struct hlist_node *tmp; 260 |
261 rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode, 262 br_sg_port_rht_params); |
|
244 rcu_assign_pointer(*pp, pg->next); 245 hlist_del_init(&pg->mglist); 246 hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node) 247 br_multicast_del_group_src(ent); 248 br_mdb_notify(br->dev, mp, pg, RTM_DELMDB); 249 hlist_add_head(&pg->mcast_gc.gc_node, &br->mcast_gc_list); 250 queue_work(system_long_wq, &br->mcast_gc_work); 251 252 if (!mp->ports && !mp->host_joined && netif_running(br->dev)) 253 mod_timer(&mp->timer, jiffies); 254} 255 256static void br_multicast_find_del_pg(struct net_bridge *br, 257 struct net_bridge_port_group *pg) 258{ 259 struct net_bridge_port_group __rcu **pp; 260 struct net_bridge_mdb_entry *mp; 261 struct net_bridge_port_group *p; 262 | 263 rcu_assign_pointer(*pp, pg->next); 264 hlist_del_init(&pg->mglist); 265 hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node) 266 br_multicast_del_group_src(ent); 267 br_mdb_notify(br->dev, mp, pg, RTM_DELMDB); 268 hlist_add_head(&pg->mcast_gc.gc_node, &br->mcast_gc_list); 269 queue_work(system_long_wq, &br->mcast_gc_work); 270 271 if (!mp->ports && !mp->host_joined && netif_running(br->dev)) 272 mod_timer(&mp->timer, jiffies); 273} 274 275static void br_multicast_find_del_pg(struct net_bridge *br, 276 struct net_bridge_port_group *pg) 277{ 278 struct net_bridge_port_group __rcu **pp; 279 struct net_bridge_mdb_entry *mp; 280 struct net_bridge_port_group *p; 281 |
263 mp = br_mdb_ip_get(br, &pg->addr); | 282 mp = br_mdb_ip_get(br, &pg->key.addr); |
264 if (WARN_ON(!mp)) 265 return; 266 267 for (pp = &mp->ports; 268 (p = mlock_dereference(*pp, br)) != NULL; 269 pp = &p->next) { 270 if (p != pg) 271 continue; --- 4 unchanged lines hidden (view full) --- 276 277 WARN_ON(1); 278} 279 280static void br_multicast_port_group_expired(struct timer_list *t) 281{ 282 struct net_bridge_port_group *pg = from_timer(pg, t, timer); 283 struct net_bridge_group_src *src_ent; | 283 if (WARN_ON(!mp)) 284 return; 285 286 for (pp = &mp->ports; 287 (p = mlock_dereference(*pp, br)) != NULL; 288 pp = &p->next) { 289 if (p != pg) 290 continue; --- 4 unchanged lines hidden (view full) --- 295 296 WARN_ON(1); 297} 298 299static void br_multicast_port_group_expired(struct timer_list *t) 300{ 301 struct net_bridge_port_group *pg = from_timer(pg, t, timer); 302 struct net_bridge_group_src *src_ent; |
284 struct net_bridge *br = pg->port->br; | 303 struct net_bridge *br = pg->key.port->br; |
285 struct hlist_node *tmp; 286 bool changed; 287 288 spin_lock(&br->multicast_lock); 289 if (!netif_running(br->dev) || timer_pending(&pg->timer) || 290 hlist_unhashed(&pg->mglist) || pg->flags & MDB_PG_FLAGS_PERMANENT) 291 goto out; 292 --- 4 unchanged lines hidden (view full) --- 297 br_multicast_del_group_src(src_ent); 298 changed = true; 299 } 300 } 301 302 if (hlist_empty(&pg->src_list)) { 303 br_multicast_find_del_pg(br, pg); 304 } else if (changed) { | 304 struct hlist_node *tmp; 305 bool changed; 306 307 spin_lock(&br->multicast_lock); 308 if (!netif_running(br->dev) || timer_pending(&pg->timer) || 309 hlist_unhashed(&pg->mglist) || pg->flags & MDB_PG_FLAGS_PERMANENT) 310 goto out; 311 --- 4 unchanged lines hidden (view full) --- 316 br_multicast_del_group_src(src_ent); 317 changed = true; 318 } 319 } 320 321 if (hlist_empty(&pg->src_list)) { 322 br_multicast_find_del_pg(br, pg); 323 } else if (changed) { |
305 struct net_bridge_mdb_entry *mp = br_mdb_ip_get(br, &pg->addr); | 324 struct net_bridge_mdb_entry *mp = br_mdb_ip_get(br, &pg->key.addr); |
306 307 if (WARN_ON(!mp)) 308 goto out; 309 br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB); 310 } 311out: 312 spin_unlock(&br->multicast_lock); 313} --- 11 unchanged lines hidden (view full) --- 325 326static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, 327 struct net_bridge_port_group *pg, 328 __be32 ip_dst, __be32 group, 329 bool with_srcs, bool over_lmqt, 330 u8 sflag, u8 *igmp_type, 331 bool *need_rexmit) 332{ | 325 326 if (WARN_ON(!mp)) 327 goto out; 328 br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB); 329 } 330out: 331 spin_unlock(&br->multicast_lock); 332} --- 11 unchanged lines hidden (view full) --- 344 345static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, 346 struct net_bridge_port_group *pg, 347 __be32 ip_dst, __be32 group, 348 bool with_srcs, bool over_lmqt, 349 u8 sflag, u8 *igmp_type, 350 bool *need_rexmit) 351{ |
333 struct net_bridge_port *p = pg ? pg->port : NULL; | 352 struct net_bridge_port *p = pg ? pg->key.port : NULL; |
334 struct net_bridge_group_src *ent; 335 size_t pkt_size, igmp_hdr_size; 336 unsigned long now = jiffies; 337 struct igmpv3_query *ihv3; 338 void *csum_start = NULL; 339 __sum16 *csum = NULL; 340 struct sk_buff *skb; 341 struct igmphdr *ih; --- 129 unchanged lines hidden (view full) --- 471static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, 472 struct net_bridge_port_group *pg, 473 const struct in6_addr *ip6_dst, 474 const struct in6_addr *group, 475 bool with_srcs, bool over_llqt, 476 u8 sflag, u8 *igmp_type, 477 bool *need_rexmit) 478{ | 353 struct net_bridge_group_src *ent; 354 size_t pkt_size, igmp_hdr_size; 355 unsigned long now = jiffies; 356 struct igmpv3_query *ihv3; 357 void *csum_start = NULL; 358 __sum16 *csum = NULL; 359 struct sk_buff *skb; 360 struct igmphdr *ih; --- 129 unchanged lines hidden (view full) --- 490static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, 491 struct net_bridge_port_group *pg, 492 const struct in6_addr *ip6_dst, 493 const struct in6_addr *group, 494 bool with_srcs, bool over_llqt, 495 u8 sflag, u8 *igmp_type, 496 bool *need_rexmit) 497{ |
479 struct net_bridge_port *p = pg ? pg->port : NULL; | 498 struct net_bridge_port *p = pg ? pg->key.port : NULL; |
480 struct net_bridge_group_src *ent; 481 size_t pkt_size, mld_hdr_size; 482 unsigned long now = jiffies; 483 struct mld2_query *mld2q; 484 void *csum_start = NULL; 485 unsigned long interval; 486 __sum16 *csum = NULL; 487 struct ipv6hdr *ip6h; --- 285 unchanged lines hidden (view full) --- 773#endif 774 } 775 776 grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC); 777 if (unlikely(!grp_src)) 778 return NULL; 779 780 grp_src->pg = pg; | 499 struct net_bridge_group_src *ent; 500 size_t pkt_size, mld_hdr_size; 501 unsigned long now = jiffies; 502 struct mld2_query *mld2q; 503 void *csum_start = NULL; 504 unsigned long interval; 505 __sum16 *csum = NULL; 506 struct ipv6hdr *ip6h; --- 285 unchanged lines hidden (view full) --- 792#endif 793 } 794 795 grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC); 796 if (unlikely(!grp_src)) 797 return NULL; 798 799 grp_src->pg = pg; |
781 grp_src->br = pg->port->br; | 800 grp_src->br = pg->key.port->br; |
782 grp_src->addr = *src_ip; 783 grp_src->mcast_gc.destroy = br_multicast_destroy_group_src; 784 timer_setup(&grp_src->timer, br_multicast_group_src_expired, 0); 785 786 hlist_add_head_rcu(&grp_src->node, &pg->src_list); 787 pg->src_ents++; 788 789 return grp_src; --- 9 unchanged lines hidden (view full) --- 799 u8 rt_protocol) 800{ 801 struct net_bridge_port_group *p; 802 803 p = kzalloc(sizeof(*p), GFP_ATOMIC); 804 if (unlikely(!p)) 805 return NULL; 806 | 801 grp_src->addr = *src_ip; 802 grp_src->mcast_gc.destroy = br_multicast_destroy_group_src; 803 timer_setup(&grp_src->timer, br_multicast_group_src_expired, 0); 804 805 hlist_add_head_rcu(&grp_src->node, &pg->src_list); 806 pg->src_ents++; 807 808 return grp_src; --- 9 unchanged lines hidden (view full) --- 818 u8 rt_protocol) 819{ 820 struct net_bridge_port_group *p; 821 822 p = kzalloc(sizeof(*p), GFP_ATOMIC); 823 if (unlikely(!p)) 824 return NULL; 825 |
807 p->addr = *group; 808 p->port = port; | 826 p->key.addr = *group; 827 p->key.port = port; |
809 p->flags = flags; 810 p->filter_mode = filter_mode; 811 p->rt_protocol = rt_protocol; 812 p->mcast_gc.destroy = br_multicast_destroy_port_group; 813 INIT_HLIST_HEAD(&p->src_list); | 828 p->flags = flags; 829 p->filter_mode = filter_mode; 830 p->rt_protocol = rt_protocol; 831 p->mcast_gc.destroy = br_multicast_destroy_port_group; 832 INIT_HLIST_HEAD(&p->src_list); |
833 834 if (!br_multicast_is_star_g(group) && 835 rhashtable_lookup_insert_fast(&port->br->sg_port_tbl, &p->rhnode, 836 br_sg_port_rht_params)) { 837 kfree(p); 838 return NULL; 839 } 840 |
|
814 rcu_assign_pointer(p->next, next); 815 timer_setup(&p->timer, br_multicast_port_group_expired, 0); 816 timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0); 817 hlist_add_head(&p->mglist, &port->mglist); 818 819 if (src) 820 memcpy(p->eth_addr, src, ETH_ALEN); 821 else 822 eth_broadcast_addr(p->eth_addr); 823 824 return p; 825} 826 827static bool br_port_group_equal(struct net_bridge_port_group *p, 828 struct net_bridge_port *port, 829 const unsigned char *src) 830{ | 841 rcu_assign_pointer(p->next, next); 842 timer_setup(&p->timer, br_multicast_port_group_expired, 0); 843 timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0); 844 hlist_add_head(&p->mglist, &port->mglist); 845 846 if (src) 847 memcpy(p->eth_addr, src, ETH_ALEN); 848 else 849 eth_broadcast_addr(p->eth_addr); 850 851 return p; 852} 853 854static bool br_port_group_equal(struct net_bridge_port_group *p, 855 struct net_bridge_port *port, 856 const unsigned char *src) 857{ |
831 if (p->port != port) | 858 if (p->key.port != port) |
832 return false; 833 834 if (!(port->flags & BR_MULTICAST_TO_UNICAST)) 835 return true; 836 837 return ether_addr_equal(src, p->eth_addr); 838} 839 --- 45 unchanged lines hidden (view full) --- 885 goto out; 886 } 887 888 for (pp = &mp->ports; 889 (p = mlock_dereference(*pp, br)) != NULL; 890 pp = &p->next) { 891 if (br_port_group_equal(p, port, src)) 892 goto found; | 859 return false; 860 861 if (!(port->flags & BR_MULTICAST_TO_UNICAST)) 862 return true; 863 864 return ether_addr_equal(src, p->eth_addr); 865} 866 --- 45 unchanged lines hidden (view full) --- 912 goto out; 913 } 914 915 for (pp = &mp->ports; 916 (p = mlock_dereference(*pp, br)) != NULL; 917 pp = &p->next) { 918 if (br_port_group_equal(p, port, src)) 919 goto found; |
893 if ((unsigned long)p->port < (unsigned long)port) | 920 if ((unsigned long)p->key.port < (unsigned long)port) |
894 break; 895 } 896 897 p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode, 898 RTPROT_KERNEL); 899 if (unlikely(!p)) 900 goto err; 901 rcu_assign_pointer(*pp, p); --- 259 unchanged lines hidden (view full) --- 1161 br_multicast_port_query_expired(port, &port->ip6_own_query); 1162} 1163#endif 1164 1165static void br_multicast_port_group_rexmit(struct timer_list *t) 1166{ 1167 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer); 1168 struct bridge_mcast_other_query *other_query = NULL; | 921 break; 922 } 923 924 p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode, 925 RTPROT_KERNEL); 926 if (unlikely(!p)) 927 goto err; 928 rcu_assign_pointer(*pp, p); --- 259 unchanged lines hidden (view full) --- 1188 br_multicast_port_query_expired(port, &port->ip6_own_query); 1189} 1190#endif 1191 1192static void br_multicast_port_group_rexmit(struct timer_list *t) 1193{ 1194 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer); 1195 struct bridge_mcast_other_query *other_query = NULL; |
1169 struct net_bridge *br = pg->port->br; | 1196 struct net_bridge *br = pg->key.port->br; |
1170 bool need_rexmit = false; 1171 1172 spin_lock(&br->multicast_lock); 1173 if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) || 1174 !br_opt_get(br, BROPT_MULTICAST_ENABLED) || 1175 !br_opt_get(br, BROPT_MULTICAST_QUERIER)) 1176 goto out; 1177 | 1197 bool need_rexmit = false; 1198 1199 spin_lock(&br->multicast_lock); 1200 if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) || 1201 !br_opt_get(br, BROPT_MULTICAST_ENABLED) || 1202 !br_opt_get(br, BROPT_MULTICAST_QUERIER)) 1203 goto out; 1204 |
1178 if (pg->addr.proto == htons(ETH_P_IP)) | 1205 if (pg->key.addr.proto == htons(ETH_P_IP)) |
1179 other_query = &br->ip4_other_query; 1180#if IS_ENABLED(CONFIG_IPV6) 1181 else 1182 other_query = &br->ip6_other_query; 1183#endif 1184 1185 if (!other_query || timer_pending(&other_query->timer)) 1186 goto out; 1187 1188 if (pg->grp_query_rexmit_cnt) { 1189 pg->grp_query_rexmit_cnt--; | 1206 other_query = &br->ip4_other_query; 1207#if IS_ENABLED(CONFIG_IPV6) 1208 else 1209 other_query = &br->ip6_other_query; 1210#endif 1211 1212 if (!other_query || timer_pending(&other_query->timer)) 1213 goto out; 1214 1215 if (pg->grp_query_rexmit_cnt) { 1216 pg->grp_query_rexmit_cnt--; |
1190 __br_multicast_send_query(br, pg->port, pg, &pg->addr, 1191 &pg->addr, false, 1, NULL); | 1217 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr, 1218 &pg->key.addr, false, 1, NULL); |
1192 } | 1219 } |
1193 __br_multicast_send_query(br, pg->port, pg, &pg->addr, 1194 &pg->addr, true, 0, &need_rexmit); | 1220 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr, 1221 &pg->key.addr, true, 0, &need_rexmit); |
1195 1196 if (pg->grp_query_rexmit_cnt || need_rexmit) 1197 mod_timer(&pg->rexmit_timer, jiffies + 1198 br->multicast_last_member_interval); 1199out: 1200 spin_unlock(&br->multicast_lock); 1201} 1202 --- 117 unchanged lines hidden (view full) --- 1320 } 1321 1322 return deleted; 1323} 1324 1325static void __grp_src_query_marked_and_rexmit(struct net_bridge_port_group *pg) 1326{ 1327 struct bridge_mcast_other_query *other_query = NULL; | 1222 1223 if (pg->grp_query_rexmit_cnt || need_rexmit) 1224 mod_timer(&pg->rexmit_timer, jiffies + 1225 br->multicast_last_member_interval); 1226out: 1227 spin_unlock(&br->multicast_lock); 1228} 1229 --- 117 unchanged lines hidden (view full) --- 1347 } 1348 1349 return deleted; 1350} 1351 1352static void __grp_src_query_marked_and_rexmit(struct net_bridge_port_group *pg) 1353{ 1354 struct bridge_mcast_other_query *other_query = NULL; |
1328 struct net_bridge *br = pg->port->br; | 1355 struct net_bridge *br = pg->key.port->br; |
1329 u32 lmqc = br->multicast_last_member_count; 1330 unsigned long lmqt, lmi, now = jiffies; 1331 struct net_bridge_group_src *ent; 1332 1333 if (!netif_running(br->dev) || 1334 !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1335 return; 1336 | 1356 u32 lmqc = br->multicast_last_member_count; 1357 unsigned long lmqt, lmi, now = jiffies; 1358 struct net_bridge_group_src *ent; 1359 1360 if (!netif_running(br->dev) || 1361 !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1362 return; 1363 |
1337 if (pg->addr.proto == htons(ETH_P_IP)) | 1364 if (pg->key.addr.proto == htons(ETH_P_IP)) |
1338 other_query = &br->ip4_other_query; 1339#if IS_ENABLED(CONFIG_IPV6) 1340 else 1341 other_query = &br->ip6_other_query; 1342#endif 1343 1344 lmqt = now + br_multicast_lmqt(br); 1345 hlist_for_each_entry(ent, &pg->src_list, node) { --- 8 unchanged lines hidden (view full) --- 1354 } 1355 } 1356 } 1357 1358 if (!br_opt_get(br, BROPT_MULTICAST_QUERIER) || 1359 !other_query || timer_pending(&other_query->timer)) 1360 return; 1361 | 1365 other_query = &br->ip4_other_query; 1366#if IS_ENABLED(CONFIG_IPV6) 1367 else 1368 other_query = &br->ip6_other_query; 1369#endif 1370 1371 lmqt = now + br_multicast_lmqt(br); 1372 hlist_for_each_entry(ent, &pg->src_list, node) { --- 8 unchanged lines hidden (view full) --- 1381 } 1382 } 1383 } 1384 1385 if (!br_opt_get(br, BROPT_MULTICAST_QUERIER) || 1386 !other_query || timer_pending(&other_query->timer)) 1387 return; 1388 |
1362 __br_multicast_send_query(br, pg->port, pg, &pg->addr, 1363 &pg->addr, true, 1, NULL); | 1389 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr, 1390 &pg->key.addr, true, 1, NULL); |
1364 1365 lmi = now + br->multicast_last_member_interval; 1366 if (!timer_pending(&pg->rexmit_timer) || 1367 time_after(pg->rexmit_timer.expires, lmi)) 1368 mod_timer(&pg->rexmit_timer, lmi); 1369} 1370 1371static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg) 1372{ 1373 struct bridge_mcast_other_query *other_query = NULL; | 1391 1392 lmi = now + br->multicast_last_member_interval; 1393 if (!timer_pending(&pg->rexmit_timer) || 1394 time_after(pg->rexmit_timer.expires, lmi)) 1395 mod_timer(&pg->rexmit_timer, lmi); 1396} 1397 1398static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg) 1399{ 1400 struct bridge_mcast_other_query *other_query = NULL; |
1374 struct net_bridge *br = pg->port->br; | 1401 struct net_bridge *br = pg->key.port->br; |
1375 unsigned long now = jiffies, lmi; 1376 1377 if (!netif_running(br->dev) || 1378 !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1379 return; 1380 | 1402 unsigned long now = jiffies, lmi; 1403 1404 if (!netif_running(br->dev) || 1405 !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1406 return; 1407 |
1381 if (pg->addr.proto == htons(ETH_P_IP)) | 1408 if (pg->key.addr.proto == htons(ETH_P_IP)) |
1382 other_query = &br->ip4_other_query; 1383#if IS_ENABLED(CONFIG_IPV6) 1384 else 1385 other_query = &br->ip6_other_query; 1386#endif 1387 1388 if (br_opt_get(br, BROPT_MULTICAST_QUERIER) && 1389 other_query && !timer_pending(&other_query->timer)) { 1390 lmi = now + br->multicast_last_member_interval; 1391 pg->grp_query_rexmit_cnt = br->multicast_last_member_count - 1; | 1409 other_query = &br->ip4_other_query; 1410#if IS_ENABLED(CONFIG_IPV6) 1411 else 1412 other_query = &br->ip6_other_query; 1413#endif 1414 1415 if (br_opt_get(br, BROPT_MULTICAST_QUERIER) && 1416 other_query && !timer_pending(&other_query->timer)) { 1417 lmi = now + br->multicast_last_member_interval; 1418 pg->grp_query_rexmit_cnt = br->multicast_last_member_count - 1; |
1392 __br_multicast_send_query(br, pg->port, pg, &pg->addr, 1393 &pg->addr, false, 0, NULL); | 1419 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr, 1420 &pg->key.addr, false, 0, NULL); |
1394 if (!timer_pending(&pg->rexmit_timer) || 1395 time_after(pg->rexmit_timer.expires, lmi)) 1396 mod_timer(&pg->rexmit_timer, lmi); 1397 } 1398 1399 if (pg->filter_mode == MCAST_EXCLUDE && 1400 (!timer_pending(&pg->timer) || 1401 time_after(pg->timer.expires, now + br_multicast_lmqt(br)))) 1402 mod_timer(&pg->timer, now + br_multicast_lmqt(br)); 1403} 1404 1405/* State Msg type New state Actions 1406 * INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI 1407 * INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI 1408 * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI 1409 */ 1410static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg, 1411 void *srcs, u32 nsrcs, size_t src_size) 1412{ | 1421 if (!timer_pending(&pg->rexmit_timer) || 1422 time_after(pg->rexmit_timer.expires, lmi)) 1423 mod_timer(&pg->rexmit_timer, lmi); 1424 } 1425 1426 if (pg->filter_mode == MCAST_EXCLUDE && 1427 (!timer_pending(&pg->timer) || 1428 time_after(pg->timer.expires, now + br_multicast_lmqt(br)))) 1429 mod_timer(&pg->timer, now + br_multicast_lmqt(br)); 1430} 1431 1432/* State Msg type New state Actions 1433 * INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI 1434 * INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI 1435 * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI 1436 */ 1437static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg, 1438 void *srcs, u32 nsrcs, size_t src_size) 1439{ |
1413 struct net_bridge *br = pg->port->br; | 1440 struct net_bridge *br = pg->key.port->br; |
1414 struct net_bridge_group_src *ent; 1415 unsigned long now = jiffies; 1416 bool changed = false; 1417 struct br_ip src_ip; 1418 u32 src_idx; 1419 1420 memset(&src_ip, 0, sizeof(src_ip)); | 1441 struct net_bridge_group_src *ent; 1442 unsigned long now = jiffies; 1443 bool changed = false; 1444 struct br_ip src_ip; 1445 u32 src_idx; 1446 1447 memset(&src_ip, 0, sizeof(src_ip)); |
1421 src_ip.proto = pg->addr.proto; | 1448 src_ip.proto = pg->key.addr.proto; |
1422 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1423 memcpy(&src_ip.src, srcs, src_size); 1424 ent = br_multicast_find_group_src(pg, &src_ip); 1425 if (!ent) { 1426 ent = br_multicast_new_group_src(pg, &src_ip); 1427 if (ent) 1428 changed = true; 1429 } --- 17 unchanged lines hidden (view full) --- 1447 struct net_bridge_group_src *ent; 1448 struct br_ip src_ip; 1449 u32 src_idx; 1450 1451 hlist_for_each_entry(ent, &pg->src_list, node) 1452 ent->flags |= BR_SGRP_F_DELETE; 1453 1454 memset(&src_ip, 0, sizeof(src_ip)); | 1449 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1450 memcpy(&src_ip.src, srcs, src_size); 1451 ent = br_multicast_find_group_src(pg, &src_ip); 1452 if (!ent) { 1453 ent = br_multicast_new_group_src(pg, &src_ip); 1454 if (ent) 1455 changed = true; 1456 } --- 17 unchanged lines hidden (view full) --- 1474 struct net_bridge_group_src *ent; 1475 struct br_ip src_ip; 1476 u32 src_idx; 1477 1478 hlist_for_each_entry(ent, &pg->src_list, node) 1479 ent->flags |= BR_SGRP_F_DELETE; 1480 1481 memset(&src_ip, 0, sizeof(src_ip)); |
1455 src_ip.proto = pg->addr.proto; | 1482 src_ip.proto = pg->key.addr.proto; |
1456 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1457 memcpy(&src_ip.src, srcs, src_size); 1458 ent = br_multicast_find_group_src(pg, &src_ip); 1459 if (ent) 1460 ent->flags &= ~BR_SGRP_F_DELETE; 1461 else 1462 br_multicast_new_group_src(pg, &src_ip); 1463 srcs += src_size; --- 6 unchanged lines hidden (view full) --- 1470 * EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI 1471 * Delete (X-A) 1472 * Delete (Y-A) 1473 * Group Timer=GMI 1474 */ 1475static bool __grp_src_isexc_excl(struct net_bridge_port_group *pg, 1476 void *srcs, u32 nsrcs, size_t src_size) 1477{ | 1483 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1484 memcpy(&src_ip.src, srcs, src_size); 1485 ent = br_multicast_find_group_src(pg, &src_ip); 1486 if (ent) 1487 ent->flags &= ~BR_SGRP_F_DELETE; 1488 else 1489 br_multicast_new_group_src(pg, &src_ip); 1490 srcs += src_size; --- 6 unchanged lines hidden (view full) --- 1497 * EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI 1498 * Delete (X-A) 1499 * Delete (Y-A) 1500 * Group Timer=GMI 1501 */ 1502static bool __grp_src_isexc_excl(struct net_bridge_port_group *pg, 1503 void *srcs, u32 nsrcs, size_t src_size) 1504{ |
1478 struct net_bridge *br = pg->port->br; | 1505 struct net_bridge *br = pg->key.port->br; |
1479 struct net_bridge_group_src *ent; 1480 unsigned long now = jiffies; 1481 bool changed = false; 1482 struct br_ip src_ip; 1483 u32 src_idx; 1484 1485 hlist_for_each_entry(ent, &pg->src_list, node) 1486 ent->flags |= BR_SGRP_F_DELETE; 1487 1488 memset(&src_ip, 0, sizeof(src_ip)); | 1506 struct net_bridge_group_src *ent; 1507 unsigned long now = jiffies; 1508 bool changed = false; 1509 struct br_ip src_ip; 1510 u32 src_idx; 1511 1512 hlist_for_each_entry(ent, &pg->src_list, node) 1513 ent->flags |= BR_SGRP_F_DELETE; 1514 1515 memset(&src_ip, 0, sizeof(src_ip)); |
1489 src_ip.proto = pg->addr.proto; | 1516 src_ip.proto = pg->key.addr.proto; |
1490 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1491 memcpy(&src_ip.src, srcs, src_size); 1492 ent = br_multicast_find_group_src(pg, &src_ip); 1493 if (ent) { 1494 ent->flags &= ~BR_SGRP_F_DELETE; 1495 } else { 1496 ent = br_multicast_new_group_src(pg, &src_ip); 1497 if (ent) { --- 9 unchanged lines hidden (view full) --- 1507 changed = true; 1508 1509 return changed; 1510} 1511 1512static bool br_multicast_isexc(struct net_bridge_port_group *pg, 1513 void *srcs, u32 nsrcs, size_t src_size) 1514{ | 1517 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1518 memcpy(&src_ip.src, srcs, src_size); 1519 ent = br_multicast_find_group_src(pg, &src_ip); 1520 if (ent) { 1521 ent->flags &= ~BR_SGRP_F_DELETE; 1522 } else { 1523 ent = br_multicast_new_group_src(pg, &src_ip); 1524 if (ent) { --- 9 unchanged lines hidden (view full) --- 1534 changed = true; 1535 1536 return changed; 1537} 1538 1539static bool br_multicast_isexc(struct net_bridge_port_group *pg, 1540 void *srcs, u32 nsrcs, size_t src_size) 1541{ |
1515 struct net_bridge *br = pg->port->br; | 1542 struct net_bridge *br = pg->key.port->br; |
1516 bool changed = false; 1517 1518 switch (pg->filter_mode) { 1519 case MCAST_INCLUDE: 1520 __grp_src_isexc_incl(pg, srcs, nsrcs, src_size); 1521 changed = true; 1522 break; 1523 case MCAST_EXCLUDE: --- 9 unchanged lines hidden (view full) --- 1533 1534/* State Msg type New state Actions 1535 * INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI 1536 * Send Q(G,A-B) 1537 */ 1538static bool __grp_src_toin_incl(struct net_bridge_port_group *pg, 1539 void *srcs, u32 nsrcs, size_t src_size) 1540{ | 1543 bool changed = false; 1544 1545 switch (pg->filter_mode) { 1546 case MCAST_INCLUDE: 1547 __grp_src_isexc_incl(pg, srcs, nsrcs, src_size); 1548 changed = true; 1549 break; 1550 case MCAST_EXCLUDE: --- 9 unchanged lines hidden (view full) --- 1560 1561/* State Msg type New state Actions 1562 * INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI 1563 * Send Q(G,A-B) 1564 */ 1565static bool __grp_src_toin_incl(struct net_bridge_port_group *pg, 1566 void *srcs, u32 nsrcs, size_t src_size) 1567{ |
1541 struct net_bridge *br = pg->port->br; | 1568 struct net_bridge *br = pg->key.port->br; |
1542 u32 src_idx, to_send = pg->src_ents; 1543 struct net_bridge_group_src *ent; 1544 unsigned long now = jiffies; 1545 bool changed = false; 1546 struct br_ip src_ip; 1547 1548 hlist_for_each_entry(ent, &pg->src_list, node) 1549 ent->flags |= BR_SGRP_F_SEND; 1550 1551 memset(&src_ip, 0, sizeof(src_ip)); | 1569 u32 src_idx, to_send = pg->src_ents; 1570 struct net_bridge_group_src *ent; 1571 unsigned long now = jiffies; 1572 bool changed = false; 1573 struct br_ip src_ip; 1574 1575 hlist_for_each_entry(ent, &pg->src_list, node) 1576 ent->flags |= BR_SGRP_F_SEND; 1577 1578 memset(&src_ip, 0, sizeof(src_ip)); |
1552 src_ip.proto = pg->addr.proto; | 1579 src_ip.proto = pg->key.addr.proto; |
1553 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1554 memcpy(&src_ip.src, srcs, src_size); 1555 ent = br_multicast_find_group_src(pg, &src_ip); 1556 if (ent) { 1557 ent->flags &= ~BR_SGRP_F_SEND; 1558 to_send--; 1559 } else { 1560 ent = br_multicast_new_group_src(pg, &src_ip); --- 14 unchanged lines hidden (view full) --- 1575/* State Msg type New state Actions 1576 * EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI 1577 * Send Q(G,X-A) 1578 * Send Q(G) 1579 */ 1580static bool __grp_src_toin_excl(struct net_bridge_port_group *pg, 1581 void *srcs, u32 nsrcs, size_t src_size) 1582{ | 1580 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1581 memcpy(&src_ip.src, srcs, src_size); 1582 ent = br_multicast_find_group_src(pg, &src_ip); 1583 if (ent) { 1584 ent->flags &= ~BR_SGRP_F_SEND; 1585 to_send--; 1586 } else { 1587 ent = br_multicast_new_group_src(pg, &src_ip); --- 14 unchanged lines hidden (view full) --- 1602/* State Msg type New state Actions 1603 * EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI 1604 * Send Q(G,X-A) 1605 * Send Q(G) 1606 */ 1607static bool __grp_src_toin_excl(struct net_bridge_port_group *pg, 1608 void *srcs, u32 nsrcs, size_t src_size) 1609{ |
1583 struct net_bridge *br = pg->port->br; | 1610 struct net_bridge *br = pg->key.port->br; |
1584 u32 src_idx, to_send = pg->src_ents; 1585 struct net_bridge_group_src *ent; 1586 unsigned long now = jiffies; 1587 bool changed = false; 1588 struct br_ip src_ip; 1589 1590 hlist_for_each_entry(ent, &pg->src_list, node) 1591 if (timer_pending(&ent->timer)) 1592 ent->flags |= BR_SGRP_F_SEND; 1593 1594 memset(&src_ip, 0, sizeof(src_ip)); | 1611 u32 src_idx, to_send = pg->src_ents; 1612 struct net_bridge_group_src *ent; 1613 unsigned long now = jiffies; 1614 bool changed = false; 1615 struct br_ip src_ip; 1616 1617 hlist_for_each_entry(ent, &pg->src_list, node) 1618 if (timer_pending(&ent->timer)) 1619 ent->flags |= BR_SGRP_F_SEND; 1620 1621 memset(&src_ip, 0, sizeof(src_ip)); |
1595 src_ip.proto = pg->addr.proto; | 1622 src_ip.proto = pg->key.addr.proto; |
1596 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1597 memcpy(&src_ip.src, srcs, src_size); 1598 ent = br_multicast_find_group_src(pg, &src_ip); 1599 if (ent) { 1600 if (timer_pending(&ent->timer)) { 1601 ent->flags &= ~BR_SGRP_F_SEND; 1602 to_send--; 1603 } --- 44 unchanged lines hidden (view full) --- 1648 struct net_bridge_group_src *ent; 1649 u32 src_idx, to_send = 0; 1650 struct br_ip src_ip; 1651 1652 hlist_for_each_entry(ent, &pg->src_list, node) 1653 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE; 1654 1655 memset(&src_ip, 0, sizeof(src_ip)); | 1623 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1624 memcpy(&src_ip.src, srcs, src_size); 1625 ent = br_multicast_find_group_src(pg, &src_ip); 1626 if (ent) { 1627 if (timer_pending(&ent->timer)) { 1628 ent->flags &= ~BR_SGRP_F_SEND; 1629 to_send--; 1630 } --- 44 unchanged lines hidden (view full) --- 1675 struct net_bridge_group_src *ent; 1676 u32 src_idx, to_send = 0; 1677 struct br_ip src_ip; 1678 1679 hlist_for_each_entry(ent, &pg->src_list, node) 1680 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE; 1681 1682 memset(&src_ip, 0, sizeof(src_ip)); |
1656 src_ip.proto = pg->addr.proto; | 1683 src_ip.proto = pg->key.addr.proto; |
1657 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1658 memcpy(&src_ip.src, srcs, src_size); 1659 ent = br_multicast_find_group_src(pg, &src_ip); 1660 if (ent) { 1661 ent->flags = (ent->flags & ~BR_SGRP_F_DELETE) | 1662 BR_SGRP_F_SEND; 1663 to_send++; 1664 } else { --- 21 unchanged lines hidden (view full) --- 1686 u32 src_idx, to_send = 0; 1687 bool changed = false; 1688 struct br_ip src_ip; 1689 1690 hlist_for_each_entry(ent, &pg->src_list, node) 1691 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE; 1692 1693 memset(&src_ip, 0, sizeof(src_ip)); | 1684 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1685 memcpy(&src_ip.src, srcs, src_size); 1686 ent = br_multicast_find_group_src(pg, &src_ip); 1687 if (ent) { 1688 ent->flags = (ent->flags & ~BR_SGRP_F_DELETE) | 1689 BR_SGRP_F_SEND; 1690 to_send++; 1691 } else { --- 21 unchanged lines hidden (view full) --- 1713 u32 src_idx, to_send = 0; 1714 bool changed = false; 1715 struct br_ip src_ip; 1716 1717 hlist_for_each_entry(ent, &pg->src_list, node) 1718 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE; 1719 1720 memset(&src_ip, 0, sizeof(src_ip)); |
1694 src_ip.proto = pg->addr.proto; | 1721 src_ip.proto = pg->key.addr.proto; |
1695 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1696 memcpy(&src_ip.src, srcs, src_size); 1697 ent = br_multicast_find_group_src(pg, &src_ip); 1698 if (ent) { 1699 ent->flags &= ~BR_SGRP_F_DELETE; 1700 } else { 1701 ent = br_multicast_new_group_src(pg, &src_ip); 1702 if (ent) { --- 14 unchanged lines hidden (view full) --- 1717 __grp_src_query_marked_and_rexmit(pg); 1718 1719 return changed; 1720} 1721 1722static bool br_multicast_toex(struct net_bridge_port_group *pg, 1723 void *srcs, u32 nsrcs, size_t src_size) 1724{ | 1722 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1723 memcpy(&src_ip.src, srcs, src_size); 1724 ent = br_multicast_find_group_src(pg, &src_ip); 1725 if (ent) { 1726 ent->flags &= ~BR_SGRP_F_DELETE; 1727 } else { 1728 ent = br_multicast_new_group_src(pg, &src_ip); 1729 if (ent) { --- 14 unchanged lines hidden (view full) --- 1744 __grp_src_query_marked_and_rexmit(pg); 1745 1746 return changed; 1747} 1748 1749static bool br_multicast_toex(struct net_bridge_port_group *pg, 1750 void *srcs, u32 nsrcs, size_t src_size) 1751{ |
1725 struct net_bridge *br = pg->port->br; | 1752 struct net_bridge *br = pg->key.port->br; |
1726 bool changed = false; 1727 1728 switch (pg->filter_mode) { 1729 case MCAST_INCLUDE: 1730 __grp_src_toex_incl(pg, srcs, nsrcs, src_size); 1731 changed = true; 1732 break; 1733 case MCAST_EXCLUDE: --- 16 unchanged lines hidden (view full) --- 1750 struct net_bridge_group_src *ent; 1751 u32 src_idx, to_send = 0; 1752 struct br_ip src_ip; 1753 1754 hlist_for_each_entry(ent, &pg->src_list, node) 1755 ent->flags &= ~BR_SGRP_F_SEND; 1756 1757 memset(&src_ip, 0, sizeof(src_ip)); | 1753 bool changed = false; 1754 1755 switch (pg->filter_mode) { 1756 case MCAST_INCLUDE: 1757 __grp_src_toex_incl(pg, srcs, nsrcs, src_size); 1758 changed = true; 1759 break; 1760 case MCAST_EXCLUDE: --- 16 unchanged lines hidden (view full) --- 1777 struct net_bridge_group_src *ent; 1778 u32 src_idx, to_send = 0; 1779 struct br_ip src_ip; 1780 1781 hlist_for_each_entry(ent, &pg->src_list, node) 1782 ent->flags &= ~BR_SGRP_F_SEND; 1783 1784 memset(&src_ip, 0, sizeof(src_ip)); |
1758 src_ip.proto = pg->addr.proto; | 1785 src_ip.proto = pg->key.addr.proto; |
1759 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1760 memcpy(&src_ip.src, srcs, src_size); 1761 ent = br_multicast_find_group_src(pg, &src_ip); 1762 if (ent) { 1763 ent->flags |= BR_SGRP_F_SEND; 1764 to_send++; 1765 } 1766 srcs += src_size; 1767 } 1768 1769 if (to_send) 1770 __grp_src_query_marked_and_rexmit(pg); 1771 1772 if (pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list)) | 1786 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1787 memcpy(&src_ip.src, srcs, src_size); 1788 ent = br_multicast_find_group_src(pg, &src_ip); 1789 if (ent) { 1790 ent->flags |= BR_SGRP_F_SEND; 1791 to_send++; 1792 } 1793 srcs += src_size; 1794 } 1795 1796 if (to_send) 1797 __grp_src_query_marked_and_rexmit(pg); 1798 1799 if (pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list)) |
1773 br_multicast_find_del_pg(pg->port->br, pg); | 1800 br_multicast_find_del_pg(pg->key.port->br, pg); |
1774} 1775 1776/* State Msg type New state Actions 1777 * EXCLUDE (X,Y) BLOCK (A) EXCLUDE (X+(A-Y),Y) (A-X-Y)=Group Timer 1778 * Send Q(G,A-Y) 1779 */ 1780static bool __grp_src_block_excl(struct net_bridge_port_group *pg, 1781 void *srcs, u32 nsrcs, size_t src_size) 1782{ 1783 struct net_bridge_group_src *ent; 1784 u32 src_idx, to_send = 0; 1785 bool changed = false; 1786 struct br_ip src_ip; 1787 1788 hlist_for_each_entry(ent, &pg->src_list, node) 1789 ent->flags &= ~BR_SGRP_F_SEND; 1790 1791 memset(&src_ip, 0, sizeof(src_ip)); | 1801} 1802 1803/* State Msg type New state Actions 1804 * EXCLUDE (X,Y) BLOCK (A) EXCLUDE (X+(A-Y),Y) (A-X-Y)=Group Timer 1805 * Send Q(G,A-Y) 1806 */ 1807static bool __grp_src_block_excl(struct net_bridge_port_group *pg, 1808 void *srcs, u32 nsrcs, size_t src_size) 1809{ 1810 struct net_bridge_group_src *ent; 1811 u32 src_idx, to_send = 0; 1812 bool changed = false; 1813 struct br_ip src_ip; 1814 1815 hlist_for_each_entry(ent, &pg->src_list, node) 1816 ent->flags &= ~BR_SGRP_F_SEND; 1817 1818 memset(&src_ip, 0, sizeof(src_ip)); |
1792 src_ip.proto = pg->addr.proto; | 1819 src_ip.proto = pg->key.addr.proto; |
1793 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1794 memcpy(&src_ip.src, srcs, src_size); 1795 ent = br_multicast_find_group_src(pg, &src_ip); 1796 if (!ent) { 1797 ent = br_multicast_new_group_src(pg, &src_ip); 1798 if (ent) { 1799 mod_timer(&ent->timer, pg->timer.expires); 1800 changed = true; --- 690 unchanged lines hidden (view full) --- 2491 } 2492 2493 goto out; 2494 } 2495 2496 for (p = mlock_dereference(mp->ports, br); 2497 p != NULL; 2498 p = mlock_dereference(p->next, br)) { | 1820 for (src_idx = 0; src_idx < nsrcs; src_idx++) { 1821 memcpy(&src_ip.src, srcs, src_size); 1822 ent = br_multicast_find_group_src(pg, &src_ip); 1823 if (!ent) { 1824 ent = br_multicast_new_group_src(pg, &src_ip); 1825 if (ent) { 1826 mod_timer(&ent->timer, pg->timer.expires); 1827 changed = true; --- 690 unchanged lines hidden (view full) --- 2518 } 2519 2520 goto out; 2521 } 2522 2523 for (p = mlock_dereference(mp->ports, br); 2524 p != NULL; 2525 p = mlock_dereference(p->next, br)) { |
2499 if (p->port != port) | 2526 if (p->key.port != port) |
2500 continue; 2501 2502 if (!hlist_unhashed(&p->mglist) && 2503 (timer_pending(&p->timer) ? 2504 time_after(p->timer.expires, time) : 2505 try_to_del_timer_sync(&p->timer) >= 0)) { 2506 mod_timer(&p->timer, time); 2507 } --- 743 unchanged lines hidden (view full) --- 3251 if (!port->dev || port->dev == dev) 3252 continue; 3253 3254 hlist_for_each_entry_rcu(group, &port->mglist, mglist) { 3255 entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 3256 if (!entry) 3257 goto unlock; 3258 | 2527 continue; 2528 2529 if (!hlist_unhashed(&p->mglist) && 2530 (timer_pending(&p->timer) ? 2531 time_after(p->timer.expires, time) : 2532 try_to_del_timer_sync(&p->timer) >= 0)) { 2533 mod_timer(&p->timer, time); 2534 } --- 743 unchanged lines hidden (view full) --- 3278 if (!port->dev || port->dev == dev) 3279 continue; 3280 3281 hlist_for_each_entry_rcu(group, &port->mglist, mglist) { 3282 entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 3283 if (!entry) 3284 goto unlock; 3285 |
3259 entry->addr = group->addr; | 3286 entry->addr = group->key.addr; |
3260 list_add(&entry->list, br_ip_list); 3261 count++; 3262 } 3263 } 3264 3265unlock: 3266 rcu_read_unlock(); 3267 return count; --- 240 unchanged lines hidden (view full) --- 3508 mcast_stats_add_dir(tdst.mld_v2reports, temp.mld_v2reports); 3509 tdst.mld_parse_errors += temp.mld_parse_errors; 3510 } 3511 memcpy(dest, &tdst, sizeof(*dest)); 3512} 3513 3514int br_mdb_hash_init(struct net_bridge *br) 3515{ | 3287 list_add(&entry->list, br_ip_list); 3288 count++; 3289 } 3290 } 3291 3292unlock: 3293 rcu_read_unlock(); 3294 return count; --- 240 unchanged lines hidden (view full) --- 3535 mcast_stats_add_dir(tdst.mld_v2reports, temp.mld_v2reports); 3536 tdst.mld_parse_errors += temp.mld_parse_errors; 3537 } 3538 memcpy(dest, &tdst, sizeof(*dest)); 3539} 3540 3541int br_mdb_hash_init(struct net_bridge *br) 3542{ |
3516 return rhashtable_init(&br->mdb_hash_tbl, &br_mdb_rht_params); | 3543 int err; 3544 3545 err = rhashtable_init(&br->sg_port_tbl, &br_sg_port_rht_params); 3546 if (err) 3547 return err; 3548 3549 err = rhashtable_init(&br->mdb_hash_tbl, &br_mdb_rht_params); 3550 if (err) { 3551 rhashtable_destroy(&br->sg_port_tbl); 3552 return err; 3553 } 3554 3555 return 0; |
3517} 3518 3519void br_mdb_hash_fini(struct net_bridge *br) 3520{ | 3556} 3557 3558void br_mdb_hash_fini(struct net_bridge *br) 3559{ |
3560 rhashtable_destroy(&br->sg_port_tbl); |
|
3521 rhashtable_destroy(&br->mdb_hash_tbl); 3522} | 3561 rhashtable_destroy(&br->mdb_hash_tbl); 3562} |