Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "bnxt.h"
7 : : #include "bnxt_ulp.h"
8 : : #include "ulp_tun.h"
9 : : #include "ulp_utils.h"
10 : :
11 : : /* returns negative on error, 1 if new entry is allocated or zero if old */
12 : : int32_t
13 : 0 : ulp_app_tun_search_entry(struct bnxt_ulp_context *ulp_ctx,
14 : : struct rte_flow_tunnel *app_tunnel,
15 : : struct bnxt_flow_app_tun_ent **tun_entry)
16 : : {
17 : : struct bnxt_flow_app_tun_ent *tun_ent_list;
18 : : int32_t i, rc = 0, free_entry = -1;
19 : :
20 : 0 : tun_ent_list = bnxt_ulp_cntxt_ptr2_app_tun_list_get(ulp_ctx);
21 [ # # ]: 0 : if (!tun_ent_list) {
22 : 0 : BNXT_TF_DBG(ERR, "unable to get the app tunnel list\n");
23 : 0 : return -EINVAL;
24 : : }
25 : :
26 [ # # ]: 0 : for (i = 0; i < BNXT_ULP_MAX_TUN_CACHE_ENTRIES; i++) {
27 [ # # ]: 0 : if (!tun_ent_list[i].ref_cnt) {
28 [ # # ]: 0 : if (free_entry < 0)
29 : : free_entry = i;
30 : : } else {
31 [ # # ]: 0 : if (!memcmp(&tun_ent_list[i].app_tunnel,
32 : : app_tunnel,
33 : : sizeof(struct rte_flow_tunnel))) {
34 : 0 : *tun_entry = &tun_ent_list[i];
35 : 0 : tun_ent_list[free_entry].ref_cnt++;
36 : 0 : return rc;
37 : : }
38 : : }
39 : : }
40 [ # # ]: 0 : if (free_entry >= 0) {
41 : 0 : *tun_entry = &tun_ent_list[free_entry];
42 : 0 : memcpy(&tun_ent_list[free_entry].app_tunnel, app_tunnel,
43 : : sizeof(struct rte_flow_tunnel));
44 : 0 : tun_ent_list[free_entry].ref_cnt = 1;
45 : : rc = 1;
46 : : } else {
47 : 0 : BNXT_TF_DBG(ERR, "ulp app tunnel list is full\n");
48 : 0 : return -ENOMEM;
49 : : }
50 : :
51 : 0 : return rc;
52 : : }
53 : :
54 : : void
55 : 0 : ulp_app_tun_entry_delete(struct bnxt_flow_app_tun_ent *tun_entry)
56 : : {
57 [ # # ]: 0 : if (tun_entry) {
58 [ # # ]: 0 : if (tun_entry->ref_cnt) {
59 : 0 : tun_entry->ref_cnt--;
60 [ # # ]: 0 : if (!tun_entry->ref_cnt)
61 : : memset(tun_entry, 0,
62 : : sizeof(struct bnxt_flow_app_tun_ent));
63 : : }
64 : : }
65 : 0 : }
66 : :
67 : : int32_t
68 : 0 : ulp_app_tun_entry_set_decap_action(struct bnxt_flow_app_tun_ent *tun_entry)
69 : : {
70 [ # # ]: 0 : if (!tun_entry)
71 : : return -EINVAL;
72 : :
73 : 0 : tun_entry->action.type = (typeof(tun_entry->action.type))
74 : : BNXT_RTE_FLOW_ACTION_TYPE_VXLAN_DECAP;
75 : 0 : tun_entry->action.conf = tun_entry;
76 : 0 : return 0;
77 : : }
78 : :
79 : : int32_t
80 : 0 : ulp_app_tun_entry_set_decap_item(struct bnxt_flow_app_tun_ent *tun_entry)
81 : : {
82 [ # # ]: 0 : if (!tun_entry)
83 : : return -EINVAL;
84 : :
85 : 0 : tun_entry->item.type = (typeof(tun_entry->item.type))
86 : : BNXT_RTE_FLOW_ITEM_TYPE_VXLAN_DECAP;
87 : 0 : tun_entry->item.spec = tun_entry;
88 : 0 : tun_entry->item.last = NULL;
89 : 0 : tun_entry->item.mask = NULL;
90 : 0 : return 0;
91 : : }
92 : :
93 : : struct bnxt_flow_app_tun_ent *
94 : 0 : ulp_app_tun_match_entry(struct bnxt_ulp_context *ulp_ctx,
95 : : const void *ctx)
96 : : {
97 : : struct bnxt_flow_app_tun_ent *tun_ent_list;
98 : : int32_t i;
99 : :
100 : 0 : tun_ent_list = bnxt_ulp_cntxt_ptr2_app_tun_list_get(ulp_ctx);
101 [ # # ]: 0 : if (!tun_ent_list) {
102 : 0 : BNXT_TF_DBG(ERR, "unable to get the app tunnel list\n");
103 : 0 : return NULL;
104 : : }
105 : :
106 [ # # ]: 0 : for (i = 0; i < BNXT_ULP_MAX_TUN_CACHE_ENTRIES; i++) {
107 [ # # ]: 0 : if (&tun_ent_list[i] == ctx)
108 : 0 : return &tun_ent_list[i];
109 : : }
110 : : return NULL;
111 : : }
112 : :
113 : : static int32_t
114 : 0 : ulp_get_tun_entry(struct ulp_rte_parser_params *params,
115 : : struct bnxt_tun_cache_entry **tun_entry,
116 : : uint16_t *tun_idx)
117 : : {
118 : : int32_t i, first_free_entry = BNXT_ULP_TUN_ENTRY_INVALID;
119 : : struct bnxt_tun_cache_entry *tun_tbl;
120 : : uint32_t dip_idx, dmac_idx, use_ipv4 = 0;
121 : :
122 : 0 : tun_tbl = bnxt_ulp_cntxt_ptr2_tun_tbl_get(params->ulp_ctx);
123 [ # # ]: 0 : if (!tun_tbl) {
124 : 0 : BNXT_TF_DBG(ERR, "Error: could not get Tunnel table\n");
125 : 0 : return BNXT_TF_RC_ERROR;
126 : : }
127 : :
128 : : /* get the outer destination ip field index */
129 [ # # ]: 0 : dip_idx = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_TUN_OFF_DIP_ID);
130 [ # # ]: 0 : dmac_idx = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_TUN_OFF_DMAC_ID);
131 [ # # ]: 0 : if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_IPV4))
132 : : use_ipv4 = 1;
133 : :
134 [ # # ]: 0 : for (i = 0; i < BNXT_ULP_MAX_TUN_CACHE_ENTRIES; i++) {
135 [ # # ]: 0 : if (!tun_tbl[i].t_dst_ip_valid) {
136 [ # # ]: 0 : if (first_free_entry == BNXT_ULP_TUN_ENTRY_INVALID)
137 : : first_free_entry = i;
138 : 0 : continue;
139 : : }
140 : : /* match on the destination ip of the tunnel */
141 [ # # ]: 0 : if ((use_ipv4 && !memcmp(&tun_tbl[i].t_dst_ip,
142 [ # # ]: 0 : params->hdr_field[dip_idx].spec,
143 [ # # ]: 0 : sizeof(rte_be32_t))) ||
144 : 0 : (!use_ipv4 &&
145 : 0 : !memcmp(tun_tbl[i].t_dst_ip6,
146 [ # # ]: 0 : params->hdr_field[dip_idx].spec,
147 : : sizeof(((struct bnxt_tun_cache_entry *)
148 : : NULL)->t_dst_ip6)))) {
149 : 0 : *tun_entry = &tun_tbl[i];
150 : 0 : *tun_idx = i;
151 : 0 : return 0;
152 : : }
153 : : }
154 [ # # ]: 0 : if (first_free_entry == BNXT_ULP_TUN_ENTRY_INVALID) {
155 : 0 : BNXT_TF_DBG(ERR, "Error: No entry available in tunnel table\n");
156 : 0 : return BNXT_TF_RC_ERROR;
157 : : }
158 : :
159 : 0 : *tun_idx = first_free_entry;
160 : 0 : *tun_entry = &tun_tbl[first_free_entry];
161 : 0 : tun_tbl[first_free_entry].t_dst_ip_valid = true;
162 : :
163 : : /* Update the destination ip and mac */
164 [ # # ]: 0 : if (use_ipv4)
165 : 0 : memcpy(&tun_tbl[first_free_entry].t_dst_ip,
166 : 0 : params->hdr_field[dip_idx].spec, sizeof(rte_be32_t));
167 : : else
168 : 0 : memcpy(tun_tbl[first_free_entry].t_dst_ip6,
169 : 0 : params->hdr_field[dip_idx].spec,
170 : : sizeof(((struct bnxt_tun_cache_entry *)
171 : : NULL)->t_dst_ip6));
172 : 0 : memcpy(tun_tbl[first_free_entry].t_dmac,
173 : 0 : params->hdr_field[dmac_idx].spec, RTE_ETHER_ADDR_LEN);
174 : :
175 : 0 : return 0;
176 : : }
177 : :
178 : : /* Tunnel API to delete the tunnel entry */
179 : : void
180 : 0 : ulp_tunnel_offload_entry_clear(struct bnxt_tun_cache_entry *tun_tbl,
181 : : uint8_t tun_idx)
182 : : {
183 : 0 : memset(&tun_tbl[tun_idx], 0, sizeof(struct bnxt_tun_cache_entry));
184 : 0 : }
185 : :
186 : : /* Tunnel API to perform tunnel offload process when there is F1/F2 flows */
187 : : int32_t
188 : 0 : ulp_tunnel_offload_process(struct ulp_rte_parser_params *params)
189 : : {
190 : : struct bnxt_tun_cache_entry *tun_entry;
191 : : uint16_t tun_idx;
192 : : int32_t rc = BNXT_TF_RC_SUCCESS;
193 : :
194 : : /* Perform the tunnel offload only for F1 and F2 flows */
195 : 0 : if (!ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
196 [ # # ]: 0 : BNXT_ULP_HDR_BIT_F1) &&
197 : : !ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
198 : : BNXT_ULP_HDR_BIT_F2))
199 : : return rc;
200 : :
201 : : /* search for the tunnel entry if not found create one */
202 : 0 : rc = ulp_get_tun_entry(params, &tun_entry, &tun_idx);
203 [ # # ]: 0 : if (rc == BNXT_TF_RC_ERROR)
204 : : return rc;
205 : :
206 : : /* Tunnel offload for the outer Tunnel flow */
207 [ # # ]: 0 : if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
208 : : BNXT_ULP_HDR_BIT_F1)) {
209 : : /* Reset the JUMP action bit in the action bitmap as we don't
210 : : * offload this action.
211 : : */
212 : 0 : ULP_BITMAP_RESET(params->act_bitmap.bits,
213 : : BNXT_ULP_ACT_BIT_JUMP);
214 : 0 : params->parent_flow = true;
215 : 0 : params->tun_idx = tun_idx;
216 : 0 : tun_entry->outer_tun_flow_id = params->fid;
217 [ # # ]: 0 : } else if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
218 : : BNXT_ULP_HDR_BIT_F2)) {
219 : 0 : ULP_BITMAP_RESET(params->hdr_bitmap.bits,
220 : : BNXT_ULP_HDR_BIT_F2);
221 : : /* add the vxlan decap action for F2 flows */
222 : 0 : ULP_BITMAP_SET(params->act_bitmap.bits,
223 : : BNXT_ULP_ACT_BIT_VXLAN_DECAP);
224 : 0 : params->child_flow = true;
225 : 0 : params->tun_idx = tun_idx;
226 : 0 : params->parent_flow = false;
227 : : }
228 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_TUNNEL_ID, tun_idx);
229 : 0 : return rc;
230 : : }
|