Skip to content

Commit 81f8fba

Browse files
raed-salemklassert
authored andcommitted
net/mlx5e: Add statistics for Rx/Tx IPsec offloaded flows
Add the following statistics: RX successfully IPsec flows: ipsec_rx_pkts : Number of packets passed Rx IPsec flow ipsec_rx_bytes : Number of bytes passed Rx IPsec flow Rx dropped IPsec policy packets: ipsec_rx_drop_pkts: Number of packets dropped in Rx datapath due to IPsec drop policy ipsec_rx_drop_bytes: Number of bytes dropped in Rx datapath due to IPsec drop policy TX successfully encrypted and encapsulated IPsec packets: ipsec_tx_pkts : Number of packets encrypted and encapsulated successfully ipsec_tx_bytes : Number of bytes encrypted and encapsulated successfully Tx dropped IPsec policy packets: ipsec_tx_drop_pkts: Number of packets dropped in Tx datapath due to IPsec drop policy ipsec_tx_drop_bytes: Number of bytes dropped in Tx datapath due to IPsec drop policy The above can be seen using: ethtool -S <ifc> |grep ipsec Signed-off-by: Raed Salem <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 18f38fd commit 81f8fba

File tree

5 files changed

+233
-24
lines changed

5 files changed

+233
-24
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ enum mlx5_ipsec_cap {
8787

8888
struct mlx5e_priv;
8989

90+
struct mlx5e_ipsec_hw_stats {
91+
u64 ipsec_rx_pkts;
92+
u64 ipsec_rx_bytes;
93+
u64 ipsec_rx_drop_pkts;
94+
u64 ipsec_rx_drop_bytes;
95+
u64 ipsec_tx_pkts;
96+
u64 ipsec_tx_bytes;
97+
u64 ipsec_tx_drop_pkts;
98+
u64 ipsec_tx_drop_bytes;
99+
};
100+
90101
struct mlx5e_ipsec_sw_stats {
91102
atomic64_t ipsec_rx_drop_sp_alloc;
92103
atomic64_t ipsec_rx_drop_sadb_miss;
@@ -111,6 +122,7 @@ struct mlx5e_ipsec {
111122
DECLARE_HASHTABLE(sadb_rx, MLX5E_IPSEC_SADB_RX_BITS);
112123
spinlock_t sadb_rx_lock; /* Protects sadb_rx */
113124
struct mlx5e_ipsec_sw_stats sw_stats;
125+
struct mlx5e_ipsec_hw_stats hw_stats;
114126
struct workqueue_struct *wq;
115127
struct mlx5e_flow_steering *fs;
116128
struct mlx5e_ipsec_rx *rx_ipv4;
@@ -200,6 +212,9 @@ void mlx5_accel_esp_modify_xfrm(struct mlx5e_ipsec_sa_entry *sa_entry,
200212
int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec);
201213
void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec);
202214

215+
void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv,
216+
void *ipsec_stats);
217+
203218
static inline struct mlx5_core_dev *
204219
mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry)
205220
{

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

Lines changed: 164 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99

1010
#define NUM_IPSEC_FTE BIT(15)
1111

12+
struct mlx5e_ipsec_fc {
13+
struct mlx5_fc *cnt;
14+
struct mlx5_fc *drop;
15+
};
16+
1217
struct mlx5e_ipsec_ft {
1318
struct mutex mutex; /* Protect changes to this struct */
1419
struct mlx5_flow_table *pol;
@@ -27,12 +32,14 @@ struct mlx5e_ipsec_rx {
2732
struct mlx5e_ipsec_miss pol;
2833
struct mlx5e_ipsec_miss sa;
2934
struct mlx5e_ipsec_rule status;
35+
struct mlx5e_ipsec_fc *fc;
3036
};
3137

3238
struct mlx5e_ipsec_tx {
3339
struct mlx5e_ipsec_ft ft;
3440
struct mlx5e_ipsec_miss pol;
3541
struct mlx5_flow_namespace *ns;
42+
struct mlx5e_ipsec_fc *fc;
3643
};
3744

3845
/* IPsec RX flow steering */
@@ -93,9 +100,10 @@ static int ipsec_status_rule(struct mlx5_core_dev *mdev,
93100

94101
/* create fte */
95102
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |
96-
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
103+
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
104+
MLX5_FLOW_CONTEXT_ACTION_COUNT;
97105
flow_act.modify_hdr = modify_hdr;
98-
fte = mlx5_add_flow_rules(rx->ft.status, spec, &flow_act, dest, 1);
106+
fte = mlx5_add_flow_rules(rx->ft.status, spec, &flow_act, dest, 2);
99107
if (IS_ERR(fte)) {
100108
err = PTR_ERR(fte);
101109
mlx5_core_err(mdev, "fail to add ipsec rx err copy rule err=%d\n", err);
@@ -178,7 +186,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
178186
{
179187
struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(ipsec->fs, false);
180188
struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
181-
struct mlx5_flow_destination dest;
189+
struct mlx5_flow_destination dest[2];
182190
struct mlx5_flow_table *ft;
183191
int err;
184192

@@ -189,8 +197,10 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
189197

190198
rx->ft.status = ft;
191199

192-
dest = mlx5_ttc_get_default_dest(ttc, family2tt(family));
193-
err = ipsec_status_rule(mdev, rx, &dest);
200+
dest[0] = mlx5_ttc_get_default_dest(ttc, family2tt(family));
201+
dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
202+
dest[1].counter_id = mlx5_fc_id(rx->fc->cnt);
203+
err = ipsec_status_rule(mdev, rx, dest);
194204
if (err)
195205
goto err_add;
196206

@@ -203,7 +213,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
203213
}
204214
rx->ft.sa = ft;
205215

206-
err = ipsec_miss_create(mdev, rx->ft.sa, &rx->sa, &dest);
216+
err = ipsec_miss_create(mdev, rx->ft.sa, &rx->sa, dest);
207217
if (err)
208218
goto err_fs;
209219

@@ -214,10 +224,10 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
214224
goto err_pol_ft;
215225
}
216226
rx->ft.pol = ft;
217-
memset(&dest, 0x00, sizeof(dest));
218-
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
219-
dest.ft = rx->ft.sa;
220-
err = ipsec_miss_create(mdev, rx->ft.pol, &rx->pol, &dest);
227+
memset(dest, 0x00, 2 * sizeof(*dest));
228+
dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
229+
dest[0].ft = rx->ft.sa;
230+
err = ipsec_miss_create(mdev, rx->ft.pol, &rx->pol, dest);
221231
if (err)
222232
goto err_pol_miss;
223233

@@ -605,6 +615,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
605615
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
606616
struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry);
607617
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
618+
struct mlx5_flow_destination dest = {};
608619
struct mlx5_flow_act flow_act = {};
609620
struct mlx5_flow_handle *rule;
610621
struct mlx5_flow_spec *spec;
@@ -647,8 +658,11 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
647658
flow_act.crypto.obj_id = sa_entry->ipsec_obj_id;
648659
flow_act.flags |= FLOW_ACT_NO_APPEND;
649660
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW |
650-
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT;
651-
rule = mlx5_add_flow_rules(tx->ft.sa, spec, &flow_act, NULL, 0);
661+
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
662+
MLX5_FLOW_CONTEXT_ACTION_COUNT;
663+
dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
664+
dest.counter_id = mlx5_fc_id(tx->fc->cnt);
665+
rule = mlx5_add_flow_rules(tx->ft.sa, spec, &flow_act, &dest, 1);
652666
if (IS_ERR(rule)) {
653667
err = PTR_ERR(rule);
654668
mlx5_core_err(mdev, "fail to add TX ipsec rule err=%d\n", err);
@@ -674,12 +688,12 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
674688
{
675689
struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;
676690
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);
677-
struct mlx5_flow_destination dest = {};
691+
struct mlx5_flow_destination dest[2] = {};
678692
struct mlx5_flow_act flow_act = {};
679693
struct mlx5_flow_handle *rule;
680694
struct mlx5_flow_spec *spec;
681695
struct mlx5e_ipsec_tx *tx;
682-
int err;
696+
int err, dstn = 0;
683697

684698
tx = tx_ft_get(mdev, pol_entry->ipsec);
685699
if (IS_ERR(tx))
@@ -703,7 +717,11 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
703717
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
704718
break;
705719
case XFRM_POLICY_BLOCK:
706-
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
720+
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
721+
MLX5_FLOW_CONTEXT_ACTION_COUNT;
722+
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
723+
dest[dstn].counter_id = mlx5_fc_id(tx->fc->drop);
724+
dstn++;
707725
break;
708726
default:
709727
WARN_ON(true);
@@ -712,9 +730,10 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
712730
}
713731

714732
flow_act.flags |= FLOW_ACT_NO_APPEND;
715-
dest.ft = tx->ft.sa;
716-
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
717-
rule = mlx5_add_flow_rules(tx->ft.pol, spec, &flow_act, &dest, 1);
733+
dest[dstn].ft = tx->ft.sa;
734+
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
735+
dstn++;
736+
rule = mlx5_add_flow_rules(tx->ft.pol, spec, &flow_act, dest, dstn);
718737
if (IS_ERR(rule)) {
719738
err = PTR_ERR(rule);
720739
mlx5_core_err(mdev, "fail to add TX ipsec rule err=%d\n", err);
@@ -736,12 +755,12 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
736755
{
737756
struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;
738757
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);
739-
struct mlx5_flow_destination dest = {};
758+
struct mlx5_flow_destination dest[2];
740759
struct mlx5_flow_act flow_act = {};
741760
struct mlx5_flow_handle *rule;
742761
struct mlx5_flow_spec *spec;
743762
struct mlx5e_ipsec_rx *rx;
744-
int err;
763+
int err, dstn = 0;
745764

746765
rx = rx_ft_get(mdev, pol_entry->ipsec, attrs->family);
747766
if (IS_ERR(rx))
@@ -765,7 +784,10 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
765784
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
766785
break;
767786
case XFRM_POLICY_BLOCK:
768-
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
787+
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
788+
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
789+
dest[dstn].counter_id = mlx5_fc_id(rx->fc->drop);
790+
dstn++;
769791
break;
770792
default:
771793
WARN_ON(true);
@@ -774,9 +796,10 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
774796
}
775797

776798
flow_act.flags |= FLOW_ACT_NO_APPEND;
777-
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
778-
dest.ft = rx->ft.sa;
779-
rule = mlx5_add_flow_rules(rx->ft.pol, spec, &flow_act, &dest, 1);
799+
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
800+
dest[dstn].ft = rx->ft.sa;
801+
dstn++;
802+
rule = mlx5_add_flow_rules(rx->ft.pol, spec, &flow_act, dest, dstn);
780803
if (IS_ERR(rule)) {
781804
err = PTR_ERR(rule);
782805
mlx5_core_err(mdev, "Fail to add RX IPsec policy rule err=%d\n", err);
@@ -794,6 +817,116 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
794817
return err;
795818
}
796819

820+
static void ipsec_fs_destroy_counters(struct mlx5e_ipsec *ipsec)
821+
{
822+
struct mlx5e_ipsec_rx *rx_ipv4 = ipsec->rx_ipv4;
823+
struct mlx5_core_dev *mdev = ipsec->mdev;
824+
struct mlx5e_ipsec_tx *tx = ipsec->tx;
825+
826+
mlx5_fc_destroy(mdev, tx->fc->drop);
827+
mlx5_fc_destroy(mdev, tx->fc->cnt);
828+
kfree(tx->fc);
829+
mlx5_fc_destroy(mdev, rx_ipv4->fc->drop);
830+
mlx5_fc_destroy(mdev, rx_ipv4->fc->cnt);
831+
kfree(rx_ipv4->fc);
832+
}
833+
834+
static int ipsec_fs_init_counters(struct mlx5e_ipsec *ipsec)
835+
{
836+
struct mlx5e_ipsec_rx *rx_ipv4 = ipsec->rx_ipv4;
837+
struct mlx5e_ipsec_rx *rx_ipv6 = ipsec->rx_ipv6;
838+
struct mlx5_core_dev *mdev = ipsec->mdev;
839+
struct mlx5e_ipsec_tx *tx = ipsec->tx;
840+
struct mlx5e_ipsec_fc *fc;
841+
struct mlx5_fc *counter;
842+
int err;
843+
844+
fc = kzalloc(sizeof(*rx_ipv4->fc), GFP_KERNEL);
845+
if (!fc)
846+
return -ENOMEM;
847+
848+
/* Both IPv4 and IPv6 point to same flow counters struct. */
849+
rx_ipv4->fc = fc;
850+
rx_ipv6->fc = fc;
851+
counter = mlx5_fc_create(mdev, false);
852+
if (IS_ERR(counter)) {
853+
err = PTR_ERR(counter);
854+
goto err_rx_cnt;
855+
}
856+
857+
fc->cnt = counter;
858+
counter = mlx5_fc_create(mdev, false);
859+
if (IS_ERR(counter)) {
860+
err = PTR_ERR(counter);
861+
goto err_rx_drop;
862+
}
863+
864+
fc->drop = counter;
865+
fc = kzalloc(sizeof(*tx->fc), GFP_KERNEL);
866+
if (!fc) {
867+
err = -ENOMEM;
868+
goto err_tx_fc;
869+
}
870+
871+
tx->fc = fc;
872+
counter = mlx5_fc_create(mdev, false);
873+
if (IS_ERR(counter)) {
874+
err = PTR_ERR(counter);
875+
goto err_tx_cnt;
876+
}
877+
878+
fc->cnt = counter;
879+
counter = mlx5_fc_create(mdev, false);
880+
if (IS_ERR(counter)) {
881+
err = PTR_ERR(counter);
882+
goto err_tx_drop;
883+
}
884+
885+
fc->drop = counter;
886+
return 0;
887+
888+
err_tx_drop:
889+
mlx5_fc_destroy(mdev, tx->fc->cnt);
890+
err_tx_cnt:
891+
kfree(tx->fc);
892+
err_tx_fc:
893+
mlx5_fc_destroy(mdev, rx_ipv4->fc->drop);
894+
err_rx_drop:
895+
mlx5_fc_destroy(mdev, rx_ipv4->fc->cnt);
896+
err_rx_cnt:
897+
kfree(rx_ipv4->fc);
898+
return err;
899+
}
900+
901+
void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void *ipsec_stats)
902+
{
903+
struct mlx5_core_dev *mdev = priv->mdev;
904+
struct mlx5e_ipsec *ipsec = priv->ipsec;
905+
struct mlx5e_ipsec_hw_stats *stats;
906+
struct mlx5e_ipsec_fc *fc;
907+
908+
stats = (struct mlx5e_ipsec_hw_stats *)ipsec_stats;
909+
910+
stats->ipsec_rx_pkts = 0;
911+
stats->ipsec_rx_bytes = 0;
912+
stats->ipsec_rx_drop_pkts = 0;
913+
stats->ipsec_rx_drop_bytes = 0;
914+
stats->ipsec_tx_pkts = 0;
915+
stats->ipsec_tx_bytes = 0;
916+
stats->ipsec_tx_drop_pkts = 0;
917+
stats->ipsec_tx_drop_bytes = 0;
918+
919+
fc = ipsec->rx_ipv4->fc;
920+
mlx5_fc_query(mdev, fc->cnt, &stats->ipsec_rx_pkts, &stats->ipsec_rx_bytes);
921+
mlx5_fc_query(mdev, fc->drop, &stats->ipsec_rx_drop_pkts,
922+
&stats->ipsec_rx_drop_bytes);
923+
924+
fc = ipsec->tx->fc;
925+
mlx5_fc_query(mdev, fc->cnt, &stats->ipsec_tx_pkts, &stats->ipsec_tx_bytes);
926+
mlx5_fc_query(mdev, fc->drop, &stats->ipsec_tx_drop_pkts,
927+
&stats->ipsec_tx_drop_bytes);
928+
}
929+
797930
int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
798931
{
799932
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
@@ -848,6 +981,7 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
848981
if (!ipsec->tx)
849982
return;
850983

984+
ipsec_fs_destroy_counters(ipsec);
851985
mutex_destroy(&ipsec->tx->ft.mutex);
852986
WARN_ON(ipsec->tx->ft.refcnt);
853987
kfree(ipsec->tx);
@@ -883,13 +1017,19 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)
8831017
if (!ipsec->rx_ipv6)
8841018
goto err_rx_ipv6;
8851019

1020+
err = ipsec_fs_init_counters(ipsec);
1021+
if (err)
1022+
goto err_counters;
1023+
8861024
mutex_init(&ipsec->tx->ft.mutex);
8871025
mutex_init(&ipsec->rx_ipv4->ft.mutex);
8881026
mutex_init(&ipsec->rx_ipv6->ft.mutex);
8891027
ipsec->tx->ns = ns;
8901028

8911029
return 0;
8921030

1031+
err_counters:
1032+
kfree(ipsec->rx_ipv6);
8931033
err_rx_ipv6:
8941034
kfree(ipsec->rx_ipv4);
8951035
err_rx_ipv4:

0 commit comments

Comments
 (0)