Skip to content

Commit 554f977

Browse files
Cosmin Ratiukuba-moo
Cosmin Ratiu
authored andcommittedJan 16, 2025
net/mlx5e: CT: Make mlx5_ct_fs_smfs_ct_validate_flow_rule reusable
This function checks whether a flow_rule has the right flow dissector keys and masks used for a connection tracking flow offload. It is currently used locally by the tc_ct smfs module, but is about to be used from another place, so this commit moves it to a better place, renames it to mlx5e_tc_ct_is_valid_flow_rule and drops the unused fs argument. Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com> Reviewed-by: Jianbo Liu <jianbol@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20250114130646.1937192-4-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 34eea5b commit 554f977

File tree

3 files changed

+82
-74
lines changed

3 files changed

+82
-74
lines changed
 

‎drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c

+1-74
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#define INIT_ERR_PREFIX "ct_fs_smfs init failed"
1414
#define ct_dbg(fmt, args...)\
1515
netdev_dbg(fs->netdev, "ct_fs_smfs debug: " fmt "\n", ##args)
16-
#define MLX5_CT_TCP_FLAGS_MASK cpu_to_be16(be32_to_cpu(TCP_FLAG_RST | TCP_FLAG_FIN) >> 16)
1716

1817
struct mlx5_ct_fs_smfs_matcher {
1918
struct mlx5dr_matcher *dr_matcher;
@@ -220,78 +219,6 @@ mlx5_ct_fs_smfs_destroy(struct mlx5_ct_fs *fs)
220219
mlx5_smfs_action_destroy(fs_smfs->fwd_action);
221220
}
222221

223-
static inline bool
224-
mlx5_tc_ct_valid_used_dissector_keys(const u64 used_keys)
225-
{
226-
#define DISS_BIT(name) BIT_ULL(FLOW_DISSECTOR_KEY_ ## name)
227-
const u64 basic_keys = DISS_BIT(BASIC) | DISS_BIT(CONTROL) |
228-
DISS_BIT(META);
229-
const u64 ipv4_tcp = basic_keys | DISS_BIT(IPV4_ADDRS) |
230-
DISS_BIT(PORTS) | DISS_BIT(TCP);
231-
const u64 ipv6_tcp = basic_keys | DISS_BIT(IPV6_ADDRS) |
232-
DISS_BIT(PORTS) | DISS_BIT(TCP);
233-
const u64 ipv4_udp = basic_keys | DISS_BIT(IPV4_ADDRS) |
234-
DISS_BIT(PORTS);
235-
const u64 ipv6_udp = basic_keys | DISS_BIT(IPV6_ADDRS) |
236-
DISS_BIT(PORTS);
237-
const u64 ipv4_gre = basic_keys | DISS_BIT(IPV4_ADDRS);
238-
const u64 ipv6_gre = basic_keys | DISS_BIT(IPV6_ADDRS);
239-
240-
return (used_keys == ipv4_tcp || used_keys == ipv4_udp || used_keys == ipv6_tcp ||
241-
used_keys == ipv6_udp || used_keys == ipv4_gre || used_keys == ipv6_gre);
242-
}
243-
244-
static bool
245-
mlx5_ct_fs_smfs_ct_validate_flow_rule(struct mlx5_ct_fs *fs, struct flow_rule *flow_rule)
246-
{
247-
struct flow_match_ipv4_addrs ipv4_addrs;
248-
struct flow_match_ipv6_addrs ipv6_addrs;
249-
struct flow_match_control control;
250-
struct flow_match_basic basic;
251-
struct flow_match_ports ports;
252-
struct flow_match_tcp tcp;
253-
254-
if (!mlx5_tc_ct_valid_used_dissector_keys(flow_rule->match.dissector->used_keys)) {
255-
ct_dbg("rule uses unexpected dissectors (0x%016llx)",
256-
flow_rule->match.dissector->used_keys);
257-
return false;
258-
}
259-
260-
flow_rule_match_basic(flow_rule, &basic);
261-
flow_rule_match_control(flow_rule, &control);
262-
flow_rule_match_ipv4_addrs(flow_rule, &ipv4_addrs);
263-
flow_rule_match_ipv6_addrs(flow_rule, &ipv6_addrs);
264-
if (basic.key->ip_proto != IPPROTO_GRE)
265-
flow_rule_match_ports(flow_rule, &ports);
266-
if (basic.key->ip_proto == IPPROTO_TCP)
267-
flow_rule_match_tcp(flow_rule, &tcp);
268-
269-
if (basic.mask->n_proto != htons(0xFFFF) ||
270-
(basic.key->n_proto != htons(ETH_P_IP) && basic.key->n_proto != htons(ETH_P_IPV6)) ||
271-
basic.mask->ip_proto != 0xFF ||
272-
(basic.key->ip_proto != IPPROTO_UDP && basic.key->ip_proto != IPPROTO_TCP &&
273-
basic.key->ip_proto != IPPROTO_GRE)) {
274-
ct_dbg("rule uses unexpected basic match (n_proto 0x%04x/0x%04x, ip_proto 0x%02x/0x%02x)",
275-
ntohs(basic.key->n_proto), ntohs(basic.mask->n_proto),
276-
basic.key->ip_proto, basic.mask->ip_proto);
277-
return false;
278-
}
279-
280-
if (basic.key->ip_proto != IPPROTO_GRE &&
281-
(ports.mask->src != htons(0xFFFF) || ports.mask->dst != htons(0xFFFF))) {
282-
ct_dbg("rule uses ports match (src 0x%04x, dst 0x%04x)",
283-
ports.mask->src, ports.mask->dst);
284-
return false;
285-
}
286-
287-
if (basic.key->ip_proto == IPPROTO_TCP && tcp.mask->flags != MLX5_CT_TCP_FLAGS_MASK) {
288-
ct_dbg("rule uses unexpected tcp match (flags 0x%02x)", tcp.mask->flags);
289-
return false;
290-
}
291-
292-
return true;
293-
}
294-
295222
static struct mlx5_ct_fs_rule *
296223
mlx5_ct_fs_smfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec,
297224
struct mlx5_flow_attr *attr, struct flow_rule *flow_rule)
@@ -304,7 +231,7 @@ mlx5_ct_fs_smfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec,
304231
int num_actions = 0, err;
305232
bool nat, tcp, ipv4, gre;
306233

307-
if (!mlx5_ct_fs_smfs_ct_validate_flow_rule(fs, flow_rule))
234+
if (!mlx5e_tc_ct_is_valid_flow_rule(fs->netdev, flow_rule))
308235
return ERR_PTR(-EOPNOTSUPP);
309236

310237
smfs_rule = kzalloc(sizeof(*smfs_rule), GFP_KERNEL);

‎drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c

+71
Original file line numberDiff line numberDiff line change
@@ -2430,3 +2430,74 @@ mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
24302430
atomic_inc(&ct_priv->debugfs.stats.rx_dropped);
24312431
return false;
24322432
}
2433+
2434+
static bool mlx5e_tc_ct_valid_used_dissector_keys(const u64 used_keys)
2435+
{
2436+
#define DISS_BIT(name) BIT_ULL(FLOW_DISSECTOR_KEY_ ## name)
2437+
const u64 basic_keys = DISS_BIT(BASIC) | DISS_BIT(CONTROL) |
2438+
DISS_BIT(META);
2439+
const u64 ipv4_tcp = basic_keys | DISS_BIT(IPV4_ADDRS) |
2440+
DISS_BIT(PORTS) | DISS_BIT(TCP);
2441+
const u64 ipv6_tcp = basic_keys | DISS_BIT(IPV6_ADDRS) |
2442+
DISS_BIT(PORTS) | DISS_BIT(TCP);
2443+
const u64 ipv4_udp = basic_keys | DISS_BIT(IPV4_ADDRS) |
2444+
DISS_BIT(PORTS);
2445+
const u64 ipv6_udp = basic_keys | DISS_BIT(IPV6_ADDRS) |
2446+
DISS_BIT(PORTS);
2447+
const u64 ipv4_gre = basic_keys | DISS_BIT(IPV4_ADDRS);
2448+
const u64 ipv6_gre = basic_keys | DISS_BIT(IPV6_ADDRS);
2449+
2450+
return (used_keys == ipv4_tcp || used_keys == ipv4_udp || used_keys == ipv6_tcp ||
2451+
used_keys == ipv6_udp || used_keys == ipv4_gre || used_keys == ipv6_gre);
2452+
}
2453+
2454+
bool mlx5e_tc_ct_is_valid_flow_rule(const struct net_device *dev, struct flow_rule *flow_rule)
2455+
{
2456+
struct flow_match_ipv4_addrs ipv4_addrs;
2457+
struct flow_match_ipv6_addrs ipv6_addrs;
2458+
struct flow_match_control control;
2459+
struct flow_match_basic basic;
2460+
struct flow_match_ports ports;
2461+
struct flow_match_tcp tcp;
2462+
2463+
if (!mlx5e_tc_ct_valid_used_dissector_keys(flow_rule->match.dissector->used_keys)) {
2464+
netdev_dbg(dev, "ct_debug: rule uses unexpected dissectors (0x%016llx)",
2465+
flow_rule->match.dissector->used_keys);
2466+
return false;
2467+
}
2468+
2469+
flow_rule_match_basic(flow_rule, &basic);
2470+
flow_rule_match_control(flow_rule, &control);
2471+
flow_rule_match_ipv4_addrs(flow_rule, &ipv4_addrs);
2472+
flow_rule_match_ipv6_addrs(flow_rule, &ipv6_addrs);
2473+
if (basic.key->ip_proto != IPPROTO_GRE)
2474+
flow_rule_match_ports(flow_rule, &ports);
2475+
if (basic.key->ip_proto == IPPROTO_TCP)
2476+
flow_rule_match_tcp(flow_rule, &tcp);
2477+
2478+
if (basic.mask->n_proto != htons(0xFFFF) ||
2479+
(basic.key->n_proto != htons(ETH_P_IP) && basic.key->n_proto != htons(ETH_P_IPV6)) ||
2480+
basic.mask->ip_proto != 0xFF ||
2481+
(basic.key->ip_proto != IPPROTO_UDP && basic.key->ip_proto != IPPROTO_TCP &&
2482+
basic.key->ip_proto != IPPROTO_GRE)) {
2483+
netdev_dbg(dev, "ct_debug: rule uses unexpected basic match (n_proto 0x%04x/0x%04x, ip_proto 0x%02x/0x%02x)",
2484+
ntohs(basic.key->n_proto), ntohs(basic.mask->n_proto),
2485+
basic.key->ip_proto, basic.mask->ip_proto);
2486+
return false;
2487+
}
2488+
2489+
if (basic.key->ip_proto != IPPROTO_GRE &&
2490+
(ports.mask->src != htons(0xFFFF) || ports.mask->dst != htons(0xFFFF))) {
2491+
netdev_dbg(dev, "ct_debug: rule uses ports match (src 0x%04x, dst 0x%04x)",
2492+
ports.mask->src, ports.mask->dst);
2493+
return false;
2494+
}
2495+
2496+
if (basic.key->ip_proto == IPPROTO_TCP && tcp.mask->flags != MLX5_CT_TCP_FLAGS_MASK) {
2497+
netdev_dbg(dev, "ct_debug: rule uses unexpected tcp match (flags 0x%02x)",
2498+
tcp.mask->flags);
2499+
return false;
2500+
}
2501+
2502+
return true;
2503+
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ bool
128128
mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
129129
struct sk_buff *skb, u8 zone_restore_id);
130130

131+
#define MLX5_CT_TCP_FLAGS_MASK cpu_to_be16(be32_to_cpu(TCP_FLAG_RST | TCP_FLAG_FIN) >> 16)
132+
bool mlx5e_tc_ct_is_valid_flow_rule(const struct net_device *dev, struct flow_rule *flow_rule);
133+
131134
#else /* CONFIG_MLX5_TC_CT */
132135

133136
static inline struct mlx5_tc_ct_priv *
@@ -202,5 +205,12 @@ mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
202205
return false;
203206
}
204207

208+
static inline bool
209+
mlx5e_tc_ct_is_valid_flow_rule(const struct net_device *dev,
210+
struct flow_rule *flow_rule)
211+
{
212+
return false;
213+
}
214+
205215
#endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
206216
#endif /* __MLX5_EN_TC_CT_H__ */

0 commit comments

Comments
 (0)
Please sign in to comment.