aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/bridge/br_device.c3
-rw-r--r--net/bridge/br_input.c3
-rw-r--r--net/bridge/br_multicast.c39
-rw-r--r--net/bridge/br_private.h12
4 files changed, 46 insertions, 11 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 2ef66781fedb..69363bd37f64 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -70,7 +70,8 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
70 } 70 }
71 71
72 mdst = br_mdb_get(br, skb, vid); 72 mdst = br_mdb_get(br, skb, vid);
73 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) 73 if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
74 br_multicast_querier_exists(br))
74 br_multicast_deliver(mdst, skb); 75 br_multicast_deliver(mdst, skb);
75 else 76 else
76 br_flood_deliver(br, skb, false); 77 br_flood_deliver(br, skb, false);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 1b8b8b824cd7..8c561c0aa636 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -101,7 +101,8 @@ int br_handle_frame_finish(struct sk_buff *skb)
101 unicast = false; 101 unicast = false;
102 } else if (is_multicast_ether_addr(dest)) { 102 } else if (is_multicast_ether_addr(dest)) {
103 mdst = br_mdb_get(br, skb, vid); 103 mdst = br_mdb_get(br, skb, vid);
104 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { 104 if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
105 br_multicast_querier_exists(br)) {
105 if ((mdst && mdst->mglist) || 106 if ((mdst && mdst->mglist) ||
106 br_multicast_is_router(br)) 107 br_multicast_is_router(br))
107 skb2 = skb; 108 skb2 = skb;
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 4b99c9a27044..61c5e819380e 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1014,6 +1014,16 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
1014} 1014}
1015#endif 1015#endif
1016 1016
1017static void br_multicast_update_querier_timer(struct net_bridge *br,
1018 unsigned long max_delay)
1019{
1020 if (!timer_pending(&br->multicast_querier_timer))
1021 br->multicast_querier_delay_time = jiffies + max_delay;
1022
1023 mod_timer(&br->multicast_querier_timer,
1024 jiffies + br->multicast_querier_interval);
1025}
1026
1017/* 1027/*
1018 * Add port to router_list 1028 * Add port to router_list
1019 * list is maintained ordered by pointer value 1029 * list is maintained ordered by pointer value
@@ -1064,11 +1074,11 @@ timer:
1064 1074
1065static void br_multicast_query_received(struct net_bridge *br, 1075static void br_multicast_query_received(struct net_bridge *br,
1066 struct net_bridge_port *port, 1076 struct net_bridge_port *port,
1067 int saddr) 1077 int saddr,
1078 unsigned long max_delay)
1068{ 1079{
1069 if (saddr) 1080 if (saddr)
1070 mod_timer(&br->multicast_querier_timer, 1081 br_multicast_update_querier_timer(br, max_delay);
1071 jiffies + br->multicast_querier_interval);
1072 else if (timer_pending(&br->multicast_querier_timer)) 1082 else if (timer_pending(&br->multicast_querier_timer))
1073 return; 1083 return;
1074 1084
@@ -1096,8 +1106,6 @@ static int br_ip4_multicast_query(struct net_bridge *br,
1096 (port && port->state == BR_STATE_DISABLED)) 1106 (port && port->state == BR_STATE_DISABLED))
1097 goto out; 1107 goto out;
1098 1108
1099 br_multicast_query_received(br, port, !!iph->saddr);
1100
1101 group = ih->group; 1109 group = ih->group;
1102 1110
1103 if (skb->len == sizeof(*ih)) { 1111 if (skb->len == sizeof(*ih)) {
@@ -1121,6 +1129,8 @@ static int br_ip4_multicast_query(struct net_bridge *br,
1121 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; 1129 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
1122 } 1130 }
1123 1131
1132 br_multicast_query_received(br, port, !!iph->saddr, max_delay);
1133
1124 if (!group) 1134 if (!group)
1125 goto out; 1135 goto out;
1126 1136
@@ -1176,8 +1186,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1176 (port && port->state == BR_STATE_DISABLED)) 1186 (port && port->state == BR_STATE_DISABLED))
1177 goto out; 1187 goto out;
1178 1188
1179 br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr));
1180
1181 if (skb->len == sizeof(*mld)) { 1189 if (skb->len == sizeof(*mld)) {
1182 if (!pskb_may_pull(skb, sizeof(*mld))) { 1190 if (!pskb_may_pull(skb, sizeof(*mld))) {
1183 err = -EINVAL; 1191 err = -EINVAL;
@@ -1198,6 +1206,9 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1198 max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1; 1206 max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1;
1199 } 1207 }
1200 1208
1209 br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr),
1210 max_delay);
1211
1201 if (!group) 1212 if (!group)
1202 goto out; 1213 goto out;
1203 1214
@@ -1643,6 +1654,8 @@ void br_multicast_init(struct net_bridge *br)
1643 br->multicast_querier_interval = 255 * HZ; 1654 br->multicast_querier_interval = 255 * HZ;
1644 br->multicast_membership_interval = 260 * HZ; 1655 br->multicast_membership_interval = 260 * HZ;
1645 1656
1657 br->multicast_querier_delay_time = 0;
1658
1646 spin_lock_init(&br->multicast_lock); 1659 spin_lock_init(&br->multicast_lock);
1647 setup_timer(&br->multicast_router_timer, 1660 setup_timer(&br->multicast_router_timer,
1648 br_multicast_local_router_expired, 0); 1661 br_multicast_local_router_expired, 0);
@@ -1831,6 +1844,8 @@ unlock:
1831 1844
1832int br_multicast_set_querier(struct net_bridge *br, unsigned long val) 1845int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
1833{ 1846{
1847 unsigned long max_delay;
1848
1834 val = !!val; 1849 val = !!val;
1835 1850
1836 spin_lock_bh(&br->multicast_lock); 1851 spin_lock_bh(&br->multicast_lock);
@@ -1838,8 +1853,14 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
1838 goto unlock; 1853 goto unlock;
1839 1854
1840 br->multicast_querier = val; 1855 br->multicast_querier = val;
1841 if (val) 1856 if (!val)
1842 br_multicast_start_querier(br); 1857 goto unlock;
1858
1859 max_delay = br->multicast_query_response_interval;
1860 if (!timer_pending(&br->multicast_querier_timer))
1861 br->multicast_querier_delay_time = jiffies + max_delay;
1862
1863 br_multicast_start_querier(br);
1843 1864
1844unlock: 1865unlock:
1845 spin_unlock_bh(&br->multicast_lock); 1866 spin_unlock_bh(&br->multicast_lock);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 3be89b3ce17b..2f7da41851bf 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -267,6 +267,7 @@ struct net_bridge
267 unsigned long multicast_query_interval; 267 unsigned long multicast_query_interval;
268 unsigned long multicast_query_response_interval; 268 unsigned long multicast_query_response_interval;
269 unsigned long multicast_startup_query_interval; 269 unsigned long multicast_startup_query_interval;
270 unsigned long multicast_querier_delay_time;
270 271
271 spinlock_t multicast_lock; 272 spinlock_t multicast_lock;
272 struct net_bridge_mdb_htable __rcu *mdb; 273 struct net_bridge_mdb_htable __rcu *mdb;
@@ -501,6 +502,13 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
501 (br->multicast_router == 1 && 502 (br->multicast_router == 1 &&
502 timer_pending(&br->multicast_router_timer)); 503 timer_pending(&br->multicast_router_timer));
503} 504}
505
506static inline bool br_multicast_querier_exists(struct net_bridge *br)
507{
508 return time_is_before_jiffies(br->multicast_querier_delay_time) &&
509 (br->multicast_querier ||
510 timer_pending(&br->multicast_querier_timer));
511}
504#else 512#else
505static inline int br_multicast_rcv(struct net_bridge *br, 513static inline int br_multicast_rcv(struct net_bridge *br,
506 struct net_bridge_port *port, 514 struct net_bridge_port *port,
@@ -557,6 +565,10 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
557{ 565{
558 return 0; 566 return 0;
559} 567}
568static inline bool br_multicast_querier_exists(struct net_bridge *br)
569{
570 return false;
571}
560static inline void br_mdb_init(void) 572static inline void br_mdb_init(void)
561{ 573{
562} 574}