forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/net/bridge/br_if.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Userspace interface
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>
....@@ -179,7 +175,7 @@
179175 ASSERT_RTNL();
180176
181177 if (backup_dev) {
182
- if (!br_port_exists(backup_dev))
178
+ if (!netif_is_bridge_port(backup_dev))
183179 return -ENOENT;
184180
185181 backup_p = br_port_get_rtnl(backup_dev);
....@@ -337,6 +333,8 @@
337333 br_stp_disable_port(p);
338334 spin_unlock_bh(&br->lock);
339335
336
+ br_mrp_port_del(br, p);
337
+
340338 br_ifinfo_notify(RTM_DELLINK, NULL, p);
341339
342340 list_del_rcu(&p->list);
....@@ -394,8 +392,7 @@
394392 struct net_bridge_port *p;
395393 unsigned long *inuse;
396394
397
- inuse = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long),
398
- GFP_KERNEL);
395
+ inuse = bitmap_zalloc(BR_MAX_PORTS, GFP_KERNEL);
399396 if (!inuse)
400397 return -ENOMEM;
401398
....@@ -404,7 +401,7 @@
404401 set_bit(p->port_no, inuse);
405402 }
406403 index = find_first_zero_bit(inuse, BR_MAX_PORTS);
407
- kfree(inuse);
404
+ bitmap_free(inuse);
408405
409406 return (index >= BR_MAX_PORTS) ? -EXFULL : index;
410407 }
....@@ -509,14 +506,14 @@
509506 ASSERT_RTNL();
510507
511508 /* if the bridge MTU was manually configured don't mess with it */
512
- if (br->mtu_set_by_user)
509
+ if (br_opt_get(br, BROPT_MTU_SET_BY_USER))
513510 return;
514511
515512 /* change to the minimum MTU and clear the flag which was set by
516513 * the bridge ndo_change_mtu callback
517514 */
518515 dev_set_mtu(br->dev, br_mtu_min(br));
519
- br->mtu_set_by_user = false;
516
+ br_opt_toggle(br, BROPT_MTU_SET_BY_USER, false);
520517 }
521518
522519 static void br_set_gso_limits(struct net_bridge *br)
....@@ -566,17 +563,31 @@
566563 unsigned br_hr, dev_hr;
567564 bool changed_addr, fdb_synced = false;
568565
569
- /* Don't allow bridging non-ethernet like devices, or DSA-enabled
570
- * master network devices since the bridge layer rx_handler prevents
571
- * the DSA fake ethertype handler to be invoked, so we do not strip off
572
- * the DSA switch tag protocol header and the bridge layer just return
573
- * RX_HANDLER_CONSUMED, stopping RX processing for these frames.
574
- */
566
+ /* Don't allow bridging non-ethernet like devices. */
575567 if ((dev->flags & IFF_LOOPBACK) ||
576568 dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
577
- !is_valid_ether_addr(dev->dev_addr) ||
578
- netdev_uses_dsa(dev))
569
+ !is_valid_ether_addr(dev->dev_addr))
579570 return -EINVAL;
571
+
572
+ /* Also don't allow bridging of net devices that are DSA masters, since
573
+ * the bridge layer rx_handler prevents the DSA fake ethertype handler
574
+ * to be invoked, so we don't get the chance to strip off and parse the
575
+ * DSA switch tag protocol header (the bridge layer just returns
576
+ * RX_HANDLER_CONSUMED, stopping RX processing for these frames).
577
+ * The only case where that would not be an issue is when bridging can
578
+ * already be offloaded, such as when the DSA master is itself a DSA
579
+ * or plain switchdev port, and is bridged only with other ports from
580
+ * the same hardware device.
581
+ */
582
+ if (netdev_uses_dsa(dev)) {
583
+ list_for_each_entry(p, &br->port_list, list) {
584
+ if (!netdev_port_same_parent_id(dev, p->dev)) {
585
+ NL_SET_ERR_MSG(extack,
586
+ "Cannot do software bridging with a DSA master");
587
+ return -EINVAL;
588
+ }
589
+ }
590
+ }
580591
581592 /* No bridging of bridges */
582593 if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) {
....@@ -622,7 +633,7 @@
622633 if (err)
623634 goto err3;
624635
625
- err = netdev_rx_handler_register(dev, br_handle_frame, p);
636
+ err = netdev_rx_handler_register(dev, br_get_rx_handler(dev), p);
626637 if (err)
627638 goto err4;
628639
....@@ -667,7 +678,16 @@
667678 if (br_fdb_insert(br, p, dev->dev_addr, 0))
668679 netdev_err(dev, "failed insert local address bridge forwarding table\n");
669680
670
- err = nbp_vlan_init(p);
681
+ if (br->dev->addr_assign_type != NET_ADDR_SET) {
682
+ /* Ask for permission to use this MAC address now, even if we
683
+ * don't end up choosing it below.
684
+ */
685
+ err = dev_pre_changeaddr_notify(br->dev, dev->dev_addr, extack);
686
+ if (err)
687
+ goto err7;
688
+ }
689
+
690
+ err = nbp_vlan_init(p, extack);
671691 if (err) {
672692 netdev_err(dev, "failed to initialize vlan filtering on this port\n");
673693 goto err7;
....@@ -758,3 +778,15 @@
758778 if (mask & BR_NEIGH_SUPPRESS)
759779 br_recalculate_neigh_suppress_enabled(br);
760780 }
781
+
782
+bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag)
783
+{
784
+ struct net_bridge_port *p;
785
+
786
+ p = br_port_get_rtnl_rcu(dev);
787
+ if (!p)
788
+ return false;
789
+
790
+ return p->flags & flag;
791
+}
792
+EXPORT_SYMBOL_GPL(br_port_flag_is_set);