History

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.

Linus Lüssing committed 13 years ago

Commit cc0fdd81 parent 79f9ab75 files · +240 −93Browse files

Unified · Split

5 files
  1. net/bridge/br_device.c +1 −1
  2. net/bridge/br_input.c +1 −1
  3. net/bridge/br_mdb.c +9 −5
  4. net/bridge/br_multicast.c +183 −75
  5. net/bridge/br_private.h +46 −11
net/bridge/br_device.c+1−1
@@ -71,7 +71,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) · 70 unmodified lines
7171
7272 mdst = br_mdb_get(br, skb, vid);
7373 if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
74− br_multicast_querier_exists(br))
74+ br_multicast_querier_exists(br, eth_hdr(skb)))
7575 br_multicast_deliver(mdst, skb);
7676 else
7777 br_flood_deliver(br, skb, false);
net/bridge/br_input.c+1−1
@@ -102,7 +102,7 @@ int br_handle_frame_finish(struct sk_buff *skb) · 101 unmodified lines
102102 } else if (is_multicast_ether_addr(dest)) {
103103 mdst = br_mdb_get(br, skb, vid);
104104 if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
105− br_multicast_querier_exists(br)) {
105+ br_multicast_querier_exists(br, eth_hdr(skb))) {
106106 if ((mdst && mdst->mglist) ||
107107 br_multicast_is_router(br))
108108 skb2 = skb;
net/bridge/br_mdb.c+9−5
@@ -414,16 +414,20 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) · 413 unmodified lines
414414 if (!netif_running(br->dev) || br->multicast_disabled)
415415 return -EINVAL;
416416
417− if (timer_pending(&br->multicast_querier_timer))
418− return -EBUSY;
419−
420417 ip.proto = entry->addr.proto;
421− if (ip.proto == htons(ETH_P_IP))
418+ if (ip.proto == htons(ETH_P_IP)) {
419+ if (timer_pending(&br->ip4_querier.timer))
420+ return -EBUSY;
421+
422422 ip.u.ip4 = entry->addr.u.ip4;
423423 #if IS_ENABLED(CONFIG_IPV6)
424− else
424+ } else {
425+ if (timer_pending(&br->ip6_querier.timer))
426+ return -EBUSY;
427+
425428 ip.u.ip6 = entry->addr.u.ip6;
426429 #endif
430+ }
427431
428432 spin_lock_bh(&br->multicast_lock);
429433 mdb = mlock_dereference(br->mdb, br);
net/bridge/br_multicast.c+183−75
@@ -33,7 +33,8 @@ · 32 unmodified lines
3333
3434 #include "br_private.h"
3535
36−static void br_multicast_start_querier(struct net_bridge *br);
36+static void br_multicast_start_querier(struct net_bridge *br,
37+ struct bridge_mcast_query *query);
3738 unsigned int br_mdb_rehash_seq;
3839
3940 static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
@@ -755,20 +756,35 @@ static void br_multicast_local_router_expired(unsigned long data) · 715 unmodified lines
755756 {
756757 }
757758
758−static void br_multicast_querier_expired(unsigned long data)
759+static void br_multicast_querier_expired(struct net_bridge *br,
760+ struct bridge_mcast_query *query)
759761 {
760− struct net_bridge *br = (void *)data;
761−
762762 spin_lock(&br->multicast_lock);
763763 if (!netif_running(br->dev) || br->multicast_disabled)
764764 goto out;
765765
766− br_multicast_start_querier(br);
766+ br_multicast_start_querier(br, query);
767767
768768 out:
769769 spin_unlock(&br->multicast_lock);
770770 }
771771
772+static void br_ip4_multicast_querier_expired(unsigned long data)
773+{
774+ struct net_bridge *br = (void *)data;
775+
776+ br_multicast_querier_expired(br, &br->ip4_query);
777+}
778+
779+#if IS_ENABLED(CONFIG_IPV6)
780+static void br_ip6_multicast_querier_expired(unsigned long data)
781+{
782+ struct net_bridge *br = (void *)data;
783+
784+ br_multicast_querier_expired(br, &br->ip6_query);
785+}
786+#endif
787+
772788 static void __br_multicast_send_query(struct net_bridge *br,
773789 struct net_bridge_port *port,
774790 struct br_ip *ip)
@@ -789,37 +805,45 @@ static void __br_multicast_send_query(struct net_bridge *br, · 14 unmodified lines
789805 }
790806
791807 static void br_multicast_send_query(struct net_bridge *br,
792− struct net_bridge_port *port, u32 sent)
808+ struct net_bridge_port *port,
809+ struct bridge_mcast_query *query)
793810 {
794811 unsigned long time;
795812 struct br_ip br_group;
813+ struct bridge_mcast_querier *querier = NULL;
796814
797815 if (!netif_running(br->dev) || br->multicast_disabled ||
798− !br->multicast_querier ||
799− timer_pending(&br->multicast_querier_timer))
816+ !br->multicast_querier)
800817 return;
801818
802819 memset(&br_group.u, 0, sizeof(br_group.u));
803820
804− br_group.proto = htons(ETH_P_IP);
805− __br_multicast_send_query(br, port, &br_group);
806−
821+ if (port ? (query == &port->ip4_query) :
822+ (query == &br->ip4_query)) {
823+ querier = &br->ip4_querier;
824+ br_group.proto = htons(ETH_P_IP);
807825 #if IS_ENABLED(CONFIG_IPV6)
808− br_group.proto = htons(ETH_P_IPV6);
809− __br_multicast_send_query(br, port, &br_group);
826+ } else {
827+ querier = &br->ip6_querier;
828+ br_group.proto = htons(ETH_P_IPV6);
810829 #endif
830+ }
831+
832+ if (!querier || timer_pending(&querier->timer))
833+ return;
834+
835+ __br_multicast_send_query(br, port, &br_group);
811836
812837 time = jiffies;
813− time += sent < br->multicast_startup_query_count ?
838+ time += query->startup_sent < br->multicast_startup_query_count ?
814839 br->multicast_startup_query_interval :
815840 br->multicast_query_interval;
816− mod_timer(port ? &port->multicast_query_timer :
817− &br->multicast_query_timer, time);
841+ mod_timer(&query->timer, time);
818842 }
819843
820−static void br_multicast_port_query_expired(unsigned long data)
844+static void br_multicast_port_query_expired(struct net_bridge_port *port,
845+ struct bridge_mcast_query *query)
821846 {
822− struct net_bridge_port *port = (void *)data;
823847 struct net_bridge *br = port->br;
824848
825849 spin_lock(&br->multicast_lock);
@@ -827,25 +851,43 @@ static void br_multicast_port_query_expired(unsigned long data) · 1 unmodified line
827851 port->state == BR_STATE_BLOCKING)
828852 goto out;
829853
830− if (port->multicast_startup_queries_sent <
831− br->multicast_startup_query_count)
832− port->multicast_startup_queries_sent++;
854+ if (query->startup_sent < br->multicast_startup_query_count)
855+ query->startup_sent++;
833856
834− br_multicast_send_query(port->br, port,
835− port->multicast_startup_queries_sent);
857+ br_multicast_send_query(port->br, port, query);
836858
837859 out:
838860 spin_unlock(&br->multicast_lock);
839861 }
840862
863+static void br_ip4_multicast_port_query_expired(unsigned long data)
864+{
865+ struct net_bridge_port *port = (void *)data;
866+
867+ br_multicast_port_query_expired(port, &port->ip4_query);
868+}
869+
870+#if IS_ENABLED(CONFIG_IPV6)
871+static void br_ip6_multicast_port_query_expired(unsigned long data)
872+{
873+ struct net_bridge_port *port = (void *)data;
874+
875+ br_multicast_port_query_expired(port, &port->ip6_query);
876+}
877+#endif
878+
841879 void br_multicast_add_port(struct net_bridge_port *port)
842880 {
843881 port->multicast_router = 1;
844882
845883 setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
846884 (unsigned long)port);
847− setup_timer(&port->multicast_query_timer,
848− br_multicast_port_query_expired, (unsigned long)port);
885+ setup_timer(&port->ip4_query.timer, br_ip4_multicast_port_query_expired,
886+ (unsigned long)port);
887+#if IS_ENABLED(CONFIG_IPV6)
888+ setup_timer(&port->ip6_query.timer, br_ip6_multicast_port_query_expired,
889+ (unsigned long)port);
890+#endif
849891 }
850892
851893 void br_multicast_del_port(struct net_bridge_port *port)
@@ -853,13 +895,13 @@ void br_multicast_del_port(struct net_bridge_port *port) · 1 unmodified line
853895 del_timer_sync(&port->multicast_router_timer);
854896 }
855897
856−static void __br_multicast_enable_port(struct net_bridge_port *port)
898+static void br_multicast_enable(struct bridge_mcast_query *query)
857899 {
858− port->multicast_startup_queries_sent = 0;
900+ query->startup_sent = 0;
859901
860− if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
861− del_timer(&port->multicast_query_timer))
862− mod_timer(&port->multicast_query_timer, jiffies);
902+ if (try_to_del_timer_sync(&query->timer) >= 0 ||
903+ del_timer(&query->timer))
904+ mod_timer(&query->timer, jiffies);
863905 }
864906
865907 void br_multicast_enable_port(struct net_bridge_port *port)
@@ -870,7 +912,10 @@ void br_multicast_enable_port(struct net_bridge_port *port) · 4 unmodified lines
870912 if (br->multicast_disabled || !netif_running(br->dev))
871913 goto out;
872914
873− __br_multicast_enable_port(port);
915+ br_multicast_enable(&port->ip4_query);
916+#if IS_ENABLED(CONFIG_IPV6)
917+ br_multicast_enable(&port->ip6_query);
918+#endif
874919
875920 out:
876921 spin_unlock(&br->multicast_lock);
@@ -889,7 +934,10 @@ void br_multicast_disable_port(struct net_bridge_port *port) · 12 unmodified lines
889934 if (!hlist_unhashed(&port->rlist))
890935 hlist_del_init_rcu(&port->rlist);
891936 del_timer(&port->multicast_router_timer);
892− del_timer(&port->multicast_query_timer);
937+ del_timer(&port->ip4_query.timer);
938+#if IS_ENABLED(CONFIG_IPV6)
939+ del_timer(&port->ip6_query.timer);
940+#endif
893941 spin_unlock(&br->multicast_lock);
894942 }
895943
@@ -1014,14 +1062,15 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, · 118 unmodified lines
10141062 }
10151063 #endif
10161064
1017−static void br_multicast_update_querier_timer(struct net_bridge *br,
1018− unsigned long max_delay)
1065+static void
1066+br_multicast_update_querier_timer(struct net_bridge *br,
1067+ struct bridge_mcast_querier *querier,
1068+ unsigned long max_delay)
10191069 {
1020− if (!timer_pending(&br->multicast_querier_timer))
1021− br->multicast_querier_delay_time = jiffies + max_delay;
1070+ if (!timer_pending(&querier->timer))
1071+ querier->delay_time = jiffies + max_delay;
10221072
1023− mod_timer(&br->multicast_querier_timer,
1024− jiffies + br->multicast_querier_interval);
1073+ mod_timer(&querier->timer, jiffies + br->multicast_querier_interval);
10251074 }
10261075
10271076 /*
@@ -1074,12 +1123,13 @@ timer: · 46 unmodified lines
10741123
10751124 static void br_multicast_query_received(struct net_bridge *br,
10761125 struct net_bridge_port *port,
1126+ struct bridge_mcast_querier *querier,
10771127 int saddr,
10781128 unsigned long max_delay)
10791129 {
10801130 if (saddr)
1081− br_multicast_update_querier_timer(br, max_delay);
1082− else if (timer_pending(&br->multicast_querier_timer))
1131+ br_multicast_update_querier_timer(br, querier, max_delay);
1132+ else if (timer_pending(&querier->timer))
10831133 return;
10841134
10851135 br_multicast_mark_router(br, port);
@@ -1129,7 +1179,8 @@ static int br_ip4_multicast_query(struct net_bridge *br, · 43 unmodified lines
11291179 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
11301180 }
11311181
1132− br_multicast_query_received(br, port, !!iph->saddr, max_delay);
1182+ br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
1183+ max_delay);
11331184
11341185 if (!group)
11351186 goto out;
@@ -1206,8 +1257,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, · 70 unmodified lines
12061257 max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1;
12071258 }
12081259
1209− br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr),
1210− max_delay);
1260+ br_multicast_query_received(br, port, &br->ip6_querier,
1261+ !ipv6_addr_any(&ip6h->saddr), max_delay);
12111262
12121263 if (!group)
12131264 goto out;
@@ -1244,7 +1295,9 @@ out: · 30 unmodified lines
12441295
12451296 static void br_multicast_leave_group(struct net_bridge *br,
12461297 struct net_bridge_port *port,
1247− struct br_ip *group)
1298+ struct br_ip *group,
1299+ struct bridge_mcast_querier *querier,
1300+ struct bridge_mcast_query *query)
12481301 {
12491302 struct net_bridge_mdb_htable *mdb;
12501303 struct net_bridge_mdb_entry *mp;
@@ -1255,7 +1308,7 @@ static void br_multicast_leave_group(struct net_bridge *br, · 4 unmodified lines
12551308 spin_lock(&br->multicast_lock);
12561309 if (!netif_running(br->dev) ||
12571310 (port && port->state == BR_STATE_DISABLED) ||
1258− timer_pending(&br->multicast_querier_timer))
1311+ timer_pending(&querier->timer))
12591312 goto out;
12601313
12611314 mdb = mlock_dereference(br->mdb, br);
@@ -1263,14 +1316,13 @@ static void br_multicast_leave_group(struct net_bridge *br, · 1 unmodified line
12631316 if (!mp)
12641317 goto out;
12651318
1266− if (br->multicast_querier &&
1267− !timer_pending(&br->multicast_querier_timer)) {
1319+ if (br->multicast_querier) {
12681320 __br_multicast_send_query(br, port, &mp->addr);
12691321
12701322 time = jiffies + br->multicast_last_member_count *
12711323 br->multicast_last_member_interval;
1272− mod_timer(port ? &port->multicast_query_timer :
1273− &br->multicast_query_timer, time);
1324+
1325+ mod_timer(&query->timer, time);
12741326
12751327 for (p = mlock_dereference(mp->ports, br);
12761328 p != NULL;
@@ -1323,7 +1375,6 @@ static void br_multicast_leave_group(struct net_bridge *br, · 46 unmodified lines
13231375 mod_timer(&mp->timer, time);
13241376 }
13251377 }
1326−
13271378 out:
13281379 spin_unlock(&br->multicast_lock);
13291380 }
@@ -1334,6 +1385,8 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br, · 4 unmodified lines
13341385 __u16 vid)
13351386 {
13361387 struct br_ip br_group;
1388+ struct bridge_mcast_query *query = port ? &port->ip4_query :
1389+ &br->ip4_query;
13371390
13381391 if (ipv4_is_local_multicast(group))
13391392 return;
@@ -1342,7 +1395,7 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br, · 2 unmodified lines
13421395 br_group.proto = htons(ETH_P_IP);
13431396 br_group.vid = vid;
13441397
1345− br_multicast_leave_group(br, port, &br_group);
1398+ br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query);
13461399 }
13471400
13481401 #if IS_ENABLED(CONFIG_IPV6)
@@ -1352,6 +1405,9 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, · 3 unmodified lines
13521405 __u16 vid)
13531406 {
13541407 struct br_ip br_group;
1408+ struct bridge_mcast_query *query = port ? &port->ip6_query :
1409+ &br->ip6_query;
1410+
13551411
13561412 if (!ipv6_is_transient_multicast(group))
13571413 return;
@@ -1360,7 +1416,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, · 2 unmodified lines
13601416 br_group.proto = htons(ETH_P_IPV6);
13611417 br_group.vid = vid;
13621418
1363− br_multicast_leave_group(br, port, &br_group);
1419+ br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query);
13641420 }
13651421 #endif
13661422
@@ -1622,19 +1678,32 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, · 255 unmodified lines
16221678 return 0;
16231679 }
16241680
1625−static void br_multicast_query_expired(unsigned long data)
1681+static void br_multicast_query_expired(struct net_bridge *br,
1682+ struct bridge_mcast_query *query)
1683+{
1684+ spin_lock(&br->multicast_lock);
1685+ if (query->startup_sent < br->multicast_startup_query_count)
1686+ query->startup_sent++;
1687+
1688+ br_multicast_send_query(br, NULL, query);
1689+ spin_unlock(&br->multicast_lock);
1690+}
1691+
1692+static void br_ip4_multicast_query_expired(unsigned long data)
16261693 {
16271694 struct net_bridge *br = (void *)data;
16281695
1629− spin_lock(&br->multicast_lock);
1630− if (br->multicast_startup_queries_sent <
1631− br->multicast_startup_query_count)
1632− br->multicast_startup_queries_sent++;
1696+ br_multicast_query_expired(br, &br->ip4_query);
1697+}
16331698
1634− br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent);
1699+#if IS_ENABLED(CONFIG_IPV6)
1700+static void br_ip6_multicast_query_expired(unsigned long data)
1701+{
1702+ struct net_bridge *br = (void *)data;
16351703
1636− spin_unlock(&br->multicast_lock);
1704+ br_multicast_query_expired(br, &br->ip6_query);
16371705 }
1706+#endif
16381707
16391708 void br_multicast_init(struct net_bridge *br)
16401709 {
@@ -1654,25 +1723,43 @@ void br_multicast_init(struct net_bridge *br) · 13 unmodified lines
16541723 br->multicast_querier_interval = 255 * HZ;
16551724 br->multicast_membership_interval = 260 * HZ;
16561725
1657− br->multicast_querier_delay_time = 0;
1726+ br->ip4_querier.delay_time = 0;
1727+#if IS_ENABLED(CONFIG_IPV6)
1728+ br->ip6_querier.delay_time = 0;
1729+#endif
16581730
16591731 spin_lock_init(&br->multicast_lock);
16601732 setup_timer(&br->multicast_router_timer,
16611733 br_multicast_local_router_expired, 0);
1662− setup_timer(&br->multicast_querier_timer,
1663− br_multicast_querier_expired, (unsigned long)br);
1664− setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
1734+ setup_timer(&br->ip4_querier.timer, br_ip4_multicast_querier_expired,
1735+ (unsigned long)br);
1736+ setup_timer(&br->ip4_query.timer, br_ip4_multicast_query_expired,
16651737 (unsigned long)br);
1738+#if IS_ENABLED(CONFIG_IPV6)
1739+ setup_timer(&br->ip6_querier.timer, br_ip6_multicast_querier_expired,
1740+ (unsigned long)br);
1741+ setup_timer(&br->ip6_query.timer, br_ip6_multicast_query_expired,
1742+ (unsigned long)br);
1743+#endif
16661744 }
16671745
1668−void br_multicast_open(struct net_bridge *br)
1746+static void __br_multicast_open(struct net_bridge *br,
1747+ struct bridge_mcast_query *query)
16691748 {
1670− br->multicast_startup_queries_sent = 0;
1749+ query->startup_sent = 0;
16711750
16721751 if (br->multicast_disabled)
16731752 return;
16741753
1675− mod_timer(&br->multicast_query_timer, jiffies);
1754+ mod_timer(&query->timer, jiffies);
1755+}
1756+
1757+void br_multicast_open(struct net_bridge *br)
1758+{
1759+ __br_multicast_open(br, &br->ip4_query);
1760+#if IS_ENABLED(CONFIG_IPV6)
1761+ __br_multicast_open(br, &br->ip6_query);
1762+#endif
16761763 }
16771764
16781765 void br_multicast_stop(struct net_bridge *br)
@@ -1684,8 +1771,12 @@ void br_multicast_stop(struct net_bridge *br) · 5 unmodified lines
16841771 int i;
16851772
16861773 del_timer_sync(&br->multicast_router_timer);
1687− del_timer_sync(&br->multicast_querier_timer);
1688− del_timer_sync(&br->multicast_query_timer);
1774+ del_timer_sync(&br->ip4_querier.timer);
1775+ del_timer_sync(&br->ip4_query.timer);
1776+#if IS_ENABLED(CONFIG_IPV6)
1777+ del_timer_sync(&br->ip6_querier.timer);
1778+ del_timer_sync(&br->ip6_query.timer);
1779+#endif
16891780
16901781 spin_lock_bh(&br->multicast_lock);
16911782 mdb = mlock_dereference(br->mdb, br);
@@ -1788,18 +1879,24 @@ unlock: · 96 unmodified lines
17881879 return err;
17891880 }
17901881
1791−static void br_multicast_start_querier(struct net_bridge *br)
1882+static void br_multicast_start_querier(struct net_bridge *br,
1883+ struct bridge_mcast_query *query)
17921884 {
17931885 struct net_bridge_port *port;
17941886
1795− br_multicast_open(br);
1887+ __br_multicast_open(br, query);
17961888
17971889 list_for_each_entry(port, &br->port_list, list) {
17981890 if (port->state == BR_STATE_DISABLED ||
17991891 port->state == BR_STATE_BLOCKING)
18001892 continue;
18011893
1802− __br_multicast_enable_port(port);
1894+ if (query == &br->ip4_query)
1895+ br_multicast_enable(&port->ip4_query);
1896+#if IS_ENABLED(CONFIG_IPV6)
1897+ else
1898+ br_multicast_enable(&port->ip6_query);
1899+#endif
18031900 }
18041901 }
18051902
@@ -1834,7 +1931,10 @@ rollback: · 28 unmodified lines
18341931 goto rollback;
18351932 }
18361933
1837− br_multicast_start_querier(br);
1934+ br_multicast_start_querier(br, &br->ip4_query);
1935+#if IS_ENABLED(CONFIG_IPV6)
1936+ br_multicast_start_querier(br, &br->ip6_query);
1937+#endif
18381938
18391939 unlock:
18401940 spin_unlock_bh(&br->multicast_lock);
@@ -1857,10 +1957,18 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val) · 16 unmodified lines
18571957 goto unlock;
18581958
18591959 max_delay = br->multicast_query_response_interval;
1860− if (!timer_pending(&br->multicast_querier_timer))
1861− br->multicast_querier_delay_time = jiffies + max_delay;
18621960
1863− br_multicast_start_querier(br);
1961+ if (!timer_pending(&br->ip4_querier.timer))
1962+ br->ip4_querier.delay_time = jiffies + max_delay;
1963+
1964+ br_multicast_start_querier(br, &br->ip4_query);
1965+
1966+#if IS_ENABLED(CONFIG_IPV6)
1967+ if (!timer_pending(&br->ip6_querier.timer))
1968+ br->ip6_querier.delay_time = jiffies + max_delay;
1969+
1970+ br_multicast_start_querier(br, &br->ip6_query);
1971+#endif
18641972
18651973 unlock:
18661974 spin_unlock_bh(&br->multicast_lock);
net/bridge/br_private.h+46−11
@@ -66,6 +66,20 @@ struct br_ip · 65 unmodified lines
6666 __u16 vid;
6767 };
6868
69+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
70+/* our own querier */
71+struct bridge_mcast_query {
72+ struct timer_list timer;
73+ u32 startup_sent;
74+};
75+
76+/* other querier */
77+struct bridge_mcast_querier {
78+ struct timer_list timer;
79+ unsigned long delay_time;
80+};
81+#endif
82+
6983 struct net_port_vlans {
7084 u16 port_idx;
7185 u16 pvid;
@@ -162,10 +176,12 @@ struct net_bridge_port · 90 unmodified lines
162176 #define BR_FLOOD 0x00000040
163177
164178 #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) */
166183 unsigned char multicast_router;
167184 struct timer_list multicast_router_timer;
168− struct timer_list multicast_query_timer;
169185 struct hlist_head mglist;
170186 struct hlist_node rlist;
171187 #endif
@@ -258,7 +274,6 @@ struct net_bridge · 86 unmodified lines
258274 u32 hash_max;
259275
260276 u32 multicast_last_member_count;
261− u32 multicast_startup_queries_sent;
262277 u32 multicast_startup_query_count;
263278
264279 unsigned long multicast_last_member_interval;
@@ -267,15 +282,18 @@ struct net_bridge · 2 unmodified lines
267282 unsigned long multicast_query_interval;
268283 unsigned long multicast_query_response_interval;
269284 unsigned long multicast_startup_query_interval;
270− unsigned long multicast_querier_delay_time;
271285
272286 spinlock_t multicast_lock;
273287 struct net_bridge_mdb_htable __rcu *mdb;
274288 struct hlist_head router_list;
275289
276290 struct timer_list multicast_router_timer;
277− struct timer_list multicast_querier_timer;
278− struct timer_list multicast_query_timer;
291+ struct bridge_mcast_querier ip4_querier;
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) */
279297 #endif
280298
281299 struct timer_list hello_timer;
@@ -503,11 +521,27 @@ static inline bool br_multicast_is_router(struct net_bridge *br) · 221 unmodified lines
503521 timer_pending(&br->multicast_router_timer));
504522 }
505523
506−static inline bool br_multicast_querier_exists(struct net_bridge *br)
524+static 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+
532+static inline bool br_multicast_querier_exists(struct net_bridge *br,
533+ struct ethhdr *eth)
507534 {
508− return time_is_before_jiffies(br->multicast_querier_delay_time) &&
509− (br->multicast_querier ||
510− timer_pending(&br->multicast_querier_timer));
535+ switch (eth->h_proto) {
536+ case (htons(ETH_P_IP)):
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+ }
511545 }
512546 #else
513547 static inline int br_multicast_rcv(struct net_bridge *br,
@@ -565,7 +599,8 @@ static inline bool br_multicast_is_router(struct net_bridge *br) · 51 unmodified lines
565599 {
566600 return 0;
567601 }
568−static inline bool br_multicast_querier_exists(struct net_bridge *br)
602+static inline bool br_multicast_querier_exists(struct net_bridge *br,
603+ struct ethhdr *eth)
569604 {
570605 return false;
571606 }