@@ -41,46 +41,88 @@ static bool mlx5_esw_bridge_dev_same_hw(struct net_device *dev, struct mlx5_eswi
4141 return system_guid == esw_system_guid ;
4242}
4343
44- static int mlx5_esw_bridge_vport_num_vhca_id_get (struct net_device * dev , struct mlx5_eswitch * esw ,
45- u16 * vport_num , u16 * esw_owner_vhca_id )
44+ static struct net_device *
45+ mlx5_esw_bridge_lag_rep_get (struct net_device * dev , struct mlx5_eswitch * esw )
46+ {
47+ struct net_device * lower ;
48+ struct list_head * iter ;
49+
50+ netdev_for_each_lower_dev (dev , lower , iter ) {
51+ struct mlx5_core_dev * mdev ;
52+ struct mlx5e_priv * priv ;
53+
54+ if (!mlx5e_eswitch_rep (lower ))
55+ continue ;
56+
57+ priv = netdev_priv (lower );
58+ mdev = priv -> mdev ;
59+ if (mlx5_lag_is_shared_fdb (mdev ) && mlx5_esw_bridge_dev_same_esw (lower , esw ))
60+ return lower ;
61+ }
62+
63+ return NULL ;
64+ }
65+
66+ static struct net_device *
67+ mlx5_esw_bridge_rep_vport_num_vhca_id_get (struct net_device * dev , struct mlx5_eswitch * esw ,
68+ u16 * vport_num , u16 * esw_owner_vhca_id )
4669{
4770 struct mlx5e_rep_priv * rpriv ;
4871 struct mlx5e_priv * priv ;
4972
50- if (!mlx5e_eswitch_rep (dev ) || !mlx5_esw_bridge_dev_same_hw (dev , esw ))
51- return - ENODEV ;
73+ if (netif_is_lag_master (dev ))
74+ dev = mlx5_esw_bridge_lag_rep_get (dev , esw );
75+
76+ if (!dev || !mlx5e_eswitch_rep (dev ) || !mlx5_esw_bridge_dev_same_hw (dev , esw ))
77+ return NULL ;
5278
5379 priv = netdev_priv (dev );
5480 rpriv = priv -> ppriv ;
5581 * vport_num = rpriv -> rep -> vport ;
5682 * esw_owner_vhca_id = MLX5_CAP_GEN (priv -> mdev , vhca_id );
57- return 0 ;
83+ return dev ;
5884}
5985
60- static int
86+ static struct net_device *
6187mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (struct net_device * dev , struct mlx5_eswitch * esw ,
6288 u16 * vport_num , u16 * esw_owner_vhca_id )
6389{
6490 struct net_device * lower_dev ;
6591 struct list_head * iter ;
6692
67- if (mlx5e_eswitch_rep (dev ))
68- return mlx5_esw_bridge_vport_num_vhca_id_get (dev , esw , vport_num ,
69- esw_owner_vhca_id );
93+ if (netif_is_lag_master ( dev ) || mlx5e_eswitch_rep (dev ))
94+ return mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , esw , vport_num ,
95+ esw_owner_vhca_id );
7096
7197 netdev_for_each_lower_dev (dev , lower_dev , iter ) {
72- int err ;
98+ struct net_device * rep ;
7399
74100 if (netif_is_bridge_master (lower_dev ))
75101 continue ;
76102
77- err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (lower_dev , esw , vport_num ,
103+ rep = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (lower_dev , esw , vport_num ,
78104 esw_owner_vhca_id );
79- if (! err )
80- return 0 ;
105+ if (rep )
106+ return rep ;
81107 }
82108
83- return - ENODEV ;
109+ return NULL ;
110+ }
111+
112+ static bool mlx5_esw_bridge_is_local (struct net_device * dev , struct net_device * rep ,
113+ struct mlx5_eswitch * esw )
114+ {
115+ struct mlx5_core_dev * mdev ;
116+ struct mlx5e_priv * priv ;
117+
118+ if (!mlx5_esw_bridge_dev_same_esw (rep , esw ))
119+ return false;
120+
121+ priv = netdev_priv (rep );
122+ mdev = priv -> mdev ;
123+ if (netif_is_lag_master (dev ))
124+ return mlx5_lag_is_shared_fdb (mdev ) && mlx5_lag_is_master (mdev );
125+ return true;
84126}
85127
86128static int mlx5_esw_bridge_port_changeupper (struct notifier_block * nb , void * ptr )
@@ -90,8 +132,8 @@ static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr
90132 netdev_nb );
91133 struct net_device * dev = netdev_notifier_info_to_dev (ptr );
92134 struct netdev_notifier_changeupper_info * info = ptr ;
135+ struct net_device * upper = info -> upper_dev , * rep ;
93136 struct mlx5_eswitch * esw = br_offloads -> esw ;
94- struct net_device * upper = info -> upper_dev ;
95137 u16 vport_num , esw_owner_vhca_id ;
96138 struct netlink_ext_ack * extack ;
97139 int ifindex = upper -> ifindex ;
@@ -100,20 +142,19 @@ static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr
100142 if (!netif_is_bridge_master (upper ))
101143 return 0 ;
102144
103- err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
104- & esw_owner_vhca_id );
105- if (err )
145+ rep = mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , esw , & vport_num , & esw_owner_vhca_id );
146+ if (!rep )
106147 return 0 ;
107148
108149 extack = netdev_notifier_info_to_extack (& info -> info );
109150
110- if (mlx5_esw_bridge_dev_same_esw (dev , esw ))
151+ if (mlx5_esw_bridge_is_local (dev , rep , esw ))
111152 err = info -> linking ?
112153 mlx5_esw_bridge_vport_link (ifindex , vport_num , esw_owner_vhca_id ,
113154 br_offloads , extack ) :
114155 mlx5_esw_bridge_vport_unlink (ifindex , vport_num , esw_owner_vhca_id ,
115156 br_offloads , extack );
116- else if (mlx5_esw_bridge_dev_same_hw (dev , esw ))
157+ else if (mlx5_esw_bridge_dev_same_hw (rep , esw ))
117158 err = info -> linking ?
118159 mlx5_esw_bridge_vport_peer_link (ifindex , vport_num , esw_owner_vhca_id ,
119160 br_offloads , extack ) :
@@ -151,9 +192,8 @@ mlx5_esw_bridge_port_obj_add(struct net_device *dev,
151192 u16 vport_num , esw_owner_vhca_id ;
152193 int err ;
153194
154- err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
155- & esw_owner_vhca_id );
156- if (err )
195+ if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
196+ & esw_owner_vhca_id ))
157197 return 0 ;
158198
159199 port_obj_info -> handled = true;
@@ -178,11 +218,9 @@ mlx5_esw_bridge_port_obj_del(struct net_device *dev,
178218 const struct switchdev_obj * obj = port_obj_info -> obj ;
179219 const struct switchdev_obj_port_vlan * vlan ;
180220 u16 vport_num , esw_owner_vhca_id ;
181- int err ;
182221
183- err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
184- & esw_owner_vhca_id );
185- if (err )
222+ if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
223+ & esw_owner_vhca_id ))
186224 return 0 ;
187225
188226 port_obj_info -> handled = true;
@@ -208,9 +246,8 @@ mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
208246 u16 vport_num , esw_owner_vhca_id ;
209247 int err ;
210248
211- err = mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
212- & esw_owner_vhca_id );
213- if (err )
249+ if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
250+ & esw_owner_vhca_id ))
214251 return 0 ;
215252
216253 port_attr_info -> handled = true;
@@ -283,13 +320,11 @@ static void mlx5_esw_bridge_switchdev_fdb_event_work(struct work_struct *work)
283320 fdb_work -> br_offloads ;
284321 struct net_device * dev = fdb_work -> dev ;
285322 u16 vport_num , esw_owner_vhca_id ;
286- int err ;
287323
288324 rtnl_lock ();
289325
290- err = mlx5_esw_bridge_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
291- & esw_owner_vhca_id );
292- if (err )
326+ if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , br_offloads -> esw , & vport_num ,
327+ & esw_owner_vhca_id ))
293328 goto out ;
294329
295330 if (fdb_work -> add )
@@ -343,8 +378,10 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
343378 struct net_device * dev = switchdev_notifier_info_to_dev (ptr );
344379 struct switchdev_notifier_fdb_info * fdb_info ;
345380 struct mlx5_bridge_switchdev_fdb_work * work ;
381+ struct mlx5_eswitch * esw = br_offloads -> esw ;
346382 struct switchdev_notifier_info * info = ptr ;
347- struct net_device * upper ;
383+ u16 vport_num , esw_owner_vhca_id ;
384+ struct net_device * upper , * rep ;
348385
349386 if (event == SWITCHDEV_PORT_ATTR_SET ) {
350387 int err = mlx5_esw_bridge_port_obj_attr_set (dev , ptr , br_offloads );
@@ -358,13 +395,25 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
358395 if (!netif_is_bridge_master (upper ))
359396 return NOTIFY_DONE ;
360397
361- if (!mlx5e_eswitch_rep (dev ))
398+ rep = mlx5_esw_bridge_rep_vport_num_vhca_id_get (dev , esw , & vport_num , & esw_owner_vhca_id );
399+ if (!rep )
362400 return NOTIFY_DONE ;
363401
364402 switch (event ) {
403+ case SWITCHDEV_FDB_ADD_TO_BRIDGE :
404+ /* only handle the event on native eswtich of representor */
405+ if (!mlx5_esw_bridge_is_local (dev , rep , esw ))
406+ break ;
407+
408+ fdb_info = container_of (info ,
409+ struct switchdev_notifier_fdb_info ,
410+ info );
411+ mlx5_esw_bridge_fdb_update_used (dev , vport_num , esw_owner_vhca_id , br_offloads ,
412+ fdb_info );
413+ break ;
365414 case SWITCHDEV_FDB_DEL_TO_BRIDGE :
366- /* only handle the event when source is on another eswitch */
367- if (mlx5_esw_bridge_dev_same_esw (dev , br_offloads -> esw ))
415+ /* only handle the event on peers */
416+ if (mlx5_esw_bridge_is_local (dev , rep , esw ))
368417 break ;
369418 fallthrough ;
370419 case SWITCHDEV_FDB_ADD_TO_DEVICE :
0 commit comments