diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index a9929396c3..f426785ca4 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -1736,6 +1736,14 @@ int rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, uint32_t direction); +/** + * @internal + * Register mbuf dynamic field and flag for IP reassembly incomplete case. + */ +__rte_internal +int +rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag); + /* * Legacy ethdev API used internally by drivers. diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 1f63201024..3755a31795 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -6723,6 +6723,34 @@ rte_eth_ip_reassembly_conf_set(uint16_t port_id, (*dev->dev_ops->ip_reassembly_conf_set)(dev, conf)); } +int +rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset) +{ + static const struct rte_mbuf_dynfield field_desc = { + .name = RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, + .size = sizeof(rte_eth_ip_reassembly_dynfield_t), + .align = __alignof__(rte_eth_ip_reassembly_dynfield_t), + }; + static const struct rte_mbuf_dynflag ip_reassembly_dynflag = { + .name = RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, + }; + int offset; + + offset = rte_mbuf_dynfield_register(&field_desc); + if (offset < 0) + return -1; + if (field_offset != NULL) + *field_offset = offset; + + offset = rte_mbuf_dynflag_register(&ip_reassembly_dynflag); + if (offset < 0) + return -1; + if (flag_offset != NULL) + *flag_offset = offset; + + return 0; +} + RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO); RTE_INIT(ethdev_init_telemetry) diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 13d84abb89..bee798604c 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -5389,6 +5389,12 @@ int rte_eth_ip_reassembly_conf_get(uint16_t port_id, * configuration. The use of this API is mandatory to enable this feature and * should be called before rte_eth_dev_start(). * + * In datapath, PMD cannot guarantee that IP reassembly is always successful. + * Hence, PMD shall register mbuf dynamic field and dynamic flag using + * rte_eth_ip_reassembly_dynfield_register() to denote incomplete IP reassembly. + * If dynfield is not successfully registered, error will be returned and + * IP reassembly offload cannot be used. + * * @param port_id * The port identifier of the device. * @param conf @@ -5398,13 +5404,33 @@ int rte_eth_ip_reassembly_conf_get(uint16_t port_id, * - (-ENODEV) if *port_id* invalid. * - (-EIO) if device is removed. * - (-EINVAL) if device is not configured or if device is already started or - * if *conf* passed is NULL. + * if *conf* passed is NULL or if mbuf dynfield is not registered + * successfully by the PMD. * - (0) on success. */ __rte_experimental int rte_eth_ip_reassembly_conf_set(uint16_t port_id, const struct rte_eth_ip_reassembly_params *conf); +/** + * In case of IP reassembly offload failure, packet will be updated with + * dynamic flag - RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME and packets + * will be returned without alteration. + * The application can retrieve the attached fragments using mbuf dynamic field + * RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME. + */ +typedef struct { + /** + * Next fragment packet. Application should fetch dynamic field of + * each fragment until a NULL is received and nb_frags is 0. + */ + struct rte_mbuf *next_frag; + /** Time spent(in ms) by HW in waiting for further fragments. */ + uint16_t time_spent; + /** Number of more fragments attached in mbuf dynamic fields. */ + uint16_t nb_frags; +} rte_eth_ip_reassembly_dynfield_t; + #include diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index a2cc0d2f24..1ca7ec33ee 100644 --- a/lib/ethdev/version.map +++ b/lib/ethdev/version.map @@ -287,6 +287,7 @@ INTERNAL { rte_eth_hairpin_queue_peer_bind; rte_eth_hairpin_queue_peer_unbind; rte_eth_hairpin_queue_peer_update; + rte_eth_ip_reassembly_dynfield_register; rte_eth_representor_id_get; rte_eth_switch_domain_alloc; rte_eth_switch_domain_free; diff --git a/lib/mbuf/rte_mbuf_dyn.h b/lib/mbuf/rte_mbuf_dyn.h index 29abe8da53..5e981ac633 100644 --- a/lib/mbuf/rte_mbuf_dyn.h +++ b/lib/mbuf/rte_mbuf_dyn.h @@ -320,6 +320,15 @@ int rte_mbuf_dyn_rx_timestamp_register(int *field_offset, uint64_t *rx_flag); */ int rte_mbuf_dyn_tx_timestamp_register(int *field_offset, uint64_t *tx_flag); +/** + * For the PMDs which support IP reassembly of packets, PMD will update the + * packet with RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME to denote that + * IP reassembly is incomplete and application can retrieve the packets back + * using RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME. + */ +#define RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME "rte_dynfield_ip_reassembly" +#define RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME "rte_dynflag_ip_reassembly_incomplete" + #ifdef __cplusplus } #endif