/*-
* BSD LICENSE
*
- * Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#define MAX_KEY_SIZE 128
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
+#define MAX_SESSIONS 32
+#define SESSION_POOL_CACHE_SIZE 0
#define MAXIMUM_IV_LENGTH 16
#define IV_OFFSET (sizeof(struct rte_crypto_op) + \
char string_type[MAX_STR_LEN];
uint64_t cryptodev_mask;
+
+ unsigned int mac_updating;
};
/** l2fwd crypto lcore params */
struct rte_mempool *l2fwd_pktmbuf_pool;
struct rte_mempool *l2fwd_crypto_op_pool;
+struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 };
/* Per-port statistics struct */
struct l2fwd_port_statistics {
}
static void
-l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid)
+l2fwd_mac_updating(struct rte_mbuf *m, unsigned int dest_portid)
{
struct ether_hdr *eth;
void *tmp;
- unsigned dst_port;
- dst_port = l2fwd_dst_ports[portid];
eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
/* 02:00:00:00:00:xx */
tmp = ð->d_addr.addr_bytes[0];
- *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40);
+ *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
/* src addr */
- ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], ð->s_addr);
+ ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], ð->s_addr);
+}
+
+static void
+l2fwd_simple_forward(struct rte_mbuf *m, unsigned int portid,
+ struct l2fwd_crypto_options *options)
+{
+ unsigned int dst_port;
+
+ dst_port = l2fwd_dst_ports[portid];
+
+ if (options->mac_updating)
+ l2fwd_mac_updating(m, dst_port);
l2fwd_send_packet(m, (uint8_t) dst_port);
}
}
static struct rte_cryptodev_sym_session *
-initialize_crypto_session(struct l2fwd_crypto_options *options,
- uint8_t cdev_id)
+initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id)
{
struct rte_crypto_sym_xform *first_xform;
+ struct rte_cryptodev_sym_session *session;
+ int retval = rte_cryptodev_socket_id(cdev_id);
+
+ if (retval < 0)
+ return NULL;
+
+ uint8_t socket_id = (uint8_t) retval;
+ struct rte_mempool *sess_mp = session_pool_socket[socket_id];
if (options->xform_chain == L2FWD_CRYPTO_AEAD) {
first_xform = &options->aead_xform;
first_xform = &options->auth_xform;
}
- /* Setup Cipher Parameters */
- return rte_cryptodev_sym_session_create(cdev_id, first_xform);
+ session = rte_cryptodev_sym_session_create(sess_mp);
+
+ if (session == NULL)
+ return NULL;
+
+ if (rte_cryptodev_sym_session_init(cdev_id, session,
+ first_xform, sess_mp) < 0)
+ return NULL;
+
+ return session;
}
static void
US_PER_S * BURST_TX_DRAIN_US;
struct l2fwd_crypto_params *cparams;
struct l2fwd_crypto_params port_cparams[qconf->nb_crypto_devs];
+ struct rte_cryptodev_sym_session *session;
if (qconf->nb_rx_ports == 0) {
RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id);
port_cparams[i].hash_verify = 0;
port_cparams[i].auth_algo = options->auth_xform.auth.algo;
+ port_cparams[i].digest_length =
+ options->auth_xform.auth.digest_length;
/* Set IV parameters */
if (options->auth_iv.length) {
options->auth_xform.auth.iv.offset =
}
if (port_cparams[i].do_aead) {
+ port_cparams[i].aead_iv.data = options->aead_iv.data;
+ port_cparams[i].aead_iv.length = options->aead_iv.length;
+ if (!options->aead_iv_param)
+ generate_random_key(port_cparams[i].aead_iv.data,
+ port_cparams[i].aead_iv.length);
port_cparams[i].aead_algo = options->aead_xform.aead.algo;
port_cparams[i].digest_length =
options->aead_xform.aead.digest_length;
- if (options->aead_xform.aead.add_auth_data_length) {
+ if (options->aead_xform.aead.aad_length) {
port_cparams[i].aad.data = options->aad.data;
port_cparams[i].aad.phys_addr = options->aad.phys_addr;
port_cparams[i].aad.length = options->aad.length;
options->cipher_iv.length;
}
- port_cparams[i].session = initialize_crypto_session(options,
+ session = initialize_crypto_session(options,
port_cparams[i].dev_id);
+ if (session == NULL)
+ rte_exit(EXIT_FAILURE, "Failed to initialize crypto session\n");
+
+ port_cparams[i].session = session;
- if (port_cparams[i].session == NULL)
- return;
RTE_LOG(INFO, L2FWD, " -- lcoreid=%u cryptoid=%u\n", lcore_id,
port_cparams[i].dev_id);
}
m = ops_burst[j]->sym->m_src;
rte_crypto_op_free(ops_burst[j]);
- l2fwd_simple_forward(m, portid);
+ l2fwd_simple_forward(m, portid,
+ options);
}
} while (nb_rx == MAX_PKT_BURST);
}
" --digest_size SIZE: size of digest to be generated/verified\n"
" --sessionless\n"
- " --cryptodev_mask MASK: hexadecimal bitmask of crypto devices to configure\n",
+ " --cryptodev_mask MASK: hexadecimal bitmask of crypto devices to configure\n"
+
+ " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n"
+ " When enabled:\n"
+ " - The source MAC address is replaced by the TX port MAC address\n"
+ " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n",
prgname);
}
else if (strcmp(lgopts[option_index].name, "cryptodev_mask") == 0)
return parse_cryptodev_mask(options, optarg);
+ else if (strcmp(lgopts[option_index].name, "mac-updating") == 0) {
+ options->mac_updating = 1;
+ return 0;
+ }
+
+ else if (strcmp(lgopts[option_index].name, "no-mac-updating") == 0) {
+ options->mac_updating = 0;
+ return 0;
+ }
+
return -1;
}
options->aead_iv_random_size = -1;
options->aead_iv.length = 0;
+ options->auth_xform.aead.algo = RTE_CRYPTO_AEAD_AES_GCM;
+ options->auth_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT;
+
options->aad_param = 0;
options->aad_random_size = -1;
options->aad.length = 0;
options->type = CDEV_TYPE_ANY;
options->cryptodev_mask = UINT64_MAX;
+
+ options->mac_updating = 1;
}
static void
{ "sessionless", no_argument, 0, 0 },
{ "cryptodev_mask", required_argument, 0, 0},
+ { "mac-updating", no_argument, 0, 0},
+ { "no-mac-updating", no_argument, 0, 0},
+
{ NULL, 0, 0, 0 }
};
{
unsigned int cdev_id, cdev_count, enabled_cdev_count = 0;
const struct rte_cryptodev_capabilities *cap;
+ unsigned int sess_sz, max_sess_sz = 0;
int retval;
cdev_count = rte_cryptodev_count();
return -1;
}
+ for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) {
+ sess_sz = rte_cryptodev_get_private_session_size(cdev_id);
+ if (sess_sz > max_sess_sz)
+ max_sess_sz = sess_sz;
+ }
+
for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports;
cdev_id++) {
struct rte_cryptodev_qp_conf qp_conf;
struct rte_cryptodev_info dev_info;
+ retval = rte_cryptodev_socket_id(cdev_id);
+
+ if (retval < 0) {
+ printf("Invalid crypto device id used\n");
+ return -1;
+ }
+
+ uint8_t socket_id = (uint8_t) retval;
struct rte_cryptodev_config conf = {
.nb_queue_pairs = 1,
- .socket_id = SOCKET_ID_ANY,
- .session_mp = {
- .nb_objs = 2048,
- .cache_size = 64
- }
+ .socket_id = socket_id,
};
if (check_cryptodev_mask(options, (uint8_t)cdev_id))
rte_cryptodev_info_get(cdev_id, &dev_info);
+ if (session_pool_socket[socket_id] == NULL) {
+ char mp_name[RTE_MEMPOOL_NAMESIZE];
+ struct rte_mempool *sess_mp;
+
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "sess_mp_%u", socket_id);
+
+ /*
+ * Create enough objects for session headers and
+ * device private data
+ */
+ sess_mp = rte_mempool_create(mp_name,
+ MAX_SESSIONS * 2,
+ max_sess_sz,
+ SESSION_POOL_CACHE_SIZE,
+ 0, NULL, NULL, NULL,
+ NULL, socket_id,
+ 0);
+
+ if (sess_mp == NULL) {
+ printf("Cannot create session pool on socket %d\n",
+ socket_id);
+ return -ENOMEM;
+ }
+
+ printf("Allocated session pool on socket %d\n", socket_id);
+ session_pool_socket[socket_id] = sess_mp;
+ }
+
/* Set AEAD parameters */
if (options->xform_chain == L2FWD_CRYPTO_AEAD) {
/* Check if device supports AEAD algo */
* is supported by the algorithm chosen.
*/
} else if (options->aead_key_random_size != -1) {
- if (check_supported_size(options->ckey_random_size,
+ if (check_supported_size(options->aead_key_random_size,
cap->sym.aead.key_size.min,
cap->sym.aead.key_size.max,
cap->sym.aead.key_size.increment)
return -1;
}
options->aead_xform.aead.key.length =
- options->ckey_random_size;
+ options->aead_key_random_size;
/* No size provided, use minimum size. */
} else
options->aead_xform.aead.key.length =
} else
options->aad.length = cap->sym.auth.aad_size.min;
- options->aead_xform.aead.add_auth_data_length =
+ options->aead_xform.aead.aad_length =
options->aad.length;
/* Check if digest size is supported by the algorithm. */
qp_conf.nb_descriptors = 2048;
retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
- SOCKET_ID_ANY);
+ socket_id, session_pool_socket[socket_id]);
if (retval < 0) {
printf("Failed to setup queue pair %u on cryptodev %u",
0, cdev_id);
return -1;
}
+ retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,
+ &nb_txd);
+ if (retval < 0) {
+ printf("Cannot adjust number of descriptors: err=%d, port=%u\n",
+ retval, (unsigned) portid);
+ return -1;
+ }
+
/* init one RX queue */
fflush(stdout);
retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd,
if (ret < 0)
rte_exit(EXIT_FAILURE, "Invalid L2FWD-CRYPTO arguments\n");
+ printf("MAC updating %s\n",
+ options.mac_updating ? "enabled" : "disabled");
+
/* create the mbuf pool */
l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512,
sizeof(struct rte_crypto_op),