199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright 2019 6WIND S.A. 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _RTE_MBUF_DYN_H_ 699a2dd95SBruce Richardson #define _RTE_MBUF_DYN_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson /** 999a2dd95SBruce Richardson * @file 1099a2dd95SBruce Richardson * RTE Mbuf dynamic fields and flags 1199a2dd95SBruce Richardson * 1299a2dd95SBruce Richardson * Many DPDK features require to store data inside the mbuf. As the room 1399a2dd95SBruce Richardson * in mbuf structure is limited, it is not possible to have a field for 1499a2dd95SBruce Richardson * each feature. Also, changing fields in the mbuf structure can break 1599a2dd95SBruce Richardson * the API or ABI. 1699a2dd95SBruce Richardson * 1799a2dd95SBruce Richardson * This module addresses this issue, by enabling the dynamic 1899a2dd95SBruce Richardson * registration of fields or flags: 1999a2dd95SBruce Richardson * 2099a2dd95SBruce Richardson * - a dynamic field is a named area in the rte_mbuf structure, with a 2199a2dd95SBruce Richardson * given size (>= 1 byte) and alignment constraint. 2299a2dd95SBruce Richardson * - a dynamic flag is a named bit in the rte_mbuf structure, stored 2399a2dd95SBruce Richardson * in mbuf->ol_flags. 2499a2dd95SBruce Richardson * 2599a2dd95SBruce Richardson * The placement of the field or flag can be automatic, in this case the 2699a2dd95SBruce Richardson * zones that have the smallest size and alignment constraint are 2799a2dd95SBruce Richardson * selected in priority. Else, a specific field offset or flag bit 2899a2dd95SBruce Richardson * number can be requested through the API. 2999a2dd95SBruce Richardson * 3099a2dd95SBruce Richardson * The typical use case is when a specific offload feature requires to 3199a2dd95SBruce Richardson * register a dedicated offload field in the mbuf structure, and adding 3299a2dd95SBruce Richardson * a static field or flag is not justified. 3399a2dd95SBruce Richardson * 3499a2dd95SBruce Richardson * Example of use: 3599a2dd95SBruce Richardson * 3699a2dd95SBruce Richardson * - A rte_mbuf_dynfield structure is defined, containing the parameters 3799a2dd95SBruce Richardson * of the dynamic field to be registered: 3899a2dd95SBruce Richardson * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... }; 3999a2dd95SBruce Richardson * - The application initializes the PMD, and asks for this feature 40295968d1SFerruh Yigit * at port initialization by passing RTE_ETH_RX_OFFLOAD_MY_FEATURE in 4199a2dd95SBruce Richardson * rxconf. This will make the PMD to register the field by calling 4299a2dd95SBruce Richardson * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD 4399a2dd95SBruce Richardson * stores the returned offset. 4499a2dd95SBruce Richardson * - The application that uses the offload feature also registers 4599a2dd95SBruce Richardson * the field to retrieve the same offset. 4699a2dd95SBruce Richardson * - When the PMD receives a packet, it can set the field: 4799a2dd95SBruce Richardson * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value; 4899a2dd95SBruce Richardson * - In the main loop, the application can retrieve the value with 4999a2dd95SBruce Richardson * the same macro. 5099a2dd95SBruce Richardson * 5199a2dd95SBruce Richardson * To avoid wasting space, the dynamic fields or flags must only be 5299a2dd95SBruce Richardson * reserved on demand, when an application asks for the related feature. 5399a2dd95SBruce Richardson * 5499a2dd95SBruce Richardson * The registration can be done at any moment, but it is not possible 5599a2dd95SBruce Richardson * to unregister fields or flags for now. 5699a2dd95SBruce Richardson * 5799a2dd95SBruce Richardson * A dynamic field can be reserved and used by an application only. 5899a2dd95SBruce Richardson * It can for instance be a packet mark. 5999a2dd95SBruce Richardson * 6099a2dd95SBruce Richardson * To avoid namespace collisions, the dynamic mbuf field or flag names 6199a2dd95SBruce Richardson * have to be chosen with care. It is advised to use the same 6299a2dd95SBruce Richardson * conventions than function names in dpdk: 6399a2dd95SBruce Richardson * - "rte_mbuf_dynfield_<name>" if defined in mbuf library 6499a2dd95SBruce Richardson * - "rte_<libname>_dynfield_<name>" if defined in another library 6599a2dd95SBruce Richardson * - "rte_net_<pmd>_dynfield_<name>" if defined in a PMD 6699a2dd95SBruce Richardson * - any name that does not start with "rte_" in an application 6799a2dd95SBruce Richardson */ 6899a2dd95SBruce Richardson 6999a2dd95SBruce Richardson #include <stdio.h> 7099a2dd95SBruce Richardson #include <stdint.h> 7199a2dd95SBruce Richardson 7299a2dd95SBruce Richardson 7399a2dd95SBruce Richardson #ifdef __cplusplus 7499a2dd95SBruce Richardson extern "C" { 7599a2dd95SBruce Richardson #endif 7699a2dd95SBruce Richardson 7799a2dd95SBruce Richardson /** 7899a2dd95SBruce Richardson * Maximum length of the dynamic field or flag string. 7999a2dd95SBruce Richardson */ 8099a2dd95SBruce Richardson #define RTE_MBUF_DYN_NAMESIZE 64 8199a2dd95SBruce Richardson 8299a2dd95SBruce Richardson /** 8399a2dd95SBruce Richardson * Structure describing the parameters of a mbuf dynamic field. 8499a2dd95SBruce Richardson */ 8599a2dd95SBruce Richardson struct rte_mbuf_dynfield { 8699a2dd95SBruce Richardson char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */ 8799a2dd95SBruce Richardson size_t size; /**< The number of bytes to reserve. */ 8899a2dd95SBruce Richardson size_t align; /**< The alignment constraint (power of 2). */ 8999a2dd95SBruce Richardson unsigned int flags; /**< Reserved for future use, must be 0. */ 9099a2dd95SBruce Richardson }; 9199a2dd95SBruce Richardson 9299a2dd95SBruce Richardson /** 9399a2dd95SBruce Richardson * Structure describing the parameters of a mbuf dynamic flag. 9499a2dd95SBruce Richardson */ 9599a2dd95SBruce Richardson struct rte_mbuf_dynflag { 9699a2dd95SBruce Richardson char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */ 9799a2dd95SBruce Richardson unsigned int flags; /**< Reserved for future use, must be 0. */ 9899a2dd95SBruce Richardson }; 9999a2dd95SBruce Richardson 10099a2dd95SBruce Richardson /** 10199a2dd95SBruce Richardson * Register space for a dynamic field in the mbuf structure. 10299a2dd95SBruce Richardson * 10399a2dd95SBruce Richardson * If the field is already registered (same name and parameters), its 10499a2dd95SBruce Richardson * offset is returned. 10599a2dd95SBruce Richardson * 10699a2dd95SBruce Richardson * @param params 10799a2dd95SBruce Richardson * A structure containing the requested parameters (name, size, 10899a2dd95SBruce Richardson * alignment constraint and flags). 10999a2dd95SBruce Richardson * @return 11099a2dd95SBruce Richardson * The offset in the mbuf structure, or -1 on error. 11199a2dd95SBruce Richardson * Possible values for rte_errno: 11299a2dd95SBruce Richardson * - EINVAL: invalid parameters (size, align, or flags). 11399a2dd95SBruce Richardson * - EEXIST: this name is already register with different parameters. 11499a2dd95SBruce Richardson * - EPERM: called from a secondary process. 11599a2dd95SBruce Richardson * - ENOENT: not enough room in mbuf. 11699a2dd95SBruce Richardson * - ENOMEM: allocation failure. 11799a2dd95SBruce Richardson * - ENAMETOOLONG: name does not ends with \0. 11899a2dd95SBruce Richardson */ 11999a2dd95SBruce Richardson int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params); 12099a2dd95SBruce Richardson 12199a2dd95SBruce Richardson /** 12299a2dd95SBruce Richardson * Register space for a dynamic field in the mbuf structure at offset. 12399a2dd95SBruce Richardson * 12499a2dd95SBruce Richardson * If the field is already registered (same name, parameters and offset), 12599a2dd95SBruce Richardson * the offset is returned. 12699a2dd95SBruce Richardson * 12799a2dd95SBruce Richardson * @param params 12899a2dd95SBruce Richardson * A structure containing the requested parameters (name, size, 12999a2dd95SBruce Richardson * alignment constraint and flags). 13099a2dd95SBruce Richardson * @param offset 13199a2dd95SBruce Richardson * The requested offset. Ignored if SIZE_MAX is passed. 13299a2dd95SBruce Richardson * @return 13399a2dd95SBruce Richardson * The offset in the mbuf structure, or -1 on error. 13499a2dd95SBruce Richardson * Possible values for rte_errno: 13599a2dd95SBruce Richardson * - EINVAL: invalid parameters (size, align, flags, or offset). 13699a2dd95SBruce Richardson * - EEXIST: this name is already register with different parameters. 13799a2dd95SBruce Richardson * - EBUSY: the requested offset cannot be used. 13899a2dd95SBruce Richardson * - EPERM: called from a secondary process. 13999a2dd95SBruce Richardson * - ENOENT: not enough room in mbuf. 14099a2dd95SBruce Richardson * - ENOMEM: allocation failure. 14199a2dd95SBruce Richardson * - ENAMETOOLONG: name does not ends with \0. 14299a2dd95SBruce Richardson */ 14399a2dd95SBruce Richardson int rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params, 14499a2dd95SBruce Richardson size_t offset); 14599a2dd95SBruce Richardson 14699a2dd95SBruce Richardson /** 14799a2dd95SBruce Richardson * Lookup for a registered dynamic mbuf field. 14899a2dd95SBruce Richardson * 14999a2dd95SBruce Richardson * @param name 15099a2dd95SBruce Richardson * A string identifying the dynamic field. 15199a2dd95SBruce Richardson * @param params 15299a2dd95SBruce Richardson * If not NULL, and if the lookup is successful, the structure is 15399a2dd95SBruce Richardson * filled with the parameters of the dynamic field. 15499a2dd95SBruce Richardson * @return 15599a2dd95SBruce Richardson * The offset of this field in the mbuf structure, or -1 on error. 15699a2dd95SBruce Richardson * Possible values for rte_errno: 15799a2dd95SBruce Richardson * - ENOENT: no dynamic field matches this name. 15899a2dd95SBruce Richardson */ 15999a2dd95SBruce Richardson int rte_mbuf_dynfield_lookup(const char *name, 16099a2dd95SBruce Richardson struct rte_mbuf_dynfield *params); 16199a2dd95SBruce Richardson 16299a2dd95SBruce Richardson /** 16399a2dd95SBruce Richardson * Register a dynamic flag in the mbuf structure. 16499a2dd95SBruce Richardson * 16599a2dd95SBruce Richardson * If the flag is already registered (same name and parameters), its 16699a2dd95SBruce Richardson * bitnum is returned. 16799a2dd95SBruce Richardson * 16899a2dd95SBruce Richardson * @param params 16999a2dd95SBruce Richardson * A structure containing the requested parameters of the dynamic 17099a2dd95SBruce Richardson * flag (name and options). 17199a2dd95SBruce Richardson * @return 17299a2dd95SBruce Richardson * The number of the reserved bit, or -1 on error. 17399a2dd95SBruce Richardson * Possible values for rte_errno: 17499a2dd95SBruce Richardson * - EINVAL: invalid parameters (size, align, or flags). 17599a2dd95SBruce Richardson * - EEXIST: this name is already register with different parameters. 17699a2dd95SBruce Richardson * - EPERM: called from a secondary process. 17799a2dd95SBruce Richardson * - ENOENT: no more flag available. 17899a2dd95SBruce Richardson * - ENOMEM: allocation failure. 17999a2dd95SBruce Richardson * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1. 18099a2dd95SBruce Richardson */ 18199a2dd95SBruce Richardson int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params); 18299a2dd95SBruce Richardson 18399a2dd95SBruce Richardson /** 18499a2dd95SBruce Richardson * Register a dynamic flag in the mbuf structure specifying bitnum. 18599a2dd95SBruce Richardson * 18699a2dd95SBruce Richardson * If the flag is already registered (same name, parameters and bitnum), 18799a2dd95SBruce Richardson * the bitnum is returned. 18899a2dd95SBruce Richardson * 18999a2dd95SBruce Richardson * @param params 19099a2dd95SBruce Richardson * A structure containing the requested parameters of the dynamic 19199a2dd95SBruce Richardson * flag (name and options). 19299a2dd95SBruce Richardson * @param bitnum 19399a2dd95SBruce Richardson * The requested bitnum. Ignored if UINT_MAX is passed. 19499a2dd95SBruce Richardson * @return 19599a2dd95SBruce Richardson * The number of the reserved bit, or -1 on error. 19699a2dd95SBruce Richardson * Possible values for rte_errno: 19799a2dd95SBruce Richardson * - EINVAL: invalid parameters (size, align, or flags). 19899a2dd95SBruce Richardson * - EEXIST: this name is already register with different parameters. 19999a2dd95SBruce Richardson * - EBUSY: the requested bitnum cannot be used. 20099a2dd95SBruce Richardson * - EPERM: called from a secondary process. 20199a2dd95SBruce Richardson * - ENOENT: no more flag available. 20299a2dd95SBruce Richardson * - ENOMEM: allocation failure. 20399a2dd95SBruce Richardson * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1. 20499a2dd95SBruce Richardson */ 20599a2dd95SBruce Richardson int rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params, 20699a2dd95SBruce Richardson unsigned int bitnum); 20799a2dd95SBruce Richardson 20899a2dd95SBruce Richardson /** 20999a2dd95SBruce Richardson * Lookup for a registered dynamic mbuf flag. 21099a2dd95SBruce Richardson * 21199a2dd95SBruce Richardson * @param name 21299a2dd95SBruce Richardson * A string identifying the dynamic flag. 21399a2dd95SBruce Richardson * @param params 21499a2dd95SBruce Richardson * If not NULL, and if the lookup is successful, the structure is 21599a2dd95SBruce Richardson * filled with the parameters of the dynamic flag. 21699a2dd95SBruce Richardson * @return 21799a2dd95SBruce Richardson * The offset of this flag in the mbuf structure, or -1 on error. 21899a2dd95SBruce Richardson * Possible values for rte_errno: 21999a2dd95SBruce Richardson * - ENOENT: no dynamic flag matches this name. 22099a2dd95SBruce Richardson */ 22199a2dd95SBruce Richardson int rte_mbuf_dynflag_lookup(const char *name, 22299a2dd95SBruce Richardson struct rte_mbuf_dynflag *params); 22399a2dd95SBruce Richardson 22499a2dd95SBruce Richardson /** 22599a2dd95SBruce Richardson * Helper macro to access to a dynamic field. 22699a2dd95SBruce Richardson */ 22799a2dd95SBruce Richardson #define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset))) 22899a2dd95SBruce Richardson 22999a2dd95SBruce Richardson /** 23099a2dd95SBruce Richardson * Dump the status of dynamic fields and flags. 23199a2dd95SBruce Richardson * 23299a2dd95SBruce Richardson * @param out 23399a2dd95SBruce Richardson * The stream where the status is displayed. 23499a2dd95SBruce Richardson */ 23599a2dd95SBruce Richardson void rte_mbuf_dyn_dump(FILE *out); 23699a2dd95SBruce Richardson 23799a2dd95SBruce Richardson /* 23899a2dd95SBruce Richardson * Placeholder for dynamic fields and flags declarations. 23999a2dd95SBruce Richardson * This is centralizing point to gather all field names 24099a2dd95SBruce Richardson * and parameters together. 24199a2dd95SBruce Richardson */ 24299a2dd95SBruce Richardson 24399a2dd95SBruce Richardson /* 24499a2dd95SBruce Richardson * The metadata dynamic field provides some extra packet information 24599a2dd95SBruce Richardson * to interact with RTE Flow engine. The metadata in sent mbufs can be 24699a2dd95SBruce Richardson * used to match on some Flows. The metadata in received mbufs can 24799a2dd95SBruce Richardson * provide some feedback from the Flows. The metadata flag tells 24899a2dd95SBruce Richardson * whether the field contains actual value to send, or received one. 24999a2dd95SBruce Richardson */ 25099a2dd95SBruce Richardson #define RTE_MBUF_DYNFIELD_METADATA_NAME "rte_flow_dynfield_metadata" 25199a2dd95SBruce Richardson #define RTE_MBUF_DYNFLAG_METADATA_NAME "rte_flow_dynflag_metadata" 25299a2dd95SBruce Richardson 25399a2dd95SBruce Richardson /** 25499a2dd95SBruce Richardson * The timestamp dynamic field provides some timing information, the 25599a2dd95SBruce Richardson * units and time references (initial phase) are not explicitly defined 25699a2dd95SBruce Richardson * but are maintained always the same for a given port. Some devices allow 25799a2dd95SBruce Richardson * to query rte_eth_read_clock() that will return the current device 25899a2dd95SBruce Richardson * timestamp. The dynamic Tx timestamp flag tells whether the field contains 25999a2dd95SBruce Richardson * actual timestamp value for the packets being sent, this value can be 26099a2dd95SBruce Richardson * used by PMD to schedule packet sending. 26199a2dd95SBruce Richardson */ 26299a2dd95SBruce Richardson #define RTE_MBUF_DYNFIELD_TIMESTAMP_NAME "rte_dynfield_timestamp" 26399a2dd95SBruce Richardson typedef uint64_t rte_mbuf_timestamp_t; 26499a2dd95SBruce Richardson 26599a2dd95SBruce Richardson /** 26699a2dd95SBruce Richardson * Indicate that the timestamp field in the mbuf was filled by the driver. 26799a2dd95SBruce Richardson */ 26899a2dd95SBruce Richardson #define RTE_MBUF_DYNFLAG_RX_TIMESTAMP_NAME "rte_dynflag_rx_timestamp" 26999a2dd95SBruce Richardson 27099a2dd95SBruce Richardson /** 27199a2dd95SBruce Richardson * Register dynamic mbuf field and flag for Rx timestamp. 27299a2dd95SBruce Richardson * 27399a2dd95SBruce Richardson * @param field_offset 27499a2dd95SBruce Richardson * Pointer to the offset of the registered mbuf field, can be NULL. 27599a2dd95SBruce Richardson * The same field is shared for Rx and Tx timestamp. 27699a2dd95SBruce Richardson * @param rx_flag 27799a2dd95SBruce Richardson * Pointer to the mask of the registered offload flag, can be NULL. 27899a2dd95SBruce Richardson * @return 27999a2dd95SBruce Richardson * 0 on success, -1 otherwise. 28099a2dd95SBruce Richardson * Possible values for rte_errno: 28199a2dd95SBruce Richardson * - EEXIST: already registered with different parameters. 28299a2dd95SBruce Richardson * - EPERM: called from a secondary process. 28399a2dd95SBruce Richardson * - ENOENT: no more field or flag available. 28499a2dd95SBruce Richardson * - ENOMEM: allocation failure. 28599a2dd95SBruce Richardson */ 28699a2dd95SBruce Richardson int rte_mbuf_dyn_rx_timestamp_register(int *field_offset, uint64_t *rx_flag); 28799a2dd95SBruce Richardson 28899a2dd95SBruce Richardson /** 28999a2dd95SBruce Richardson * When PMD sees the RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME flag set on the 29099a2dd95SBruce Richardson * packet being sent it tries to synchronize the time of packet appearing 29199a2dd95SBruce Richardson * on the wire with the specified packet timestamp. If the specified one 29299a2dd95SBruce Richardson * is in the past it should be ignored, if one is in the distant future 29399a2dd95SBruce Richardson * it should be capped with some reasonable value (in range of seconds). 29499a2dd95SBruce Richardson * 29599a2dd95SBruce Richardson * There is no any packet reordering according to timestamps is supposed, 29699a2dd95SBruce Richardson * neither for packet within the burst, nor for the whole bursts, it is 29799a2dd95SBruce Richardson * an entirely application responsibility to generate packets and its 29899a2dd95SBruce Richardson * timestamps in desired order. The timestamps might be put only in 29999a2dd95SBruce Richardson * the first packet in the burst providing the entire burst scheduling. 30099a2dd95SBruce Richardson */ 30199a2dd95SBruce Richardson #define RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME "rte_dynflag_tx_timestamp" 30299a2dd95SBruce Richardson 30399a2dd95SBruce Richardson /** 30499a2dd95SBruce Richardson * Register dynamic mbuf field and flag for Tx timestamp. 30599a2dd95SBruce Richardson * 30699a2dd95SBruce Richardson * @param field_offset 30799a2dd95SBruce Richardson * Pointer to the offset of the registered mbuf field, can be NULL. 30899a2dd95SBruce Richardson * The same field is shared for Rx and Tx timestamp. 30999a2dd95SBruce Richardson * @param tx_flag 31099a2dd95SBruce Richardson * Pointer to the mask of the registered offload flag, can be NULL. 31199a2dd95SBruce Richardson * @return 31299a2dd95SBruce Richardson * 0 on success, -1 otherwise. 31399a2dd95SBruce Richardson * Possible values for rte_errno: 31499a2dd95SBruce Richardson * - EEXIST: already registered with different parameters. 31599a2dd95SBruce Richardson * - EPERM: called from a secondary process. 31699a2dd95SBruce Richardson * - ENOENT: no more field or flag available. 31799a2dd95SBruce Richardson * - ENOMEM: allocation failure. 31899a2dd95SBruce Richardson */ 31999a2dd95SBruce Richardson int rte_mbuf_dyn_tx_timestamp_register(int *field_offset, uint64_t *tx_flag); 32099a2dd95SBruce Richardson 321*3c059b2cSAkhil Goyal /** 322*3c059b2cSAkhil Goyal * For the PMDs which support IP reassembly of packets, PMD will update the 323*3c059b2cSAkhil Goyal * packet with RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME to denote that 324*3c059b2cSAkhil Goyal * IP reassembly is incomplete and application can retrieve the packets back 325*3c059b2cSAkhil Goyal * using RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME. 326*3c059b2cSAkhil Goyal */ 327*3c059b2cSAkhil Goyal #define RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME "rte_dynfield_ip_reassembly" 328*3c059b2cSAkhil Goyal #define RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME "rte_dynflag_ip_reassembly_incomplete" 329*3c059b2cSAkhil Goyal 33099a2dd95SBruce Richardson #ifdef __cplusplus 33199a2dd95SBruce Richardson } 33299a2dd95SBruce Richardson #endif 33399a2dd95SBruce Richardson 33499a2dd95SBruce Richardson #endif /* _RTE_MBUF_DYN_H_ */ 335