1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. */
3
4 #include "en_tc.h"
5 #include "en/tc_ct.h"
6 #include "en/tc/ct_fs.h"
7
8 #define ct_dbg(fmt, args...)\
9 netdev_dbg(fs->netdev, "ct_fs_dmfs debug: " fmt "\n", ##args)
10
11 struct mlx5_ct_fs_dmfs_rule {
12 struct mlx5_ct_fs_rule fs_rule;
13 struct mlx5_flow_handle *rule;
14 struct mlx5_flow_attr *attr;
15 };
16
17 static int
mlx5_ct_fs_dmfs_init(struct mlx5_ct_fs * fs,struct mlx5_flow_table * ct,struct mlx5_flow_table * ct_nat,struct mlx5_flow_table * post_ct)18 mlx5_ct_fs_dmfs_init(struct mlx5_ct_fs *fs, struct mlx5_flow_table *ct,
19 struct mlx5_flow_table *ct_nat, struct mlx5_flow_table *post_ct)
20 {
21 return 0;
22 }
23
24 static void
mlx5_ct_fs_dmfs_destroy(struct mlx5_ct_fs * fs)25 mlx5_ct_fs_dmfs_destroy(struct mlx5_ct_fs *fs)
26 {
27 }
28
29 static struct mlx5_ct_fs_rule *
mlx5_ct_fs_dmfs_ct_rule_add(struct mlx5_ct_fs * fs,struct mlx5_flow_spec * spec,struct mlx5_flow_attr * attr,struct flow_rule * flow_rule)30 mlx5_ct_fs_dmfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec,
31 struct mlx5_flow_attr *attr, struct flow_rule *flow_rule)
32 {
33 struct mlx5e_priv *priv = netdev_priv(fs->netdev);
34 struct mlx5_ct_fs_dmfs_rule *dmfs_rule;
35 int err;
36
37 dmfs_rule = kzalloc(sizeof(*dmfs_rule), GFP_KERNEL);
38 if (!dmfs_rule)
39 return ERR_PTR(-ENOMEM);
40
41 dmfs_rule->rule = mlx5_tc_rule_insert(priv, spec, attr);
42 if (IS_ERR(dmfs_rule->rule)) {
43 err = PTR_ERR(dmfs_rule->rule);
44 ct_dbg("Failed to add ct entry fs rule");
45 goto err_insert;
46 }
47
48 dmfs_rule->attr = attr;
49
50 return &dmfs_rule->fs_rule;
51
52 err_insert:
53 kfree(dmfs_rule);
54 return ERR_PTR(err);
55 }
56
57 static void
mlx5_ct_fs_dmfs_ct_rule_del(struct mlx5_ct_fs * fs,struct mlx5_ct_fs_rule * fs_rule)58 mlx5_ct_fs_dmfs_ct_rule_del(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule)
59 {
60 struct mlx5_ct_fs_dmfs_rule *dmfs_rule = container_of(fs_rule,
61 struct mlx5_ct_fs_dmfs_rule,
62 fs_rule);
63
64 mlx5_tc_rule_delete(netdev_priv(fs->netdev), dmfs_rule->rule, dmfs_rule->attr);
65 kfree(dmfs_rule);
66 }
67
mlx5_ct_fs_dmfs_ct_rule_update(struct mlx5_ct_fs * fs,struct mlx5_ct_fs_rule * fs_rule,struct mlx5_flow_spec * spec,struct mlx5_flow_attr * attr)68 static int mlx5_ct_fs_dmfs_ct_rule_update(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule,
69 struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr)
70 {
71 struct mlx5_ct_fs_dmfs_rule *dmfs_rule = container_of(fs_rule,
72 struct mlx5_ct_fs_dmfs_rule,
73 fs_rule);
74 struct mlx5e_priv *priv = netdev_priv(fs->netdev);
75 struct mlx5_flow_handle *rule;
76
77 rule = mlx5_tc_rule_insert(priv, spec, attr);
78 if (IS_ERR(rule))
79 return PTR_ERR(rule);
80 mlx5_tc_rule_delete(priv, dmfs_rule->rule, dmfs_rule->attr);
81
82 dmfs_rule->rule = rule;
83 dmfs_rule->attr = attr;
84
85 return 0;
86 }
87
88 static struct mlx5_ct_fs_ops dmfs_ops = {
89 .ct_rule_add = mlx5_ct_fs_dmfs_ct_rule_add,
90 .ct_rule_del = mlx5_ct_fs_dmfs_ct_rule_del,
91 .ct_rule_update = mlx5_ct_fs_dmfs_ct_rule_update,
92
93 .init = mlx5_ct_fs_dmfs_init,
94 .destroy = mlx5_ct_fs_dmfs_destroy,
95 };
96
mlx5_ct_fs_dmfs_ops_get(void)97 struct mlx5_ct_fs_ops *mlx5_ct_fs_dmfs_ops_get(void)
98 {
99 return &dmfs_ops;
100 }
101