/* SPDX-License-Identifier: Apache-2.0
* Copyright(c) 2022 Cisco Systems, Inc.
*/
#include <vnet/fib/ip6_fib.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/l2/feat_bitmap.h>
#include <vnet/fib/fib_table.h>
#include <vnet/srv6/sr.h>
#include <vnet/srv6/sr_pt.h>
/**
* @brief PT node trace
*/
typedef struct
{
u32 iface;
u16 id;
u8 load;
timestamp_64_t t64;
u8 tts_template;
u8 tts;
u8 behavior;
} pt_trace_t;
static u8 *
format_pt_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
pt_trace_t *t = va_arg (*args, pt_trace_t *);
switch (t->behavior)
{
case PT_BEHAVIOR_MID:
s = format (
s,
"Behavior Midpoint, outgoing interface %U, outgoing interface id %u, "
"outgoing interface load %u, t64_sec %u, t64_nsec %u, tts_template "
"%u, tts %u",
format_vnet_sw_if_index_name, vnet_get_main (), t->iface, t->id,
t->load, clib_host_to_net_u32 (t->t64.sec),
clib_host_to_net_u32 (t->t64.nsec), t->tts_template, t->tts);
break;
default:
break;
}
return s;
}
static_always_inline void
pt_midpoint_processing (vlib_main_t *vm, vlib_node_runtime_t *node,
vlib_buffer_t *b0, ip6_header_t *ip0,
sr_pt_iface_t *ls, timestamp_64_t t64)
{
ip6_hop_by_hop_header_t *hbh;
ip6_hop_by_hop_option_t *hbh_opt;
ip6_hop_by_hop_option_pt_t *hbh_opt_pt;
if (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS)
{
hbh = (void *) (ip0 + 1);
hbh_opt = (void *) (hbh + 1);
if (hbh_opt/*
* Copyright (c) 2017 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DPDK_IPSEC_H__
#define __DPDK_IPSEC_H__
#include <vnet/vnet.h>
#include <vppinfra/cache.h>
#include <vnet/ipsec/ipsec.h>
#undef always_inline
#include <rte_config.h>
#include <rte_crypto.h>
#include <rte_cryptodev.h>
#if CLIB_DEBUG > 0
#define always_inline static inline
#else
#define always_inline static inline __attribute__ ((__always_inline__))
#endif
#define foreach_dpdk_crypto_input_next \
_(DROP, "error-drop") \
_(IP4_LOOKUP, "ip4-lookup") \
_(IP6_LOOKUP, "ip6-lookup") \
_(INTERFACE_OUTPUT, "interface-output") \
_(DECRYPT_POST, "dpdk-esp-decrypt-post")
typedef enum
{
#define _(f,s) DPDK_CRYPTO_INPUT_NEXT_##f,
foreach_dpdk_crypto_input_next
#undef _
DPDK_CRYPTO_INPUT_N_NEXT,
} dpdk_crypto_input_next_t;
#define MAX_QP_PER_LCORE 16
typedef struct
{
u32 salt;
u32 iv[2];
u32 cnt;
} dpdk_gcm_cnt_blk;
typedef struct
{
u32 next;
dpdk_gcm_cnt_blk cb __attribute__ ((aligned (16)));
u8 aad[16];
u8 icv[32];
} dpdk_op_priv_t;
typedef struct
{
u16 *resource_idx;
struct rte_crypto_op **ops;
u16 cipher_resource_idx[IPSEC_CRYPTO_N_ALG];
u16 auth_resource_idx[IPSEC_INTEG_N_ALG];
CLIB_CACHE_LINE_ALIGN_MARK (pad);
} crypto_worker_main_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
typedef struct
{
char *name;
enum rte_crypto_sym_xform_type type;
u32 alg;
u8 key_len;
u8 iv_len;
u8 trunc_size;
u8 boundary;
u8 disabled;
u8 resources;
} crypto_alg_t __attribute__ ((aligned (8)));
typedef struct
{
u16 *free_resources;
u16 *used_resources;
u8 cipher_support[IPSEC_CRYPTO_N_ALG];
u8 auth_support[IPSEC_INTEG_N_ALG];
u8 drv_id;
u8 numa;
u16 id;
const char *name;
u32 max_qp;
u64 features;
} crypto_dev_t;
typedef struct
{
const char *name;
u16 *devs;
} crypto_drv_t;
typedef struct
{
u16 thread_idx;
u8 remove;
u8 drv_id;
u8 dev_id;
u8 numa;
u16 qp_id;
u16 inflights[2];
u16 n_ops;
u16 __unused;
struct rte_crypto_op *ops[VLIB_FRAME_SIZE];
u32 bi[VLIB_FRAME_SIZE];
} crypto_resource_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
typedef struct
{
u64 ts;
struct rte_cryptodev_sym_session *session;
} crypto_session_disposal_t;
typedef struct
{
struct rte_cryptodev_sym_session *session;
u64 dev_mask;
} crypto_session_by_drv_t;
typedef struct
{
/* Required for vec_validate_aligned */
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
struct rte_mempool *crypto_op;
struct rte_mempool *session_h;
struct rte_mempool **session_drv;
crypto_session_disposal_t *session_disposal;
uword *session_by_sa_index;
u64 crypto_op_get_failed;
u64 session_h_failed;
u64 *session_drv_failed;
crypto_session_by_drv_t *session_by_drv_id_and_sa_index;
clib_spinlock_t lockp;
} crypto_data_t;
typedef struct
{
crypto_worker_main_t *workers_main;
crypto_dev_t *dev;
crypto_resource_t *resource;
crypto_alg_t *cipher_algs;
crypto_alg_t *auth_algs;
crypto_data_t *data;
crypto_drv_t *drv;
u64 session_timeout; /* nsec */
u8 enabled;
} dpdk_crypto_main_t;
extern dpdk_crypto_main_t dpdk_crypto_main;
static const u8 pad_data[] =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 };
void crypto_auto_placement (void);
clib_error_t *create_sym_session (struct rte_cryptodev_sym_session **session,
u32 sa_idx, crypto_resource_t * res,
crypto_worker_main_t * cwm, u8 is_outbound);
static_always_inline u32
crypto_op_len (void)
{
const u32 align = 4;
u32 op_size =
sizeof (struct rte_crypto_op) + sizeof (struct rte_crypto_sym_op);
return ((op_size + align - 1) & ~(align - 1)) + sizeof (dpdk_op_priv_t);
}
static_always_inline u32
crypto_op_get_priv_offset (