File: rte_node_mbuf_dynfield.h

package info (click to toggle)
dpdk 25.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 127,892 kB
  • sloc: ansic: 2,358,479; python: 16,426; sh: 4,474; makefile: 1,713; awk: 70
file content (158 lines) | stat: -rw-r--r-- 4,772 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(C) 2025 Marvell International Ltd.
 */

#ifndef _RTE_GRAPH_MBUF_DYNFIELD_H_
#define _RTE_GRAPH_MBUF_DYNFIELD_H_

#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_mbuf_dyn.h>

/**
 * @file: rte_node_mbuf_dynfield.h
 *
 * @warning
 * @b EXPERIMENTAL: this API may change without prior notice.
 *
 * Defines rte_node specific mbuf dynamic field region [rte_node_mbuf_dynfield_t]
 * which can be used by both DPDK built-in and out-of-tree nodes
 * for storing per-mbuf fields for graph walk.
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE
/** Size of persistent mbuf fields */
#define RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE          (0)
#endif /* !RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE */

#ifndef RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE
/** Size of overloadable mbuf fields */
#define RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE        (8)
#endif /* !RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE */

/** Size of node mbuf dynamic field */
#define RTE_NODE_MBUF_DYNFIELD_SIZE     \
	(RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE + RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE)

/**
 * Node mbuf overloadable data.
 *
 * Out-of-tree nodes can repurpose overloadable fields via
 * rte_node_mbuf_overload_fields_get(mbuf). Overloadable fields are not
 * preserved and typically can be used with-in two adjacent nodes in the graph.
 */
typedef struct rte_node_mbuf_overload_fields {
	union {
		/* Following fields used by ip[4|6]-lookup -> ip[4|6]-rewrite nodes */
		union {
			struct {
				uint16_t nh;
				uint16_t ttl;
				uint32_t cksum;
			};
			uint64_t u;
		};
		uint8_t data[RTE_NODE_MBUF_OVERLOADABLE_FIELDS_SIZE];
	};
} rte_node_mbuf_overload_fields_t;

/**
 * rte_node specific mbuf dynamic field structure [rte_node_mbuf_dynfield_t]
 *
 * It holds two types of fields:
 * 1. Persistent fields: Fields which are preserved across nodes during graph walk.
 *    - Eg: rx/tx interface etc
 * 2. Overloadable fields: Fields which can be repurposed by two adjacent nodes.
 */
typedef struct rte_node_mbuf_dynfield {
#if RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE > 0
	/**
	 * Persistent mbuf region across nodes in graph walk
	 *
	 * These fields are preserved across graph walk and can be accessed by
	 * rte_node_mbuf_dynfield_get() in fast path.
	 */
	union {
		uint8_t persistent_data[RTE_NODE_MBUF_PERSISTENT_FIELDS_SIZE];
	};
#endif
	/**
	 * Overloadable mbuf fields across graph walk. Fields which can change.
	 *
	 * Two adjacent nodes (producer, consumer) can use this memory region for
	 * sharing per-mbuf specific information. Once mbuf leaves a consumer node,
	 * this region can be repurposed by another sets of [producer, consumer] node.
	 *
	 * In fast path, this region can be accessed by rte_node_mbuf_overload_fields_get().
	 */
	rte_node_mbuf_overload_fields_t overloadable_data;
} rte_node_mbuf_dynfield_t;

/**
 * For a given mbuf and dynamic offset, return pointer to rte_node_mbuf_dynfield_t *
 *
 * @param m
 *   Mbuf
 * @param offset
 *   Dynamic offset returned by @ref rte_node_mbuf_dynfield_register()
 * @return
 *  Pointer to node specific mbuf dynamic field structure
 */
__rte_experimental
static __rte_always_inline rte_node_mbuf_dynfield_t *
rte_node_mbuf_dynfield_get(struct rte_mbuf *m, const int offset)
{
	return RTE_MBUF_DYNFIELD(m, offset, struct rte_node_mbuf_dynfield *);
}

/**
 * For a given mbuf and dynamic offset, return pointer to overloadable fields.
 * Nodes can typecast returned pointer to reuse for their own purpose.
 *
 * @param m
 *   Mbuf
 * @param offset
 *   Dynamic offset returned by @ref rte_node_mbuf_dynfield_register()
 * @return
 * Pointer to node mbuf overloadable fields
 */
__rte_experimental
static __rte_always_inline rte_node_mbuf_overload_fields_t *
rte_node_mbuf_overload_fields_get(struct rte_mbuf *m, const int offset)
{
	rte_node_mbuf_dynfield_t *f = NULL;

	f = RTE_MBUF_DYNFIELD(m, offset, rte_node_mbuf_dynfield_t *);

	return &(f->overloadable_data);
}

/**
 *  Register rte_node specific common mbuf dynamic field region. Can be called
 *  in rte_node_register()->init() function to save offset in node->ctx
 *
 *  In process() function, node->ctx can be passed to
 *  - rte_node_mbuf_dynfield_get(mbuf, offset)
 *  - rte_node_mbuf_overload_fields_get(mbuf, offset)
 *
 *  Can be called multiple times by any number of nodes in init() function.
 *  - Very first call registers dynamic field and returns offset.
 *  - Subsequent calls return same offset.
 *
 *  @return
 *   <0 on error: rte_errno set to one of:
 *    - ENOMEM - no memory
 *   >=0 on success: dynamic field offset
 */
__rte_experimental
int rte_node_mbuf_dynfield_register(void);

#ifdef __cplusplus
}
#endif

#endif /* _RTE_GRAPH_MBUF_DYNFIELD_H_ */