@@ -83,6 +83,31 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
83
83
return false;
84
84
}
85
85
86
+ static void mlx5e_ipsec_init_limits (struct mlx5e_ipsec_sa_entry * sa_entry ,
87
+ struct mlx5_accel_esp_xfrm_attrs * attrs )
88
+ {
89
+ struct xfrm_state * x = sa_entry -> x ;
90
+
91
+ attrs -> hard_packet_limit = x -> lft .hard_packet_limit ;
92
+ if (x -> lft .soft_packet_limit == XFRM_INF )
93
+ return ;
94
+
95
+ /* Hardware decrements hard_packet_limit counter through
96
+ * the operation. While fires an event when soft_packet_limit
97
+ * is reached. It emans that we need substitute the numbers
98
+ * in order to properly count soft limit.
99
+ *
100
+ * As an example:
101
+ * XFRM user sets soft limit is 2 and hard limit is 9 and
102
+ * expects to see soft event after 2 packets and hard event
103
+ * after 9 packets. In our case, the hard limit will be set
104
+ * to 9 and soft limit is comparator to 7 so user gets the
105
+ * soft event after 2 packeta
106
+ */
107
+ attrs -> soft_packet_limit =
108
+ x -> lft .hard_packet_limit - x -> lft .soft_packet_limit ;
109
+ }
110
+
86
111
static void
87
112
mlx5e_ipsec_build_accel_xfrm_attrs (struct mlx5e_ipsec_sa_entry * sa_entry ,
88
113
struct mlx5_accel_esp_xfrm_attrs * attrs )
@@ -134,6 +159,8 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
134
159
attrs -> family = x -> props .family ;
135
160
attrs -> type = x -> xso .type ;
136
161
attrs -> reqid = x -> props .reqid ;
162
+
163
+ mlx5e_ipsec_init_limits (sa_entry , attrs );
137
164
}
138
165
139
166
static inline int mlx5e_xfrm_validate_state (struct xfrm_state * x )
@@ -222,6 +249,21 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
222
249
netdev_info (netdev , "Cannot offload without reqid\n" );
223
250
return - EINVAL ;
224
251
}
252
+
253
+ if (x -> lft .hard_byte_limit != XFRM_INF ||
254
+ x -> lft .soft_byte_limit != XFRM_INF ) {
255
+ netdev_info (netdev ,
256
+ "Device doesn't support limits in bytes\n" );
257
+ return - EINVAL ;
258
+ }
259
+
260
+ if (x -> lft .soft_packet_limit >= x -> lft .hard_packet_limit &&
261
+ x -> lft .hard_packet_limit != XFRM_INF ) {
262
+ /* XFRM stack doesn't prevent such configuration :(. */
263
+ netdev_info (netdev ,
264
+ "Hard packet limit must be greater than soft one\n" );
265
+ return - EINVAL ;
266
+ }
225
267
}
226
268
return 0 ;
227
269
}
@@ -415,6 +457,26 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)
415
457
queue_work (sa_entry -> ipsec -> wq , & modify_work -> work );
416
458
}
417
459
460
+ static void mlx5e_xfrm_update_curlft (struct xfrm_state * x )
461
+ {
462
+ struct mlx5e_ipsec_sa_entry * sa_entry = to_ipsec_sa_entry (x );
463
+ int err ;
464
+
465
+ lockdep_assert_held (& x -> lock );
466
+
467
+ if (sa_entry -> attrs .soft_packet_limit == XFRM_INF )
468
+ /* Limits are not configured, as soft limit
469
+ * must be lowever than hard limit.
470
+ */
471
+ return ;
472
+
473
+ err = mlx5e_ipsec_aso_query (sa_entry );
474
+ if (err )
475
+ return ;
476
+
477
+ mlx5e_ipsec_aso_update_curlft (sa_entry , & x -> curlft .packets );
478
+ }
479
+
418
480
static int mlx5e_xfrm_validate_policy (struct xfrm_policy * x )
419
481
{
420
482
struct net_device * netdev = x -> xdo .real_dev ;
@@ -526,6 +588,7 @@ static const struct xfrmdev_ops mlx5e_ipsec_packet_xfrmdev_ops = {
526
588
.xdo_dev_offload_ok = mlx5e_ipsec_offload_ok ,
527
589
.xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state ,
528
590
591
+ .xdo_dev_state_update_curlft = mlx5e_xfrm_update_curlft ,
529
592
.xdo_dev_policy_add = mlx5e_xfrm_add_policy ,
530
593
.xdo_dev_policy_free = mlx5e_xfrm_free_policy ,
531
594
};
0 commit comments