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);