hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/bridge/br_switchdev.c
....@@ -14,7 +14,7 @@
1414
1515 /* dev is yet to be added to the port list. */
1616 list_for_each_entry(p, &br->port_list, list) {
17
- if (switchdev_port_same_parent_id(dev, p->dev))
17
+ if (netdev_port_same_parent_id(dev, p->dev))
1818 return p->offload_fwd_mark;
1919 }
2020
....@@ -23,15 +23,12 @@
2323
2424 int nbp_switchdev_mark_set(struct net_bridge_port *p)
2525 {
26
- struct switchdev_attr attr = {
27
- .orig_dev = p->dev,
28
- .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
29
- };
26
+ struct netdev_phys_item_id ppid = { };
3027 int err;
3128
3229 ASSERT_RTNL();
3330
34
- err = switchdev_port_attr_get(p->dev, &attr);
31
+ err = dev_get_port_parent_id(p->dev, &ppid, true);
3532 if (err) {
3633 if (err == -EOPNOTSUPP)
3734 return 0;
....@@ -67,21 +64,25 @@
6764 {
6865 struct switchdev_attr attr = {
6966 .orig_dev = p->dev,
70
- .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
67
+ .id = SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
68
+ .u.brport_flags = mask,
69
+ };
70
+ struct switchdev_notifier_port_attr_info info = {
71
+ .attr = &attr,
7172 };
7273 int err;
7374
7475 if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
7576 return 0;
7677
77
- err = switchdev_port_attr_get(p->dev, &attr);
78
+ /* We run from atomic context here */
79
+ err = call_switchdev_notifiers(SWITCHDEV_PORT_ATTR_SET, p->dev,
80
+ &info.info, NULL);
81
+ err = notifier_to_errno(err);
7882 if (err == -EOPNOTSUPP)
7983 return 0;
80
- if (err)
81
- return err;
8284
83
- /* Check if specific bridge flag attribute offload is supported */
84
- if (!(attr.u.brport_flags_support & mask)) {
85
+ if (err) {
8586 br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
8687 (unsigned int)p->port_no, p->dev->name);
8788 return -EOPNOTSUPP;
....@@ -90,6 +91,7 @@
9091 attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
9192 attr.flags = SWITCHDEV_F_DEFER;
9293 attr.u.brport_flags = flags;
94
+
9395 err = switchdev_port_attr_set(p->dev, &attr);
9496 if (err) {
9597 br_warn(p->br, "error setting offload flag on port %u(%s)\n",
....@@ -103,7 +105,7 @@
103105 static void
104106 br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
105107 u16 vid, struct net_device *dev,
106
- bool added_by_user)
108
+ bool added_by_user, bool offloaded)
107109 {
108110 struct switchdev_notifier_fdb_info info;
109111 unsigned long notifier_type;
....@@ -111,8 +113,9 @@
111113 info.addr = mac;
112114 info.vid = vid;
113115 info.added_by_user = added_by_user;
116
+ info.offloaded = offloaded;
114117 notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_DEVICE : SWITCHDEV_FDB_DEL_TO_DEVICE;
115
- call_switchdev_notifiers(notifier_type, dev, &info.info);
118
+ call_switchdev_notifiers(notifier_type, dev, &info.info, NULL);
116119 }
117120
118121 void
....@@ -120,24 +123,33 @@
120123 {
121124 if (!fdb->dst)
122125 return;
126
+ if (test_bit(BR_FDB_LOCAL, &fdb->flags))
127
+ return;
123128
124129 switch (type) {
125130 case RTM_DELNEIGH:
126131 br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
127132 fdb->key.vlan_id,
128133 fdb->dst->dev,
129
- fdb->added_by_user);
134
+ test_bit(BR_FDB_ADDED_BY_USER,
135
+ &fdb->flags),
136
+ test_bit(BR_FDB_OFFLOADED,
137
+ &fdb->flags));
130138 break;
131139 case RTM_NEWNEIGH:
132140 br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
133141 fdb->key.vlan_id,
134142 fdb->dst->dev,
135
- fdb->added_by_user);
143
+ test_bit(BR_FDB_ADDED_BY_USER,
144
+ &fdb->flags),
145
+ test_bit(BR_FDB_OFFLOADED,
146
+ &fdb->flags));
136147 break;
137148 }
138149 }
139150
140
-int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags)
151
+int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
152
+ struct netlink_ext_ack *extack)
141153 {
142154 struct switchdev_obj_port_vlan v = {
143155 .obj.orig_dev = dev,
....@@ -147,7 +159,7 @@
147159 .vid_end = vid,
148160 };
149161
150
- return switchdev_port_obj_add(dev, &v.obj);
162
+ return switchdev_port_obj_add(dev, &v.obj, extack);
151163 }
152164
153165 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)