hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/bridge/br_device.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Device handling code
34 * Linux ethernet bridge
45 *
56 * Authors:
67 * Lennert Buytenhek <buytenh@gnu.org>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
128 */
139
1410 #include <linux/kernel.h>
....@@ -28,8 +24,6 @@
2824 const struct nf_br_ops __rcu *nf_br_ops __read_mostly;
2925 EXPORT_SYMBOL_GPL(nf_br_ops);
3026
31
-static struct lock_class_key bridge_netdev_addr_lock_key;
32
-
3327 /* net device transmit always called with BH disabled */
3428 netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
3529 {
....@@ -38,6 +32,7 @@
3832 struct net_bridge_mdb_entry *mdst;
3933 struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats);
4034 const struct nf_br_ops *nf_ops;
35
+ u8 state = BR_STATE_FORWARDING;
4136 const unsigned char *dest;
4237 u16 vid = 0;
4338
....@@ -57,21 +52,22 @@
5752
5853 br_switchdev_frame_unmark(skb);
5954 BR_INPUT_SKB_CB(skb)->brdev = dev;
55
+ BR_INPUT_SKB_CB(skb)->frag_max_size = 0;
6056
6157 skb_reset_mac_header(skb);
6258 skb_pull(skb, ETH_HLEN);
6359
64
- if (!br_allowed_ingress(br, br_vlan_group_rcu(br), skb, &vid))
60
+ if (!br_allowed_ingress(br, br_vlan_group_rcu(br), skb, &vid, &state))
6561 goto out;
6662
6763 if (IS_ENABLED(CONFIG_INET) &&
6864 (eth_hdr(skb)->h_proto == htons(ETH_P_ARP) ||
6965 eth_hdr(skb)->h_proto == htons(ETH_P_RARP)) &&
70
- br->neigh_suppress_enabled) {
66
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
7167 br_do_proxy_suppress_arp(skb, br, vid, NULL);
7268 } else if (IS_ENABLED(CONFIG_IPV6) &&
7369 skb->protocol == htons(ETH_P_IPV6) &&
74
- br->neigh_suppress_enabled &&
70
+ br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
7571 pskb_may_pull(skb, sizeof(struct ipv6hdr) +
7672 sizeof(struct nd_msg)) &&
7773 ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
....@@ -111,6 +107,8 @@
111107 return NETDEV_TX_OK;
112108 }
113109
110
+static struct lock_class_key bridge_netdev_addr_lock_key;
111
+
114112 static void br_set_lockdep_class(struct net_device *dev)
115113 {
116114 lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key);
....@@ -131,9 +129,17 @@
131129 return err;
132130 }
133131
132
+ err = br_mdb_hash_init(br);
133
+ if (err) {
134
+ free_percpu(br->stats);
135
+ br_fdb_hash_fini(br);
136
+ return err;
137
+ }
138
+
134139 err = br_vlan_init(br);
135140 if (err) {
136141 free_percpu(br->stats);
142
+ br_mdb_hash_fini(br);
137143 br_fdb_hash_fini(br);
138144 return err;
139145 }
....@@ -142,10 +148,11 @@
142148 if (err) {
143149 free_percpu(br->stats);
144150 br_vlan_flush(br);
151
+ br_mdb_hash_fini(br);
145152 br_fdb_hash_fini(br);
146153 }
147
- br_set_lockdep_class(dev);
148154
155
+ br_set_lockdep_class(dev);
149156 return err;
150157 }
151158
....@@ -156,6 +163,7 @@
156163 br_multicast_dev_del(br);
157164 br_multicast_uninit_stats(br);
158165 br_vlan_flush(br);
166
+ br_mdb_hash_fini(br);
159167 br_fdb_hash_fini(br);
160168 free_percpu(br->stats);
161169 }
....@@ -168,6 +176,9 @@
168176 netif_start_queue(dev);
169177 br_stp_enable_bridge(br);
170178 br_multicast_open(br);
179
+
180
+ if (br_opt_get(br, BROPT_MULTICAST_ENABLED))
181
+ br_multicast_join_snoopers(br);
171182
172183 return 0;
173184 }
....@@ -189,6 +200,9 @@
189200 br_stp_disable_bridge(br);
190201 br_multicast_stop(br);
191202
203
+ if (br_opt_get(br, BROPT_MULTICAST_ENABLED))
204
+ br_multicast_leave_snoopers(br);
205
+
192206 netif_stop_queue(dev);
193207
194208 return 0;
....@@ -198,28 +212,9 @@
198212 struct rtnl_link_stats64 *stats)
199213 {
200214 struct net_bridge *br = netdev_priv(dev);
201
- struct pcpu_sw_netstats tmp, sum = { 0 };
202
- unsigned int cpu;
203
-
204
- for_each_possible_cpu(cpu) {
205
- unsigned int start;
206
- const struct pcpu_sw_netstats *bstats
207
- = per_cpu_ptr(br->stats, cpu);
208
- do {
209
- start = u64_stats_fetch_begin_irq(&bstats->syncp);
210
- memcpy(&tmp, bstats, sizeof(tmp));
211
- } while (u64_stats_fetch_retry_irq(&bstats->syncp, start));
212
- sum.tx_bytes += tmp.tx_bytes;
213
- sum.tx_packets += tmp.tx_packets;
214
- sum.rx_bytes += tmp.rx_bytes;
215
- sum.rx_packets += tmp.rx_packets;
216
- }
217215
218216 netdev_stats_to_stats64(stats, &dev->stats);
219
- stats->tx_bytes = sum.tx_bytes;
220
- stats->tx_packets = sum.tx_packets;
221
- stats->rx_bytes = sum.rx_bytes;
222
- stats->rx_packets = sum.rx_packets;
217
+ dev_fetch_sw_netstats(stats, br->stats);
223218 }
224219
225220 static int br_change_mtu(struct net_device *dev, int new_mtu)
....@@ -229,7 +224,7 @@
229224 dev->mtu = new_mtu;
230225
231226 /* this flag will be cleared if the MTU was automatically adjusted */
232
- br->mtu_set_by_user = true;
227
+ br_opt_toggle(br, BROPT_MTU_SET_BY_USER, true);
233228 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
234229 /* remember the MTU in the rtable for PMTU */
235230 dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
....@@ -269,6 +264,37 @@
269264 strlcpy(info->version, BR_VERSION, sizeof(info->version));
270265 strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
271266 strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
267
+}
268
+
269
+static int br_get_link_ksettings(struct net_device *dev,
270
+ struct ethtool_link_ksettings *cmd)
271
+{
272
+ struct net_bridge *br = netdev_priv(dev);
273
+ struct net_bridge_port *p;
274
+
275
+ cmd->base.duplex = DUPLEX_UNKNOWN;
276
+ cmd->base.port = PORT_OTHER;
277
+ cmd->base.speed = SPEED_UNKNOWN;
278
+
279
+ list_for_each_entry(p, &br->port_list, list) {
280
+ struct ethtool_link_ksettings ecmd;
281
+ struct net_device *pdev = p->dev;
282
+
283
+ if (!netif_running(pdev) || !netif_oper_up(pdev))
284
+ continue;
285
+
286
+ if (__ethtool_get_link_ksettings(pdev, &ecmd))
287
+ continue;
288
+
289
+ if (ecmd.base.speed == (__u32)SPEED_UNKNOWN)
290
+ continue;
291
+
292
+ if (cmd->base.speed == (__u32)SPEED_UNKNOWN ||
293
+ cmd->base.speed < ecmd.base.speed)
294
+ cmd->base.speed = ecmd.base.speed;
295
+ }
296
+
297
+ return 0;
272298 }
273299
274300 static netdev_features_t br_fix_features(struct net_device *dev,
....@@ -351,7 +377,7 @@
351377
352378 p->np = NULL;
353379
354
- __netpoll_free_async(np);
380
+ __netpoll_free(np);
355381 }
356382
357383 #endif
....@@ -373,8 +399,9 @@
373399 }
374400
375401 static const struct ethtool_ops br_ethtool_ops = {
376
- .get_drvinfo = br_getinfo,
377
- .get_link = ethtool_op_get_link,
402
+ .get_drvinfo = br_getinfo,
403
+ .get_link = ethtool_op_get_link,
404
+ .get_link_ksettings = br_get_link_ksettings,
378405 };
379406
380407 static const struct net_device_ops br_netdev_ops = {
....@@ -400,6 +427,7 @@
400427 .ndo_fdb_add = br_fdb_add,
401428 .ndo_fdb_del = br_fdb_delete,
402429 .ndo_fdb_dump = br_fdb_dump,
430
+ .ndo_fdb_get = br_fdb_get,
403431 .ndo_bridge_getlink = br_getlink,
404432 .ndo_bridge_setlink = br_setlink,
405433 .ndo_bridge_dellink = br_dellink,
....@@ -433,6 +461,9 @@
433461 spin_lock_init(&br->lock);
434462 INIT_LIST_HEAD(&br->port_list);
435463 INIT_HLIST_HEAD(&br->fdb_list);
464
+#if IS_ENABLED(CONFIG_BRIDGE_MRP)
465
+ INIT_LIST_HEAD(&br->mrp_list);
466
+#endif
436467 spin_lock_init(&br->hash_lock);
437468
438469 br->bridge_id.prio[0] = 0x80;