#include "ipsec.h"
#include "parser.h"
+#include "sad.h"
#define RTE_LOGTYPE_IPSEC RTE_LOGTYPE_USER1
{ 0, ETHADDR(0x00, 0x16, 0x3e, 0x49, 0x9e, 0xdd) }
};
+struct flow_info flow_info_tbl[RTE_MAX_ETHPORTS];
+
#define CMD_LINE_OPT_CONFIG "config"
#define CMD_LINE_OPT_SINGLE_SA "single-sa"
#define CMD_LINE_OPT_CRYPTODEV_MASK "cryptodev_mask"
static uint64_t frag_ttl_ns = MAX_FRAG_TTL_NS;
/* application wide librte_ipsec/SA parameters */
-struct app_sa_prm app_sa_prm = {.enable = 0};
+struct app_sa_prm app_sa_prm = {
+ .enable = 0,
+ .cache_sz = SA_CACHE_SZ
+ };
static const char *cfgfile;
struct lcore_rx_queue {
}
pkt->l2_len = 0;
pkt->l3_len = sizeof(*iph4);
+ pkt->packet_type |= RTE_PTYPE_L3_IPV4;
} else if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) {
int next_proto;
size_t l3len, ext_len;
}
pkt->l2_len = 0;
pkt->l3_len = l3len;
+ pkt->packet_type |= RTE_PTYPE_L3_IPV6;
} else {
/* Unknown/Unsupported type, drop the packet */
RTE_LOG(ERR, IPSEC, "Unsupported packet type 0x%x\n",
continue;
}
- sa_idx = SPI2IDX(res);
+ sa_idx = res - 1;
if (!inbound_sa_check(sa, m, sa_idx)) {
rte_pktmbuf_free(m);
continue;
j = 0;
for (i = 0; i < ip->num; i++) {
m = ip->pkts[i];
- sa_idx = SPI2IDX(ip->res[i]);
+ sa_idx = ip->res[i] - 1;
if (ip->res[i] == DISCARD)
rte_pktmbuf_free(m);
else if (ip->res[i] == BYPASS)
uint16_t portid;
uint8_t queueid;
struct lcore_conf *qconf;
- int32_t socket_id;
+ int32_t rc, socket_id;
const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1)
/ US_PER_S * BURST_TX_DRAIN_US;
struct lcore_rx_queue *rxql;
qconf->frag.pool_dir = socket_ctx[socket_id].mbuf_pool;
qconf->frag.pool_indir = socket_ctx[socket_id].mbuf_pool_indir;
+ rc = ipsec_sad_lcore_cache_init(app_sa_prm.cache_sz);
+ if (rc != 0) {
+ RTE_LOG(ERR, IPSEC,
+ "SAD cache init on lcore %u, failed with code: %d\n",
+ lcore_id, rc);
+ return rc;
+ }
+
if (qconf->nb_rx_queue == 0) {
RTE_LOG(DEBUG, IPSEC, "lcore %u has nothing to do\n",
lcore_id);
" [-w REPLAY_WINDOW_SIZE]"
" [-e]"
" [-a]"
+ " [-c]"
" -f CONFIG_FILE"
" --config (port,queue,lcore)[,(port,queue,lcore)]"
" [--single-sa SAIDX]"
" size for each SA\n"
" -e enables ESN\n"
" -a enables SA SQN atomic behaviour\n"
+ " -c specifies inbound SAD cache size,\n"
+ " zero value disables the cache (default value: 128)\n"
" -f CONFIG_FILE: Configuration file\n"
" --config (port,queue,lcore): Rx queue configuration\n"
" --single-sa SAIDX: Use single SA index for outbound traffic,\n"
argvopt = argv;
- while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:",
+ while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:c:",
lgopts, &option_index)) != EOF) {
switch (opt) {
app_sa_prm.enable = 1;
app_sa_prm.flags |= RTE_IPSEC_SAFLAG_SQN_ATOM;
break;
+ case 'c':
+ ret = parse_decimal(optarg);
+ if (ret < 0) {
+ printf("Invalid SA cache size: %s\n", optarg);
+ print_usage(prgname);
+ return -1;
+ }
+ app_sa_prm.cache_sz = ret;
+ break;
case CMD_LINE_OPT_CONFIG_NUM:
ret = parse_config(optarg);
if (ret) {
return rc;
}
+static void
+create_default_ipsec_flow(uint16_t port_id, uint64_t rx_offloads)
+{
+ struct rte_flow_action action[2];
+ struct rte_flow_item pattern[2];
+ struct rte_flow_attr attr = {0};
+ struct rte_flow_error err;
+ struct rte_flow *flow;
+ int ret;
+
+ if (!(rx_offloads & DEV_RX_OFFLOAD_SECURITY))
+ return;
+
+ /* Add the default rte_flow to enable SECURITY for all ESP packets */
+
+ pattern[0].type = RTE_FLOW_ITEM_TYPE_ESP;
+ pattern[0].spec = NULL;
+ pattern[0].mask = NULL;
+ pattern[0].last = NULL;
+ pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
+
+ action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
+ action[0].conf = NULL;
+ action[1].type = RTE_FLOW_ACTION_TYPE_END;
+ action[1].conf = NULL;
+
+ attr.ingress = 1;
+
+ ret = rte_flow_validate(port_id, &attr, pattern, action, &err);
+ if (ret)
+ return;
+
+ flow = rte_flow_create(port_id, &attr, pattern, action, &err);
+ if (flow == NULL)
+ return;
+
+ flow_info_tbl[port_id].rx_def_flow = flow;
+ RTE_LOG(INFO, IPSEC,
+ "Created default flow enabling SECURITY for all ESP traffic on port %d\n",
+ port_id);
+}
+
int32_t
main(int32_t argc, char **argv)
{
uint32_t i;
uint8_t socket_id;
uint16_t portid;
- uint64_t req_rx_offloads, req_tx_offloads;
+ uint64_t req_rx_offloads[RTE_MAX_ETHPORTS];
+ uint64_t req_tx_offloads[RTE_MAX_ETHPORTS];
size_t sess_sz;
/* init EAL */
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
- sa_check_offloads(portid, &req_rx_offloads, &req_tx_offloads);
- port_init(portid, req_rx_offloads, req_tx_offloads);
+ sa_check_offloads(portid, &req_rx_offloads[portid],
+ &req_tx_offloads[portid]);
+ port_init(portid, req_rx_offloads[portid],
+ req_tx_offloads[portid]);
}
cryptodevs_init();
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
- /*
- * Start device
- * note: device must be started before a flow rule
- * can be installed.
- */
+ /* Create flow before starting the device */
+ create_default_ipsec_flow(portid, req_rx_offloads[portid]);
+
ret = rte_eth_dev_start(portid);
if (ret < 0)
rte_exit(EXIT_FAILURE, "rte_eth_dev_start: "