Skip to content

Commit 3ee6233

Browse files
w1ldptrSaeed Mahameed
authored andcommitted
net/mlx5: Bridge, identify port by vport_num+esw_owner_vhca_id pair
Following patches in series allow traffic between vports of different eswitch instances, which requires addressing bridge port by vport_num+esw_owner_vhca_id pair since vport_num is only unique per-eswitch. As a preparation, extend struct mlx5_esw_bridge_port with 'esw_owner_vhca_id' field and use it as part of key for mlx5_esw_bridge->vports xarray. With this change we can't rely on switchdev_handle_port_obj_add() helper to get mlx5 representor from stacked device because we need specifically representor from parent eswitch that registered the callback to obtain correct esw_owner_vhca_id. The helper doesn't allow passing additional parameters to predicate function and doesn't provide access to the notifier block to obtain eswitch through br_offloads. Implement custom helpers to obtain mlx5 representor and use them in mlx5_esw_bridge_port_obj_{add|del|attr_set}() implementations. Remove direct pointer to parent bridge from struct mlx5_vport as it is no longer needed. Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Reviewed-by: Mark Bloch <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent a514d17 commit 3ee6233

File tree

6 files changed

+263
-208
lines changed

6 files changed

+263
-208
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c

Lines changed: 133 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,83 @@ struct mlx5_bridge_switchdev_fdb_work {
1818
bool add;
1919
};
2020

21+
static bool mlx5_esw_bridge_dev_same_esw(struct net_device *dev, struct mlx5_eswitch *esw)
22+
{
23+
struct mlx5e_priv *priv = netdev_priv(dev);
24+
25+
return esw == priv->mdev->priv.eswitch;
26+
}
27+
28+
static int mlx5_esw_bridge_vport_num_vhca_id_get(struct net_device *dev, struct mlx5_eswitch *esw,
29+
u16 *vport_num, u16 *esw_owner_vhca_id)
30+
{
31+
struct mlx5e_rep_priv *rpriv;
32+
struct mlx5e_priv *priv;
33+
34+
if (!mlx5e_eswitch_rep(dev) || !mlx5_esw_bridge_dev_same_esw(dev, esw))
35+
return -ENODEV;
36+
37+
priv = netdev_priv(dev);
38+
rpriv = priv->ppriv;
39+
*vport_num = rpriv->rep->vport;
40+
*esw_owner_vhca_id = MLX5_CAP_GEN(priv->mdev, vhca_id);
41+
return 0;
42+
}
43+
44+
static int
45+
mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct mlx5_eswitch *esw,
46+
u16 *vport_num, u16 *esw_owner_vhca_id)
47+
{
48+
struct net_device *lower_dev;
49+
struct list_head *iter;
50+
51+
if (mlx5e_eswitch_rep(dev) && mlx5_esw_bridge_dev_same_esw(dev, esw))
52+
return mlx5_esw_bridge_vport_num_vhca_id_get(dev, esw, vport_num,
53+
esw_owner_vhca_id);
54+
55+
netdev_for_each_lower_dev(dev, lower_dev, iter) {
56+
int err;
57+
58+
if (netif_is_bridge_master(lower_dev))
59+
continue;
60+
61+
err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(lower_dev, esw, vport_num,
62+
esw_owner_vhca_id);
63+
if (!err)
64+
return 0;
65+
}
66+
67+
return -ENODEV;
68+
}
69+
2170
static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr)
2271
{
2372
struct mlx5_esw_bridge_offloads *br_offloads = container_of(nb,
2473
struct mlx5_esw_bridge_offloads,
2574
netdev_nb);
2675
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
2776
struct netdev_notifier_changeupper_info *info = ptr;
77+
struct net_device *upper = info->upper_dev;
78+
u16 vport_num, esw_owner_vhca_id;
2879
struct netlink_ext_ack *extack;
29-
struct mlx5e_rep_priv *rpriv;
30-
struct mlx5_eswitch *esw;
31-
struct mlx5_vport *vport;
32-
struct net_device *upper;
33-
struct mlx5e_priv *priv;
34-
u16 vport_num;
35-
36-
if (!mlx5e_eswitch_rep(dev))
37-
return 0;
80+
int ifindex = upper->ifindex;
81+
int err;
3882

39-
upper = info->upper_dev;
4083
if (!netif_is_bridge_master(upper))
4184
return 0;
4285

43-
esw = br_offloads->esw;
44-
priv = netdev_priv(dev);
45-
if (esw != priv->mdev->priv.eswitch)
86+
err = mlx5_esw_bridge_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
87+
&esw_owner_vhca_id);
88+
if (err)
4689
return 0;
4790

48-
rpriv = priv->ppriv;
49-
vport_num = rpriv->rep->vport;
50-
vport = mlx5_eswitch_get_vport(esw, vport_num);
51-
if (IS_ERR(vport))
52-
return PTR_ERR(vport);
53-
5491
extack = netdev_notifier_info_to_extack(&info->info);
5592

5693
return info->linking ?
57-
mlx5_esw_bridge_vport_link(upper->ifindex, br_offloads, vport, extack) :
58-
mlx5_esw_bridge_vport_unlink(upper->ifindex, br_offloads, vport, extack);
94+
mlx5_esw_bridge_vport_link(ifindex, vport_num, esw_owner_vhca_id, br_offloads,
95+
extack) :
96+
mlx5_esw_bridge_vport_unlink(ifindex, vport_num, esw_owner_vhca_id, br_offloads,
97+
extack);
5998
}
6099

61100
static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
@@ -75,87 +114,80 @@ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
75114
return notifier_from_errno(err);
76115
}
77116

78-
static int mlx5_esw_bridge_port_obj_add(struct net_device *dev,
79-
const void *ctx,
80-
const struct switchdev_obj *obj,
81-
struct netlink_ext_ack *extack)
117+
static int
118+
mlx5_esw_bridge_port_obj_add(struct net_device *dev,
119+
struct switchdev_notifier_port_obj_info *port_obj_info,
120+
struct mlx5_esw_bridge_offloads *br_offloads)
82121
{
122+
struct netlink_ext_ack *extack = switchdev_notifier_info_to_extack(&port_obj_info->info);
123+
const struct switchdev_obj *obj = port_obj_info->obj;
83124
const struct switchdev_obj_port_vlan *vlan;
84-
struct mlx5e_rep_priv *rpriv;
85-
struct mlx5_eswitch *esw;
86-
struct mlx5_vport *vport;
87-
struct mlx5e_priv *priv;
88-
u16 vport_num;
89-
int err = 0;
125+
u16 vport_num, esw_owner_vhca_id;
126+
int err;
90127

91-
priv = netdev_priv(dev);
92-
rpriv = priv->ppriv;
93-
vport_num = rpriv->rep->vport;
94-
esw = priv->mdev->priv.eswitch;
95-
vport = mlx5_eswitch_get_vport(esw, vport_num);
96-
if (IS_ERR(vport))
97-
return PTR_ERR(vport);
128+
err = mlx5_esw_bridge_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
129+
&esw_owner_vhca_id);
130+
if (err)
131+
return 0;
132+
133+
port_obj_info->handled = true;
98134

99135
switch (obj->id) {
100136
case SWITCHDEV_OBJ_ID_PORT_VLAN:
101137
vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
102-
err = mlx5_esw_bridge_port_vlan_add(vlan->vid, vlan->flags, esw, vport, extack);
138+
err = mlx5_esw_bridge_port_vlan_add(vport_num, esw_owner_vhca_id, vlan->vid,
139+
vlan->flags, br_offloads, extack);
103140
break;
104141
default:
105142
return -EOPNOTSUPP;
106143
}
107144
return err;
108145
}
109146

110-
static int mlx5_esw_bridge_port_obj_del(struct net_device *dev,
111-
const void *ctx,
112-
const struct switchdev_obj *obj)
147+
static int
148+
mlx5_esw_bridge_port_obj_del(struct net_device *dev,
149+
struct switchdev_notifier_port_obj_info *port_obj_info,
150+
struct mlx5_esw_bridge_offloads *br_offloads)
113151
{
152+
const struct switchdev_obj *obj = port_obj_info->obj;
114153
const struct switchdev_obj_port_vlan *vlan;
115-
struct mlx5e_rep_priv *rpriv;
116-
struct mlx5_eswitch *esw;
117-
struct mlx5_vport *vport;
118-
struct mlx5e_priv *priv;
119-
u16 vport_num;
154+
u16 vport_num, esw_owner_vhca_id;
155+
int err;
120156

121-
priv = netdev_priv(dev);
122-
rpriv = priv->ppriv;
123-
vport_num = rpriv->rep->vport;
124-
esw = priv->mdev->priv.eswitch;
125-
vport = mlx5_eswitch_get_vport(esw, vport_num);
126-
if (IS_ERR(vport))
127-
return PTR_ERR(vport);
157+
err = mlx5_esw_bridge_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
158+
&esw_owner_vhca_id);
159+
if (err)
160+
return 0;
161+
162+
port_obj_info->handled = true;
128163

129164
switch (obj->id) {
130165
case SWITCHDEV_OBJ_ID_PORT_VLAN:
131166
vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
132-
mlx5_esw_bridge_port_vlan_del(vlan->vid, esw, vport);
167+
mlx5_esw_bridge_port_vlan_del(vport_num, esw_owner_vhca_id, vlan->vid, br_offloads);
133168
break;
134169
default:
135170
return -EOPNOTSUPP;
136171
}
137172
return 0;
138173
}
139174

140-
static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
141-
const void *ctx,
142-
const struct switchdev_attr *attr,
143-
struct netlink_ext_ack *extack)
175+
static int
176+
mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
177+
struct switchdev_notifier_port_attr_info *port_attr_info,
178+
struct mlx5_esw_bridge_offloads *br_offloads)
144179
{
145-
struct mlx5e_rep_priv *rpriv;
146-
struct mlx5_eswitch *esw;
147-
struct mlx5_vport *vport;
148-
struct mlx5e_priv *priv;
149-
u16 vport_num;
150-
int err = 0;
180+
struct netlink_ext_ack *extack = switchdev_notifier_info_to_extack(&port_attr_info->info);
181+
const struct switchdev_attr *attr = port_attr_info->attr;
182+
u16 vport_num, esw_owner_vhca_id;
183+
int err;
151184

152-
priv = netdev_priv(dev);
153-
rpriv = priv->ppriv;
154-
vport_num = rpriv->rep->vport;
155-
esw = priv->mdev->priv.eswitch;
156-
vport = mlx5_eswitch_get_vport(esw, vport_num);
157-
if (IS_ERR(vport))
158-
return PTR_ERR(vport);
185+
err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
186+
&esw_owner_vhca_id);
187+
if (err)
188+
return 0;
189+
190+
port_attr_info->handled = true;
159191

160192
switch (attr->id) {
161193
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
@@ -167,10 +199,12 @@ static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
167199
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
168200
break;
169201
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
170-
err = mlx5_esw_bridge_ageing_time_set(attr->u.ageing_time, esw, vport);
202+
err = mlx5_esw_bridge_ageing_time_set(vport_num, esw_owner_vhca_id,
203+
attr->u.ageing_time, br_offloads);
171204
break;
172205
case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
173-
err = mlx5_esw_bridge_vlan_filtering_set(attr->u.vlan_filtering, esw, vport);
206+
err = mlx5_esw_bridge_vlan_filtering_set(vport_num, esw_owner_vhca_id,
207+
attr->u.vlan_filtering, br_offloads);
174208
break;
175209
default:
176210
err = -EOPNOTSUPP;
@@ -179,27 +213,24 @@ static int mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
179213
return err;
180214
}
181215

182-
static int mlx5_esw_bridge_event_blocking(struct notifier_block *unused,
216+
static int mlx5_esw_bridge_event_blocking(struct notifier_block *nb,
183217
unsigned long event, void *ptr)
184218
{
219+
struct mlx5_esw_bridge_offloads *br_offloads = container_of(nb,
220+
struct mlx5_esw_bridge_offloads,
221+
nb_blk);
185222
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
186223
int err;
187224

188225
switch (event) {
189226
case SWITCHDEV_PORT_OBJ_ADD:
190-
err = switchdev_handle_port_obj_add(dev, ptr,
191-
mlx5e_eswitch_rep,
192-
mlx5_esw_bridge_port_obj_add);
227+
err = mlx5_esw_bridge_port_obj_add(dev, ptr, br_offloads);
193228
break;
194229
case SWITCHDEV_PORT_OBJ_DEL:
195-
err = switchdev_handle_port_obj_del(dev, ptr,
196-
mlx5e_eswitch_rep,
197-
mlx5_esw_bridge_port_obj_del);
230+
err = mlx5_esw_bridge_port_obj_del(dev, ptr, br_offloads);
198231
break;
199232
case SWITCHDEV_PORT_ATTR_SET:
200-
err = switchdev_handle_port_attr_set(dev, ptr,
201-
mlx5e_eswitch_rep,
202-
mlx5_esw_bridge_port_obj_attr_set);
233+
err = mlx5_esw_bridge_port_obj_attr_set(dev, ptr, br_offloads);
203234
break;
204235
default:
205236
err = 0;
@@ -222,27 +253,27 @@ static void mlx5_esw_bridge_switchdev_fdb_event_work(struct work_struct *work)
222253
container_of(work, struct mlx5_bridge_switchdev_fdb_work, work);
223254
struct switchdev_notifier_fdb_info *fdb_info =
224255
&fdb_work->fdb_info;
256+
struct mlx5_esw_bridge_offloads *br_offloads;
225257
struct net_device *dev = fdb_work->dev;
226-
struct mlx5e_rep_priv *rpriv;
227-
struct mlx5_eswitch *esw;
228-
struct mlx5_vport *vport;
258+
u16 vport_num, esw_owner_vhca_id;
229259
struct mlx5e_priv *priv;
230-
u16 vport_num;
260+
int err;
231261

232262
rtnl_lock();
233263

234264
priv = netdev_priv(dev);
235-
rpriv = priv->ppriv;
236-
vport_num = rpriv->rep->vport;
237-
esw = priv->mdev->priv.eswitch;
238-
vport = mlx5_eswitch_get_vport(esw, vport_num);
239-
if (IS_ERR(vport))
265+
br_offloads = priv->mdev->priv.eswitch->br_offloads;
266+
err = mlx5_esw_bridge_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
267+
&esw_owner_vhca_id);
268+
if (err)
240269
goto out;
241270

242271
if (fdb_work->add)
243-
mlx5_esw_bridge_fdb_create(dev, esw, vport, fdb_info);
272+
mlx5_esw_bridge_fdb_create(dev, vport_num, esw_owner_vhca_id, br_offloads,
273+
fdb_info);
244274
else
245-
mlx5_esw_bridge_fdb_remove(dev, esw, vport, fdb_info);
275+
mlx5_esw_bridge_fdb_remove(dev, vport_num, esw_owner_vhca_id, br_offloads,
276+
fdb_info);
246277

247278
out:
248279
rtnl_unlock();
@@ -288,18 +319,10 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
288319
struct mlx5_bridge_switchdev_fdb_work *work;
289320
struct switchdev_notifier_info *info = ptr;
290321
struct net_device *upper;
291-
struct mlx5e_priv *priv;
292-
293-
if (!mlx5e_eswitch_rep(dev))
294-
return NOTIFY_DONE;
295-
priv = netdev_priv(dev);
296-
if (priv->mdev->priv.eswitch != br_offloads->esw)
297-
return NOTIFY_DONE;
298322

299323
if (event == SWITCHDEV_PORT_ATTR_SET) {
300-
int err = switchdev_handle_port_attr_set(dev, ptr,
301-
mlx5e_eswitch_rep,
302-
mlx5_esw_bridge_port_obj_attr_set);
324+
int err = mlx5_esw_bridge_port_obj_attr_set(dev, ptr, br_offloads);
325+
303326
return notifier_from_errno(err);
304327
}
305328

@@ -309,6 +332,11 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
309332
if (!netif_is_bridge_master(upper))
310333
return NOTIFY_DONE;
311334

335+
if (!mlx5e_eswitch_rep(dev))
336+
return NOTIFY_DONE;
337+
if (!mlx5_esw_bridge_dev_same_esw(dev, br_offloads->esw))
338+
return NOTIFY_DONE;
339+
312340
switch (event) {
313341
case SWITCHDEV_FDB_ADD_TO_DEVICE:
314342
case SWITCHDEV_FDB_DEL_TO_DEVICE:

0 commit comments

Comments
 (0)