return (struct mlx5e_ipsec_pol_entry *)x->xdo.offload_handle;
}
-static void mlx5e_ipsec_handle_tx_limit(struct work_struct *_work)
+static void mlx5e_ipsec_handle_sw_limits(struct work_struct *_work)
{
struct mlx5e_ipsec_dwork *dwork =
container_of(_work, struct mlx5e_ipsec_dwork, dwork.work);
return -EINVAL;
}
- if (x->lft.hard_byte_limit != XFRM_INF ||
- x->lft.soft_byte_limit != XFRM_INF) {
- NL_SET_ERR_MSG_MOD(extack, "Device doesn't support limits in bytes");
+ if (x->lft.soft_byte_limit >= x->lft.hard_byte_limit &&
+ x->lft.hard_byte_limit != XFRM_INF) {
+ /* XFRM stack doesn't prevent such configuration :(. */
+ NL_SET_ERR_MSG_MOD(extack, "Hard byte limit must be greater than soft one");
+ return -EINVAL;
+ }
+
+ if (!x->lft.soft_byte_limit || !x->lft.hard_byte_limit) {
+ NL_SET_ERR_MSG_MOD(extack, "Soft/hard byte limits can't be 0");
return -EINVAL;
}
if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
return 0;
- if (x->xso.dir != XFRM_DEV_OFFLOAD_OUT)
- return 0;
-
if (x->lft.soft_packet_limit == XFRM_INF &&
- x->lft.hard_packet_limit == XFRM_INF)
+ x->lft.hard_packet_limit == XFRM_INF &&
+ x->lft.soft_byte_limit == XFRM_INF &&
+ x->lft.hard_byte_limit == XFRM_INF)
return 0;
dwork = kzalloc(sizeof(*dwork), GFP_KERNEL);
return -ENOMEM;
dwork->sa_entry = sa_entry;
- INIT_DELAYED_WORK(&dwork->dwork, mlx5e_ipsec_handle_tx_limit);
+ INIT_DELAYED_WORK(&dwork->dwork, mlx5e_ipsec_handle_sw_limits);
sa_entry->dwork = dwork;
return 0;
}
setup_fte_no_frags(spec);
setup_fte_upper_proto_match(spec, &attrs->upspec);
- if (rx != ipsec->rx_esw)
- err = setup_modify_header(ipsec, attrs->type,
- sa_entry->ipsec_obj_id | BIT(31),
- XFRM_DEV_OFFLOAD_IN, &flow_act);
- else
- err = mlx5_esw_ipsec_rx_setup_modify_header(sa_entry, &flow_act);
+ if (!attrs->drop) {
+ if (rx != ipsec->rx_esw)
+ err = setup_modify_header(ipsec, attrs->type,
+ sa_entry->ipsec_obj_id | BIT(31),
+ XFRM_DEV_OFFLOAD_IN, &flow_act);
+ else
+ err = mlx5_esw_ipsec_rx_setup_modify_header(sa_entry, &flow_act);
- if (err)
- goto err_mod_header;
+ if (err)
+ goto err_mod_header;
+ }
switch (attrs->type) {
case XFRM_DEV_OFFLOAD_PACKET:
if (flow_act.pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, flow_act.pkt_reformat);
err_pkt_reformat:
- mlx5_modify_header_dealloc(mdev, flow_act.modify_hdr);
+ if (flow_act.modify_hdr)
+ mlx5_modify_header_dealloc(mdev, flow_act.modify_hdr);
err_mod_header:
kvfree(spec);
err_alloc:
return;
}
- mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
+ if (ipsec_rule->modify_hdr)
+ mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
mlx5_esw_ipsec_rx_id_mapping_remove(sa_entry);
rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type);
}