br_multicast.c (07f8ac4a1e26e8283542cdaf658a6e2a12fd6980) | br_multicast.c (2cd4143192e8c60f66cb32c3a30c76d0470a372d) |
---|---|
1/* 2 * Bridge multicast support. 3 * 4 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) --- 1067 unchanged lines hidden (view full) --- 1076 break; 1077 } 1078 1079 return err; 1080} 1081#endif 1082 1083static bool br_ip4_multicast_select_querier(struct net_bridge *br, | 1/* 2 * Bridge multicast support. 3 * 4 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) --- 1067 unchanged lines hidden (view full) --- 1076 break; 1077 } 1078 1079 return err; 1080} 1081#endif 1082 1083static bool br_ip4_multicast_select_querier(struct net_bridge *br, |
1084 struct net_bridge_port *port, |
|
1084 __be32 saddr) 1085{ 1086 if (!timer_pending(&br->ip4_own_query.timer) && 1087 !timer_pending(&br->ip4_other_query.timer)) 1088 goto update; 1089 1090 if (!br->ip4_querier.addr.u.ip4) 1091 goto update; 1092 1093 if (ntohl(saddr) <= ntohl(br->ip4_querier.addr.u.ip4)) 1094 goto update; 1095 1096 return false; 1097 1098update: 1099 br->ip4_querier.addr.u.ip4 = saddr; 1100 | 1085 __be32 saddr) 1086{ 1087 if (!timer_pending(&br->ip4_own_query.timer) && 1088 !timer_pending(&br->ip4_other_query.timer)) 1089 goto update; 1090 1091 if (!br->ip4_querier.addr.u.ip4) 1092 goto update; 1093 1094 if (ntohl(saddr) <= ntohl(br->ip4_querier.addr.u.ip4)) 1095 goto update; 1096 1097 return false; 1098 1099update: 1100 br->ip4_querier.addr.u.ip4 = saddr; 1101 |
1102 /* update protected by general multicast_lock by caller */ 1103 rcu_assign_pointer(br->ip4_querier.port, port); 1104 |
|
1101 return true; 1102} 1103 1104#if IS_ENABLED(CONFIG_IPV6) 1105static bool br_ip6_multicast_select_querier(struct net_bridge *br, | 1105 return true; 1106} 1107 1108#if IS_ENABLED(CONFIG_IPV6) 1109static bool br_ip6_multicast_select_querier(struct net_bridge *br, |
1110 struct net_bridge_port *port, |
|
1106 struct in6_addr *saddr) 1107{ 1108 if (!timer_pending(&br->ip6_own_query.timer) && 1109 !timer_pending(&br->ip6_other_query.timer)) 1110 goto update; 1111 1112 if (ipv6_addr_cmp(saddr, &br->ip6_querier.addr.u.ip6) <= 0) 1113 goto update; 1114 1115 return false; 1116 1117update: 1118 br->ip6_querier.addr.u.ip6 = *saddr; 1119 | 1111 struct in6_addr *saddr) 1112{ 1113 if (!timer_pending(&br->ip6_own_query.timer) && 1114 !timer_pending(&br->ip6_other_query.timer)) 1115 goto update; 1116 1117 if (ipv6_addr_cmp(saddr, &br->ip6_querier.addr.u.ip6) <= 0) 1118 goto update; 1119 1120 return false; 1121 1122update: 1123 br->ip6_querier.addr.u.ip6 = *saddr; 1124 |
1125 /* update protected by general multicast_lock by caller */ 1126 rcu_assign_pointer(br->ip6_querier.port, port); 1127 |
|
1120 return true; 1121} 1122#endif 1123 1124static bool br_multicast_select_querier(struct net_bridge *br, | 1128 return true; 1129} 1130#endif 1131 1132static bool br_multicast_select_querier(struct net_bridge *br, |
1133 struct net_bridge_port *port, |
|
1125 struct br_ip *saddr) 1126{ 1127 switch (saddr->proto) { 1128 case htons(ETH_P_IP): | 1134 struct br_ip *saddr) 1135{ 1136 switch (saddr->proto) { 1137 case htons(ETH_P_IP): |
1129 return br_ip4_multicast_select_querier(br, saddr->u.ip4); | 1138 return br_ip4_multicast_select_querier(br, port, saddr->u.ip4); |
1130#if IS_ENABLED(CONFIG_IPV6) 1131 case htons(ETH_P_IPV6): | 1139#if IS_ENABLED(CONFIG_IPV6) 1140 case htons(ETH_P_IPV6): |
1132 return br_ip6_multicast_select_querier(br, &saddr->u.ip6); | 1141 return br_ip6_multicast_select_querier(br, port, &saddr->u.ip6); |
1133#endif 1134 } 1135 1136 return false; 1137} 1138 1139static void 1140br_multicast_update_query_timer(struct net_bridge *br, --- 55 unchanged lines hidden (view full) --- 1196} 1197 1198static void br_multicast_query_received(struct net_bridge *br, 1199 struct net_bridge_port *port, 1200 struct bridge_mcast_other_query *query, 1201 struct br_ip *saddr, 1202 unsigned long max_delay) 1203{ | 1142#endif 1143 } 1144 1145 return false; 1146} 1147 1148static void 1149br_multicast_update_query_timer(struct net_bridge *br, --- 55 unchanged lines hidden (view full) --- 1205} 1206 1207static void br_multicast_query_received(struct net_bridge *br, 1208 struct net_bridge_port *port, 1209 struct bridge_mcast_other_query *query, 1210 struct br_ip *saddr, 1211 unsigned long max_delay) 1212{ |
1204 if (!br_multicast_select_querier(br, saddr)) | 1213 if (!br_multicast_select_querier(br, port, saddr)) |
1205 return; 1206 1207 br_multicast_update_query_timer(br, query, max_delay); 1208 br_multicast_mark_router(br, port); 1209} 1210 1211static int br_ip4_multicast_query(struct net_bridge *br, 1212 struct net_bridge_port *port, --- 586 unchanged lines hidden (view full) --- 1799 return br_multicast_ipv6_rcv(br, port, skb, vid); 1800#endif 1801 } 1802 1803 return 0; 1804} 1805 1806static void br_multicast_query_expired(struct net_bridge *br, | 1214 return; 1215 1216 br_multicast_update_query_timer(br, query, max_delay); 1217 br_multicast_mark_router(br, port); 1218} 1219 1220static int br_ip4_multicast_query(struct net_bridge *br, 1221 struct net_bridge_port *port, --- 586 unchanged lines hidden (view full) --- 1808 return br_multicast_ipv6_rcv(br, port, skb, vid); 1809#endif 1810 } 1811 1812 return 0; 1813} 1814 1815static void br_multicast_query_expired(struct net_bridge *br, |
1807 struct bridge_mcast_own_query *query) | 1816 struct bridge_mcast_own_query *query, 1817 struct bridge_mcast_querier *querier) |
1808{ 1809 spin_lock(&br->multicast_lock); 1810 if (query->startup_sent < br->multicast_startup_query_count) 1811 query->startup_sent++; 1812 | 1818{ 1819 spin_lock(&br->multicast_lock); 1820 if (query->startup_sent < br->multicast_startup_query_count) 1821 query->startup_sent++; 1822 |
1823 rcu_assign_pointer(querier, NULL); |
|
1813 br_multicast_send_query(br, NULL, query); 1814 spin_unlock(&br->multicast_lock); 1815} 1816 1817static void br_ip4_multicast_query_expired(unsigned long data) 1818{ 1819 struct net_bridge *br = (void *)data; 1820 | 1824 br_multicast_send_query(br, NULL, query); 1825 spin_unlock(&br->multicast_lock); 1826} 1827 1828static void br_ip4_multicast_query_expired(unsigned long data) 1829{ 1830 struct net_bridge *br = (void *)data; 1831 |
1821 br_multicast_query_expired(br, &br->ip4_own_query); | 1832 br_multicast_query_expired(br, &br->ip4_own_query, &br->ip4_querier); |
1822} 1823 1824#if IS_ENABLED(CONFIG_IPV6) 1825static void br_ip6_multicast_query_expired(unsigned long data) 1826{ 1827 struct net_bridge *br = (void *)data; 1828 | 1833} 1834 1835#if IS_ENABLED(CONFIG_IPV6) 1836static void br_ip6_multicast_query_expired(unsigned long data) 1837{ 1838 struct net_bridge *br = (void *)data; 1839 |
1829 br_multicast_query_expired(br, &br->ip6_own_query); | 1840 br_multicast_query_expired(br, &br->ip6_own_query, &br->ip6_querier); |
1830} 1831#endif 1832 1833void br_multicast_init(struct net_bridge *br) 1834{ 1835 br->hash_elasticity = 4; 1836 br->hash_max = 512; 1837 --- 6 unchanged lines hidden (view full) --- 1844 br->multicast_last_member_interval = HZ; 1845 br->multicast_query_response_interval = 10 * HZ; 1846 br->multicast_startup_query_interval = 125 * HZ / 4; 1847 br->multicast_query_interval = 125 * HZ; 1848 br->multicast_querier_interval = 255 * HZ; 1849 br->multicast_membership_interval = 260 * HZ; 1850 1851 br->ip4_other_query.delay_time = 0; | 1841} 1842#endif 1843 1844void br_multicast_init(struct net_bridge *br) 1845{ 1846 br->hash_elasticity = 4; 1847 br->hash_max = 512; 1848 --- 6 unchanged lines hidden (view full) --- 1855 br->multicast_last_member_interval = HZ; 1856 br->multicast_query_response_interval = 10 * HZ; 1857 br->multicast_startup_query_interval = 125 * HZ / 4; 1858 br->multicast_query_interval = 125 * HZ; 1859 br->multicast_querier_interval = 255 * HZ; 1860 br->multicast_membership_interval = 260 * HZ; 1861 1862 br->ip4_other_query.delay_time = 0; |
1863 br->ip4_querier.port = NULL; |
|
1852#if IS_ENABLED(CONFIG_IPV6) 1853 br->ip6_other_query.delay_time = 0; | 1864#if IS_ENABLED(CONFIG_IPV6) 1865 br->ip6_other_query.delay_time = 0; |
1866 br->ip6_querier.port = NULL; |
|
1854#endif 1855 1856 spin_lock_init(&br->multicast_lock); 1857 setup_timer(&br->multicast_router_timer, 1858 br_multicast_local_router_expired, 0); 1859 setup_timer(&br->ip4_other_query.timer, 1860 br_ip4_multicast_querier_expired, (unsigned long)br); 1861 setup_timer(&br->ip4_own_query.timer, br_ip4_multicast_query_expired, --- 332 unchanged lines hidden (view full) --- 2194 } 2195 } 2196 2197unlock: 2198 rcu_read_unlock(); 2199 return count; 2200} 2201EXPORT_SYMBOL_GPL(br_multicast_list_adjacent); | 1867#endif 1868 1869 spin_lock_init(&br->multicast_lock); 1870 setup_timer(&br->multicast_router_timer, 1871 br_multicast_local_router_expired, 0); 1872 setup_timer(&br->ip4_other_query.timer, 1873 br_ip4_multicast_querier_expired, (unsigned long)br); 1874 setup_timer(&br->ip4_own_query.timer, br_ip4_multicast_query_expired, --- 332 unchanged lines hidden (view full) --- 2207 } 2208 } 2209 2210unlock: 2211 rcu_read_unlock(); 2212 return count; 2213} 2214EXPORT_SYMBOL_GPL(br_multicast_list_adjacent); |
2215 2216/** 2217 * br_multicast_has_querier_adjacent - Checks for a querier behind a bridge port 2218 * @dev: The bridge port adjacent to which to check for a querier 2219 * @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6 2220 * 2221 * Checks whether the given interface has a bridge on top and if so returns 2222 * true if a selected querier is behind one of the other ports of this 2223 * bridge. Otherwise returns false. 2224 */ 2225bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto) 2226{ 2227 struct net_bridge *br; 2228 struct net_bridge_port *port; 2229 bool ret = false; 2230 2231 rcu_read_lock(); 2232 if (!br_port_exists(dev)) 2233 goto unlock; 2234 2235 port = br_port_get_rcu(dev); 2236 if (!port || !port->br) 2237 goto unlock; 2238 2239 br = port->br; 2240 2241 switch (proto) { 2242 case ETH_P_IP: 2243 if (!timer_pending(&br->ip4_other_query.timer) || 2244 rcu_dereference(br->ip4_querier.port) == port) 2245 goto unlock; 2246 break; 2247 case ETH_P_IPV6: 2248 if (!timer_pending(&br->ip6_other_query.timer) || 2249 rcu_dereference(br->ip6_querier.port) == port) 2250 goto unlock; 2251 break; 2252 default: 2253 goto unlock; 2254 } 2255 2256 ret = true; 2257unlock: 2258 rcu_read_unlock(); 2259 return ret; 2260} 2261EXPORT_SYMBOL_GPL(br_multicast_has_querier_adjacent); |
|