| 151 | } |
| 152 | |
| 153 | static int |
| 154 | sfc_ft_ctx_attach(struct sfc_adapter *sa, const struct rte_flow_tunnel *tunnel, |
| 155 | struct sfc_ft_ctx **ft_ctxp) |
| 156 | { |
| 157 | sfc_ft_ctx_id_t ft_ctx_id; |
| 158 | struct sfc_ft_ctx *ft_ctx; |
| 159 | const char *ft_ctx_status; |
| 160 | int ft_ctx_id_free = -1; |
| 161 | int rc; |
| 162 | |
| 163 | SFC_ASSERT(sfc_adapter_is_locked(sa)); |
| 164 | |
| 165 | rc = sfc_dp_ft_ctx_id_register(); |
| 166 | if (rc != 0) |
| 167 | return rc; |
| 168 | |
| 169 | if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) { |
| 170 | sfc_err(sa, "FT: unsupported tunnel (encapsulation) type"); |
| 171 | return ENOTSUP; |
| 172 | } |
| 173 | |
| 174 | for (ft_ctx_id = 0; ft_ctx_id < SFC_FT_MAX_NTUNNELS; ++ft_ctx_id) { |
| 175 | ft_ctx = &sa->ft_ctx_pool[ft_ctx_id]; |
| 176 | |
| 177 | if (ft_ctx->refcnt == 0) { |
| 178 | if (ft_ctx_id_free == -1) |
| 179 | ft_ctx_id_free = ft_ctx_id; |
| 180 | |
| 181 | continue; |
| 182 | } |
| 183 | |
| 184 | if (memcmp(tunnel, &ft_ctx->tunnel, sizeof(*tunnel)) == 0) { |
| 185 | ft_ctx_status = "existing"; |
| 186 | goto attach; |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | if (ft_ctx_id_free == -1) { |
| 191 | sfc_err(sa, "FT: no free slot for the new context"); |
| 192 | return ENOBUFS; |
| 193 | } |
| 194 | |
| 195 | ft_ctx_id = ft_ctx_id_free; |
| 196 | ft_ctx = &sa->ft_ctx_pool[ft_ctx_id]; |
| 197 | |
| 198 | memcpy(&ft_ctx->tunnel, tunnel, sizeof(*tunnel)); |
| 199 | |
| 200 | ft_ctx->encap_type = EFX_TUNNEL_PROTOCOL_VXLAN; |
| 201 | |
| 202 | ft_ctx->action_mark.id = SFC_FT_CTX_ID_TO_FLOW_MARK(ft_ctx_id); |
| 203 | ft_ctx->action.type = RTE_FLOW_ACTION_TYPE_MARK; |
| 204 | ft_ctx->action.conf = &ft_ctx->action_mark; |
| 205 | |
| 206 | ft_ctx->item_mark_v.id = ft_ctx->action_mark.id; |
| 207 | ft_ctx->item.type = RTE_FLOW_ITEM_TYPE_MARK; |
| 208 | ft_ctx->item.spec = &ft_ctx->item_mark_v; |
| 209 | ft_ctx->item.mask = &ft_ctx->item_mark_m; |
| 210 | ft_ctx->item_mark_m.id = UINT32_MAX; |
no test coverage detected