.. | .. |
---|
14 | 14 | |
---|
15 | 15 | /* dev is yet to be added to the port list. */ |
---|
16 | 16 | 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)) |
---|
18 | 18 | return p->offload_fwd_mark; |
---|
19 | 19 | } |
---|
20 | 20 | |
---|
.. | .. |
---|
23 | 23 | |
---|
24 | 24 | int nbp_switchdev_mark_set(struct net_bridge_port *p) |
---|
25 | 25 | { |
---|
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 = { }; |
---|
30 | 27 | int err; |
---|
31 | 28 | |
---|
32 | 29 | ASSERT_RTNL(); |
---|
33 | 30 | |
---|
34 | | - err = switchdev_port_attr_get(p->dev, &attr); |
---|
| 31 | + err = dev_get_port_parent_id(p->dev, &ppid, true); |
---|
35 | 32 | if (err) { |
---|
36 | 33 | if (err == -EOPNOTSUPP) |
---|
37 | 34 | return 0; |
---|
.. | .. |
---|
67 | 64 | { |
---|
68 | 65 | struct switchdev_attr attr = { |
---|
69 | 66 | .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, |
---|
71 | 72 | }; |
---|
72 | 73 | int err; |
---|
73 | 74 | |
---|
74 | 75 | if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD) |
---|
75 | 76 | return 0; |
---|
76 | 77 | |
---|
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); |
---|
78 | 82 | if (err == -EOPNOTSUPP) |
---|
79 | 83 | return 0; |
---|
80 | | - if (err) |
---|
81 | | - return err; |
---|
82 | 84 | |
---|
83 | | - /* Check if specific bridge flag attribute offload is supported */ |
---|
84 | | - if (!(attr.u.brport_flags_support & mask)) { |
---|
| 85 | + if (err) { |
---|
85 | 86 | br_warn(p->br, "bridge flag offload is not supported %u(%s)\n", |
---|
86 | 87 | (unsigned int)p->port_no, p->dev->name); |
---|
87 | 88 | return -EOPNOTSUPP; |
---|
.. | .. |
---|
90 | 91 | attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS; |
---|
91 | 92 | attr.flags = SWITCHDEV_F_DEFER; |
---|
92 | 93 | attr.u.brport_flags = flags; |
---|
| 94 | + |
---|
93 | 95 | err = switchdev_port_attr_set(p->dev, &attr); |
---|
94 | 96 | if (err) { |
---|
95 | 97 | br_warn(p->br, "error setting offload flag on port %u(%s)\n", |
---|
.. | .. |
---|
103 | 105 | static void |
---|
104 | 106 | br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac, |
---|
105 | 107 | u16 vid, struct net_device *dev, |
---|
106 | | - bool added_by_user) |
---|
| 108 | + bool added_by_user, bool offloaded) |
---|
107 | 109 | { |
---|
108 | 110 | struct switchdev_notifier_fdb_info info; |
---|
109 | 111 | unsigned long notifier_type; |
---|
.. | .. |
---|
111 | 113 | info.addr = mac; |
---|
112 | 114 | info.vid = vid; |
---|
113 | 115 | info.added_by_user = added_by_user; |
---|
| 116 | + info.offloaded = offloaded; |
---|
114 | 117 | 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); |
---|
116 | 119 | } |
---|
117 | 120 | |
---|
118 | 121 | void |
---|
.. | .. |
---|
120 | 123 | { |
---|
121 | 124 | if (!fdb->dst) |
---|
122 | 125 | return; |
---|
| 126 | + if (test_bit(BR_FDB_LOCAL, &fdb->flags)) |
---|
| 127 | + return; |
---|
123 | 128 | |
---|
124 | 129 | switch (type) { |
---|
125 | 130 | case RTM_DELNEIGH: |
---|
126 | 131 | br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr, |
---|
127 | 132 | fdb->key.vlan_id, |
---|
128 | 133 | 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)); |
---|
130 | 138 | break; |
---|
131 | 139 | case RTM_NEWNEIGH: |
---|
132 | 140 | br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr, |
---|
133 | 141 | fdb->key.vlan_id, |
---|
134 | 142 | 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)); |
---|
136 | 147 | break; |
---|
137 | 148 | } |
---|
138 | 149 | } |
---|
139 | 150 | |
---|
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) |
---|
141 | 153 | { |
---|
142 | 154 | struct switchdev_obj_port_vlan v = { |
---|
143 | 155 | .obj.orig_dev = dev, |
---|
.. | .. |
---|
147 | 159 | .vid_end = vid, |
---|
148 | 160 | }; |
---|
149 | 161 | |
---|
150 | | - return switchdev_port_obj_add(dev, &v.obj); |
---|
| 162 | + return switchdev_port_obj_add(dev, &v.obj, extack); |
---|
151 | 163 | } |
---|
152 | 164 | |
---|
153 | 165 | int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid) |
---|