NDN-DPDK
High-Speed Named Data Networking Forwarder
Loading...
Searching...
No Matches
tlv-decoder.h
Go to the documentation of this file.
1#ifndef NDNDPDK_NDNI_TLV_DECODER_H
2#define NDNDPDK_NDNI_TLV_DECODER_H
3
5
6#include "nni.h"
7
9static __rte_always_inline bool
10TlvDecoder_IsCriticalType(uint32_t type) {
11 return type <= 0x1F || (type % 2) == 1;
12}
13
15typedef struct TlvDecoder {
16 struct rte_mbuf* p;
17 struct rte_mbuf* m;
18 uint32_t length;
19 uint16_t offset;
21
23__attribute__((nonnull)) static inline TlvDecoder
24TlvDecoder_Init(struct rte_mbuf* p) {
25 return (TlvDecoder){
26 .p = p,
27 .m = p,
28 .length = p->pkt_len,
29 };
30}
31
32__attribute__((nonnull)) static inline void
33TlvDecoder_Skip_(TlvDecoder* d, uint32_t count, struct rte_mbuf** last) {
34 NDNDPDK_ASSERT(count <= d->length);
35 for (uint32_t remain = count; remain > 0;) {
36 *last = d->m;
37 uint32_t here = d->m->data_len - d->offset;
38 if (likely(remain < here)) {
39 d->offset += remain;
40 break;
41 }
42 remain -= here;
43 d->m = d->m->next;
44 d->offset = 0;
45 }
46 d->length -= count;
47}
48
53__attribute__((nonnull)) static inline void
54TlvDecoder_Skip(TlvDecoder* d, uint32_t count) {
55 struct rte_mbuf* unusedLast = NULL;
56 TlvDecoder_Skip_(d, count, &unusedLast);
57}
58
66void
68
69__attribute__((nonnull)) void
70TlvDecoder_Copy_(TlvDecoder* d, uint8_t* output, uint16_t count);
71
77__attribute__((nonnull)) static inline void
78TlvDecoder_Copy(TlvDecoder* d, uint8_t* output, uint16_t count) {
79 NDNDPDK_ASSERT(count <= d->length);
80 if (unlikely(count == 0)) {
81 return;
82 }
83
84 uint16_t here = d->m->data_len - d->offset;
85 if (likely(count < here)) {
86 rte_memcpy(output, rte_pktmbuf_mtod_offset(d->m, const uint8_t*, d->offset), count);
87 d->offset += count;
88 d->length -= count;
89 return;
90 }
91
92 TlvDecoder_Copy_(d, output, count);
93}
94
95__attribute__((nonnull, returns_nonnull)) static inline const uint8_t*
96TlvDecoder_Read_Contiguous_(TlvDecoder* d, uint16_t count) {
97 uint16_t here = d->m->data_len - d->offset;
98 const uint8_t* output = rte_pktmbuf_mtod_offset(d->m, const uint8_t*, d->offset);
99
100 d->length -= count;
101 if (likely(count < here)) {
102 d->offset += count;
103 } else {
104 NDNDPDK_ASSERT(count == here);
105 d->m = d->m->next;
106 d->offset = 0;
107 }
108
109 return output;
110}
111
119__attribute__((nonnull, returns_nonnull)) static inline const uint8_t*
120TlvDecoder_Read(TlvDecoder* d, uint8_t* scratch, uint16_t count) {
121 NDNDPDK_ASSERT(count <= d->length);
122 if (unlikely(count == 0)) {
123 return scratch;
124 }
125 if (likely(count <= d->m->data_len - d->offset)) {
126 return TlvDecoder_Read_Contiguous_(d, count);
127 }
128 TlvDecoder_Copy_(d, scratch, count);
129 return scratch;
130}
131
139__attribute__((nonnull)) struct rte_mbuf*
140TlvDecoder_Clone(TlvDecoder* d, uint32_t count, struct rte_mempool* indirectMp);
141
154__attribute__((nonnull)) void
155TlvDecoder_Fragment(TlvDecoder* d, uint32_t count, struct rte_mbuf* frames[], uint32_t* fragIndex,
156 uint32_t fragCount, uint16_t fragSize, uint16_t headroom);
157
158__attribute__((nonnull)) const uint8_t*
160
169__attribute__((nonnull)) static inline const uint8_t*
170TlvDecoder_Linearize(TlvDecoder* d, uint16_t count) {
171 NDNDPDK_ASSERT(count <= d->length);
172 if (unlikely(count == 0)) {
173 return NULL;
174 }
175 if (likely(count < d->m->data_len - d->offset)) {
176 return TlvDecoder_Read_Contiguous_(d, count);
177 }
179}
180
186__attribute__((nonnull)) static inline bool
187TlvDecoder_ReadVarNum(TlvDecoder* d, uint32_t* n) {
188 if (unlikely(d->length < 1)) {
189 return false;
190 }
191 uint8_t scratch[4];
192 uint8_t first = *TlvDecoder_Read(d, scratch, 1);
193 switch (first) {
194 case 0xFD:
195 if (likely(d->length >= 2)) {
196 *n = rte_be_to_cpu_16(*(const unaligned_uint16_t*)TlvDecoder_Read(d, scratch, 2));
197 return likely(*n >= 0xFD);
198 }
199 return false;
200 case 0xFE:
201 if (likely(d->length >= 4)) {
202 *n = rte_be_to_cpu_32(*(const unaligned_uint32_t*)TlvDecoder_Read(d, scratch, 4));
203 return likely(*n > UINT16_MAX);
204 }
205 return false;
206 case 0xFF:
207 return false;
208 default:
209 *n = first;
210 return true;
211 }
212}
213
221__attribute__((nonnull)) static __rte_always_inline uint32_t
222TlvDecoder_ReadTL_MaybeTruncated(TlvDecoder* d, uint32_t* length) {
223 *length = 0;
224 uint32_t type;
225 if (likely(TlvDecoder_ReadVarNum(d, &type)) && likely(TlvDecoder_ReadVarNum(d, length))) {
226 return type;
227 }
228 return 0;
229}
230
238__attribute__((nonnull)) static inline uint32_t
239TlvDecoder_ReadTL(TlvDecoder* d, uint32_t* length) {
240 uint32_t type = TlvDecoder_ReadTL_MaybeTruncated(d, length);
241 if (unlikely(*length > d->length)) {
242 return 0;
243 }
244 return type;
245}
246
257#define TlvDecoder_EachTL(d, typeVar, lengthVar) \
258 for (uint32_t lengthVar, typeVar = TlvDecoder_ReadTL((d), &lengthVar); typeVar != 0; \
259 typeVar = TlvDecoder_ReadTL((d), &lengthVar))
260
268__attribute__((nonnull)) static inline TlvDecoder
269TlvDecoder_MakeValueDecoder(TlvDecoder* d, uint32_t length) {
270 TlvDecoder vd = *d;
271 vd.length = length;
272 TlvDecoder_Skip(d, length);
273 return vd;
274}
275
282__attribute__((nonnull)) static __rte_always_inline bool
283TlvDecoder_ReadNni(TlvDecoder* d, uint32_t length, uint64_t max, uint64_t* n) {
284 uint8_t scratch[8];
285 const uint8_t* value = TlvDecoder_Read(d, scratch, RTE_MIN(sizeof(scratch), length));
286 return Nni_Decode(length, value, n) && *n <= max;
287}
288
289#define TlvDecoder_ReadNniToTypeMax_(sizeofValue) \
290 (sizeofValue) == sizeof(uint8_t) ? UINT8_MAX \
291 : (sizeofValue) == sizeof(uint16_t) ? UINT16_MAX \
292 : (sizeofValue) == sizeof(uint32_t) ? UINT32_MAX \
293 : (sizeofValue) == sizeof(uint64_t) ? UINT64_MAX \
294 : 0
295#define TlvDecoder_ReadNniTo4_(d, length, max, ptr) \
296 __extension__({ \
297 static_assert(__builtin_constant_p(TlvDecoder_ReadNniToTypeMax_(sizeof(*(ptr)))), ""); \
298 uint64_t value; \
299 bool ok = TlvDecoder_ReadNni( \
300 (d), (length), RTE_MIN((max), TlvDecoder_ReadNniToTypeMax_(sizeof(*(ptr)))), &value); \
301 *(ptr) = value; \
302 ok; \
303 })
304#define TlvDecoder_ReadNniTo3_(d, length, ptr) \
305 TlvDecoder_ReadNniTo4_((d), (length), UINT64_MAX, (ptr))
306#define TlvDecoder_ReadNniToArg5_(a1, a2, a3, a4, a5, ...) a5
307#define TlvDecoder_ReadNniToChoose_(...) \
308 TlvDecoder_ReadNniToArg5_(__VA_ARGS__, TlvDecoder_ReadNniTo4_, TlvDecoder_ReadNniTo3_, )
309
321#define TlvDecoder_ReadNniTo(...) (TlvDecoder_ReadNniToChoose_(__VA_ARGS__)(__VA_ARGS__))
322
323#endif // NDNDPDK_NDNI_TLV_DECODER_H
#define NDNDPDK_ASSERT(x)
Definition common.h:60
TLV decoder.
Definition tlv-decoder.h:15
uint16_t offset
offset within current segment
Definition tlv-decoder.h:19
struct rte_mbuf * p
first segment
Definition tlv-decoder.h:16
struct rte_mbuf * m
current segment
Definition tlv-decoder.h:17
uint32_t length
remaining byte length
Definition tlv-decoder.h:18
void TlvDecoder_Truncate(TlvDecoder *d)
Truncate mbuf to the remaining bytes.
Definition tlv-decoder.c:4
void TlvDecoder_Fragment(TlvDecoder *d, uint32_t count, struct rte_mbuf *frames[], uint32_t *fragIndex, uint32_t fragCount, uint16_t fragSize, uint16_t headroom)
Copy next count octets to fragments.
Definition tlv-decoder.c:136
void TlvDecoder_Copy_(TlvDecoder *d, uint8_t *output, uint16_t count)
Definition tlv-decoder.c:52
struct rte_mbuf * TlvDecoder_Clone(TlvDecoder *d, uint32_t count, struct rte_mempool *indirectMp)
Clone next count octets to indirect mbufs.
Definition tlv-decoder.c:71
const uint8_t * TlvDecoder_Linearize_NonContiguous_(TlvDecoder *d, uint16_t count)
Definition tlv-decoder.c:226