Skip to content

Commit 82f9378

Browse files
PatrisiousHaddadrleon
authored andcommitted
net/mlx5: Handle IPsec steering upon master unbind/bind
When the master device is unbinded, make sure to clean up all of the steering rules or flow tables that were created over the master, in order to allow proper unbinding of master, and for ethernet traffic to continue to work independently. Upon bringing master device back up and attaching the slave to it, checks if the slave already has IPsec configured and if so reconfigure the rules needed to support RoCE traffic. Note that while master device is unbound, the user is unable to configure IPsec again, since they are in a kind of illegal state in which they are in MPV mode but the slave has no master. However if IPsec was configured before hand, it will continue to work for ethernet traffic while master is unbound, and would continue to work for all traffic when the master is bound back again. Signed-off-by: Patrisious Haddad <[email protected]> Reviewed-by: Mark Bloch <[email protected]> Link: https://lore.kernel.org/r/8434e88912c588affe51b34669900382a132e873.1695296682.git.leon@kernel.org Signed-off-by: Leon Romanovsky <[email protected]>
1 parent f2f0231 commit 82f9378

File tree

8 files changed

+225
-32
lines changed

8 files changed

+225
-32
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ struct page_pool;
168168
#define mlx5e_state_dereference(priv, p) \
169169
rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock))
170170

171+
enum mlx5e_devcom_events {
172+
MPV_DEVCOM_MASTER_UP,
173+
MPV_DEVCOM_MASTER_DOWN,
174+
MPV_DEVCOM_IPSEC_MASTER_UP,
175+
MPV_DEVCOM_IPSEC_MASTER_DOWN,
176+
};
177+
171178
static inline u8 mlx5e_get_num_lag_ports(struct mlx5_core_dev *mdev)
172179
{
173180
if (mlx5_lag_is_lacp_owner(mdev))

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv)
850850

851851
xa_init_flags(&ipsec->sadb, XA_FLAGS_ALLOC);
852852
ipsec->mdev = priv->mdev;
853+
init_completion(&ipsec->comp);
853854
ipsec->wq = alloc_workqueue("mlx5e_ipsec: %s", WQ_UNBOUND, 0,
854855
priv->netdev->name);
855856
if (!ipsec->wq)

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
#define MLX5E_IPSEC_SADB_RX_BITS 10
4444
#define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L
4545

46-
#define MPV_DEVCOM_MASTER_UP 1
47-
4846
struct aes_gcm_keymat {
4947
u64 seq_iv;
5048

@@ -224,12 +222,20 @@ struct mlx5e_ipsec_tx_create_attr {
224222
enum mlx5_flow_namespace_type chains_ns;
225223
};
226224

225+
struct mlx5e_ipsec_mpv_work {
226+
int event;
227+
struct work_struct work;
228+
struct mlx5e_priv *slave_priv;
229+
struct mlx5e_priv *master_priv;
230+
};
231+
227232
struct mlx5e_ipsec {
228233
struct mlx5_core_dev *mdev;
229234
struct xarray sadb;
230235
struct mlx5e_ipsec_sw_stats sw_stats;
231236
struct mlx5e_ipsec_hw_stats hw_stats;
232237
struct workqueue_struct *wq;
238+
struct completion comp;
233239
struct mlx5e_flow_steering *fs;
234240
struct mlx5e_ipsec_rx *rx_ipv4;
235241
struct mlx5e_ipsec_rx *rx_ipv6;
@@ -241,6 +247,7 @@ struct mlx5e_ipsec {
241247
struct notifier_block netevent_nb;
242248
struct mlx5_ipsec_fs *roce;
243249
u8 is_uplink_rep: 1;
250+
struct mlx5e_ipsec_mpv_work mpv_work;
244251
};
245252

246253
struct mlx5e_ipsec_esn_state {
@@ -331,6 +338,10 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv,
331338

332339
void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
333340
struct mlx5_accel_esp_xfrm_attrs *attrs);
341+
void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,
342+
struct mlx5e_priv *master_priv);
343+
void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event);
344+
334345
static inline struct mlx5_core_dev *
335346
mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry)
336347
{
@@ -366,6 +377,15 @@ static inline u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
366377
{
367378
return 0;
368379
}
380+
381+
static inline void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,
382+
struct mlx5e_priv *master_priv)
383+
{
384+
}
385+
386+
static inline void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event)
387+
{
388+
}
369389
#endif
370390

371391
#endif /* __MLX5E_IPSEC_H__ */

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,83 @@ static int ipsec_miss_create(struct mlx5_core_dev *mdev,
229229
return err;
230230
}
231231

232+
static void handle_ipsec_rx_bringup(struct mlx5e_ipsec *ipsec, u32 family)
233+
{
234+
struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, XFRM_DEV_OFFLOAD_PACKET);
235+
struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(ipsec->fs, false);
236+
struct mlx5_flow_destination old_dest, new_dest;
237+
238+
old_dest = mlx5_ttc_get_default_dest(mlx5e_fs_get_ttc(ipsec->fs, false),
239+
family2tt(family));
240+
241+
mlx5_ipsec_fs_roce_rx_create(ipsec->mdev, ipsec->roce, ns, &old_dest, family,
242+
MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL, MLX5E_NIC_PRIO);
243+
244+
new_dest.ft = mlx5_ipsec_fs_roce_ft_get(ipsec->roce, family);
245+
new_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
246+
mlx5_modify_rule_destination(rx->status.rule, &new_dest, &old_dest);
247+
mlx5_modify_rule_destination(rx->sa.rule, &new_dest, &old_dest);
248+
}
249+
250+
static void handle_ipsec_rx_cleanup(struct mlx5e_ipsec *ipsec, u32 family)
251+
{
252+
struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, XFRM_DEV_OFFLOAD_PACKET);
253+
struct mlx5_flow_destination old_dest, new_dest;
254+
255+
old_dest.ft = mlx5_ipsec_fs_roce_ft_get(ipsec->roce, family);
256+
old_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
257+
new_dest = mlx5_ttc_get_default_dest(mlx5e_fs_get_ttc(ipsec->fs, false),
258+
family2tt(family));
259+
mlx5_modify_rule_destination(rx->sa.rule, &new_dest, &old_dest);
260+
mlx5_modify_rule_destination(rx->status.rule, &new_dest, &old_dest);
261+
262+
mlx5_ipsec_fs_roce_rx_destroy(ipsec->roce, family, ipsec->mdev);
263+
}
264+
265+
static void ipsec_mpv_work_handler(struct work_struct *_work)
266+
{
267+
struct mlx5e_ipsec_mpv_work *work = container_of(_work, struct mlx5e_ipsec_mpv_work, work);
268+
struct mlx5e_ipsec *ipsec = work->slave_priv->ipsec;
269+
270+
switch (work->event) {
271+
case MPV_DEVCOM_IPSEC_MASTER_UP:
272+
mutex_lock(&ipsec->tx->ft.mutex);
273+
if (ipsec->tx->ft.refcnt)
274+
mlx5_ipsec_fs_roce_tx_create(ipsec->mdev, ipsec->roce, ipsec->tx->ft.pol,
275+
true);
276+
mutex_unlock(&ipsec->tx->ft.mutex);
277+
278+
mutex_lock(&ipsec->rx_ipv4->ft.mutex);
279+
if (ipsec->rx_ipv4->ft.refcnt)
280+
handle_ipsec_rx_bringup(ipsec, AF_INET);
281+
mutex_unlock(&ipsec->rx_ipv4->ft.mutex);
282+
283+
mutex_lock(&ipsec->rx_ipv6->ft.mutex);
284+
if (ipsec->rx_ipv6->ft.refcnt)
285+
handle_ipsec_rx_bringup(ipsec, AF_INET6);
286+
mutex_unlock(&ipsec->rx_ipv6->ft.mutex);
287+
break;
288+
case MPV_DEVCOM_IPSEC_MASTER_DOWN:
289+
mutex_lock(&ipsec->tx->ft.mutex);
290+
if (ipsec->tx->ft.refcnt)
291+
mlx5_ipsec_fs_roce_tx_destroy(ipsec->roce, ipsec->mdev);
292+
mutex_unlock(&ipsec->tx->ft.mutex);
293+
294+
mutex_lock(&ipsec->rx_ipv4->ft.mutex);
295+
if (ipsec->rx_ipv4->ft.refcnt)
296+
handle_ipsec_rx_cleanup(ipsec, AF_INET);
297+
mutex_unlock(&ipsec->rx_ipv4->ft.mutex);
298+
299+
mutex_lock(&ipsec->rx_ipv6->ft.mutex);
300+
if (ipsec->rx_ipv6->ft.refcnt)
301+
handle_ipsec_rx_cleanup(ipsec, AF_INET6);
302+
mutex_unlock(&ipsec->rx_ipv6->ft.mutex);
303+
break;
304+
}
305+
306+
complete(&work->master_priv->ipsec->comp);
307+
}
308+
232309
static void ipsec_rx_ft_disconnect(struct mlx5e_ipsec *ipsec, u32 family)
233310
{
234311
struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
@@ -665,7 +742,7 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
665742
}
666743

667744
connect_roce:
668-
err = mlx5_ipsec_fs_roce_tx_create(mdev, roce, tx->ft.pol);
745+
err = mlx5_ipsec_fs_roce_tx_create(mdev, roce, tx->ft.pol, false);
669746
if (err)
670747
goto err_roce;
671748
return 0;
@@ -1942,6 +2019,8 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec,
19422019
xa_init_flags(&ipsec->rx_esw->ipsec_obj_id_map, XA_FLAGS_ALLOC1);
19432020
} else if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ROCE) {
19442021
ipsec->roce = mlx5_ipsec_fs_roce_init(mdev, devcom);
2022+
} else {
2023+
mlx5_core_warn(mdev, "IPsec was initialized without RoCE support\n");
19452024
}
19462025

19472026
return 0;
@@ -1988,3 +2067,33 @@ bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry)
19882067

19892068
return rx->allow_tunnel_mode;
19902069
}
2070+
2071+
void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,
2072+
struct mlx5e_priv *master_priv)
2073+
{
2074+
struct mlx5e_ipsec_mpv_work *work;
2075+
2076+
reinit_completion(&master_priv->ipsec->comp);
2077+
2078+
if (!slave_priv->ipsec) {
2079+
complete(&master_priv->ipsec->comp);
2080+
return;
2081+
}
2082+
2083+
work = &slave_priv->ipsec->mpv_work;
2084+
2085+
INIT_WORK(&work->work, ipsec_mpv_work_handler);
2086+
work->event = event;
2087+
work->slave_priv = slave_priv;
2088+
work->master_priv = master_priv;
2089+
queue_work(slave_priv->ipsec->wq, &work->work);
2090+
}
2091+
2092+
void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event)
2093+
{
2094+
if (!priv->ipsec)
2095+
return; /* IPsec not supported */
2096+
2097+
mlx5_devcom_send_event(priv->devcom, event, event, priv);
2098+
wait_for_completion(&priv->ipsec->comp);
2099+
}

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "en.h"
66
#include "ipsec.h"
77
#include "lib/crypto.h"
8+
#include "lib/ipsec_fs_roce.h"
89

910
enum {
1011
MLX5_IPSEC_ASO_REMOVE_FLOW_PKT_CNT_OFFSET,
@@ -63,7 +64,7 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
6364
caps |= MLX5_IPSEC_CAP_ESPINUDP;
6465
}
6566

66-
if (mlx5_get_roce_state(mdev) &&
67+
if (mlx5_get_roce_state(mdev) && mlx5_ipsec_fs_is_mpv_roce_supported(mdev) &&
6768
MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) & MLX5_FT_NIC_RX_2_NIC_RX_RDMA &&
6869
MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) & MLX5_FT_NIC_TX_RDMA_2_NIC_TX)
6970
caps |= MLX5_IPSEC_CAP_ROCE;

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,20 @@ static int mlx5e_devcom_event_mpv(int event, void *my_data, void *event_data)
183183
{
184184
struct mlx5e_priv *slave_priv = my_data;
185185

186-
mlx5_devcom_comp_set_ready(slave_priv->devcom, true);
186+
switch (event) {
187+
case MPV_DEVCOM_MASTER_UP:
188+
mlx5_devcom_comp_set_ready(slave_priv->devcom, true);
189+
break;
190+
case MPV_DEVCOM_MASTER_DOWN:
191+
/* no need for comp set ready false since we unregister after
192+
* and it hurts cleanup flow.
193+
*/
194+
break;
195+
case MPV_DEVCOM_IPSEC_MASTER_UP:
196+
case MPV_DEVCOM_IPSEC_MASTER_DOWN:
197+
mlx5e_ipsec_handle_mpv_event(event, my_data, event_data);
198+
break;
199+
}
187200

188201
return 0;
189202
}
@@ -198,15 +211,26 @@ static int mlx5e_devcom_init_mpv(struct mlx5e_priv *priv, u64 *data)
198211
if (IS_ERR_OR_NULL(priv->devcom))
199212
return -EOPNOTSUPP;
200213

201-
if (mlx5_core_is_mp_master(priv->mdev))
214+
if (mlx5_core_is_mp_master(priv->mdev)) {
202215
mlx5_devcom_send_event(priv->devcom, MPV_DEVCOM_MASTER_UP,
203216
MPV_DEVCOM_MASTER_UP, priv);
217+
mlx5e_ipsec_send_event(priv, MPV_DEVCOM_IPSEC_MASTER_UP);
218+
}
204219

205220
return 0;
206221
}
207222

208223
static void mlx5e_devcom_cleanup_mpv(struct mlx5e_priv *priv)
209224
{
225+
if (IS_ERR_OR_NULL(priv->devcom))
226+
return;
227+
228+
if (mlx5_core_is_mp_master(priv->mdev)) {
229+
mlx5_devcom_send_event(priv->devcom, MPV_DEVCOM_MASTER_DOWN,
230+
MPV_DEVCOM_MASTER_DOWN, priv);
231+
mlx5e_ipsec_send_event(priv, MPV_DEVCOM_IPSEC_MASTER_DOWN);
232+
}
233+
210234
mlx5_devcom_unregister_component(priv->devcom);
211235
}
212236

0 commit comments

Comments
 (0)