aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_private.h
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@web.de>2013-08-30 11:28:17 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-30 15:24:37 -0400
commitcc0fdd802859eaeb00e1c87dbb655594bed2844c (patch)
treeeb5643ad4e5c783b28a6d936a1a91bb40e905447 /net/bridge/br_private.h
parent79f9ab7e0a8ec452e58b5a5267b9eb019ff493d0 (diff)
bridge: separate querier and query timer into IGMP/IPv4 and MLD/IPv6 ones
Currently we would still potentially suffer multicast packet loss if there is just either an IGMP or an MLD querier: For the former case, we would possibly drop IPv6 multicast packets, for the latter IPv4 ones. This is because we are currently assuming that if either an IGMP or MLD querier is present that the other one is present, too. This patch makes the behaviour and fix added in "bridge: disable snooping if there is no querier" (b00589af3b04) to also work if there is either just an IGMP or an MLD querier on the link: It refines the deactivation of the snooping to be protocol specific by using separate timers for the snooped IGMP and MLD queries as well as separate timers for our internal IGMP and MLD queriers. Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_private.h')
-rw-r--r--net/bridge/br_private.h57
1 files changed, 46 insertions, 11 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 2f7da41851bf..263ba9034468 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -66,6 +66,20 @@ struct br_ip
66 __u16 vid; 66 __u16 vid;
67}; 67};
68 68
69#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
70/* our own querier */
71struct bridge_mcast_query {
72 struct timer_list timer;
73 u32 startup_sent;
74};
75
76/* other querier */
77struct bridge_mcast_querier {
78 struct timer_list timer;
79 unsigned long delay_time;
80};
81#endif
82
69struct net_port_vlans { 83struct net_port_vlans {
70 u16 port_idx; 84 u16 port_idx;
71 u16 pvid; 85 u16 pvid;
@@ -162,10 +176,12 @@ struct net_bridge_port
162#define BR_FLOOD 0x00000040 176#define BR_FLOOD 0x00000040
163 177
164#ifdef CONFIG_BRIDGE_IGMP_SNOOPING 178#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
165 u32 multicast_startup_queries_sent; 179 struct bridge_mcast_query ip4_query;
180#if IS_ENABLED(CONFIG_IPV6)
181 struct bridge_mcast_query ip6_query;
182#endif /* IS_ENABLED(CONFIG_IPV6) */
166 unsigned char multicast_router; 183 unsigned char multicast_router;
167 struct timer_list multicast_router_timer; 184 struct timer_list multicast_router_timer;
168 struct timer_list multicast_query_timer;
169 struct hlist_head mglist; 185 struct hlist_head mglist;
170 struct hlist_node rlist; 186 struct hlist_node rlist;
171#endif 187#endif
@@ -258,7 +274,6 @@ struct net_bridge
258 u32 hash_max; 274 u32 hash_max;
259 275
260 u32 multicast_last_member_count; 276 u32 multicast_last_member_count;
261 u32 multicast_startup_queries_sent;
262 u32 multicast_startup_query_count; 277 u32 multicast_startup_query_count;
263 278
264 unsigned long multicast_last_member_interval; 279 unsigned long multicast_last_member_interval;
@@ -267,15 +282,18 @@ struct net_bridge
267 unsigned long multicast_query_interval; 282 unsigned long multicast_query_interval;
268 unsigned long multicast_query_response_interval; 283 unsigned long multicast_query_response_interval;
269 unsigned long multicast_startup_query_interval; 284 unsigned long multicast_startup_query_interval;
270 unsigned long multicast_querier_delay_time;
271 285
272 spinlock_t multicast_lock; 286 spinlock_t multicast_lock;
273 struct net_bridge_mdb_htable __rcu *mdb; 287 struct net_bridge_mdb_htable __rcu *mdb;
274 struct hlist_head router_list; 288 struct hlist_head router_list;
275 289
276 struct timer_list multicast_router_timer; 290 struct timer_list multicast_router_timer;
277 struct timer_list multicast_querier_timer; 291 struct bridge_mcast_querier ip4_querier;
278 struct timer_list multicast_query_timer; 292 struct bridge_mcast_query ip4_query;
293#if IS_ENABLED(CONFIG_IPV6)
294 struct bridge_mcast_querier ip6_querier;
295 struct bridge_mcast_query ip6_query;
296#endif /* IS_ENABLED(CONFIG_IPV6) */
279#endif 297#endif
280 298
281 struct timer_list hello_timer; 299 struct timer_list hello_timer;
@@ -503,11 +521,27 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
503 timer_pending(&br->multicast_router_timer)); 521 timer_pending(&br->multicast_router_timer));
504} 522}
505 523
506static inline bool br_multicast_querier_exists(struct net_bridge *br) 524static inline bool
525__br_multicast_querier_exists(struct net_bridge *br,
526 struct bridge_mcast_querier *querier)
527{
528 return time_is_before_jiffies(querier->delay_time) &&
529 (br->multicast_querier || timer_pending(&querier->timer));
530}
531
532static inline bool br_multicast_querier_exists(struct net_bridge *br,
533 struct ethhdr *eth)
507{ 534{
508 return time_is_before_jiffies(br->multicast_querier_delay_time) && 535 switch (eth->h_proto) {
509 (br->multicast_querier || 536 case (htons(ETH_P_IP)):
510 timer_pending(&br->multicast_querier_timer)); 537 return __br_multicast_querier_exists(br, &br->ip4_querier);
538#if IS_ENABLED(CONFIG_IPV6)
539 case (htons(ETH_P_IPV6)):
540 return __br_multicast_querier_exists(br, &br->ip6_querier);
541#endif
542 default:
543 return false;
544 }
511} 545}
512#else 546#else
513static inline int br_multicast_rcv(struct net_bridge *br, 547static inline int br_multicast_rcv(struct net_bridge *br,
@@ -565,7 +599,8 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
565{ 599{
566 return 0; 600 return 0;
567} 601}
568static inline bool br_multicast_querier_exists(struct net_bridge *br) 602static inline bool br_multicast_querier_exists(struct net_bridge *br,
603 struct ethhdr *eth)
569{ 604{
570 return false; 605 return false;
571} 606}