1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2021 Xilinx, Inc.
11 #include "sfc_dp_rx.h"
12 #include "sfc_flow_tunnel.h"
16 sfc_flow_tunnel_is_supported(struct sfc_adapter *sa)
18 SFC_ASSERT(sfc_adapter_is_locked(sa));
20 return ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_MARK) != 0 &&
21 sa->mae.status == SFC_MAE_STATUS_SUPPORTED);
25 sfc_flow_tunnel_is_active(struct sfc_adapter *sa)
27 SFC_ASSERT(sfc_adapter_is_locked(sa));
29 return ((sa->negotiated_rx_metadata &
30 RTE_ETH_RX_METADATA_TUNNEL_ID) != 0);
33 struct sfc_flow_tunnel *
34 sfc_flow_tunnel_pick(struct sfc_adapter *sa, uint32_t ft_mark)
36 uint32_t tunnel_mark = SFC_FT_GET_TUNNEL_MARK(ft_mark);
38 SFC_ASSERT(sfc_adapter_is_locked(sa));
40 if (tunnel_mark != SFC_FT_TUNNEL_MARK_INVALID) {
41 sfc_ft_id_t ft_id = SFC_FT_TUNNEL_MARK_TO_ID(tunnel_mark);
42 struct sfc_flow_tunnel *ft = &sa->flow_tunnels[ft_id];
53 sfc_flow_tunnel_detect_jump_rule(struct sfc_adapter *sa,
54 const struct rte_flow_action *actions,
55 struct sfc_flow_spec_mae *spec,
56 struct rte_flow_error *error)
58 const struct rte_flow_action_mark *action_mark = NULL;
59 const struct rte_flow_action_jump *action_jump = NULL;
60 struct sfc_flow_tunnel *ft;
64 SFC_ASSERT(sfc_adapter_is_locked(sa));
66 if (!sfc_flow_tunnel_is_active(sa)) {
67 /* Tunnel-related actions (if any) will be turned down later. */
71 if (actions == NULL) {
72 rte_flow_error_set(error, EINVAL,
73 RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
78 for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
79 if (actions->type == RTE_FLOW_ACTION_TYPE_VOID)
82 if (actions->conf == NULL) {
87 switch (actions->type) {
88 case RTE_FLOW_ACTION_TYPE_MARK:
89 if (action_mark == NULL) {
90 action_mark = actions->conf;
91 ft_mark = action_mark->id;
96 case RTE_FLOW_ACTION_TYPE_JUMP:
97 if (action_jump == NULL) {
98 action_jump = actions->conf;
99 if (action_jump->group != 0)
111 ft = sfc_flow_tunnel_pick(sa, ft_mark);
112 if (ft != NULL && action_jump != 0) {
113 sfc_dbg(sa, "tunnel offload: JUMP: detected");
116 /* The loop above might have spotted wrong actions. */
117 sfc_err(sa, "tunnel offload: JUMP: invalid actions: %s",
122 if (ft->refcnt == 0) {
123 sfc_err(sa, "tunnel offload: JUMP: tunnel=%u does not exist",
129 if (ft->jump_rule_is_set) {
130 sfc_err(sa, "tunnel offload: JUMP: already exists in tunnel=%u",
136 spec->ft_rule_type = SFC_FT_RULE_JUMP;
143 return rte_flow_error_set(error, rc,
144 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
145 "tunnel offload: JUMP: preparsing failed");