From 100ac9747f2c66eb3ab400ca8ce48f6d895c7fbd Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 9 Nov 2022 15:28:37 +0200 Subject: linux-gen: timer: fix GCC 9.2 warning GCC 9.2 warns that queue handle may be used uninitialized, although it is set always when the event handle is set. Initialize queue handle to avoid the warning. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- platform/linux-generic/odp_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 90e83a4f2..05660eb7a 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -652,7 +652,7 @@ static odp_event_t timer_cancel(timer_pool_t *tp, uint32_t idx) static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick) { uint64_t exp_tck; - odp_queue_t queue; + odp_queue_t queue = ODP_QUEUE_INVALID; _odp_timer_t *tim = &tp->timers[idx]; tick_buf_t *tb = &tp->tick_buf[idx]; odp_event_t tmo_event = ODP_EVENT_INVALID; -- cgit v1.2.3 From 5e2c0ee9d3e6b0ad7ba173b3956eeaa714d5481d Mon Sep 17 00:00:00 2001 From: Aakash Sasidharan Date: Thu, 28 Oct 2021 13:59:22 +0530 Subject: linux-gen: ipsec: generate status event for SA expiry Generate status event for SA expiry when in inline outbound mode. Signed-off-by: Aakash Sasidharan Reviewed-by: Anoob Joseph Reviewed-by: Janne Peltonen --- platform/linux-generic/include/odp_ipsec_internal.h | 8 ++++++++ platform/linux-generic/odp_ipsec.c | 19 +++++++++++++++++++ platform/linux-generic/odp_ipsec_sad.c | 1 + 3 files changed, 28 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h index 8e0cb925e..dad6211b0 100644 --- a/platform/linux-generic/include/odp_ipsec_internal.h +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -272,6 +272,14 @@ struct ipsec_sa_s { } out; }; } sa_info; + + /* + * Flag to check if the SA soft expiry status event was already + * sent. This field is applicable only for the soft expiry status + * event that gets generated for IPsec SAs configured in inline + * outbound mode. + */ + odp_atomic_u32_t soft_expiry_notified; }; /** diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 6be1a01ad..4d0350e36 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -2477,6 +2477,25 @@ static void ipsec_out_inline_finalize(odp_packet_t pkt_in[], ipsec_inline_op_t *op = &ops[i]; odp_packet_t *pkt = &pkt_in[i]; + if (op->op.status.warn.soft_exp_packets || op->op.status.warn.soft_exp_bytes) { + if (!odp_atomic_load_u32(&op->op.sa->soft_expiry_notified)) { + int rc; + + /* + * Another thread may have sent the notification by now but we do + * not care since sending duplicate expiry notifications is allowed. + */ + rc = _odp_ipsec_status_send(op->op.sa->queue, + ODP_IPSEC_STATUS_WARN, + op->op.sa->ipsec_sa_hdl, + 0, op->op.status.warn); + if (rc == 0) + odp_atomic_store_u32(&op->op.sa->soft_expiry_notified, 1); + else + _ODP_DBG("IPsec status event submission failed\n"); + } + } + if (odp_unlikely(op->op.status.error.all)) goto handle_err; diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c index 3097bef4b..f95a6d58e 100644 --- a/platform/linux-generic/odp_ipsec_sad.c +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -562,6 +562,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) odp_atomic_init_u64(&ipsec_sa->stats.hard_exp_pkts_err, 0); odp_atomic_init_u64(&ipsec_sa->stats.post_lifetime_err_pkts, 0); odp_atomic_init_u64(&ipsec_sa->stats.post_lifetime_err_bytes, 0); + odp_atomic_init_u32(&ipsec_sa->soft_expiry_notified, 0); if (ODP_IPSEC_MODE_TUNNEL == ipsec_sa->mode && ODP_IPSEC_DIR_OUTBOUND == param->dir) { -- cgit v1.2.3 From d2220a24e0a285bfe6a5259387d7e30cb1af9a26 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Thu, 10 Nov 2022 09:54:05 +0200 Subject: linux-gen: ipsec: remove unnecessary sequence number wraparound check This implementation keeps internally a 64 bit sequence number for outbound SAs whether ESNs are used or not. Since a 64 bit packet counter cannot wrap in any reasonable time frame, remove the sequence number wraparound check from the generation of counter based IVs. Signed-off-by: Janne Peltonen Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_ipsec.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 4d0350e36..7c3f65edc 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -1404,10 +1404,6 @@ static int ipsec_out_iv(ipsec_state_t *state, /* Both GCM and CTR use 8-bit counters */ _ODP_ASSERT(sizeof(seq_no) == ipsec_sa->esp_iv_len); - /* Check for overrun */ - if (seq_no == 0) - return -1; - memcpy(state->iv, ipsec_sa->salt, ipsec_sa->salt_length); memcpy(state->iv + ipsec_sa->salt_length, &seq_no, ipsec_sa->esp_iv_len); -- cgit v1.2.3 From 332cbe9c056d400ded3c59eb1f157d80bb77a1bf Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Thu, 10 Nov 2022 09:54:07 +0200 Subject: linux-gen: ipsec: use non-random IV for AES-CBC Generating random ESP IVs can be slow, depending on the underlying random number generator. Change IV generation for AES-CBC to not depend on the random number generator except at SA creation time. Generate an unpredicable ESP IV for AES-CBC by creating a nonce and by encrypting it with the same algorithm and key. The nonce is formed by concatenating 8 bytes of per-session random data with the internal 8-byte packet sequence number. Ciphering the nonce is done as part of ciphering the data by placing the nonce in the cipher IV, by zeroing the ESP IV field of the packet and by adjusting the cipher range to include the ESP IV field. This can be done since the cipher is in CBC mode and the ESP IV field immediately precedes the payload data to be ciphered. Including per-session random bytes in the IV construction in addition to the sequence number is done to prevent different SAs that use the same key (e.g. in case of a manually keyed SA across system restart) from having the same IV sequence, as that would allow an observer to predict IVs of an SA by observing the IVs of another SA. Signed-off-by: Janne Peltonen Reviewed-by: Tuomas Taipale --- .../linux-generic/include/odp_ipsec_internal.h | 9 +++- platform/linux-generic/odp_ipsec.c | 50 +++++++++++++++++++--- platform/linux-generic/odp_ipsec_sad.c | 23 ++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h index dad6211b0..baffcd4e3 100644 --- a/platform/linux-generic/include/odp_ipsec_internal.h +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -87,6 +87,9 @@ int _odp_ipsec_status_send(odp_queue_t queue, #define IPSEC_MAX_SALT_LEN 4 /**< Maximum salt length in bytes */ +#define CBC_SALT_LEN 8 +#define CBC_IV_LEN (CBC_SALT_LEN + sizeof(uint64_t)) + #define IPSEC_SEQ_HI_LEN 4 /**< ESN Higher bits length in bytes */ /* The minimum supported AR window size */ @@ -167,7 +170,10 @@ struct ipsec_sa_s { uint32_t esp_iv_len; uint32_t esp_pad_mask; - uint8_t salt[IPSEC_MAX_SALT_LEN]; + union { + uint8_t salt[IPSEC_MAX_SALT_LEN]; + uint8_t cbc_salt[CBC_SALT_LEN]; + }; uint32_t salt_length; odp_ipsec_lookup_mode_t lookup_mode; @@ -186,6 +192,7 @@ struct ipsec_sa_s { /* Only for outbound */ unsigned use_counter_iv : 1; + unsigned use_cbc_iv : 1; unsigned tun_ipv4 : 1; /* Only for inbound */ diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 7c3f65edc..8a583c1b1 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -1396,6 +1396,9 @@ static int ipsec_random_data(uint8_t *data, uint32_t len) return 0; } +/* + * Generate cipher IV for outbound processing. + */ static int ipsec_out_iv(ipsec_state_t *state, ipsec_sa_t *ipsec_sa, uint64_t seq_no) @@ -1414,7 +1417,26 @@ static int ipsec_out_iv(ipsec_state_t *state, state->iv[14] = 0; state->iv[15] = 1; } - } else if (ipsec_sa->esp_iv_len) { + } else if (ipsec_sa->use_cbc_iv) { + /* + * For CBC mode ciphers with 16 byte IV we generate the cipher + * IV by concatenating a per-session random salt value and + * 64-bit sequence number. The ESP IV will be generated at + * ciphering time by CBC-encrypting a zero block using the + * cipher IV. + * + * This way each packet of an SA will have an unpredictable + * IV and different SAs (e.g. manually keyed SAs across + * restarts) will have different IV sequences (so one cannot + * predict IVs of an SA by observing the IVs of another SA + * with the same key). + */ + _ODP_ASSERT(CBC_SALT_LEN + sizeof(seq_no) == ipsec_sa->esp_iv_len); + ODP_STATIC_ASSERT(CBC_SALT_LEN + sizeof(seq_no) <= IPSEC_MAX_IV_LEN, + "IPSEC_MAX_IV_LEN too small for CBC IV construction"); + memcpy(state->iv, ipsec_sa->cbc_salt, CBC_SALT_LEN); + memcpy(state->iv + CBC_SALT_LEN, &seq_no, sizeof(seq_no)); + } else if (odp_unlikely(ipsec_sa->esp_iv_len)) { if (ipsec_random_data(state->iv, ipsec_sa->esp_iv_len)) return -1; } @@ -1555,10 +1577,13 @@ static int ipsec_out_esp(odp_packet_t *pkt, odp_packet_copy_from_mem(*pkt, ipsec_offset, _ODP_ESPHDR_LEN, &esp); - odp_packet_copy_from_mem(*pkt, - ipsec_offset + _ODP_ESPHDR_LEN, - ipsec_sa->esp_iv_len, - state->iv + ipsec_sa->salt_length); + if (!ipsec_sa->use_cbc_iv) { + /* copy the relevant part of cipher IV to ESP IV */ + odp_packet_copy_from_mem(*pkt, + ipsec_offset + _ODP_ESPHDR_LEN, + ipsec_sa->esp_iv_len, + state->iv + ipsec_sa->salt_length); + } /* 0xa5 is a good value to fill data instead of generating random data * to create TFC padding */ _odp_packet_set_data(*pkt, esptrl_offset - esptrl.pad_len - tfc_len, @@ -1609,6 +1634,21 @@ static int ipsec_out_esp(odp_packet_t *pkt, ipsec_sa->icv_len; state->stats_length = param->cipher_range.length; + + if (ipsec_sa->use_cbc_iv) { + /* + * Encrypt zeroed ESP IV field using the special cipher IV + * to create the final unpredictable ESP IV + */ + _ODP_ASSERT(ipsec_sa->esp_iv_len == CBC_IV_LEN); + param->cipher_range.offset -= CBC_IV_LEN; + param->cipher_range.length += CBC_IV_LEN; + _odp_packet_set_data(*pkt, + ipsec_offset + _ODP_ESPHDR_LEN, + 0, + CBC_IV_LEN); + } + param->session = ipsec_sa->session; return 0; diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c index f95a6d58e..1b3a90e6a 100644 --- a/platform/linux-generic/odp_ipsec_sad.c +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -485,6 +485,25 @@ static void store_sa_info(ipsec_sa_t *ipsec_sa, const odp_ipsec_sa_param_t *p) ipsec_sa->sa_info.out.mtu = p->outbound.mtu; } +static int init_cbc_salt(ipsec_sa_t *ipsec_sa) +{ + int filled = 0; + int rc; + + if (!ipsec_sa->use_cbc_iv) + return 0; + + while (filled < CBC_SALT_LEN) { + rc = odp_random_data(&ipsec_sa->cbc_salt[filled], + CBC_SALT_LEN - filled, + ODP_RANDOM_CRYPTO); + if (rc < 0) + return -1; + filled += rc; + } + return 0; +} + odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) { ipsec_sa_t *ipsec_sa; @@ -656,6 +675,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) ipsec_sa->esp_pad_mask = esp_block_len_to_mask(8); break; case ODP_CIPHER_ALG_AES_CBC: + ipsec_sa->use_cbc_iv = 1; ipsec_sa->esp_iv_len = 16; ipsec_sa->esp_pad_mask = esp_block_len_to_mask(16); break; @@ -746,6 +766,9 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) memcpy(ipsec_sa->salt, salt_param->data, ipsec_sa->salt_length); } + if (init_cbc_salt(ipsec_sa)) + goto error; + if (odp_crypto_session_create(&crypto_param, &ipsec_sa->session, &ses_create_rc)) goto error; -- cgit v1.2.3 From 25c01f0bfa6564e335c40550e3f2d87dc6d179fc Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Thu, 10 Nov 2022 09:54:08 +0200 Subject: linux-gen: ipsec: shrink the cipher IV field of ipsec state Shrink the IV field of the ipsec state struct to the minimum size needed and add a couple of asserts to notice if it is too small. This saves a bit of stack space. Signed-off-by: Janne Peltonen Reviewed-by: Tuomas Taipale --- platform/linux-generic/include/odp_ipsec_internal.h | 2 +- platform/linux-generic/odp_ipsec.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h index baffcd4e3..571796691 100644 --- a/platform/linux-generic/include/odp_ipsec_internal.h +++ b/platform/linux-generic/include/odp_ipsec_internal.h @@ -83,7 +83,7 @@ int _odp_ipsec_status_send(odp_queue_t queue, int result, odp_ipsec_warn_t warn); -#define IPSEC_MAX_IV_LEN 32 /**< Maximum IV length in bytes */ +#define IPSEC_MAX_IV_LEN 16 /**< Maximum cipher IV length in bytes */ #define IPSEC_MAX_SALT_LEN 4 /**< Maximum salt length in bytes */ diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 8a583c1b1..7e82f17eb 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -550,6 +550,7 @@ static int ipsec_in_iv(odp_packet_t pkt, ipsec_sa_t *ipsec_sa, uint16_t iv_offset) { + _ODP_ASSERT(ipsec_sa->salt_length + ipsec_sa->esp_iv_len <= IPSEC_MAX_IV_LEN); memcpy(state->iv, ipsec_sa->salt, ipsec_sa->salt_length); if (odp_packet_copy_to_mem(pkt, iv_offset, @@ -558,6 +559,7 @@ static int ipsec_in_iv(odp_packet_t pkt, return -1; if (ipsec_sa->aes_ctr_iv) { + ODP_STATIC_ASSERT(IPSEC_MAX_IV_LEN >= 16, "IPSEC_MAX_IV_LEN too small"); state->iv[12] = 0; state->iv[13] = 0; state->iv[14] = 0; @@ -1407,11 +1409,13 @@ static int ipsec_out_iv(ipsec_state_t *state, /* Both GCM and CTR use 8-bit counters */ _ODP_ASSERT(sizeof(seq_no) == ipsec_sa->esp_iv_len); + _ODP_ASSERT(ipsec_sa->salt_length + ipsec_sa->esp_iv_len <= IPSEC_MAX_IV_LEN); memcpy(state->iv, ipsec_sa->salt, ipsec_sa->salt_length); memcpy(state->iv + ipsec_sa->salt_length, &seq_no, ipsec_sa->esp_iv_len); if (ipsec_sa->aes_ctr_iv) { + ODP_STATIC_ASSERT(IPSEC_MAX_IV_LEN >= 16, "IPSEC_MAX_IV_LEN too small"); state->iv[12] = 0; state->iv[13] = 0; state->iv[14] = 0; @@ -1437,6 +1441,7 @@ static int ipsec_out_iv(ipsec_state_t *state, memcpy(state->iv, ipsec_sa->cbc_salt, CBC_SALT_LEN); memcpy(state->iv + CBC_SALT_LEN, &seq_no, sizeof(seq_no)); } else if (odp_unlikely(ipsec_sa->esp_iv_len)) { + _ODP_ASSERT(ipsec_sa->esp_iv_len <= IPSEC_MAX_IV_LEN); if (ipsec_random_data(state->iv, ipsec_sa->esp_iv_len)) return -1; } -- cgit v1.2.3 From 2f133a0764463928e8b8357c8965ba9328a4e881 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Thu, 10 Nov 2022 09:54:10 +0200 Subject: linux-gen: ipsec: call memcpy with constant length Call memcpy with constant length in the critical path when possible to enable the copy operations to be inlined and better optimized. Signed-off-by: Janne Peltonen Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_ipsec.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 7e82f17eb..b26b71d1c 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -550,8 +550,13 @@ static int ipsec_in_iv(odp_packet_t pkt, ipsec_sa_t *ipsec_sa, uint16_t iv_offset) { + if (ipsec_sa->salt_length > 0) { + /* It is faster to just copy MAX_SALT_LEN bytes than the exact length */ + ODP_STATIC_ASSERT(IPSEC_MAX_SALT_LEN <= IPSEC_MAX_IV_LEN, + "IPSEC_MAX_SALT_LEN too large"); + memcpy(state->iv, ipsec_sa->salt, IPSEC_MAX_SALT_LEN); + } _ODP_ASSERT(ipsec_sa->salt_length + ipsec_sa->esp_iv_len <= IPSEC_MAX_IV_LEN); - memcpy(state->iv, ipsec_sa->salt, ipsec_sa->salt_length); if (odp_packet_copy_to_mem(pkt, iv_offset, ipsec_sa->esp_iv_len, @@ -1409,10 +1414,13 @@ static int ipsec_out_iv(ipsec_state_t *state, /* Both GCM and CTR use 8-bit counters */ _ODP_ASSERT(sizeof(seq_no) == ipsec_sa->esp_iv_len); - _ODP_ASSERT(ipsec_sa->salt_length + ipsec_sa->esp_iv_len <= IPSEC_MAX_IV_LEN); - memcpy(state->iv, ipsec_sa->salt, ipsec_sa->salt_length); - memcpy(state->iv + ipsec_sa->salt_length, &seq_no, - ipsec_sa->esp_iv_len); + /* It is faster to just copy MAX_SALT_LEN bytes than the exact length */ + ODP_STATIC_ASSERT(IPSEC_MAX_SALT_LEN <= IPSEC_MAX_IV_LEN, + "IPSEC_MAX_SALT_LEN too large"); + memcpy(state->iv, ipsec_sa->salt, IPSEC_MAX_SALT_LEN); + + _ODP_ASSERT(ipsec_sa->salt_length + sizeof(seq_no) <= IPSEC_MAX_IV_LEN); + memcpy(state->iv + ipsec_sa->salt_length, &seq_no, sizeof(seq_no)); if (ipsec_sa->aes_ctr_iv) { ODP_STATIC_ASSERT(IPSEC_MAX_IV_LEN >= 16, "IPSEC_MAX_IV_LEN too small"); -- cgit v1.2.3 From fa8d79d033a4977d8dcc04d2d5490f5ee382071a Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 28 Oct 2022 11:50:31 +0300 Subject: api: ipsec: split header files Split IPsec API into separate header files for functions and types. This enables inline implementation of API functions. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- platform/linux-generic/Makefile.am | 1 + .../linux-generic/include-abi/odp/api/abi/ipsec.h | 14 ++------ .../include-abi/odp/api/abi/ipsec_types.h | 41 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 platform/linux-generic/include-abi/odp/api/abi/ipsec_types.h (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index ce8b0ba09..19506b5ff 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -82,6 +82,7 @@ odpapiabiarchinclude_HEADERS += \ include-abi/odp/api/abi/hash.h \ include-abi/odp/api/abi/init.h \ include-abi/odp/api/abi/ipsec.h \ + include-abi/odp/api/abi/ipsec_types.h \ include-abi/odp/api/abi/packet.h \ include-abi/odp/api/abi/packet_types.h \ include-abi/odp/api/abi/packet_flags.h \ diff --git a/platform/linux-generic/include-abi/odp/api/abi/ipsec.h b/platform/linux-generic/include-abi/odp/api/abi/ipsec.h index a04bb1741..f314f6a41 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/ipsec.h +++ b/platform/linux-generic/include-abi/odp/api/abi/ipsec.h @@ -1,4 +1,5 @@ /* Copyright (c) 2016-2018, Linaro Limited + * Copyright (c) 2022, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,7 +8,7 @@ /** * @file * - * ODP IPSEC API - platform specific types + * ODP IPsec */ #ifndef ODP_API_ABI_IPSEC_H_ @@ -17,16 +18,7 @@ extern "C" { #endif -#include -#include - -/** @ingroup odp_ipsec - * @{ - */ - -typedef ODP_HANDLE_T(odp_ipsec_sa_t); - -#define ODP_IPSEC_SA_INVALID _odp_cast_scalar(odp_ipsec_sa_t, 0) +/* Placeholder for inlined API functions */ /** * @} diff --git a/platform/linux-generic/include-abi/odp/api/abi/ipsec_types.h b/platform/linux-generic/include-abi/odp/api/abi/ipsec_types.h new file mode 100644 index 000000000..376666ded --- /dev/null +++ b/platform/linux-generic/include-abi/odp/api/abi/ipsec_types.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2016-2018, Linaro Limited + * Copyright (c) 2022, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP IPsec platform specific types + */ + +#ifndef ODP_API_ABI_IPSEC_TYPES_H_ +#define ODP_API_ABI_IPSEC_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +/** @ingroup odp_ipsec + * @{ + */ + +typedef ODP_HANDLE_T(odp_ipsec_sa_t); + +#define ODP_IPSEC_SA_INVALID _odp_cast_scalar(odp_ipsec_sa_t, 0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3 From 0a8460c27a0592933cccefa3c16fe73dc2e3e50a Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 28 Oct 2022 13:14:42 +0300 Subject: linux-gen: ipsec: inline event conversion functions Inline odp_ipsec_packet_from_event() and odp_ipsec_packet_to_event() function implementations. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- platform/linux-generic/Makefile.am | 2 ++ .../linux-generic/include-abi/odp/api/abi/ipsec.h | 3 +- .../include/odp/api/plat/ipsec_inlines.h | 41 ++++++++++++++++++++++ platform/linux-generic/odp_ipsec.c | 15 ++------ platform/linux-generic/odp_ipsec_api.c | 11 ++++++ 5 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 platform/linux-generic/include/odp/api/plat/ipsec_inlines.h create mode 100644 platform/linux-generic/odp_ipsec_api.c (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 19506b5ff..e762148aa 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -39,6 +39,7 @@ odpapiplatinclude_HEADERS = \ include/odp/api/plat/event_inline_types.h \ include/odp/api/plat/event_vector_inline_types.h \ include/odp/api/plat/hash_inlines.h \ + include/odp/api/plat/ipsec_inlines.h \ include/odp/api/plat/packet_flag_inlines.h \ include/odp/api/plat/packet_inline_types.h \ include/odp/api/plat/packet_inlines.h \ @@ -289,6 +290,7 @@ __LIB__libodp_linux_la_SOURCES += \ odp_cpu_api.c \ odp_event_api.c \ odp_hash_api.c \ + odp_ipsec_api.c \ odp_packet_api.c \ odp_packet_flags_api.c \ odp_packet_io_api.c \ diff --git a/platform/linux-generic/include-abi/odp/api/abi/ipsec.h b/platform/linux-generic/include-abi/odp/api/abi/ipsec.h index f314f6a41..1817e5564 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/ipsec.h +++ b/platform/linux-generic/include-abi/odp/api/abi/ipsec.h @@ -18,7 +18,8 @@ extern "C" { #endif -/* Placeholder for inlined API functions */ +/* Inlined API functions */ +#include /** * @} diff --git a/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h new file mode 100644 index 000000000..a40a05dbf --- /dev/null +++ b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2022, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_PLAT_IPSEC_INLINES_H_ +#define ODP_PLAT_IPSEC_INLINES_H_ + +#include +#include + +#include + +/** @cond _ODP_HIDE_FROM_DOXYGEN_ */ + +#ifndef _ODP_NO_INLINE + /* Inline functions by default */ + #define _ODP_INLINE static inline + #define odp_ipsec_packet_from_event __odp_ipsec_packet_from_event + #define odp_ipsec_packet_to_event __odp_ipsec_packet_to_event +#else + #define _ODP_INLINE +#endif + +_ODP_INLINE odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) +{ + _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); + _ODP_ASSERT(odp_event_subtype(ev) == ODP_EVENT_PACKET_IPSEC); + + return odp_packet_from_event(ev); +} + +_ODP_INLINE odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt) +{ + return odp_packet_to_event(pkt); +} + +/** @endcond */ + +#endif diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index b26b71d1c..e459203fb 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -9,8 +9,9 @@ #include #include -#include #include +#include +#include #include #include @@ -2619,18 +2620,6 @@ int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) return 0; } -odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) -{ - _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); - _ODP_ASSERT(odp_event_subtype(ev) == ODP_EVENT_PACKET_IPSEC); - return odp_packet_from_event(ev); -} - -odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt) -{ - return odp_packet_to_event(pkt); -} - int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats) { ipsec_sa_t *ipsec_sa; diff --git a/platform/linux-generic/odp_ipsec_api.c b/platform/linux-generic/odp_ipsec_api.c new file mode 100644 index 000000000..1d1abe84a --- /dev/null +++ b/platform/linux-generic/odp_ipsec_api.c @@ -0,0 +1,11 @@ +/* Copyright (c) 2022, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* Non-inlined versions of API functions */ +#define _ODP_NO_INLINE +#include -- cgit v1.2.3 From 4a3bb9ca46667a67fd2255a7b2efd2b9a840229f Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 28 Oct 2022 14:07:45 +0300 Subject: linux-gen: ipsec: inline odp_ipsec_result() implementation Inline odp_ipsec_result() function implementation. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .../include/odp/api/plat/ipsec_inlines.h | 19 +++++++++++++++++++ .../include/odp/api/plat/packet_inline_types.h | 1 + platform/linux-generic/odp_ipsec.c | 16 ---------------- platform/linux-generic/odp_packet.c | 4 ++-- 4 files changed, 22 insertions(+), 18 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h index a40a05dbf..efedfe626 100644 --- a/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h @@ -8,9 +8,11 @@ #define ODP_PLAT_IPSEC_INLINES_H_ #include +#include #include #include +#include /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ @@ -19,10 +21,13 @@ #define _ODP_INLINE static inline #define odp_ipsec_packet_from_event __odp_ipsec_packet_from_event #define odp_ipsec_packet_to_event __odp_ipsec_packet_to_event + #define odp_ipsec_result __odp_ipsec_result #else #define _ODP_INLINE #endif +extern const _odp_packet_inline_offset_t _odp_packet_inline; + _ODP_INLINE odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) { _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); @@ -36,6 +41,20 @@ _ODP_INLINE odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt) return odp_packet_to_event(pkt); } +_ODP_INLINE int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t pkt) +{ + odp_ipsec_packet_result_t *res; + + _ODP_ASSERT(result != NULL); + _ODP_ASSERT(odp_packet_subtype(pkt) == ODP_EVENT_PACKET_IPSEC); + + res = _odp_pkt_get_ptr(pkt, odp_ipsec_packet_result_t, ipsec_ctx); + + *result = *res; + + return 0; +} + /** @endcond */ #endif diff --git a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h index 2ae0829c3..c1dcc0ecb 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h @@ -52,6 +52,7 @@ typedef struct _odp_packet_inline_offset_t { uint16_t flags; uint16_t subtype; uint16_t cls_mark; + uint16_t ipsec_ctx; } _odp_packet_inline_offset_t; diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index e459203fb..28d46c794 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -2604,22 +2604,6 @@ int odp_ipsec_test_sa_update(odp_ipsec_sa_t sa, return 0; } -int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) -{ - odp_ipsec_packet_result_t *res; - - _ODP_ASSERT(result != NULL); - - res = ipsec_pkt_result(packet); - - /* FIXME: maybe postprocess here, setting alg error in case of crypto - * error instead of processing packet fully in ipsec_in/out_single */ - - *result = *res; - - return 0; -} - int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats) { ipsec_sa_t *ipsec_sa; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 2ebf602e8..212e48de0 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -67,8 +67,8 @@ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { .input_flags = offsetof(odp_packet_hdr_t, p.input_flags), .flags = offsetof(odp_packet_hdr_t, p.flags), .subtype = offsetof(odp_packet_hdr_t, subtype), - .cls_mark = offsetof(odp_packet_hdr_t, cls_mark) - + .cls_mark = offsetof(odp_packet_hdr_t, cls_mark), + .ipsec_ctx = offsetof(odp_packet_hdr_t, ipsec_ctx), }; #include -- cgit v1.2.3 From c0871ea33e73fc77d1e001f650af3bd397922847 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 2 Nov 2022 09:01:58 +0200 Subject: linux-gen: move inline offset variable declarations Move declarations of extern inline offset variables to same headers with related accessor macros. This way each user of accessor macros won't have to redeclare the same variables. Unnecessary Doxygen comment syntax has been removed from pool_inline_types.h. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .../include/odp/api/plat/buffer_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/buffer_inlines.h | 4 ---- .../include/odp/api/plat/event_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/event_inlines.h | 3 --- .../include/odp/api/plat/event_vector_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/ipsec_inlines.h | 2 -- .../include/odp/api/plat/packet_flag_inlines.h | 2 -- .../include/odp/api/plat/packet_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/packet_inlines.h | 3 --- .../include/odp/api/plat/packet_vector_inlines.h | 2 -- .../include/odp/api/plat/pool_inline_types.h | 17 ++++++++++------- .../linux-generic/include/odp/api/plat/pool_inlines.h | 2 -- .../include/odp/api/plat/queue_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/queue_inlines.h | 1 - .../include/odp/api/plat/timer_inline_types.h | 2 ++ .../linux-generic/include/odp/api/plat/timer_inlines.h | 2 -- 16 files changed, 22 insertions(+), 28 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp/api/plat/buffer_inline_types.h b/platform/linux-generic/include/odp/api/plat/buffer_inline_types.h index 9689ddd06..f64a176f5 100644 --- a/platform/linux-generic/include/odp/api/plat/buffer_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/buffer_inline_types.h @@ -26,6 +26,8 @@ typedef struct _odp_buffer_inline_offset_t { } _odp_buffer_inline_offset_t; +extern const _odp_buffer_inline_offset_t _odp_buffer_inline_offset; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp/api/plat/buffer_inlines.h b/platform/linux-generic/include/odp/api/plat/buffer_inlines.h index d876f60f4..f3e133910 100644 --- a/platform/linux-generic/include/odp/api/plat/buffer_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/buffer_inlines.h @@ -19,10 +19,6 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern const _odp_event_inline_offset_t _odp_event_inline_offset; -extern const _odp_buffer_inline_offset_t _odp_buffer_inline_offset; -extern const _odp_pool_inline_offset_t _odp_pool_inline; - #ifndef _ODP_NO_INLINE /* Inline functions by default */ #define _ODP_INLINE static inline diff --git a/platform/linux-generic/include/odp/api/plat/event_inline_types.h b/platform/linux-generic/include/odp/api/plat/event_inline_types.h index 77a0deecb..caa075871 100644 --- a/platform/linux-generic/include/odp/api/plat/event_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/event_inline_types.h @@ -33,6 +33,8 @@ typedef struct _odp_event_inline_offset_t { } _odp_event_inline_offset_t; +extern const _odp_event_inline_offset_t _odp_event_inline_offset; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp/api/plat/event_inlines.h b/platform/linux-generic/include/odp/api/plat/event_inlines.h index dd8e9249c..37c015b21 100644 --- a/platform/linux-generic/include/odp/api/plat/event_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/event_inlines.h @@ -16,9 +16,6 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern const _odp_event_inline_offset_t _odp_event_inline_offset; -extern const _odp_packet_inline_offset_t _odp_packet_inline; - #ifndef _ODP_NO_INLINE /* Inline functions by default */ #define _ODP_INLINE static inline diff --git a/platform/linux-generic/include/odp/api/plat/event_vector_inline_types.h b/platform/linux-generic/include/odp/api/plat/event_vector_inline_types.h index 723e1a3d1..773f5171c 100644 --- a/platform/linux-generic/include/odp/api/plat/event_vector_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/event_vector_inline_types.h @@ -40,6 +40,8 @@ typedef struct _odp_event_vector_inline_offset_t { } _odp_event_vector_inline_offset_t; +extern const _odp_event_vector_inline_offset_t _odp_event_vector_inline; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h index efedfe626..1d1f6ec61 100644 --- a/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/ipsec_inlines.h @@ -26,8 +26,6 @@ #define _ODP_INLINE #endif -extern const _odp_packet_inline_offset_t _odp_packet_inline; - _ODP_INLINE odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) { _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); diff --git a/platform/linux-generic/include/odp/api/plat/packet_flag_inlines.h b/platform/linux-generic/include/odp/api/plat/packet_flag_inlines.h index 04ad9e968..9330d89f8 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_flag_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/packet_flag_inlines.h @@ -20,8 +20,6 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern const _odp_packet_inline_offset_t _odp_packet_inline; - static inline uint64_t _odp_packet_input_flags(odp_packet_t pkt) { return _odp_pkt_get(pkt, uint64_t, input_flags); diff --git a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h index c1dcc0ecb..ae03457f9 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h @@ -56,6 +56,8 @@ typedef struct _odp_packet_inline_offset_t { } _odp_packet_inline_offset_t; +extern const _odp_packet_inline_offset_t _odp_packet_inline; + /* Packet input & protocol flags */ typedef union { /* All input flags */ diff --git a/platform/linux-generic/include/odp/api/plat/packet_inlines.h b/platform/linux-generic/include/odp/api/plat/packet_inlines.h index 21d184ac5..01d47d837 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/packet_inlines.h @@ -111,9 +111,6 @@ int _odp_packet_copy_from_mem_seg(odp_packet_t pkt, uint32_t offset, int _odp_packet_copy_to_mem_seg(odp_packet_t pkt, uint32_t offset, uint32_t len, void *dst); -extern const _odp_packet_inline_offset_t _odp_packet_inline; -extern const _odp_pool_inline_offset_t _odp_pool_inline; - _ODP_INLINE void *odp_packet_data(odp_packet_t pkt) { return _odp_pkt_get(pkt, void *, seg_data); diff --git a/platform/linux-generic/include/odp/api/plat/packet_vector_inlines.h b/platform/linux-generic/include/odp/api/plat/packet_vector_inlines.h index 08fb07a62..2f8e0a709 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_vector_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/packet_vector_inlines.h @@ -42,8 +42,6 @@ #define _ODP_INLINE #endif -extern const _odp_event_vector_inline_offset_t _odp_event_vector_inline; - _ODP_INLINE odp_packet_vector_t odp_packet_vector_from_event(odp_event_t ev) { _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET_VECTOR); diff --git a/platform/linux-generic/include/odp/api/plat/pool_inline_types.h b/platform/linux-generic/include/odp/api/plat/pool_inline_types.h index 9deec89a1..02f59f982 100644 --- a/platform/linux-generic/include/odp/api/plat/pool_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/pool_inline_types.h @@ -17,25 +17,28 @@ extern "C" { #endif -/** @internal Pool field accessor */ +#include + +/** @cond _ODP_HIDE_FROM_DOXYGEN_ */ + +/** Pool field accessor */ #define _odp_pool_get(pool, cast, field) \ (*(cast *)(uintptr_t)((uint8_t *)pool + _odp_pool_inline.field)) -/** @internal Pool header field offsets for inline functions */ +/** Pool header field offsets for inline functions */ typedef struct _odp_pool_inline_offset_t { - /** @internal field offset */ uint16_t index; - /** @internal field offset */ uint16_t seg_len; - /** @internal field offset */ uint16_t uarea_size; - /** @internal field offset */ uint16_t ext_head_offset; - /** @internal field offset */ uint16_t ext_pkt_buf_size; } _odp_pool_inline_offset_t; +extern const _odp_pool_inline_offset_t _odp_pool_inline; + +/** @endcond */ + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/include/odp/api/plat/pool_inlines.h b/platform/linux-generic/include/odp/api/plat/pool_inlines.h index a304d2881..58d66fad2 100644 --- a/platform/linux-generic/include/odp/api/plat/pool_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/pool_inlines.h @@ -19,8 +19,6 @@ extern "C" { /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern const _odp_pool_inline_offset_t _odp_pool_inline; - #ifndef _ODP_NO_INLINE /* Inline functions by default */ #define _ODP_INLINE static inline diff --git a/platform/linux-generic/include/odp/api/plat/queue_inline_types.h b/platform/linux-generic/include/odp/api/plat/queue_inline_types.h index 4eade3dea..e957785c4 100644 --- a/platform/linux-generic/include/odp/api/plat/queue_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/queue_inline_types.h @@ -56,6 +56,8 @@ typedef struct { } _odp_queue_api_fn_t; +extern _odp_queue_inline_offset_t _odp_queue_inline_offset; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp/api/plat/queue_inlines.h b/platform/linux-generic/include/odp/api/plat/queue_inlines.h index c557b4ba3..22673a887 100644 --- a/platform/linux-generic/include/odp/api/plat/queue_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/queue_inlines.h @@ -11,7 +11,6 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern _odp_queue_inline_offset_t _odp_queue_inline_offset; extern const _odp_queue_api_fn_t *_odp_queue_api; #ifndef _ODP_NO_INLINE diff --git a/platform/linux-generic/include/odp/api/plat/timer_inline_types.h b/platform/linux-generic/include/odp/api/plat/timer_inline_types.h index ec6804c72..330cbe4ce 100644 --- a/platform/linux-generic/include/odp/api/plat/timer_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/timer_inline_types.h @@ -29,6 +29,8 @@ typedef struct _odp_timeout_inline_offset_t { } _odp_timeout_inline_offset_t; +extern const _odp_timeout_inline_offset_t _odp_timeout_inline_offset; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-generic/include/odp/api/plat/timer_inlines.h b/platform/linux-generic/include/odp/api/plat/timer_inlines.h index 4f5620caf..648459c78 100644 --- a/platform/linux-generic/include/odp/api/plat/timer_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/timer_inlines.h @@ -17,8 +17,6 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ -extern const _odp_timeout_inline_offset_t _odp_timeout_inline_offset; - #ifndef _ODP_NO_INLINE /* Inline functions by default */ #define _ODP_INLINE static inline -- cgit v1.2.3 From 4ee35763f485a2de95617db536f4e8f21c82fcc1 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 25 Oct 2022 15:21:45 +0300 Subject: api: packet: support additional l3 and l4 protocol types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move odp_proto_l2_type_t, odp_proto_l3_type_t, and odp_proto_l4_type_t types and defines from ABI to API header. L3 protocol type define values have been changed to match actual EtherType values. The size of odp_proto_l3_type_t is increased to accommodate this. Allow odp_packet_l3_type() and odp_packet_l4_type() functions to return also other protocol types than the ones defined in ODP_PROTO_L3_TYPE_* and ODP_PROTO_L4_TYPE_* defines. This enables implementations to support additional protocols without having to add each one to the ODP API. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen Reviewed-by: Kiran Kumar K --- .../include-abi/odp/api/abi/packet_types.h | 33 ---------------------- 1 file changed, 33 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include-abi/odp/api/abi/packet_types.h b/platform/linux-generic/include-abi/odp/api/abi/packet_types.h index be2cb9df6..4da9332ba 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/packet_types.h +++ b/platform/linux-generic/include-abi/odp/api/abi/packet_types.h @@ -49,39 +49,6 @@ typedef ODP_HANDLE_T(odp_packet_tx_compl_t); #define ODP_PACKET_OFFSET_INVALID 0xffff -typedef uint8_t odp_proto_l2_type_t; - -#define ODP_PROTO_L2_TYPE_NONE 0 -#define ODP_PROTO_L2_TYPE_ETH 1 - -typedef uint8_t odp_proto_l3_type_t; - -#define ODP_PROTO_L3_TYPE_NONE 0 -#define ODP_PROTO_L3_TYPE_ARP 1 -#define ODP_PROTO_L3_TYPE_RARP 2 -#define ODP_PROTO_L3_TYPE_MPLS 3 -#define ODP_PROTO_L3_TYPE_IPV4 4 -#define ODP_PROTO_L3_TYPE_IPV6 6 - -typedef uint8_t odp_proto_l4_type_t; - -/* Numbers from IANA Assigned Internet Protocol Numbers list */ -#define ODP_PROTO_L4_TYPE_NONE 0 -#define ODP_PROTO_L4_TYPE_ICMPV4 1 -#define ODP_PROTO_L4_TYPE_IGMP 2 -#define ODP_PROTO_L4_TYPE_IPV4 4 -#define ODP_PROTO_L4_TYPE_TCP 6 -#define ODP_PROTO_L4_TYPE_UDP 17 -#define ODP_PROTO_L4_TYPE_IPV6 41 -#define ODP_PROTO_L4_TYPE_GRE 47 -#define ODP_PROTO_L4_TYPE_ESP 50 -#define ODP_PROTO_L4_TYPE_AH 51 -#define ODP_PROTO_L4_TYPE_ICMPV6 58 -#define ODP_PROTO_L4_TYPE_NO_NEXT 59 -#define ODP_PROTO_L4_TYPE_IPCOMP 108 -#define ODP_PROTO_L4_TYPE_SCTP 132 -#define ODP_PROTO_L4_TYPE_ROHC 142 - typedef enum { ODP_PACKET_GREEN = 0, ODP_PACKET_YELLOW = 1, -- cgit v1.2.3 From 19bcb9061ad1205eb63fd216411b8d8aac29dd77 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 21 Oct 2022 17:34:19 +0300 Subject: linux-gen: buffer: implement multi variants of event conversion functions Implement new odp_buffer_from_event_multi() and odp_buffer_to_event_multi() functions. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale Reviewed-by: Petri Savolainen --- .../linux-generic/include/odp/api/plat/buffer_inlines.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp/api/plat/buffer_inlines.h b/platform/linux-generic/include/odp/api/plat/buffer_inlines.h index f3e133910..34d4b5675 100644 --- a/platform/linux-generic/include/odp/api/plat/buffer_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/buffer_inlines.h @@ -23,7 +23,9 @@ /* Inline functions by default */ #define _ODP_INLINE static inline #define odp_buffer_from_event __odp_buffer_from_event + #define odp_buffer_from_event_multi __odp_buffer_from_event_multi #define odp_buffer_to_event __odp_buffer_to_event + #define odp_buffer_to_event_multi __odp_buffer_to_event_multi #define odp_buffer_addr __odp_buffer_addr #define odp_buffer_size __odp_buffer_size #define odp_buffer_pool __odp_buffer_pool @@ -39,11 +41,23 @@ _ODP_INLINE odp_buffer_t odp_buffer_from_event(odp_event_t ev) return (odp_buffer_t)ev; } +_ODP_INLINE void odp_buffer_from_event_multi(odp_buffer_t buf[], const odp_event_t ev[], int num) +{ + for (int i = 0; i < num; i++) + buf[i] = odp_buffer_from_event(ev[i]); +} + _ODP_INLINE odp_event_t odp_buffer_to_event(odp_buffer_t buf) { return (odp_event_t)buf; } +_ODP_INLINE void odp_buffer_to_event_multi(const odp_buffer_t buf[], odp_event_t ev[], int num) +{ + for (int i = 0; i < num; i++) + ev[i] = odp_buffer_to_event(buf[i]); +} + _ODP_INLINE void *odp_buffer_addr(odp_buffer_t buf) { return _odp_event_hdr_field((odp_event_t)buf, void *, base_data); -- cgit v1.2.3 From 6ed6bbf27a48d26fb4681391af1dde2943d20b00 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 28 Oct 2022 10:06:57 +0300 Subject: api: pktio: add ODP_PKTIN_MAX_QUEUES define Add ODP_PKTIN_MAX_QUEUES define for maximum number of packet input queues. Signed-off-by: Matias Elo Reviewed-by: Nithin Dabilpuram Reviewed-by: Petri Savolainen --- platform/linux-generic/include-abi/odp/api/abi/packet_io_types.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include-abi/odp/api/abi/packet_io_types.h b/platform/linux-generic/include-abi/odp/api/abi/packet_io_types.h index 3106f26a7..1692e71b1 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/packet_io_types.h +++ b/platform/linux-generic/include-abi/odp/api/abi/packet_io_types.h @@ -47,6 +47,8 @@ typedef struct odp_pktout_queue_t { #define ODP_PKTIN_NO_WAIT 0 +#define ODP_PKTIN_MAX_QUEUES 64 + #define ODP_PKTOUT_MAX_QUEUES 64 #define ODP_PKTIO_STATS_EXTRA_NAME_LEN 64 -- cgit v1.2.3 From 5234e07944fa288836042b7673056f203b11c6df Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 31 Oct 2022 13:06:29 +0200 Subject: linux-gen: pcapng: move pcapng data out of common pktio_entry_t Reduce size of pktio_entry_t by moving pcapng specific data to a separate SHM block, which is allocated only when pcapng is enabled. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- .../linux-generic/include/odp_packet_io_internal.h | 8 --- platform/linux-generic/include/odp_pcapng.h | 4 +- platform/linux-generic/odp_packet_io.c | 18 ++---- platform/linux-generic/odp_pcapng.c | 70 +++++++++++++++------- 4 files changed, 56 insertions(+), 44 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index 844088ac1..e6373852b 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -165,14 +165,6 @@ typedef struct ODP_ALIGNED_CACHE { odp_pktout_queue_t pktout; } out_queue[PKTIO_MAX_QUEUES]; - /**< inotify instance for pcapng fifos */ - struct { - enum { - PCAPNG_WR_STOP = 0, - PCAPNG_WR_PKT, - } state[PKTIO_MAX_QUEUES]; - int fd[PKTIO_MAX_QUEUES]; - } pcapng; } pktio_entry_t; typedef struct { diff --git a/platform/linux-generic/include/odp_pcapng.h b/platform/linux-generic/include/odp_pcapng.h index b88427238..6f2a3dda5 100644 --- a/platform/linux-generic/include/odp_pcapng.h +++ b/platform/linux-generic/include/odp_pcapng.h @@ -19,8 +19,8 @@ extern "C" { int _odp_pcapng_start(pktio_entry_t *entry); void _odp_pcapng_stop(pktio_entry_t *entry); -int _odp_pcapng_write_pkts(pktio_entry_t *entry, int qidx, - const odp_packet_t packets[], int num); +int _odp_pcapng_dump_pkts(pktio_entry_t *entry, int qidx, + const odp_packet_t packets[], int num); #ifdef __cplusplus } diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 794452127..dcea113bc 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -2660,13 +2660,6 @@ int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num) return num_queues; } -static inline void _odp_dump_pcapng_pkts(pktio_entry_t *entry, int qidx, - const odp_packet_t packets[], int num) -{ - if (odp_unlikely(entry->pcapng.state[qidx] == PCAPNG_WR_PKT)) - _odp_pcapng_write_pkts(entry, qidx, packets, num); -} - int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num) { pktio_entry_t *entry; @@ -2684,7 +2677,7 @@ int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num) ret = entry->ops->recv(entry, queue.index, packets, num); if (_ODP_PCAPNG) - _odp_dump_pcapng_pkts(entry, queue.index, packets, ret); + _odp_pcapng_dump_pkts(entry, queue.index, packets, ret); return ret; } @@ -2715,7 +2708,7 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], int num, ret = entry->ops->recv_tmo(entry, queue.index, packets, num, wait); if (_ODP_PCAPNG) - _odp_dump_pcapng_pkts(entry, queue.index, packets, ret); + _odp_pcapng_dump_pkts(entry, queue.index, packets, ret); return ret; } @@ -2723,7 +2716,7 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], int num, while (1) { ret = entry->ops->recv(entry, queue.index, packets, num); if (_ODP_PCAPNG) - _odp_dump_pcapng_pkts(entry, queue.index, packets, ret); + _odp_pcapng_dump_pkts(entry, queue.index, packets, ret); if (ret != 0 || wait == 0) return ret; @@ -2791,8 +2784,7 @@ int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], uint32_t num_q, uint entry = get_pktio_entry(queues[lfrom].pktio); if (entry) - _odp_dump_pcapng_pkts(entry, lfrom, packets, - ret); + _odp_pcapng_dump_pkts(entry, lfrom, packets, ret); } return ret; @@ -2910,7 +2902,7 @@ int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], return 0; if (_ODP_PCAPNG) - _odp_dump_pcapng_pkts(entry, queue.index, packets, num); + _odp_pcapng_dump_pkts(entry, queue.index, packets, num); if (odp_unlikely(_odp_pktio_tx_compl_enabled(entry))) { for (int i = 0; i < num; i++) diff --git a/platform/linux-generic/odp_pcapng.c b/platform/linux-generic/odp_pcapng.c index d97e1ca9d..b08df3fc9 100644 --- a/platform/linux-generic/odp_pcapng.c +++ b/platform/linux-generic/odp_pcapng.c @@ -1,5 +1,5 @@ /* Copyright (c) 2018, Linaro Limited - * Copyright (c) 2019, Nokia + * Copyright (c) 2019-2022, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -11,11 +11,14 @@ #if defined(_ODP_PCAPNG) && _ODP_PCAPNG == 1 +#include #include #include #include +#include +#include #include #include #include @@ -73,19 +76,36 @@ typedef struct pcapng_enhanced_packet_block_s { uint32_t packet_len; } pcapng_enhanced_packet_block_t; +/** Pktio entry specific data */ +typedef struct { + pktio_entry_t *pktio_entry; + + /* inotify instances for pcapng fifos */ + enum { + PCAPNG_WR_STOP = 0, + PCAPNG_WR_PKT, + } state[PKTIO_MAX_QUEUES]; + int fd[PKTIO_MAX_QUEUES]; +} pcapng_entry_t; + typedef struct ODP_ALIGNED_CACHE { odp_shm_t shm; - pktio_entry_t *entry[ODP_CONFIG_PKTIO_ENTRIES]; int num_entries; pthread_t inotify_thread; int inotify_fd; int inotify_watch_fd; int inotify_is_running; odp_spinlock_t lock; + pcapng_entry_t entry[ODP_CONFIG_PKTIO_ENTRIES]; } pcapng_global_t; static pcapng_global_t *pcapng_gbl; +static inline pcapng_entry_t *pcapng_entry(pktio_entry_t *pktio_entry) +{ + return &pcapng_gbl->entry[odp_pktio_index(pktio_entry->handle)]; +} + int write_pcapng_hdr(pktio_entry_t *entry, int qidx); int _odp_pcapng_init_global(void) @@ -132,6 +152,7 @@ static void pcapng_drain_fifo(int fd) static void inotify_event_handle(pktio_entry_t *entry, int qidx, struct inotify_event *event) { + pcapng_entry_t *pcapng = pcapng_entry(entry); int mtu = _ODP_MAX(odp_pktin_maxlen(entry->handle), odp_pktout_maxlen(entry->handle)); if (event->mask & IN_OPEN) { @@ -140,23 +161,23 @@ static void inotify_event_handle(pktio_entry_t *entry, int qidx, if (PIPE_BUF < mtu + sizeof(pcapng_enhanced_packet_block_t) + sizeof(uint32_t)) { _ODP_ERR("PIPE_BUF:%d too small. Disabling pcap\n", PIPE_BUF); - entry->pcapng.state[qidx] = PCAPNG_WR_STOP; + pcapng->state[qidx] = PCAPNG_WR_STOP; return; } ret = write_pcapng_hdr(entry, qidx); if (ret) { - entry->pcapng.state[qidx] = PCAPNG_WR_STOP; + pcapng->state[qidx] = PCAPNG_WR_STOP; } else { - entry->pcapng.state[qidx] = PCAPNG_WR_PKT; + pcapng->state[qidx] = PCAPNG_WR_PKT; _ODP_DBG("Open %s for pcap tracing\n", event->name); } } else if (event->mask & IN_CLOSE) { - int fd = entry->pcapng.fd[qidx]; + int fd = pcapng->fd[qidx]; pcapng_drain_fifo(fd); - entry->pcapng.state[qidx] = PCAPNG_WR_STOP; + pcapng->state[qidx] = PCAPNG_WR_STOP; _ODP_DBG("Close %s for pcap tracing\n", event->name); } else { _ODP_ERR("Unknown inotify event 0x%08x\n", event->mask); @@ -207,7 +228,7 @@ static pktio_entry_t *pktio_from_event(struct inotify_event *event) odp_spinlock_lock(&pcapng_gbl->lock); for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; i++) { - pktio_entry_t *entry = pcapng_gbl->entry[i]; + pktio_entry_t *entry = pcapng_gbl->entry[i].pktio_entry; if (entry == NULL) continue; @@ -287,6 +308,7 @@ static int get_fifo_max_size(void) int _odp_pcapng_start(pktio_entry_t *entry) { + pcapng_entry_t *pcapng = pcapng_entry(entry); int ret = -1, fd; pthread_attr_t attr; unsigned int i; @@ -301,8 +323,8 @@ int _odp_pcapng_start(pktio_entry_t *entry) char pcapng_name[128]; char pcapng_path[256]; - entry->pcapng.fd[i] = -1; - entry->pcapng.state[i] = PCAPNG_WR_STOP; + pcapng->fd[i] = -1; + pcapng->state[i] = PCAPNG_WR_STOP; get_pcapng_fifo_name(pcapng_name, sizeof(pcapng_name), entry->name, i); @@ -320,7 +342,7 @@ int _odp_pcapng_start(pktio_entry_t *entry) fd = open(pcapng_path, O_RDWR | O_NONBLOCK); if (fd == -1) { _ODP_ERR("Fail to open fifo\n"); - entry->pcapng.state[i] = PCAPNG_WR_STOP; + pcapng->state[i] = PCAPNG_WR_STOP; if (remove(pcapng_path) == -1) _ODP_ERR("Can't remove fifo %s\n", pcapng_path); continue; @@ -333,14 +355,14 @@ int _odp_pcapng_start(pktio_entry_t *entry) _ODP_DBG("set pcap fifo size %i\n", fifo_sz); } - entry->pcapng.fd[i] = fd; + pcapng->fd[i] = fd; } odp_spinlock_lock(&pcapng_gbl->lock); /* already running from a previous pktio */ if (pcapng_gbl->inotify_is_running == 1) { - pcapng_gbl->entry[odp_pktio_index(entry->handle)] = entry; + pcapng->pktio_entry = entry; pcapng_gbl->num_entries++; odp_spinlock_unlock(&pcapng_gbl->lock); return 0; @@ -371,7 +393,7 @@ int _odp_pcapng_start(pktio_entry_t *entry) if (ret) { _ODP_ERR("Can't start inotify thread (ret=%d). pcapng disabled.\n", ret); } else { - pcapng_gbl->entry[odp_pktio_index(entry->handle)] = entry; + pcapng->pktio_entry = entry; pcapng_gbl->num_entries++; pcapng_gbl->inotify_is_running = 1; } @@ -390,13 +412,14 @@ out_destroy: void _odp_pcapng_stop(pktio_entry_t *entry) { + pcapng_entry_t *pcapng = pcapng_entry(entry); int ret; unsigned int i; unsigned int max_queue = _ODP_MAX(entry->num_in_queue, entry->num_out_queue); odp_spinlock_lock(&pcapng_gbl->lock); - pcapng_gbl->entry[odp_pktio_index(entry->handle)] = NULL; + pcapng->pktio_entry = NULL; pcapng_gbl->num_entries--; if (pcapng_gbl->inotify_is_running == 1 && @@ -427,8 +450,8 @@ void _odp_pcapng_stop(pktio_entry_t *entry) char pcapng_name[128]; char pcapng_path[256]; - entry->pcapng.state[i] = PCAPNG_WR_STOP; - close(entry->pcapng.fd[i]); + pcapng->state[i] = PCAPNG_WR_STOP; + close(pcapng->fd[i]); get_pcapng_fifo_name(pcapng_name, sizeof(pcapng_name), entry->name, i); @@ -442,10 +465,11 @@ void _odp_pcapng_stop(pktio_entry_t *entry) int write_pcapng_hdr(pktio_entry_t *entry, int qidx) { + pcapng_entry_t *pcapng = pcapng_entry(entry); size_t len; pcapng_section_hdr_block_t shb; pcapng_interface_description_block_t idb; - int fd = entry->pcapng.fd[qidx]; + int fd = pcapng->fd[qidx]; memset(&shb, 0, sizeof(shb)); memset(&idb, 0, sizeof(idb)); @@ -503,17 +527,21 @@ static ssize_t write_fifo(int fd, struct iovec *iov, int iovcnt) return len; } -int _odp_pcapng_write_pkts(pktio_entry_t *entry, int qidx, - const odp_packet_t packets[], int num) +int _odp_pcapng_dump_pkts(pktio_entry_t *entry, int qidx, + const odp_packet_t packets[], int num) { + pcapng_entry_t *pcapng = pcapng_entry(entry); int i = 0; struct iovec packet_iov[3 * num]; pcapng_enhanced_packet_block_t epb[num]; int iovcnt = 0; ssize_t block_len = 0; - int fd = entry->pcapng.fd[qidx]; + int fd = pcapng->fd[qidx]; ssize_t len = 0, wlen; + if (odp_likely(pcapng->state[qidx] != PCAPNG_WR_PKT)) + return 0; + for (i = 0; i < num; i++) { odp_packet_hdr_t *pkt_hdr = packet_hdr(packets[i]); uint32_t seg_len; -- cgit v1.2.3 From 5569a65116f998fa087ccaed221bd58a24ae62dc Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 31 Oct 2022 14:36:24 +0200 Subject: linux-gen: pktio: use ODP_PKTIN_MAX_QUEUES and ODP_PKTOUT_MAX_QUEUES Use separate ODP_PKTIN_MAX_QUEUES and ODP_PKTOUT_MAX_QUEUES defines where applicable. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- .../linux-generic/include/odp_packet_io_internal.h | 5 ++--- platform/linux-generic/odp_packet_io.c | 4 ++-- platform/linux-generic/odp_pcapng.c | 3 +++ platform/linux-generic/odp_schedule_scalable.c | 2 +- platform/linux-generic/pktio/dpdk.c | 19 ++++++++++--------- platform/linux-generic/pktio/netmap.c | 21 ++++++++++++--------- platform/linux-generic/pktio/null.c | 4 ++-- platform/linux-generic/pktio/socket_xdp.c | 8 ++++---- 8 files changed, 36 insertions(+), 30 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index e6373852b..73da0c2be 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -39,7 +39,6 @@ extern "C" { #include #include -#define PKTIO_MAX_QUEUES ODP_PKTOUT_MAX_QUEUES #define PKTIO_LSO_PROFILES 16 /* Assume at least Ethernet header per each segment */ #define PKTIO_LSO_MIN_PAYLOAD_OFFSET 14 @@ -158,12 +157,12 @@ typedef struct ODP_ALIGNED_CACHE { odp_queue_t queue; odp_pktin_queue_t pktin; odp_pktin_vector_config_t vector; - } in_queue[PKTIO_MAX_QUEUES]; + } in_queue[ODP_PKTIN_MAX_QUEUES]; struct { odp_queue_t queue; odp_pktout_queue_t pktout; - } out_queue[PKTIO_MAX_QUEUES]; + } out_queue[ODP_PKTOUT_MAX_QUEUES]; } pktio_entry_t; diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index dcea113bc..4eccbdc7d 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -259,7 +259,7 @@ static void init_out_queues(pktio_entry_t *entry) { int i; - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++) { entry->out_queue[i].queue = ODP_QUEUE_INVALID; entry->out_queue[i].pktout = PKTOUT_INVALID; } @@ -279,7 +279,7 @@ static void init_pktio_entry(pktio_entry_t *entry) odp_atomic_init_u64(&entry->stats_extra.out_discards, 0); odp_atomic_init_u64(&entry->tx_ts, 0); - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) { entry->in_queue[i].queue = ODP_QUEUE_INVALID; entry->in_queue[i].pktin = PKTIN_INVALID; } diff --git a/platform/linux-generic/odp_pcapng.c b/platform/linux-generic/odp_pcapng.c index b08df3fc9..4423b0483 100644 --- a/platform/linux-generic/odp_pcapng.c +++ b/platform/linux-generic/odp_pcapng.c @@ -46,6 +46,9 @@ #define INOTIFY_BUF_LEN (16 * (sizeof(struct inotify_event))) #define PCAPNG_WATCH_DIR "/var/run/odp/" +#define PKTIO_MAX_QUEUES (ODP_PKTIN_MAX_QUEUES > ODP_PKTOUT_MAX_QUEUES ? \ + ODP_PKTIN_MAX_QUEUES : ODP_PKTOUT_MAX_QUEUES) + /* pcapng: enhanced packet block file encoding */ typedef struct ODP_PACKED pcapng_section_hdr_block_s { uint32_t block_type; diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index f90189d05..172a4d336 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -716,7 +716,7 @@ static void pktio_start(int pktio_idx, _ODP_ASSERT(pktio_idx < ODP_CONFIG_PKTIO_ENTRIES); for (i = 0; i < num_in_queue; i++) { rxq = in_queue_idx[i]; - _ODP_ASSERT(rxq < PKTIO_MAX_QUEUES); + _ODP_ASSERT(rxq < ODP_PKTIN_MAX_QUEUES); __atomic_fetch_add(&global->poll_count[pktio_idx], 1, __ATOMIC_RELAXED); qentry = _odp_qentry_from_ext(odpq[i]); diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 30e6a0e61..205cf1075 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -141,7 +141,7 @@ typedef struct ODP_ALIGNED_CACHE { /* Minimum RX burst size */ uint8_t min_rx_burst; /* Cache for storing extra RX packets */ - pkt_cache_t rx_cache[PKTIO_MAX_QUEUES]; + pkt_cache_t rx_cache[ODP_PKTIN_MAX_QUEUES]; /* --- Control path data --- */ @@ -162,14 +162,14 @@ typedef struct ODP_ALIGNED_CACHE { /* Use system call to get/set vdev promisc mode */ uint8_t vdev_sysc_promisc; /* Number of TX descriptors per queue */ - uint16_t num_tx_desc[PKTIO_MAX_QUEUES]; + uint16_t num_tx_desc[ODP_PKTOUT_MAX_QUEUES]; /* --- Locks for MT safe operations --- */ /* RX queue locks */ - odp_ticketlock_t rx_lock[PKTIO_MAX_QUEUES] ODP_ALIGNED_CACHE; + odp_ticketlock_t rx_lock[ODP_PKTIN_MAX_QUEUES] ODP_ALIGNED_CACHE; /* TX queue locks */ - odp_ticketlock_t tx_lock[PKTIO_MAX_QUEUES] ODP_ALIGNED_CACHE; + odp_ticketlock_t tx_lock[ODP_PKTOUT_MAX_QUEUES] ODP_ALIGNED_CACHE; } pkt_dpdk_t; ODP_STATIC_ASSERT(PKTIO_PRIVATE_SIZE >= sizeof(pkt_dpdk_t), @@ -1264,7 +1264,7 @@ static int dpdk_close(pktio_entry_t *pktio_entry) unsigned i, j; /* Free cache packets */ - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) { idx = pkt_dpdk->rx_cache[i].idx; for (j = 0; j < pkt_dpdk->rx_cache[i].count; j++) @@ -1572,7 +1572,7 @@ static int dpdk_init_capability(pktio_entry_t *pktio_entry, memset(capa, 0, sizeof(odp_pktio_capability_t)); capa->max_input_queues = RTE_MIN(dev_info->max_rx_queues, - PKTIO_MAX_QUEUES); + ODP_PKTIN_MAX_QUEUES); /* ixgbe devices support only 16 rx queues in RSS mode */ if (!strncmp(dev_info->driver_name, IXGBE_DRV_NAME, @@ -1581,7 +1581,7 @@ static int dpdk_init_capability(pktio_entry_t *pktio_entry, capa->max_input_queues); capa->max_output_queues = RTE_MIN(dev_info->max_tx_queues, - PKTIO_MAX_QUEUES); + ODP_PKTOUT_MAX_QUEUES); capa->min_output_queue_size = dev_info->tx_desc_lim.nb_min; capa->max_output_queue_size = dev_info->tx_desc_lim.nb_max; @@ -1845,10 +1845,11 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED, return -1; } - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) odp_ticketlock_init(&pkt_dpdk->rx_lock[i]); + + for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++) odp_ticketlock_init(&pkt_dpdk->tx_lock[i]); - } rte_eth_stats_reset(pkt_dpdk->port_id); diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 41ded2ae1..0352e33f7 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -95,9 +95,9 @@ typedef struct { odp_bool_t lockless_rx; /**< no locking for rx */ odp_bool_t lockless_tx; /**< no locking for tx */ /** mapping of pktin queues to netmap rx descriptors */ - netmap_ring_t rx_desc_ring[PKTIO_MAX_QUEUES]; + netmap_ring_t rx_desc_ring[ODP_PKTIN_MAX_QUEUES]; /** mapping of pktout queues to netmap tx descriptors */ - netmap_ring_t tx_desc_ring[PKTIO_MAX_QUEUES]; + netmap_ring_t tx_desc_ring[ODP_PKTOUT_MAX_QUEUES]; netmap_opt_t opt; /**< options */ } pkt_netmap_t; @@ -314,13 +314,15 @@ static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry) int i, j; pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry); - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) { for (j = 0; j < NM_MAX_DESC; j++) { if (pkt_nm->rx_desc_ring[i].desc[j] != NULL) { nm_close(pkt_nm->rx_desc_ring[i].desc[j]); pkt_nm->rx_desc_ring[i].desc[j] = NULL; } } + } + for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++) { for (j = 0; j < NM_MAX_DESC; j++) { if (pkt_nm->tx_desc_ring[i].desc[j] != NULL) { nm_close(pkt_nm->tx_desc_ring[i].desc[j]); @@ -422,8 +424,8 @@ static void netmap_init_capability(pktio_entry_t *pktio_entry) memset(capa, 0, sizeof(odp_pktio_capability_t)); - capa->max_input_queues = PKTIO_MAX_QUEUES; - if (pkt_nm->num_rx_rings < PKTIO_MAX_QUEUES) + capa->max_input_queues = ODP_PKTIN_MAX_QUEUES; + if (pkt_nm->num_rx_rings < ODP_PKTIN_MAX_QUEUES) capa->max_input_queues = pkt_nm->num_rx_rings; if (capa->max_input_queues > NM_MAX_DESC) { /* Have to use a single descriptor to fetch packets from all @@ -434,8 +436,8 @@ static void netmap_init_capability(pktio_entry_t *pktio_entry) NM_MAX_DESC, capa->max_input_queues); } - capa->max_output_queues = PKTIO_MAX_QUEUES; - if (pkt_nm->num_tx_rings < PKTIO_MAX_QUEUES) + capa->max_output_queues = ODP_PKTOUT_MAX_QUEUES; + if (pkt_nm->num_tx_rings < ODP_PKTOUT_MAX_QUEUES) capa->max_output_queues = pkt_nm->num_tx_rings; if (capa->max_output_queues > NM_MAX_DESC) { capa->max_output_queues = NM_MAX_DESC; @@ -578,10 +580,11 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry, nm_close(desc); - for (i = 0; i < PKTIO_MAX_QUEUES; i++) { + for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) odp_ticketlock_init(&pkt_nm->rx_desc_ring[i].lock); + + for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++) odp_ticketlock_init(&pkt_nm->tx_desc_ring[i].lock); - } if (pkt_nm->is_virtual) { static unsigned int mac; diff --git a/platform/linux-generic/pktio/null.c b/platform/linux-generic/pktio/null.c index 0bd33f517..b067a68ec 100644 --- a/platform/linux-generic/pktio/null.c +++ b/platform/linux-generic/pktio/null.c @@ -130,8 +130,8 @@ static int null_capability(pktio_entry_t *pktio_entry ODP_UNUSED, { memset(capa, 0, sizeof(odp_pktio_capability_t)); - capa->max_input_queues = PKTIO_MAX_QUEUES; - capa->max_output_queues = PKTIO_MAX_QUEUES; + capa->max_input_queues = ODP_PKTIN_MAX_QUEUES; + capa->max_output_queues = ODP_PKTOUT_MAX_QUEUES; capa->set_op.op.promisc_mode = 0; odp_pktio_config_init(&capa->config); diff --git a/platform/linux-generic/pktio/socket_xdp.c b/platform/linux-generic/pktio/socket_xdp.c index b10fc9fce..be79ca267 100644 --- a/platform/linux-generic/pktio/socket_xdp.c +++ b/platform/linux-generic/pktio/socket_xdp.c @@ -94,7 +94,7 @@ typedef struct { } xdp_umem_info_t; typedef struct { - xdp_sock_t qs[PKTIO_MAX_QUEUES]; + xdp_sock_t qs[ODP_PKTOUT_MAX_QUEUES]; xdp_umem_info_t *umem_info; uint32_t num_q; int pktio_idx; @@ -275,7 +275,7 @@ static int sock_xdp_open(odp_pktio_t pktio, pktio_entry_t *pktio_entry, const ch priv->max_mtu = pool->seg_len; - for (int i = 0; i < PKTIO_MAX_QUEUES; ++i) { + for (int i = 0; i < ODP_PKTOUT_MAX_QUEUES; ++i) { odp_ticketlock_init(&priv->qs[i].rx_lock); odp_ticketlock_init(&priv->qs[i].tx_lock); } @@ -852,8 +852,8 @@ static int set_queue_capability(int fd, const char *devname, odp_pktio_capabilit channels.max_combined = 1U; } - max_channels = _ODP_MIN((uint32_t)PKTIO_MAX_QUEUES, channels.max_combined); - capa->max_input_queues = max_channels; + max_channels = _ODP_MIN((uint32_t)ODP_PKTOUT_MAX_QUEUES, channels.max_combined); + capa->max_input_queues = _ODP_MIN((uint32_t)ODP_PKTIN_MAX_QUEUES, max_channels); capa->max_output_queues = max_channels; return 0; -- cgit v1.2.3 From 329770bc72a56618fa417291e2b22fc4fc45471e Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 31 Oct 2022 15:48:59 +0200 Subject: linux-gen: pktio: check input queue size in odp_pktin_queue_config() Check that odp_pktin_queue_param_t.queue_size values are valid during odp_pktin_queue_config() call. All debug messages inside this function are converted into error messages, since this is not a fast path function. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- platform/linux-generic/odp_packet_io.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 4eccbdc7d..bce8df45a 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -2172,12 +2172,12 @@ int odp_pktin_queue_config(odp_pktio_t pktio, entry = get_pktio_entry(pktio); if (entry == NULL) { - _ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio); + _ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio); return -1; } if (entry->state == PKTIO_STATE_STARTED) { - _ODP_DBG("pktio %s: not stopped\n", entry->name); + _ODP_ERR("pktio %s: not stopped\n", entry->name); return -1; } @@ -2188,7 +2188,7 @@ int odp_pktin_queue_config(odp_pktio_t pktio, return 0; if (!param->classifier_enable && param->num_queues == 0) { - _ODP_DBG("invalid num_queues for operation mode\n"); + _ODP_ERR("invalid num_queues for operation mode\n"); return -1; } @@ -2196,17 +2196,39 @@ int odp_pktin_queue_config(odp_pktio_t pktio, rc = odp_pktio_capability(pktio, &capa); if (rc) { - _ODP_DBG("pktio %s: unable to read capabilities\n", entry->name); + _ODP_ERR("pktio %s: unable to read capabilities\n", entry->name); return -1; } entry->enabled.cls = !!param->classifier_enable; if (num_queues > capa.max_input_queues) { - _ODP_DBG("pktio %s: too many input queues\n", entry->name); + _ODP_ERR("pktio %s: too many input queues\n", entry->name); return -1; } + /* Check input queue sizes in direct mode */ + for (i = 0; i < num_queues && mode == ODP_PKTIN_MODE_DIRECT; i++) { + uint32_t queue_size = param->queue_size[i]; + + if (queue_size == 0) + continue; + + if (capa.max_input_queue_size == 0) { + _ODP_ERR("pktio %s: configuring input queue size not supported\n", + entry->name); + return -1; + } + if (queue_size < capa.min_input_queue_size) { + _ODP_ERR("pktio %s: input queue size too small\n", entry->name); + return -1; + } + if (queue_size > capa.max_input_queue_size) { + _ODP_ERR("pktio %s: input queue size too large\n", entry->name); + return -1; + } + } + /* Validate packet vector parameters */ if (param->vector.enable) { odp_pool_t pool = param->vector.pool; @@ -2282,7 +2304,7 @@ int odp_pktin_queue_config(odp_pktio_t pktio, queue = odp_queue_create(name, &queue_param); if (queue == ODP_QUEUE_INVALID) { - _ODP_DBG("pktio %s: event queue create failed\n", entry->name); + _ODP_ERR("pktio %s: event queue create failed\n", entry->name); destroy_in_queues(entry, i + 1); return -1; } -- cgit v1.2.3 From f94a1e914d2670a955f0c79596d7d528437a2a49 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 1 Nov 2022 09:24:19 +0200 Subject: linux-gen: loop: implement new packet input queue size parameter Implement new packet input queue size API for loop pktio. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- platform/linux-generic/pktio/loop.c | 53 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 947edd476..b30535f22 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -44,12 +44,15 @@ #define LOOP_MTU_MIN 68 #define LOOP_MTU_MAX UINT16_MAX -#define LOOP_MAX_TX_QUEUE_SIZE 1024 +#define LOOP_MAX_QUEUE_SIZE 1024 typedef struct { odp_queue_t loopq; /**< loopback queue for "loop" device */ + uint32_t pktin_queue_size; /**< input queue size */ + uint32_t pktout_queue_size; /**< output queue size */ uint16_t mtu; /**< link MTU */ uint8_t idx; /**< index of "loop" device */ + uint8_t queue_create; /**< create or re-create queue during start */ } pkt_loop_t; ODP_STATIC_ASSERT(PKTIO_PRIVATE_SIZE >= sizeof(pkt_loop_t), @@ -84,9 +87,11 @@ static int loopback_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry, return -1; } + memset(pkt_loop, 0, sizeof(pkt_loop_t)); pkt_loop->idx = idx; pkt_loop->mtu = LOOP_MTU_MAX; pkt_loop->loopq = ODP_QUEUE_INVALID; + pkt_loop->queue_create = 1; loopback_stats_reset(pktio_entry); loopback_init_capability(pktio_entry); @@ -112,19 +117,23 @@ static int loopback_queue_destroy(odp_queue_t queue) return 0; } -static int loopback_pktout_queue_config(pktio_entry_t *pktio_entry, - const odp_pktout_queue_param_t *param) +static int loopback_start(pktio_entry_t *pktio_entry) { pkt_loop_t *pkt_loop = pkt_priv(pktio_entry); odp_queue_param_t queue_param; char queue_name[ODP_QUEUE_NAME_LEN]; + /* Re-create queue only when necessary */ + if (!pkt_loop->queue_create) + return 0; + /* Destroy old queue */ if (pkt_loop->loopq != ODP_QUEUE_INVALID && loopback_queue_destroy(pkt_loop->loopq)) return -1; odp_queue_param_init(&queue_param); - queue_param.size = param->queue_size[0]; + queue_param.size = pkt_loop->pktin_queue_size > pkt_loop->pktout_queue_size ? + pkt_loop->pktin_queue_size : pkt_loop->pktout_queue_size; snprintf(queue_name, sizeof(queue_name), "_odp_pktio_loopq-%" PRIu64 "", odp_pktio_to_u64(pktio_entry->handle)); @@ -134,6 +143,31 @@ static int loopback_pktout_queue_config(pktio_entry_t *pktio_entry, _ODP_ERR("Creating loopback pktio queue failed\n"); return -1; } + pkt_loop->queue_create = 0; + + return 0; +} + +static int loopback_pktin_queue_config(pktio_entry_t *pktio_entry, + const odp_pktin_queue_param_t *param) +{ + pkt_loop_t *pkt_loop = pkt_priv(pktio_entry); + + if (pktio_entry->param.in_mode == ODP_PKTIN_MODE_DIRECT) { + pkt_loop->pktin_queue_size = param->queue_size[0]; + pkt_loop->queue_create = 1; + } + + return 0; +} + +static int loopback_pktout_queue_config(pktio_entry_t *pktio_entry, + const odp_pktout_queue_param_t *param) +{ + pkt_loop_t *pkt_loop = pkt_priv(pktio_entry); + + pkt_loop->pktout_queue_size = param->queue_size[0]; + pkt_loop->queue_create = 1; return 0; } @@ -485,10 +519,15 @@ static int loopback_init_capability(pktio_entry_t *pktio_entry) capa->maxlen.min_output = LOOP_MTU_MIN; capa->maxlen.max_output = LOOP_MTU_MAX; + capa->min_input_queue_size = 1; + capa->max_input_queue_size = queue_capa.plain.max_size; + if (capa->max_input_queue_size == 0) + capa->max_input_queue_size = LOOP_MAX_QUEUE_SIZE; + capa->min_output_queue_size = 1; capa->max_output_queue_size = queue_capa.plain.max_size; if (capa->max_output_queue_size == 0) - capa->max_output_queue_size = LOOP_MAX_TX_QUEUE_SIZE; + capa->max_output_queue_size = LOOP_MAX_QUEUE_SIZE; odp_pktio_config_init(&capa->config); capa->config.enable_loop = 1; @@ -591,7 +630,7 @@ const pktio_if_ops_t _odp_loopback_pktio_ops = { .term = NULL, .open = loopback_open, .close = loopback_close, - .start = NULL, + .start = loopback_start, .stop = NULL, .stats = loopback_stats, .stats_reset = loopback_stats_reset, @@ -612,6 +651,6 @@ const pktio_if_ops_t _odp_loopback_pktio_ops = { .pktio_ts_from_ns = NULL, .pktio_time = NULL, .config = NULL, - .input_queues_config = NULL, + .input_queues_config = loopback_pktin_queue_config, .output_queues_config = loopback_pktout_queue_config, }; -- cgit v1.2.3 From 05f20b780bf234a791f885fb0e0df49969bbd6c5 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 1 Nov 2022 11:08:06 +0200 Subject: linux-gen: dpdk: implement new packet input queue size parameter Implement new packet input queue size API for dpdk pktio. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- .../linux-generic/include/odp_packet_io_internal.h | 4 +- platform/linux-generic/pktio/dpdk.c | 57 ++++++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index 73da0c2be..954602959 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -69,9 +69,9 @@ struct pktio_if_ops; #elif defined(_ODP_PKTIO_XDP) #define PKTIO_PRIVATE_SIZE 29696 #elif defined(_ODP_PKTIO_DPDK) && ODP_CACHE_LINE_SIZE == 128 -#define PKTIO_PRIVATE_SIZE 4032 +#define PKTIO_PRIVATE_SIZE 4160 #elif defined(_ODP_PKTIO_DPDK) -#define PKTIO_PRIVATE_SIZE 3840 +#define PKTIO_PRIVATE_SIZE 3968 #else #define PKTIO_PRIVATE_SIZE 384 #endif diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 205cf1075..7e9db90ce 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -104,7 +104,7 @@ ODP_STATIC_ASSERT(DPDK_MIN_RX_BURST <= UINT8_MAX, "DPDK_MIN_RX_BURST too large") /** DPDK runtime configuration options */ typedef struct { - int num_rx_desc; + int num_rx_desc_default; int num_tx_desc_default; uint8_t multicast_en; uint8_t rx_drop_en; @@ -161,6 +161,8 @@ typedef struct ODP_ALIGNED_CACHE { uint8_t mtu_set; /* Use system call to get/set vdev promisc mode */ uint8_t vdev_sysc_promisc; + /* Number of RX descriptors per queue */ + uint16_t num_rx_desc[ODP_PKTIN_MAX_QUEUES]; /* Number of TX descriptors per queue */ uint16_t num_tx_desc[ODP_PKTOUT_MAX_QUEUES]; @@ -227,14 +229,8 @@ static int init_options(pktio_entry_t *pktio_entry, int val; if (!lookup_opt("num_rx_desc", dev_info->driver_name, - &opt->num_rx_desc)) + &opt->num_rx_desc_default)) return -1; - if (opt->num_rx_desc < dev_info->rx_desc_lim.nb_min || - opt->num_rx_desc > dev_info->rx_desc_lim.nb_max || - opt->num_rx_desc % dev_info->rx_desc_lim.nb_align) { - _ODP_ERR("Invalid number of RX descriptors\n"); - return -1; - } if (!lookup_opt("num_tx_desc", dev_info->driver_name, &opt->num_tx_desc_default)) @@ -255,7 +251,7 @@ static int init_options(pktio_entry_t *pktio_entry, _ODP_DBG("DPDK interface (%s): %" PRIu16 "\n", dev_info->driver_name, pkt_priv(pktio_entry)->port_id); _ODP_DBG(" multicast_en: %d\n", opt->multicast_en); - _ODP_DBG(" num_rx_desc: %d\n", opt->num_rx_desc); + _ODP_DBG(" num_rx_desc: %d\n", opt->num_rx_desc_default); _ODP_DBG(" num_tx_desc: %d\n", opt->num_tx_desc_default); _ODP_DBG(" rx_drop_en: %d\n", opt->rx_drop_en); @@ -1493,21 +1489,51 @@ static void prepare_rss_conf(pktio_entry_t *pktio_entry, static int dpdk_input_queues_config(pktio_entry_t *pktio_entry, const odp_pktin_queue_param_t *p) { + struct rte_eth_dev_info dev_info; + pkt_dpdk_t *pkt_dpdk = pkt_priv(pktio_entry); odp_pktin_mode_t mode = pktio_entry->param.in_mode; uint8_t lockless; + int ret; prepare_rss_conf(pktio_entry, p); /** * Scheduler synchronizes input queue polls. Only single thread * at a time polls a queue */ - if (mode == ODP_PKTIN_MODE_SCHED || - p->op_mode == ODP_PKTIO_OP_MT_UNSAFE) + if (mode == ODP_PKTIN_MODE_SCHED || p->op_mode == ODP_PKTIO_OP_MT_UNSAFE) lockless = 1; else lockless = 0; - pkt_priv(pktio_entry)->flags.lockless_rx = lockless; + pkt_dpdk->flags.lockless_rx = lockless; + + ret = rte_eth_dev_info_get(pkt_dpdk->port_id, &dev_info); + if (ret) { + _ODP_ERR("DPDK: rte_eth_dev_info_get() failed: %d\n", ret); + return -1; + } + + /* Configure RX descriptors */ + for (uint32_t i = 0; i < p->num_queues; i++) { + uint16_t num_rx_desc = pkt_dpdk->opt.num_rx_desc_default; + + if (mode == ODP_PKTIN_MODE_DIRECT && p->queue_size[i] != 0) { + num_rx_desc = p->queue_size[i]; + /* Make sure correct alignment is used */ + if (dev_info.rx_desc_lim.nb_align) + num_rx_desc = RTE_ALIGN_MUL_CEIL(num_rx_desc, + dev_info.rx_desc_lim.nb_align); + } + + if (num_rx_desc < dev_info.rx_desc_lim.nb_min || + num_rx_desc > dev_info.rx_desc_lim.nb_max || + num_rx_desc % dev_info.rx_desc_lim.nb_align) { + _ODP_ERR("DPDK: invalid number of RX descriptors (%" PRIu16 ") for queue " + "%" PRIu32 "\n", num_rx_desc, i); + return -1; + } + pkt_dpdk->num_rx_desc[i] = num_rx_desc; + } return 0; } @@ -1548,7 +1574,8 @@ static int dpdk_output_queues_config(pktio_entry_t *pktio_entry, if (num_tx_desc < dev_info.tx_desc_lim.nb_min || num_tx_desc > dev_info.tx_desc_lim.nb_max || num_tx_desc % dev_info.tx_desc_lim.nb_align) { - _ODP_ERR("DPDK: invalid number of TX descriptors\n"); + _ODP_ERR("DPDK: invalid number of TX descriptors (%" PRIu16 ") for queue " + "%" PRIu32 "\n", num_tx_desc, i); return -1; } pkt_dpdk->num_tx_desc[i] = num_tx_desc; @@ -1573,6 +1600,8 @@ static int dpdk_init_capability(pktio_entry_t *pktio_entry, capa->max_input_queues = RTE_MIN(dev_info->max_rx_queues, ODP_PKTIN_MAX_QUEUES); + capa->min_input_queue_size = dev_info->rx_desc_lim.nb_min; + capa->max_input_queue_size = dev_info->rx_desc_lim.nb_max; /* ixgbe devices support only 16 rx queues in RSS mode */ if (!strncmp(dev_info->driver_name, IXGBE_DRV_NAME, @@ -1904,7 +1933,7 @@ static int dpdk_setup_eth_rx(const pktio_entry_t *pktio_entry, for (i = 0; i < pktio_entry->num_in_queue; i++) { ret = rte_eth_rx_queue_setup(port_id, i, - pkt_dpdk->opt.num_rx_desc, + pkt_dpdk->num_rx_desc[i], rte_eth_dev_socket_id(port_id), &rxconf, pkt_dpdk->pkt_pool); if (ret < 0) { -- cgit v1.2.3 From b1c312eced6e45d542d98bba43cfb4f44a19140e Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 21 Oct 2022 12:42:11 +0300 Subject: api: shm: add segment info Added odp_shm_segment_info() which can be used to retrieve information of each memory segment of an SHM block. Signed-off-by: Petri Savolainen Reviewed-by: Harman Kalra Reviewed-by: Tuomas Taipale --- platform/linux-generic/include-abi/odp/api/abi/shared_memory.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include-abi/odp/api/abi/shared_memory.h b/platform/linux-generic/include-abi/odp/api/abi/shared_memory.h index 648bd1ee3..551d49e30 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/shared_memory.h +++ b/platform/linux-generic/include-abi/odp/api/abi/shared_memory.h @@ -31,6 +31,9 @@ typedef ODP_HANDLE_T(odp_shm_t); #define ODP_SHM_NAME_LEN 32 +#define ODP_SHM_IOVA_INVALID ((uint64_t)-1) +#define ODP_SHM_PA_INVALID ODP_SHM_IOVA_INVALID + /** * @} */ -- cgit v1.2.3 From 12420db0842dccb57f6d8e8cd9b6e3168b121018 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 8 Nov 2022 14:49:57 +0200 Subject: linux-gen: shm: implement odp_system_meminfo() Implemented the new odp_system_meminfo() call inside SHM module to be able to access details of all memory reservations. Signed-off-by: Petri Savolainen Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_ishm.c | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index 2c4f364e3..8bb558be2 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -2174,3 +2174,71 @@ void _odp_ishm_print(int block_index) odp_spinlock_unlock(&ishm_tbl->lock); } + +int32_t odp_system_meminfo(odp_system_meminfo_t *info, odp_system_memblock_t memblock[], + int32_t max_num) +{ + ishm_block_t *block; + int name_len, proc_index; + int32_t i; + uintptr_t addr; + uint64_t len, lost, page_size; + uint64_t lost_total = 0; + uint64_t len_total = 0; + int32_t num = 0; + const uint64_t huge_sz = odp_sys_huge_page_size(); + const uint64_t normal_sz = odp_sys_page_size(); + + odp_spinlock_lock(&ishm_tbl->lock); + procsync(); + + for (i = 0; i < ISHM_MAX_NB_BLOCKS; i++) { + block = &ishm_tbl->block[i]; + + len = block->len; + if (len == 0) + continue; + + lost = len - block->user_len; + + if (num < max_num) { + odp_system_memblock_t *mb = &memblock[num]; + + name_len = strlen(block->name); + if (name_len >= ODP_SYSTEM_MEMBLOCK_NAME_LEN) + name_len = ODP_SYSTEM_MEMBLOCK_NAME_LEN - 1; + + memcpy(mb->name, block->name, name_len); + mb->name[name_len] = 0; + + addr = 0; + proc_index = procfind_block(i); + if (proc_index >= 0) + addr = (uintptr_t)ishm_proctable->entry[proc_index].start; + + page_size = 0; + if (block->huge == HUGE) + page_size = huge_sz; + else if (block->huge == NORMAL) + page_size = normal_sz; + + mb->addr = addr; + mb->used = len; + mb->overhead = lost; + mb->page_size = page_size; + } + + len_total += len; + lost_total += lost; + + num++; + } + + odp_spinlock_unlock(&ishm_tbl->lock); + + info->total_mapped = len_total; + info->total_used = len_total; + info->total_overhead = lost_total; + + return num; +} -- cgit v1.2.3 From da93a8707bffa32e6d3b0a1bda8c01aa82d0aedf Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 9 Nov 2022 13:10:32 +0200 Subject: linux-gen: shm: implement odp_shm_segment_info() Added minimal implementation of the new odp_shm_segment_info() function. Only single (virtual address) segment is supported as SHM implementation does not keep record of physical address mapping. Signed-off-by: Petri Savolainen Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_shared_memory.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index 4103568a7..a0e822a53 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -124,6 +124,31 @@ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info) info->size = ishm_info.size; info->page_size = ishm_info.page_size; info->flags = ishm_info.user_flags; + info->num_seg = 1; + + return 0; +} + +int odp_shm_segment_info(odp_shm_t shm, uint32_t index, uint32_t num, + odp_shm_segment_info_t seg_info[]) +{ + odp_shm_info_t info; + + /* No physical memory segment information available */ + if (index != 0 || num != 1) { + _ODP_ERR("Only single segment supported (%u, %u)\n", index, num); + return -1; + } + + if (odp_shm_info(shm, &info)) { + _ODP_ERR("SHM info call failed\n"); + return -1; + } + + seg_info[0].addr = (uintptr_t)info.addr; + seg_info[0].iova = ODP_SHM_IOVA_INVALID; + seg_info[0].pa = ODP_SHM_PA_INVALID; + seg_info[0].len = info.size; return 0; } -- cgit v1.2.3 From c18394be28d17be184d144b4355f1b0047823a46 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 25 Nov 2022 11:03:32 +0200 Subject: linux-gen: pktio: implement flow control capa Minimal implementation of the new flow control capability and config APIs. Flow control configuration is not supported. Signed-off-by: Petri Savolainen Reviewed-by: Nithin Dabilpuram Reviewed-by: Matias Elo --- platform/linux-generic/odp_packet_io.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index bce8df45a..22b6bc916 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -602,6 +602,12 @@ int odp_pktio_config(odp_pktio_t hdl, const odp_pktio_config_t *config) return -1; } + if (config->flow_control.pause_rx != ODP_PKTIO_LINK_PAUSE_OFF || + config->flow_control.pause_tx != ODP_PKTIO_LINK_PAUSE_OFF) { + _ODP_ERR("Link flow control is not supported\n"); + return -1; + } + lock_entry(entry); if (entry->state == PKTIO_STATE_STARTED) { unlock_entry(entry); @@ -1509,6 +1515,8 @@ void odp_pktio_config_init(odp_pktio_config_t *config) config->parser.layer = ODP_PROTO_LAYER_ALL; config->reassembly.max_num_frags = 2; + config->flow_control.pause_rx = ODP_PKTIO_LINK_PAUSE_OFF; + config->flow_control.pause_tx = ODP_PKTIO_LINK_PAUSE_OFF; } int odp_pktio_info(odp_pktio_t hdl, odp_pktio_info_t *info) @@ -1813,6 +1821,10 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) capa->reassembly.ip = false; capa->reassembly.ipv4 = false; capa->reassembly.ipv6 = false; + capa->flow_control.pause_rx = 0; + capa->flow_control.pfc_rx = 0; + capa->flow_control.pause_tx = 0; + capa->flow_control.pfc_tx = 0; return ret; } -- cgit v1.2.3 From 79f3932daa0b04815441790a9a0b4d4cb2e621aa Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Oct 2022 17:43:21 +0300 Subject: api: cls: deprecate drop policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Classifier drop policy option is not well defined and does not relate to other API features. Signed-off-by: Petri Savolainen Reviewed-by: Jere Leppänen Reviewed-by: Kiran Kumar K --- .../linux-generic/include/odp_classification_datamodel.h | 2 ++ platform/linux-generic/odp_classification.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h index 00df57bef..daa783b07 100644 --- a/platform/linux-generic/include/odp_classification_datamodel.h +++ b/platform/linux-generic/include/odp_classification_datamodel.h @@ -145,7 +145,9 @@ typedef struct ODP_ALIGNED_CACHE cos_s { bool queue_group; odp_cls_hash_proto_t hash_proto; odp_pktin_vector_config_t vector; /* Packet vector config */ +#if ODP_DEPRECATED_API odp_cls_drop_t drop_policy; /* Associated Drop Policy */ +#endif size_t headroom; /* Headroom for this CoS */ odp_spinlock_t lock; /* cos lock */ odp_queue_param_t queue_param; diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index f1291ddcd..2ff06d734 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -137,7 +137,9 @@ void odp_cls_cos_param_init(odp_cls_cos_param_t *param) param->queue = ODP_QUEUE_INVALID; param->pool = ODP_POOL_INVALID; +#if ODP_DEPRECATED_API param->drop_policy = ODP_COS_DROP_NEVER; +#endif param->num_queue = 1; param->vector.enable = false; odp_queue_param_init(¶m->queue_param); @@ -234,9 +236,11 @@ static inline void _cls_queue_unwind(uint32_t tbl_index, uint32_t j) odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_in) { +#if ODP_DEPRECATED_API + odp_cls_drop_t drop_policy; +#endif uint32_t i, j; odp_queue_t queue; - odp_cls_drop_t drop_policy; cos_t *cos; uint32_t tbl_index; odp_cls_cos_param_t param = *param_in; @@ -275,7 +279,9 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_ } } +#if ODP_DEPRECATED_API drop_policy = param.drop_policy; +#endif for (i = 0; i < CLS_COS_MAX_ENTRY; i++) { cos = &cos_tbl->cos_entry[i]; @@ -336,7 +342,9 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_ cos->pool = param.pool; cos->headroom = 0; cos->valid = 1; +#if ODP_DEPRECATED_API cos->drop_policy = drop_policy; +#endif odp_atomic_init_u32(&cos->num_rule, 0); cos->index = i; cos->vector = param.vector; @@ -493,6 +501,8 @@ uint32_t odp_cls_cos_queues(odp_cos_t cos_id, odp_queue_t queue[], return cos->num_queue; } +#if ODP_DEPRECATED_API + int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy) { cos_t *cos = get_cos_entry(cos_id); @@ -519,6 +529,8 @@ odp_cls_drop_t odp_cos_drop(odp_cos_t cos_id) return cos->drop_policy; } +#endif + int odp_pktio_default_cos_set(odp_pktio_t pktio_in, odp_cos_t default_cos) { pktio_entry_t *entry; -- cgit v1.2.3 From b73c1a5aeb6c5b6d4f0eafbcd1119cb160517184 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 31 Oct 2022 13:54:06 +0200 Subject: api: cls: deprecate odp_cos_with_l2_priority() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PMR term for matching VLAN PCP field has been added previously. It can be used instead of an odp_cos_with_l2_priority() call to setup a CoS per VLAN priority. Removing the function as it is redundant. Signed-off-by: Petri Savolainen Reviewed-by: Jere Leppänen Reviewed-by: Kiran Kumar K --- platform/linux-generic/odp_classification.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'platform/linux-generic') diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 2ff06d734..96ac4c640 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -593,10 +593,8 @@ int odp_pktio_headroom_set(odp_pktio_t pktio_in, uint32_t headroom) return 0; } -int odp_cos_with_l2_priority(odp_pktio_t pktio_in, - uint8_t num_qos, - uint8_t qos_table[], - odp_cos_t cos_table[]) +int ODP_DEPRECATE(odp_cos_with_l2_priority)(odp_pktio_t pktio_in, uint8_t num_qos, + uint8_t qos_table[], odp_cos_t cos_table[]) { pmr_l2_cos_t *l2_cos; uint32_t i; -- cgit v1.2.3