1 /** @file
2 * @brief Network packet buffer descriptor API
3 *
4 * Network data is passed between different parts of the stack via
5 * net_buf struct.
6 */
7
8 /*
9 * Copyright (c) 2016 Intel Corporation
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 */
13
14 /* Data buffer API - used for all data to/from net */
15
16 #ifndef ZEPHYR_INCLUDE_NET_NET_PKT_H_
17 #define ZEPHYR_INCLUDE_NET_NET_PKT_H_
18
19 #include <zephyr/types.h>
20 #include <stdbool.h>
21
22 #include <net/buf.h>
23
24 #include <net/net_core.h>
25 #include <net/net_linkaddr.h>
26 #include <net/net_ip.h>
27 #include <net/net_if.h>
28 #include <net/net_context.h>
29 #include <net/ethernet_vlan.h>
30 #include <net/ptp_time.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /**
37 * @brief Network packet management library
38 * @defgroup net_pkt Network Packet Library
39 * @ingroup networking
40 * @{
41 */
42
43 struct net_context;
44 struct canbus_net_isotp_tx_ctx;
45 struct canbus_net_isotp_rx_ctx;
46
47
48 /* buffer cursor used in net_pkt */
49 struct net_pkt_cursor {
50 /** Current net_buf pointer by the cursor */
51 struct net_buf *buf;
52 /** Current position in the data buffer of the net_buf */
53 uint8_t *pos;
54 };
55
56 /**
57 * @brief Network packet.
58 *
59 * Note that if you add new fields into net_pkt, remember to update
60 * net_pkt_clone() function.
61 */
62 struct net_pkt {
63 /**
64 * The fifo is used by RX/TX threads and by socket layer. The net_pkt
65 * is queued via fifo to the processing thread.
66 */
67 intptr_t fifo;
68
69 /** Slab pointer from where it belongs to */
70 struct k_mem_slab *slab;
71
72 /** buffer holding the packet */
73 union {
74 struct net_buf *frags;
75 struct net_buf *buffer;
76 };
77
78 /** Internal buffer iterator used for reading/writing */
79 struct net_pkt_cursor cursor;
80
81 /** Network connection context */
82 struct net_context *context;
83
84 /** Network interface */
85 struct net_if *iface;
86
87 /** @cond ignore */
88
89 #if defined(CONFIG_NET_ROUTING)
90 struct net_if *orig_iface; /* Original network interface */
91 #endif
92
93 #if defined(CONFIG_NET_PKT_TIMESTAMP)
94 /** Timestamp if available. */
95 struct net_ptp_time timestamp;
96 #endif
97
98 #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS)
99 struct {
100 /** Create time in cycles */
101 uint32_t create_time;
102
103 #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \
104 defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
105 /** Collect extra statistics for net_pkt processing
106 * from various points in the IP stack. See networking
107 * documentation where these points are located and how
108 * to interpret the results.
109 */
110 struct {
111 uint32_t stat[NET_PKT_DETAIL_STATS_COUNT];
112 int count;
113 } detail;
114 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL ||
115 CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
116 };
117 #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */
118
119 #if defined(CONFIG_NET_PKT_TXTIME)
120 /** Network packet TX time in the future (in nanoseconds) */
121 uint64_t txtime;
122 #endif /* CONFIG_NET_PKT_TXTIME */
123
124 /** Reference counter */
125 atomic_t atomic_ref;
126
127 /* Filled by layer 2 when network packet is received. */
128 struct net_linkaddr lladdr_src;
129 struct net_linkaddr lladdr_dst;
130
131 #if defined(CONFIG_NET_TCP2)
132 /** Allow placing the packet into sys_slist_t */
133 sys_snode_t next;
134 #endif
135
136 uint8_t ip_hdr_len; /* pre-filled in order to avoid func call */
137
138 uint8_t overwrite : 1; /* Is packet content being overwritten? */
139
140 uint8_t sent_or_eof: 1; /* For outgoing packet: is this sent or not
141 * For incoming packet of a socket: last
142 * packet before EOF
143 * Used only if defined(CONFIG_NET_TCP)
144 */
145 union {
146 uint8_t pkt_queued: 1; /* For outgoing packet: is this packet
147 * queued to be sent but has not reached
148 * the driver yet.
149 * Used only if defined(CONFIG_NET_TCP)
150 */
151 uint8_t gptp_pkt: 1; /* For outgoing packet: is this packet
152 * a GPTP packet.
153 * Used only if defined (CONFIG_NET_GPTP)
154 */
155 };
156
157 uint8_t forwarding : 1; /* Are we forwarding this pkt
158 * Used only if defined(CONFIG_NET_ROUTE)
159 */
160 uint8_t family : 3; /* IPv4 vs IPv6 */
161
162 union {
163 uint8_t ipv4_auto_arp_msg : 1; /* Is this pkt IPv4 autoconf ARP
164 * message. Used only if
165 * defined(CONFIG_NET_IPV4_AUTO).
166 * Note: family needs to be
167 * AF_INET.
168 */
169 uint8_t lldp_pkt : 1; /* Is this pkt an LLDP message.
170 * Used only if
171 * defined(CONFIG_NET_LLDP).
172 * Note: family needs to be
173 * AF_UNSPEC.
174 */
175 uint8_t ppp_msg : 1; /* This is a PPP message */
176 };
177
178 #if defined(CONFIG_NET_TCP)
179 uint8_t tcp_first_msg : 1; /* Is this the first time this pkt is
180 * sent, or is this a resend of a TCP
181 * segment.
182 */
183 #endif
184
185 uint8_t captured : 1; /* Set to 1 if this packet is already being
186 * captured
187 */
188
189 uint8_t l2_bridged : 1; /* set to 1 if this packet comes from a bridge
190 * and already contains its L2 header to be
191 * preserved. Useful only if
192 * defined(CONFIG_NET_ETHERNET_BRIDGE).
193 */
194
195 union {
196 /* IPv6 hop limit or IPv4 ttl for this network packet.
197 * The value is shared between IPv6 and IPv4.
198 */
199 uint8_t ipv6_hop_limit;
200 uint8_t ipv4_ttl;
201 };
202
203 union {
204 #if defined(CONFIG_NET_IPV4)
205 uint8_t ipv4_opts_len; /* Length if IPv4 Header Options */
206 #endif
207 #if defined(CONFIG_NET_IPV6)
208 uint16_t ipv6_ext_len; /* length of extension headers */
209 #endif
210 };
211
212 /** Network packet priority, can be left out in which case packet
213 * is not prioritised.
214 */
215 uint8_t priority;
216
217 #if defined(CONFIG_NET_VLAN)
218 /* VLAN TCI (Tag Control Information). This contains the Priority
219 * Code Point (PCP), Drop Eligible Indicator (DEI) and VLAN
220 * Identifier (VID, called more commonly VLAN tag). This value is
221 * kept in host byte order.
222 */
223 uint16_t vlan_tci;
224 #endif /* CONFIG_NET_VLAN */
225
226 #if defined(CONFIG_NET_IPV6)
227 /* Where is the start of the last header before payload data
228 * in IPv6 packet. This is offset value from start of the IPv6
229 * packet. Note that this value should be updated by who ever
230 * adds IPv6 extension headers to the network packet.
231 */
232 uint16_t ipv6_prev_hdr_start;
233
234 #if defined(CONFIG_NET_IPV6_FRAGMENT)
235 uint16_t ipv6_fragment_flags; /* Fragment offset and M (More Fragment) flag */
236 uint32_t ipv6_fragment_id; /* Fragment id */
237 uint16_t ipv6_frag_hdr_start; /* Where starts the fragment header */
238 #endif /* CONFIG_NET_IPV6_FRAGMENT */
239
240 uint8_t ipv6_ext_opt_len; /* IPv6 ND option length */
241 uint8_t ipv6_next_hdr; /* What is the very first next header */
242 #endif /* CONFIG_NET_IPV6 */
243
244 #if defined(CONFIG_IEEE802154)
245 uint8_t ieee802154_rssi; /* Received Signal Strength Indication */
246 uint8_t ieee802154_lqi; /* Link Quality Indicator */
247 uint8_t ieee802154_arb : 1; /* ACK Request Bit is set in the frame */
248 uint8_t ieee802154_ack_fpb : 1; /* Frame Pending Bit was set in the ACK */
249 uint8_t ieee802154_frame_secured : 1; /* Frame is authenticated and
250 * encrypted according to its
251 * Auxiliary Security Header
252 */
253 uint8_t ieee802154_mac_hdr_rdy : 1; /* Indicates if frame's MAC header
254 * is ready to be transmitted or if
255 * it requires further modifications,
256 * e.g. Frame Counter injection.
257 */
258 #if defined(CONFIG_IEEE802154_2015)
259 uint8_t ieee802154_fv2015 : 1; /* Frame version is IEEE 802.15.4-2015 */
260 uint8_t ieee802154_ack_seb : 1; /* Security Enabled Bit was set in the ACK */
261 uint32_t ieee802154_ack_fc; /* Frame counter set in the ACK */
262 uint8_t ieee802154_ack_keyid; /* Key index set in the ACK */
263 #endif
264 #endif
265 #if defined(CONFIG_NET_L2_CANBUS)
266 union {
267 struct canbus_isotp_tx_ctx *canbus_tx_ctx;
268 struct canbus_isotp_rx_ctx *canbus_rx_ctx;
269 };
270 #endif
271 /* @endcond */
272 };
273
274 /** @cond ignore */
275
276 /* The interface real ll address */
net_pkt_lladdr_if(struct net_pkt * pkt)277 static inline struct net_linkaddr *net_pkt_lladdr_if(struct net_pkt *pkt)
278 {
279 return net_if_get_link_addr(pkt->iface);
280 }
281
net_pkt_context(struct net_pkt * pkt)282 static inline struct net_context *net_pkt_context(struct net_pkt *pkt)
283 {
284 return pkt->context;
285 }
286
net_pkt_set_context(struct net_pkt * pkt,struct net_context * ctx)287 static inline void net_pkt_set_context(struct net_pkt *pkt,
288 struct net_context *ctx)
289 {
290 pkt->context = ctx;
291 }
292
net_pkt_iface(struct net_pkt * pkt)293 static inline struct net_if *net_pkt_iface(struct net_pkt *pkt)
294 {
295 return pkt->iface;
296 }
297
net_pkt_set_iface(struct net_pkt * pkt,struct net_if * iface)298 static inline void net_pkt_set_iface(struct net_pkt *pkt, struct net_if *iface)
299 {
300 pkt->iface = iface;
301
302 /* If the network interface is set in pkt, then also set the type of
303 * the network address that is stored in pkt. This is done here so
304 * that the address type is properly set and is not forgotten.
305 */
306 if (iface) {
307 pkt->lladdr_src.type = net_if_get_link_addr(iface)->type;
308 pkt->lladdr_dst.type = net_if_get_link_addr(iface)->type;
309 }
310 }
311
net_pkt_orig_iface(struct net_pkt * pkt)312 static inline struct net_if *net_pkt_orig_iface(struct net_pkt *pkt)
313 {
314 #if defined(CONFIG_NET_ROUTING)
315 return pkt->orig_iface;
316 #else
317 return pkt->iface;
318 #endif
319 }
320
net_pkt_set_orig_iface(struct net_pkt * pkt,struct net_if * iface)321 static inline void net_pkt_set_orig_iface(struct net_pkt *pkt,
322 struct net_if *iface)
323 {
324 #if defined(CONFIG_NET_ROUTING)
325 pkt->orig_iface = iface;
326 #endif
327 }
328
net_pkt_family(struct net_pkt * pkt)329 static inline uint8_t net_pkt_family(struct net_pkt *pkt)
330 {
331 return pkt->family;
332 }
333
net_pkt_set_family(struct net_pkt * pkt,uint8_t family)334 static inline void net_pkt_set_family(struct net_pkt *pkt, uint8_t family)
335 {
336 pkt->family = family;
337 }
338
net_pkt_is_gptp(struct net_pkt * pkt)339 static inline bool net_pkt_is_gptp(struct net_pkt *pkt)
340 {
341 return !!(pkt->gptp_pkt);
342 }
343
net_pkt_set_gptp(struct net_pkt * pkt,bool is_gptp)344 static inline void net_pkt_set_gptp(struct net_pkt *pkt, bool is_gptp)
345 {
346 pkt->gptp_pkt = is_gptp;
347 }
348
net_pkt_is_captured(struct net_pkt * pkt)349 static inline bool net_pkt_is_captured(struct net_pkt *pkt)
350 {
351 return !!(pkt->captured);
352 }
353
net_pkt_set_captured(struct net_pkt * pkt,bool is_captured)354 static inline void net_pkt_set_captured(struct net_pkt *pkt, bool is_captured)
355 {
356 pkt->captured = is_captured;
357 }
358
net_pkt_is_l2_bridged(struct net_pkt * pkt)359 static inline bool net_pkt_is_l2_bridged(struct net_pkt *pkt)
360 {
361 return IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE) ? !!(pkt->l2_bridged) : 0;
362 }
363
net_pkt_set_l2_bridged(struct net_pkt * pkt,bool is_l2_bridged)364 static inline void net_pkt_set_l2_bridged(struct net_pkt *pkt, bool is_l2_bridged)
365 {
366 if (IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE)) {
367 pkt->l2_bridged = is_l2_bridged;
368 }
369 }
370
net_pkt_ip_hdr_len(struct net_pkt * pkt)371 static inline uint8_t net_pkt_ip_hdr_len(struct net_pkt *pkt)
372 {
373 return pkt->ip_hdr_len;
374 }
375
net_pkt_set_ip_hdr_len(struct net_pkt * pkt,uint8_t len)376 static inline void net_pkt_set_ip_hdr_len(struct net_pkt *pkt, uint8_t len)
377 {
378 pkt->ip_hdr_len = len;
379 }
380
net_pkt_sent(struct net_pkt * pkt)381 static inline uint8_t net_pkt_sent(struct net_pkt *pkt)
382 {
383 return pkt->sent_or_eof;
384 }
385
net_pkt_set_sent(struct net_pkt * pkt,bool sent)386 static inline void net_pkt_set_sent(struct net_pkt *pkt, bool sent)
387 {
388 pkt->sent_or_eof = sent;
389 }
390
net_pkt_queued(struct net_pkt * pkt)391 static inline uint8_t net_pkt_queued(struct net_pkt *pkt)
392 {
393 return pkt->pkt_queued;
394 }
395
net_pkt_set_queued(struct net_pkt * pkt,bool send)396 static inline void net_pkt_set_queued(struct net_pkt *pkt, bool send)
397 {
398 pkt->pkt_queued = send;
399 }
400
net_pkt_tcp_1st_msg(struct net_pkt * pkt)401 static inline uint8_t net_pkt_tcp_1st_msg(struct net_pkt *pkt)
402 {
403 #if defined(CONFIG_NET_TCP)
404 return pkt->tcp_first_msg;
405 #else
406 return true;
407 #endif
408 }
409
net_pkt_set_tcp_1st_msg(struct net_pkt * pkt,bool is_1st)410 static inline void net_pkt_set_tcp_1st_msg(struct net_pkt *pkt, bool is_1st)
411 {
412 #if defined(CONFIG_NET_TCP)
413 pkt->tcp_first_msg = is_1st;
414 #else
415 ARG_UNUSED(pkt);
416 ARG_UNUSED(is_1st);
417 #endif
418 }
419
420 #if defined(CONFIG_NET_SOCKETS)
net_pkt_eof(struct net_pkt * pkt)421 static inline uint8_t net_pkt_eof(struct net_pkt *pkt)
422 {
423 return pkt->sent_or_eof;
424 }
425
net_pkt_set_eof(struct net_pkt * pkt,bool eof)426 static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof)
427 {
428 pkt->sent_or_eof = eof;
429 }
430 #endif
431
432 #if defined(CONFIG_NET_ROUTE)
net_pkt_forwarding(struct net_pkt * pkt)433 static inline bool net_pkt_forwarding(struct net_pkt *pkt)
434 {
435 return pkt->forwarding;
436 }
437
net_pkt_set_forwarding(struct net_pkt * pkt,bool forward)438 static inline void net_pkt_set_forwarding(struct net_pkt *pkt, bool forward)
439 {
440 pkt->forwarding = forward;
441 }
442 #else
net_pkt_forwarding(struct net_pkt * pkt)443 static inline bool net_pkt_forwarding(struct net_pkt *pkt)
444 {
445 return false;
446 }
447 #endif
448
449 #if defined(CONFIG_NET_IPV4)
net_pkt_ipv4_ttl(struct net_pkt * pkt)450 static inline uint8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
451 {
452 return pkt->ipv4_ttl;
453 }
454
net_pkt_set_ipv4_ttl(struct net_pkt * pkt,uint8_t ttl)455 static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
456 uint8_t ttl)
457 {
458 pkt->ipv4_ttl = ttl;
459 }
460
net_pkt_ipv4_opts_len(struct net_pkt * pkt)461 static inline uint8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
462 {
463 return pkt->ipv4_opts_len;
464 }
465
net_pkt_set_ipv4_opts_len(struct net_pkt * pkt,uint8_t opts_len)466 static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
467 uint8_t opts_len)
468 {
469 pkt->ipv4_opts_len = opts_len;
470 }
471 #else
net_pkt_ipv4_ttl(struct net_pkt * pkt)472 static inline uint8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
473 {
474 ARG_UNUSED(pkt);
475
476 return 0;
477 }
478
net_pkt_set_ipv4_ttl(struct net_pkt * pkt,uint8_t ttl)479 static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
480 uint8_t ttl)
481 {
482 ARG_UNUSED(pkt);
483 ARG_UNUSED(ttl);
484 }
485
net_pkt_ipv4_opts_len(struct net_pkt * pkt)486 static inline uint8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
487 {
488 ARG_UNUSED(pkt);
489 return 0;
490 }
491
net_pkt_set_ipv4_opts_len(struct net_pkt * pkt,uint8_t opts_len)492 static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
493 uint8_t opts_len)
494 {
495 ARG_UNUSED(pkt);
496 ARG_UNUSED(opts_len);
497 }
498 #endif
499
500 #if defined(CONFIG_NET_IPV6)
net_pkt_ipv6_ext_opt_len(struct net_pkt * pkt)501 static inline uint8_t net_pkt_ipv6_ext_opt_len(struct net_pkt *pkt)
502 {
503 return pkt->ipv6_ext_opt_len;
504 }
505
net_pkt_set_ipv6_ext_opt_len(struct net_pkt * pkt,uint8_t len)506 static inline void net_pkt_set_ipv6_ext_opt_len(struct net_pkt *pkt,
507 uint8_t len)
508 {
509 pkt->ipv6_ext_opt_len = len;
510 }
511
net_pkt_ipv6_next_hdr(struct net_pkt * pkt)512 static inline uint8_t net_pkt_ipv6_next_hdr(struct net_pkt *pkt)
513 {
514 return pkt->ipv6_next_hdr;
515 }
516
net_pkt_set_ipv6_next_hdr(struct net_pkt * pkt,uint8_t next_hdr)517 static inline void net_pkt_set_ipv6_next_hdr(struct net_pkt *pkt,
518 uint8_t next_hdr)
519 {
520 pkt->ipv6_next_hdr = next_hdr;
521 }
522
net_pkt_ipv6_ext_len(struct net_pkt * pkt)523 static inline uint16_t net_pkt_ipv6_ext_len(struct net_pkt *pkt)
524 {
525 return pkt->ipv6_ext_len;
526 }
527
net_pkt_set_ipv6_ext_len(struct net_pkt * pkt,uint16_t len)528 static inline void net_pkt_set_ipv6_ext_len(struct net_pkt *pkt, uint16_t len)
529 {
530 pkt->ipv6_ext_len = len;
531 }
532
net_pkt_ipv6_hdr_prev(struct net_pkt * pkt)533 static inline uint16_t net_pkt_ipv6_hdr_prev(struct net_pkt *pkt)
534 {
535 return pkt->ipv6_prev_hdr_start;
536 }
537
net_pkt_set_ipv6_hdr_prev(struct net_pkt * pkt,uint16_t offset)538 static inline void net_pkt_set_ipv6_hdr_prev(struct net_pkt *pkt,
539 uint16_t offset)
540 {
541 pkt->ipv6_prev_hdr_start = offset;
542 }
543
net_pkt_ipv6_hop_limit(struct net_pkt * pkt)544 static inline uint8_t net_pkt_ipv6_hop_limit(struct net_pkt *pkt)
545 {
546 return pkt->ipv6_hop_limit;
547 }
548
net_pkt_set_ipv6_hop_limit(struct net_pkt * pkt,uint8_t hop_limit)549 static inline void net_pkt_set_ipv6_hop_limit(struct net_pkt *pkt,
550 uint8_t hop_limit)
551 {
552 pkt->ipv6_hop_limit = hop_limit;
553 }
554 #else /* CONFIG_NET_IPV6 */
net_pkt_ipv6_ext_opt_len(struct net_pkt * pkt)555 static inline uint8_t net_pkt_ipv6_ext_opt_len(struct net_pkt *pkt)
556 {
557 ARG_UNUSED(pkt);
558
559 return 0;
560 }
561
net_pkt_set_ipv6_ext_opt_len(struct net_pkt * pkt,uint8_t len)562 static inline void net_pkt_set_ipv6_ext_opt_len(struct net_pkt *pkt,
563 uint8_t len)
564 {
565 ARG_UNUSED(pkt);
566 ARG_UNUSED(len);
567 }
568
net_pkt_ipv6_next_hdr(struct net_pkt * pkt)569 static inline uint8_t net_pkt_ipv6_next_hdr(struct net_pkt *pkt)
570 {
571 ARG_UNUSED(pkt);
572
573 return 0;
574 }
575
net_pkt_set_ipv6_next_hdr(struct net_pkt * pkt,uint8_t next_hdr)576 static inline void net_pkt_set_ipv6_next_hdr(struct net_pkt *pkt,
577 uint8_t next_hdr)
578 {
579 ARG_UNUSED(pkt);
580 ARG_UNUSED(next_hdr);
581 }
582
net_pkt_ipv6_ext_len(struct net_pkt * pkt)583 static inline uint16_t net_pkt_ipv6_ext_len(struct net_pkt *pkt)
584 {
585 ARG_UNUSED(pkt);
586
587 return 0;
588 }
589
net_pkt_set_ipv6_ext_len(struct net_pkt * pkt,uint16_t len)590 static inline void net_pkt_set_ipv6_ext_len(struct net_pkt *pkt, uint16_t len)
591 {
592 ARG_UNUSED(pkt);
593 ARG_UNUSED(len);
594 }
595
net_pkt_ipv6_hdr_prev(struct net_pkt * pkt)596 static inline uint16_t net_pkt_ipv6_hdr_prev(struct net_pkt *pkt)
597 {
598 ARG_UNUSED(pkt);
599
600 return 0;
601 }
602
net_pkt_set_ipv6_hdr_prev(struct net_pkt * pkt,uint16_t offset)603 static inline void net_pkt_set_ipv6_hdr_prev(struct net_pkt *pkt,
604 uint16_t offset)
605 {
606 ARG_UNUSED(pkt);
607 ARG_UNUSED(offset);
608 }
609
net_pkt_ipv6_hop_limit(struct net_pkt * pkt)610 static inline uint8_t net_pkt_ipv6_hop_limit(struct net_pkt *pkt)
611 {
612 ARG_UNUSED(pkt);
613
614 return 0;
615 }
616
net_pkt_set_ipv6_hop_limit(struct net_pkt * pkt,uint8_t hop_limit)617 static inline void net_pkt_set_ipv6_hop_limit(struct net_pkt *pkt,
618 uint8_t hop_limit)
619 {
620 ARG_UNUSED(pkt);
621 ARG_UNUSED(hop_limit);
622 }
623 #endif /* CONFIG_NET_IPV6 */
624
net_pkt_ip_opts_len(struct net_pkt * pkt)625 static inline uint16_t net_pkt_ip_opts_len(struct net_pkt *pkt)
626 {
627 #if defined(CONFIG_NET_IPV6)
628 return pkt->ipv6_ext_len;
629 #elif defined(CONFIG_NET_IPV4)
630 return pkt->ipv4_opts_len;
631 #else
632 ARG_UNUSED(pkt);
633
634 return 0;
635 #endif
636 }
637
638 #if defined(CONFIG_NET_IPV6_FRAGMENT)
net_pkt_ipv6_fragment_start(struct net_pkt * pkt)639 static inline uint16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
640 {
641 return pkt->ipv6_frag_hdr_start;
642 }
643
net_pkt_set_ipv6_fragment_start(struct net_pkt * pkt,uint16_t start)644 static inline void net_pkt_set_ipv6_fragment_start(struct net_pkt *pkt,
645 uint16_t start)
646 {
647 pkt->ipv6_frag_hdr_start = start;
648 }
649
net_pkt_ipv6_fragment_offset(struct net_pkt * pkt)650 static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
651 {
652 return pkt->ipv6_fragment_flags & NET_IPV6_FRAGH_OFFSET_MASK;
653 }
net_pkt_ipv6_fragment_more(struct net_pkt * pkt)654 static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
655 {
656 return (pkt->ipv6_fragment_flags & 0x01) != 0;
657 }
658
net_pkt_set_ipv6_fragment_flags(struct net_pkt * pkt,uint16_t flags)659 static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
660 uint16_t flags)
661 {
662 pkt->ipv6_fragment_flags = flags;
663 }
664
net_pkt_ipv6_fragment_id(struct net_pkt * pkt)665 static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)
666 {
667 return pkt->ipv6_fragment_id;
668 }
669
net_pkt_set_ipv6_fragment_id(struct net_pkt * pkt,uint32_t id)670 static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt,
671 uint32_t id)
672 {
673 pkt->ipv6_fragment_id = id;
674 }
675 #else /* CONFIG_NET_IPV6_FRAGMENT */
net_pkt_ipv6_fragment_start(struct net_pkt * pkt)676 static inline uint16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
677 {
678 ARG_UNUSED(pkt);
679
680 return 0;
681 }
682
net_pkt_set_ipv6_fragment_start(struct net_pkt * pkt,uint16_t start)683 static inline void net_pkt_set_ipv6_fragment_start(struct net_pkt *pkt,
684 uint16_t start)
685 {
686 ARG_UNUSED(pkt);
687 ARG_UNUSED(start);
688 }
689
net_pkt_ipv6_fragment_offset(struct net_pkt * pkt)690 static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
691 {
692 ARG_UNUSED(pkt);
693
694 return 0;
695 }
696
net_pkt_ipv6_fragment_more(struct net_pkt * pkt)697 static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
698 {
699 ARG_UNUSED(pkt);
700
701 return 0;
702 }
703
net_pkt_set_ipv6_fragment_flags(struct net_pkt * pkt,uint16_t flags)704 static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
705 uint16_t flags)
706 {
707 ARG_UNUSED(pkt);
708 ARG_UNUSED(flags);
709 }
710
net_pkt_ipv6_fragment_id(struct net_pkt * pkt)711 static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)
712 {
713 ARG_UNUSED(pkt);
714
715 return 0;
716 }
717
net_pkt_set_ipv6_fragment_id(struct net_pkt * pkt,uint32_t id)718 static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt,
719 uint32_t id)
720 {
721 ARG_UNUSED(pkt);
722 ARG_UNUSED(id);
723 }
724 #endif /* CONFIG_NET_IPV6_FRAGMENT */
725
net_pkt_priority(struct net_pkt * pkt)726 static inline uint8_t net_pkt_priority(struct net_pkt *pkt)
727 {
728 return pkt->priority;
729 }
730
net_pkt_set_priority(struct net_pkt * pkt,uint8_t priority)731 static inline void net_pkt_set_priority(struct net_pkt *pkt,
732 uint8_t priority)
733 {
734 pkt->priority = priority;
735 }
736
737 #if defined(CONFIG_NET_VLAN)
net_pkt_vlan_tag(struct net_pkt * pkt)738 static inline uint16_t net_pkt_vlan_tag(struct net_pkt *pkt)
739 {
740 return net_eth_vlan_get_vid(pkt->vlan_tci);
741 }
742
net_pkt_set_vlan_tag(struct net_pkt * pkt,uint16_t tag)743 static inline void net_pkt_set_vlan_tag(struct net_pkt *pkt, uint16_t tag)
744 {
745 pkt->vlan_tci = net_eth_vlan_set_vid(pkt->vlan_tci, tag);
746 }
747
net_pkt_vlan_priority(struct net_pkt * pkt)748 static inline uint8_t net_pkt_vlan_priority(struct net_pkt *pkt)
749 {
750 return net_eth_vlan_get_pcp(pkt->vlan_tci);
751 }
752
net_pkt_set_vlan_priority(struct net_pkt * pkt,uint8_t priority)753 static inline void net_pkt_set_vlan_priority(struct net_pkt *pkt,
754 uint8_t priority)
755 {
756 pkt->vlan_tci = net_eth_vlan_set_pcp(pkt->vlan_tci, priority);
757 }
758
net_pkt_vlan_dei(struct net_pkt * pkt)759 static inline bool net_pkt_vlan_dei(struct net_pkt *pkt)
760 {
761 return net_eth_vlan_get_dei(pkt->vlan_tci);
762 }
763
net_pkt_set_vlan_dei(struct net_pkt * pkt,bool dei)764 static inline void net_pkt_set_vlan_dei(struct net_pkt *pkt, bool dei)
765 {
766 pkt->vlan_tci = net_eth_vlan_set_dei(pkt->vlan_tci, dei);
767 }
768
net_pkt_set_vlan_tci(struct net_pkt * pkt,uint16_t tci)769 static inline void net_pkt_set_vlan_tci(struct net_pkt *pkt, uint16_t tci)
770 {
771 pkt->vlan_tci = tci;
772 }
773
net_pkt_vlan_tci(struct net_pkt * pkt)774 static inline uint16_t net_pkt_vlan_tci(struct net_pkt *pkt)
775 {
776 return pkt->vlan_tci;
777 }
778 #else
net_pkt_vlan_tag(struct net_pkt * pkt)779 static inline uint16_t net_pkt_vlan_tag(struct net_pkt *pkt)
780 {
781 return NET_VLAN_TAG_UNSPEC;
782 }
783
net_pkt_set_vlan_tag(struct net_pkt * pkt,uint16_t tag)784 static inline void net_pkt_set_vlan_tag(struct net_pkt *pkt, uint16_t tag)
785 {
786 ARG_UNUSED(pkt);
787 ARG_UNUSED(tag);
788 }
789
net_pkt_vlan_priority(struct net_pkt * pkt)790 static inline uint8_t net_pkt_vlan_priority(struct net_pkt *pkt)
791 {
792 ARG_UNUSED(pkt);
793 return 0;
794 }
795
net_pkt_vlan_dei(struct net_pkt * pkt)796 static inline bool net_pkt_vlan_dei(struct net_pkt *pkt)
797 {
798 return false;
799 }
800
net_pkt_set_vlan_dei(struct net_pkt * pkt,bool dei)801 static inline void net_pkt_set_vlan_dei(struct net_pkt *pkt, bool dei)
802 {
803 ARG_UNUSED(pkt);
804 ARG_UNUSED(dei);
805 }
806
net_pkt_vlan_tci(struct net_pkt * pkt)807 static inline uint16_t net_pkt_vlan_tci(struct net_pkt *pkt)
808 {
809 return NET_VLAN_TAG_UNSPEC; /* assumes priority is 0 */
810 }
811
net_pkt_set_vlan_tci(struct net_pkt * pkt,uint16_t tci)812 static inline void net_pkt_set_vlan_tci(struct net_pkt *pkt, uint16_t tci)
813 {
814 ARG_UNUSED(pkt);
815 ARG_UNUSED(tci);
816 }
817 #endif
818
819 #if defined(CONFIG_NET_PKT_TIMESTAMP)
net_pkt_timestamp(struct net_pkt * pkt)820 static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt)
821 {
822 return &pkt->timestamp;
823 }
824
net_pkt_set_timestamp(struct net_pkt * pkt,struct net_ptp_time * timestamp)825 static inline void net_pkt_set_timestamp(struct net_pkt *pkt,
826 struct net_ptp_time *timestamp)
827 {
828 pkt->timestamp.second = timestamp->second;
829 pkt->timestamp.nanosecond = timestamp->nanosecond;
830 }
831 #else
net_pkt_timestamp(struct net_pkt * pkt)832 static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt)
833 {
834 ARG_UNUSED(pkt);
835
836 return NULL;
837 }
838
net_pkt_set_timestamp(struct net_pkt * pkt,struct net_ptp_time * timestamp)839 static inline void net_pkt_set_timestamp(struct net_pkt *pkt,
840 struct net_ptp_time *timestamp)
841 {
842 ARG_UNUSED(pkt);
843 ARG_UNUSED(timestamp);
844 }
845 #endif /* CONFIG_NET_PKT_TIMESTAMP */
846
847 #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS)
net_pkt_create_time(struct net_pkt * pkt)848 static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
849 {
850 return pkt->create_time;
851 }
852
net_pkt_set_create_time(struct net_pkt * pkt,uint32_t create_time)853 static inline void net_pkt_set_create_time(struct net_pkt *pkt,
854 uint32_t create_time)
855 {
856 pkt->create_time = create_time;
857 }
858 #else
net_pkt_create_time(struct net_pkt * pkt)859 static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
860 {
861 ARG_UNUSED(pkt);
862
863 return 0U;
864 }
865
net_pkt_set_create_time(struct net_pkt * pkt,uint32_t create_time)866 static inline void net_pkt_set_create_time(struct net_pkt *pkt,
867 uint32_t create_time)
868 {
869 ARG_UNUSED(pkt);
870 ARG_UNUSED(create_time);
871 }
872 #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */
873
874 #if defined(CONFIG_NET_PKT_TXTIME)
net_pkt_txtime(struct net_pkt * pkt)875 static inline uint64_t net_pkt_txtime(struct net_pkt *pkt)
876 {
877 return pkt->txtime;
878 }
879
net_pkt_set_txtime(struct net_pkt * pkt,uint64_t txtime)880 static inline void net_pkt_set_txtime(struct net_pkt *pkt, uint64_t txtime)
881 {
882 pkt->txtime = txtime;
883 }
884 #else
net_pkt_txtime(struct net_pkt * pkt)885 static inline uint64_t net_pkt_txtime(struct net_pkt *pkt)
886 {
887 ARG_UNUSED(pkt);
888
889 return 0;
890 }
891
net_pkt_set_txtime(struct net_pkt * pkt,uint64_t txtime)892 static inline void net_pkt_set_txtime(struct net_pkt *pkt, uint64_t txtime)
893 {
894 ARG_UNUSED(pkt);
895 ARG_UNUSED(txtime);
896 }
897 #endif /* CONFIG_NET_PKT_TXTIME */
898
899 #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \
900 defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
net_pkt_stats_tick(struct net_pkt * pkt)901 static inline uint32_t *net_pkt_stats_tick(struct net_pkt *pkt)
902 {
903 return pkt->detail.stat;
904 }
905
net_pkt_stats_tick_count(struct net_pkt * pkt)906 static inline int net_pkt_stats_tick_count(struct net_pkt *pkt)
907 {
908 return pkt->detail.count;
909 }
910
net_pkt_stats_tick_reset(struct net_pkt * pkt)911 static inline void net_pkt_stats_tick_reset(struct net_pkt *pkt)
912 {
913 memset(&pkt->detail, 0, sizeof(pkt->detail));
914 }
915
net_pkt_set_stats_tick(struct net_pkt * pkt,uint32_t tick)916 static ALWAYS_INLINE void net_pkt_set_stats_tick(struct net_pkt *pkt,
917 uint32_t tick)
918 {
919 if (pkt->detail.count >= NET_PKT_DETAIL_STATS_COUNT) {
920 NET_ERR("Detail stats count overflow (%d >= %d)",
921 pkt->detail.count, NET_PKT_DETAIL_STATS_COUNT);
922 return;
923 }
924
925 pkt->detail.stat[pkt->detail.count++] = tick;
926 }
927
928 #define net_pkt_set_tx_stats_tick(pkt, tick) net_pkt_set_stats_tick(pkt, tick)
929 #define net_pkt_set_rx_stats_tick(pkt, tick) net_pkt_set_stats_tick(pkt, tick)
930 #else
net_pkt_stats_tick(struct net_pkt * pkt)931 static inline uint32_t *net_pkt_stats_tick(struct net_pkt *pkt)
932 {
933 ARG_UNUSED(pkt);
934
935 return NULL;
936 }
937
net_pkt_stats_tick_count(struct net_pkt * pkt)938 static inline int net_pkt_stats_tick_count(struct net_pkt *pkt)
939 {
940 ARG_UNUSED(pkt);
941
942 return 0;
943 }
944
net_pkt_stats_tick_reset(struct net_pkt * pkt)945 static inline void net_pkt_stats_tick_reset(struct net_pkt *pkt)
946 {
947 ARG_UNUSED(pkt);
948 }
949
net_pkt_set_stats_tick(struct net_pkt * pkt,uint32_t tick)950 static inline void net_pkt_set_stats_tick(struct net_pkt *pkt, uint32_t tick)
951 {
952 ARG_UNUSED(pkt);
953 ARG_UNUSED(tick);
954 }
955
956 #define net_pkt_set_tx_stats_tick(pkt, tick)
957 #define net_pkt_set_rx_stats_tick(pkt, tick)
958 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL ||
959 CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
960
net_pkt_get_len(struct net_pkt * pkt)961 static inline size_t net_pkt_get_len(struct net_pkt *pkt)
962 {
963 return net_buf_frags_len(pkt->frags);
964 }
965
net_pkt_data(struct net_pkt * pkt)966 static inline uint8_t *net_pkt_data(struct net_pkt *pkt)
967 {
968 return pkt->frags->data;
969 }
970
net_pkt_ip_data(struct net_pkt * pkt)971 static inline uint8_t *net_pkt_ip_data(struct net_pkt *pkt)
972 {
973 return pkt->frags->data;
974 }
975
net_pkt_is_empty(struct net_pkt * pkt)976 static inline bool net_pkt_is_empty(struct net_pkt *pkt)
977 {
978 return !pkt->buffer || !net_pkt_data(pkt) || pkt->buffer->len == 0;
979 }
980
net_pkt_lladdr_src(struct net_pkt * pkt)981 static inline struct net_linkaddr *net_pkt_lladdr_src(struct net_pkt *pkt)
982 {
983 return &pkt->lladdr_src;
984 }
985
net_pkt_lladdr_dst(struct net_pkt * pkt)986 static inline struct net_linkaddr *net_pkt_lladdr_dst(struct net_pkt *pkt)
987 {
988 return &pkt->lladdr_dst;
989 }
990
net_pkt_lladdr_swap(struct net_pkt * pkt)991 static inline void net_pkt_lladdr_swap(struct net_pkt *pkt)
992 {
993 uint8_t *addr = net_pkt_lladdr_src(pkt)->addr;
994
995 net_pkt_lladdr_src(pkt)->addr = net_pkt_lladdr_dst(pkt)->addr;
996 net_pkt_lladdr_dst(pkt)->addr = addr;
997 }
998
net_pkt_lladdr_clear(struct net_pkt * pkt)999 static inline void net_pkt_lladdr_clear(struct net_pkt *pkt)
1000 {
1001 net_pkt_lladdr_src(pkt)->addr = NULL;
1002 net_pkt_lladdr_src(pkt)->len = 0U;
1003 }
1004
1005 #if defined(CONFIG_IEEE802154) || defined(CONFIG_IEEE802154_RAW_MODE)
net_pkt_ieee802154_rssi(struct net_pkt * pkt)1006 static inline uint8_t net_pkt_ieee802154_rssi(struct net_pkt *pkt)
1007 {
1008 return pkt->ieee802154_rssi;
1009 }
1010
net_pkt_set_ieee802154_rssi(struct net_pkt * pkt,uint8_t rssi)1011 static inline void net_pkt_set_ieee802154_rssi(struct net_pkt *pkt,
1012 uint8_t rssi)
1013 {
1014 pkt->ieee802154_rssi = rssi;
1015 }
1016
net_pkt_ieee802154_lqi(struct net_pkt * pkt)1017 static inline uint8_t net_pkt_ieee802154_lqi(struct net_pkt *pkt)
1018 {
1019 return pkt->ieee802154_lqi;
1020 }
1021
net_pkt_set_ieee802154_lqi(struct net_pkt * pkt,uint8_t lqi)1022 static inline void net_pkt_set_ieee802154_lqi(struct net_pkt *pkt,
1023 uint8_t lqi)
1024 {
1025 pkt->ieee802154_lqi = lqi;
1026 }
1027
net_pkt_ieee802154_arb(struct net_pkt * pkt)1028 static inline bool net_pkt_ieee802154_arb(struct net_pkt *pkt)
1029 {
1030 return pkt->ieee802154_arb;
1031 }
1032
net_pkt_set_ieee802154_arb(struct net_pkt * pkt,bool arb)1033 static inline void net_pkt_set_ieee802154_arb(struct net_pkt *pkt, bool arb)
1034 {
1035 pkt->ieee802154_arb = arb;
1036 }
1037
net_pkt_ieee802154_ack_fpb(struct net_pkt * pkt)1038 static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt)
1039 {
1040 return pkt->ieee802154_ack_fpb;
1041 }
1042
net_pkt_set_ieee802154_ack_fpb(struct net_pkt * pkt,bool fpb)1043 static inline void net_pkt_set_ieee802154_ack_fpb(struct net_pkt *pkt,
1044 bool fpb)
1045 {
1046 pkt->ieee802154_ack_fpb = fpb;
1047 }
1048
net_pkt_ieee802154_frame_secured(struct net_pkt * pkt)1049 static inline bool net_pkt_ieee802154_frame_secured(struct net_pkt *pkt)
1050 {
1051 return pkt->ieee802154_frame_secured;
1052 }
1053
net_pkt_set_ieee802154_frame_secured(struct net_pkt * pkt,bool secured)1054 static inline void net_pkt_set_ieee802154_frame_secured(struct net_pkt *pkt,
1055 bool secured)
1056 {
1057 pkt->ieee802154_frame_secured = secured;
1058 }
1059
net_pkt_ieee802154_mac_hdr_rdy(struct net_pkt * pkt)1060 static inline bool net_pkt_ieee802154_mac_hdr_rdy(struct net_pkt *pkt)
1061 {
1062 return pkt->ieee802154_mac_hdr_rdy;
1063 }
1064
net_pkt_set_ieee802154_mac_hdr_rdy(struct net_pkt * pkt,bool rdy)1065 static inline void net_pkt_set_ieee802154_mac_hdr_rdy(struct net_pkt *pkt,
1066 bool rdy)
1067 {
1068 pkt->ieee802154_mac_hdr_rdy = rdy;
1069 }
1070
1071 #if defined(CONFIG_IEEE802154_2015)
net_pkt_ieee802154_fv2015(struct net_pkt * pkt)1072 static inline bool net_pkt_ieee802154_fv2015(struct net_pkt *pkt)
1073 {
1074 return pkt->ieee802154_fv2015;
1075 }
1076
net_pkt_set_ieee802154_fv2015(struct net_pkt * pkt,bool fv2015)1077 static inline void net_pkt_set_ieee802154_fv2015(struct net_pkt *pkt, bool fv2015)
1078 {
1079 pkt->ieee802154_fv2015 = fv2015;
1080 }
1081
net_pkt_ieee802154_ack_seb(struct net_pkt * pkt)1082 static inline bool net_pkt_ieee802154_ack_seb(struct net_pkt *pkt)
1083 {
1084 return pkt->ieee802154_ack_seb;
1085 }
1086
net_pkt_set_ieee802154_ack_seb(struct net_pkt * pkt,bool seb)1087 static inline void net_pkt_set_ieee802154_ack_seb(struct net_pkt *pkt, bool seb)
1088 {
1089 pkt->ieee802154_ack_seb = seb;
1090 }
1091
net_pkt_ieee802154_ack_fc(struct net_pkt * pkt)1092 static inline uint32_t net_pkt_ieee802154_ack_fc(struct net_pkt *pkt)
1093 {
1094 return pkt->ieee802154_ack_fc;
1095 }
1096
net_pkt_set_ieee802154_ack_fc(struct net_pkt * pkt,uint32_t fc)1097 static inline void net_pkt_set_ieee802154_ack_fc(struct net_pkt *pkt,
1098 uint32_t fc)
1099 {
1100 pkt->ieee802154_ack_fc = fc;
1101 }
1102
net_pkt_ieee802154_ack_keyid(struct net_pkt * pkt)1103 static inline uint8_t net_pkt_ieee802154_ack_keyid(struct net_pkt *pkt)
1104 {
1105 return pkt->ieee802154_ack_keyid;
1106 }
1107
net_pkt_set_ieee802154_ack_keyid(struct net_pkt * pkt,uint8_t keyid)1108 static inline void net_pkt_set_ieee802154_ack_keyid(struct net_pkt *pkt,
1109 uint8_t keyid)
1110 {
1111 pkt->ieee802154_ack_keyid = keyid;
1112 }
1113 #endif /* CONFIG_IEEE802154_2015 */
1114 #endif /* CONFIG_IEEE802154 || CONFIG_IEEE802154_RAW_MODE */
1115
1116 #if defined(CONFIG_NET_IPV4_AUTO)
net_pkt_ipv4_auto(struct net_pkt * pkt)1117 static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt)
1118 {
1119 return pkt->ipv4_auto_arp_msg;
1120 }
1121
net_pkt_set_ipv4_auto(struct net_pkt * pkt,bool is_auto_arp_msg)1122 static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt,
1123 bool is_auto_arp_msg)
1124 {
1125 pkt->ipv4_auto_arp_msg = is_auto_arp_msg;
1126 }
1127 #else /* CONFIG_NET_IPV4_AUTO */
net_pkt_ipv4_auto(struct net_pkt * pkt)1128 static inline bool net_pkt_ipv4_auto(struct net_pkt *pkt)
1129 {
1130 ARG_UNUSED(pkt);
1131
1132 return false;
1133 }
1134
net_pkt_set_ipv4_auto(struct net_pkt * pkt,bool is_auto_arp_msg)1135 static inline void net_pkt_set_ipv4_auto(struct net_pkt *pkt,
1136 bool is_auto_arp_msg)
1137 {
1138 ARG_UNUSED(pkt);
1139 ARG_UNUSED(is_auto_arp_msg);
1140 }
1141 #endif /* CONFIG_NET_IPV4_AUTO */
1142
1143 #if defined(CONFIG_NET_LLDP)
net_pkt_is_lldp(struct net_pkt * pkt)1144 static inline bool net_pkt_is_lldp(struct net_pkt *pkt)
1145 {
1146 return pkt->lldp_pkt;
1147 }
1148
net_pkt_set_lldp(struct net_pkt * pkt,bool is_lldp)1149 static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp)
1150 {
1151 pkt->lldp_pkt = is_lldp;
1152 }
1153 #else
net_pkt_is_lldp(struct net_pkt * pkt)1154 static inline bool net_pkt_is_lldp(struct net_pkt *pkt)
1155 {
1156 ARG_UNUSED(pkt);
1157
1158 return false;
1159 }
1160
net_pkt_set_lldp(struct net_pkt * pkt,bool is_lldp)1161 static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp)
1162 {
1163 ARG_UNUSED(pkt);
1164 ARG_UNUSED(is_lldp);
1165 }
1166 #endif /* CONFIG_NET_LLDP */
1167
1168 #if defined(CONFIG_NET_PPP)
net_pkt_is_ppp(struct net_pkt * pkt)1169 static inline bool net_pkt_is_ppp(struct net_pkt *pkt)
1170 {
1171 return pkt->ppp_msg;
1172 }
1173
net_pkt_set_ppp(struct net_pkt * pkt,bool is_ppp_msg)1174 static inline void net_pkt_set_ppp(struct net_pkt *pkt,
1175 bool is_ppp_msg)
1176 {
1177 pkt->ppp_msg = is_ppp_msg;
1178 }
1179 #else /* CONFIG_NET_PPP */
net_pkt_is_ppp(struct net_pkt * pkt)1180 static inline bool net_pkt_is_ppp(struct net_pkt *pkt)
1181 {
1182 ARG_UNUSED(pkt);
1183
1184 return false;
1185 }
1186
net_pkt_set_ppp(struct net_pkt * pkt,bool is_ppp_msg)1187 static inline void net_pkt_set_ppp(struct net_pkt *pkt,
1188 bool is_ppp_msg)
1189 {
1190 ARG_UNUSED(pkt);
1191 ARG_UNUSED(is_ppp_msg);
1192 }
1193 #endif /* CONFIG_NET_PPP */
1194
1195 #define NET_IPV6_HDR(pkt) ((struct net_ipv6_hdr *)net_pkt_ip_data(pkt))
1196 #define NET_IPV4_HDR(pkt) ((struct net_ipv4_hdr *)net_pkt_ip_data(pkt))
1197
net_pkt_set_src_ipv6_addr(struct net_pkt * pkt)1198 static inline void net_pkt_set_src_ipv6_addr(struct net_pkt *pkt)
1199 {
1200 net_if_ipv6_select_src_addr(net_context_get_iface(
1201 net_pkt_context(pkt)),
1202 &NET_IPV6_HDR(pkt)->src);
1203 }
1204
net_pkt_set_overwrite(struct net_pkt * pkt,bool overwrite)1205 static inline void net_pkt_set_overwrite(struct net_pkt *pkt, bool overwrite)
1206 {
1207 pkt->overwrite = overwrite;
1208 }
1209
net_pkt_is_being_overwritten(struct net_pkt * pkt)1210 static inline bool net_pkt_is_being_overwritten(struct net_pkt *pkt)
1211 {
1212 return pkt->overwrite;
1213 }
1214
1215 /* @endcond */
1216
1217 /**
1218 * @brief Create a net_pkt slab
1219 *
1220 * A net_pkt slab is used to store meta-information about
1221 * network packets. It must be coupled with a data fragment pool
1222 * (:c:macro:`NET_PKT_DATA_POOL_DEFINE`) used to store the actual
1223 * packet data. The macro can be used by an application to define
1224 * additional custom per-context TX packet slabs (see
1225 * :c:func:`net_context_setup_pools`).
1226 *
1227 * @param name Name of the slab.
1228 * @param count Number of net_pkt in this slab.
1229 */
1230 #define NET_PKT_SLAB_DEFINE(name, count) \
1231 K_MEM_SLAB_DEFINE(name, sizeof(struct net_pkt), count, 4)
1232
1233 /* Backward compatibility macro */
1234 #define NET_PKT_TX_SLAB_DEFINE(name, count) NET_PKT_SLAB_DEFINE(name, count)
1235
1236 /**
1237 * @brief Create a data fragment net_buf pool
1238 *
1239 * A net_buf pool is used to store actual data for
1240 * network packets. It must be coupled with a net_pkt slab
1241 * (:c:macro:`NET_PKT_SLAB_DEFINE`) used to store the packet
1242 * meta-information. The macro can be used by an application to
1243 * define additional custom per-context TX packet pools (see
1244 * :c:func:`net_context_setup_pools`).
1245 *
1246 * @param name Name of the pool.
1247 * @param count Number of net_buf in this pool.
1248 */
1249 #define NET_PKT_DATA_POOL_DEFINE(name, count) \
1250 NET_BUF_POOL_DEFINE(name, count, CONFIG_NET_BUF_DATA_SIZE, \
1251 CONFIG_NET_BUF_USER_DATA_SIZE, NULL)
1252
1253 /** @cond INTERNAL_HIDDEN */
1254
1255 #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) || \
1256 (CONFIG_NET_PKT_LOG_LEVEL >= LOG_LEVEL_DBG)
1257 #define NET_PKT_DEBUG_ENABLED
1258 #endif
1259
1260 #if defined(NET_PKT_DEBUG_ENABLED)
1261
1262 /* Debug versions of the net_pkt functions that are used when tracking
1263 * buffer usage.
1264 */
1265
1266 struct net_buf *net_pkt_get_reserve_data_debug(struct net_buf_pool *pool,
1267 k_timeout_t timeout,
1268 const char *caller,
1269 int line);
1270
1271 #define net_pkt_get_reserve_data(pool, timeout) \
1272 net_pkt_get_reserve_data_debug(pool, timeout, __func__, __LINE__)
1273
1274 struct net_buf *net_pkt_get_reserve_rx_data_debug(k_timeout_t timeout,
1275 const char *caller,
1276 int line);
1277 #define net_pkt_get_reserve_rx_data(timeout) \
1278 net_pkt_get_reserve_rx_data_debug(timeout, __func__, __LINE__)
1279
1280 struct net_buf *net_pkt_get_reserve_tx_data_debug(k_timeout_t timeout,
1281 const char *caller,
1282 int line);
1283 #define net_pkt_get_reserve_tx_data(timeout) \
1284 net_pkt_get_reserve_tx_data_debug(timeout, __func__, __LINE__)
1285
1286 struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt,
1287 k_timeout_t timeout,
1288 const char *caller, int line);
1289 #define net_pkt_get_frag(pkt, timeout) \
1290 net_pkt_get_frag_debug(pkt, timeout, __func__, __LINE__)
1291
1292 void net_pkt_unref_debug(struct net_pkt *pkt, const char *caller, int line);
1293 #define net_pkt_unref(pkt) net_pkt_unref_debug(pkt, __func__, __LINE__)
1294
1295 struct net_pkt *net_pkt_ref_debug(struct net_pkt *pkt, const char *caller,
1296 int line);
1297 #define net_pkt_ref(pkt) net_pkt_ref_debug(pkt, __func__, __LINE__)
1298
1299 struct net_buf *net_pkt_frag_ref_debug(struct net_buf *frag,
1300 const char *caller, int line);
1301 #define net_pkt_frag_ref(frag) net_pkt_frag_ref_debug(frag, __func__, __LINE__)
1302
1303 void net_pkt_frag_unref_debug(struct net_buf *frag,
1304 const char *caller, int line);
1305 #define net_pkt_frag_unref(frag) \
1306 net_pkt_frag_unref_debug(frag, __func__, __LINE__)
1307
1308 struct net_buf *net_pkt_frag_del_debug(struct net_pkt *pkt,
1309 struct net_buf *parent,
1310 struct net_buf *frag,
1311 const char *caller, int line);
1312 #define net_pkt_frag_del(pkt, parent, frag) \
1313 net_pkt_frag_del_debug(pkt, parent, frag, __func__, __LINE__)
1314
1315 void net_pkt_frag_add_debug(struct net_pkt *pkt, struct net_buf *frag,
1316 const char *caller, int line);
1317 #define net_pkt_frag_add(pkt, frag) \
1318 net_pkt_frag_add_debug(pkt, frag, __func__, __LINE__)
1319
1320 void net_pkt_frag_insert_debug(struct net_pkt *pkt, struct net_buf *frag,
1321 const char *caller, int line);
1322 #define net_pkt_frag_insert(pkt, frag) \
1323 net_pkt_frag_insert_debug(pkt, frag, __func__, __LINE__)
1324 #endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC ||
1325 * CONFIG_NET_PKT_LOG_LEVEL >= LOG_LEVEL_DBG
1326 */
1327 /** @endcond */
1328
1329 /**
1330 * @brief Print fragment list and the fragment sizes
1331 *
1332 * @details Only available if debugging is activated.
1333 *
1334 * @param pkt Network pkt.
1335 */
1336 #if defined(NET_PKT_DEBUG_ENABLED)
1337 void net_pkt_print_frags(struct net_pkt *pkt);
1338 #else
1339 #define net_pkt_print_frags(pkt)
1340 #endif
1341
1342 /**
1343 * @brief Get RX DATA buffer from pool.
1344 * Normally you should use net_pkt_get_frag() instead.
1345 *
1346 * @details Normally this version is not useful for applications
1347 * but is mainly used by network fragmentation code.
1348 *
1349 * @param timeout Affects the action taken should the net buf pool be empty.
1350 * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1351 * wait as long as necessary. Otherwise, wait up to the specified time.
1352 *
1353 * @return Network buffer if successful, NULL otherwise.
1354 */
1355 #if !defined(NET_PKT_DEBUG_ENABLED)
1356 struct net_buf *net_pkt_get_reserve_rx_data(k_timeout_t timeout);
1357 #endif
1358
1359 /**
1360 * @brief Get TX DATA buffer from pool.
1361 * Normally you should use net_pkt_get_frag() instead.
1362 *
1363 * @details Normally this version is not useful for applications
1364 * but is mainly used by network fragmentation code.
1365 *
1366 * @param timeout Affects the action taken should the net buf pool be empty.
1367 * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1368 * wait as long as necessary. Otherwise, wait up to the specified time.
1369 *
1370 * @return Network buffer if successful, NULL otherwise.
1371 */
1372 #if !defined(NET_PKT_DEBUG_ENABLED)
1373 struct net_buf *net_pkt_get_reserve_tx_data(k_timeout_t timeout);
1374 #endif
1375
1376 /**
1377 * @brief Get a data fragment that might be from user specific
1378 * buffer pool or from global DATA pool.
1379 *
1380 * @param pkt Network packet.
1381 * @param timeout Affects the action taken should the net buf pool be empty.
1382 * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1383 * wait as long as necessary. Otherwise, wait up to the specified time.
1384 *
1385 * @return Network buffer if successful, NULL otherwise.
1386 */
1387 #if !defined(NET_PKT_DEBUG_ENABLED)
1388 struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, k_timeout_t timeout);
1389 #endif
1390
1391 /**
1392 * @brief Place packet back into the available packets slab
1393 *
1394 * @details Releases the packet to other use. This needs to be
1395 * called by application after it has finished with the packet.
1396 *
1397 * @param pkt Network packet to release.
1398 *
1399 */
1400 #if !defined(NET_PKT_DEBUG_ENABLED)
1401 void net_pkt_unref(struct net_pkt *pkt);
1402 #endif
1403
1404 /**
1405 * @brief Increase the packet ref count
1406 *
1407 * @details Mark the packet to be used still.
1408 *
1409 * @param pkt Network packet to ref.
1410 *
1411 * @return Network packet if successful, NULL otherwise.
1412 */
1413 #if !defined(NET_PKT_DEBUG_ENABLED)
1414 struct net_pkt *net_pkt_ref(struct net_pkt *pkt);
1415 #endif
1416
1417 /**
1418 * @brief Increase the packet fragment ref count
1419 *
1420 * @details Mark the fragment to be used still.
1421 *
1422 * @param frag Network fragment to ref.
1423 *
1424 * @return a pointer on the referenced Network fragment.
1425 */
1426 #if !defined(NET_PKT_DEBUG_ENABLED)
1427 struct net_buf *net_pkt_frag_ref(struct net_buf *frag);
1428 #endif
1429
1430 /**
1431 * @brief Decrease the packet fragment ref count
1432 *
1433 * @param frag Network fragment to unref.
1434 */
1435 #if !defined(NET_PKT_DEBUG_ENABLED)
1436 void net_pkt_frag_unref(struct net_buf *frag);
1437 #endif
1438
1439 /**
1440 * @brief Delete existing fragment from a packet
1441 *
1442 * @param pkt Network packet from which frag belongs to.
1443 * @param parent parent fragment of frag, or NULL if none.
1444 * @param frag Fragment to delete.
1445 *
1446 * @return Pointer to the following fragment, or NULL if it had no
1447 * further fragments.
1448 */
1449 #if !defined(NET_PKT_DEBUG_ENABLED)
1450 struct net_buf *net_pkt_frag_del(struct net_pkt *pkt,
1451 struct net_buf *parent,
1452 struct net_buf *frag);
1453 #endif
1454
1455 /**
1456 * @brief Add a fragment to a packet at the end of its fragment list
1457 *
1458 * @param pkt pkt Network packet where to add the fragment
1459 * @param frag Fragment to add
1460 */
1461 #if !defined(NET_PKT_DEBUG_ENABLED)
1462 void net_pkt_frag_add(struct net_pkt *pkt, struct net_buf *frag);
1463 #endif
1464
1465 /**
1466 * @brief Insert a fragment to a packet at the beginning of its fragment list
1467 *
1468 * @param pkt pkt Network packet where to insert the fragment
1469 * @param frag Fragment to insert
1470 */
1471 #if !defined(NET_PKT_DEBUG_ENABLED)
1472 void net_pkt_frag_insert(struct net_pkt *pkt, struct net_buf *frag);
1473 #endif
1474
1475 /**
1476 * @brief Compact the fragment list of a packet.
1477 *
1478 * @details After this there is no more any free space in individual fragments.
1479 * @param pkt Network packet.
1480 *
1481 * @return True if compact success, False otherwise.
1482 */
1483 bool net_pkt_compact(struct net_pkt *pkt);
1484
1485 /**
1486 * @brief Get information about predefined RX, TX and DATA pools.
1487 *
1488 * @param rx Pointer to RX pool is returned.
1489 * @param tx Pointer to TX pool is returned.
1490 * @param rx_data Pointer to RX DATA pool is returned.
1491 * @param tx_data Pointer to TX DATA pool is returned.
1492 */
1493 void net_pkt_get_info(struct k_mem_slab **rx,
1494 struct k_mem_slab **tx,
1495 struct net_buf_pool **rx_data,
1496 struct net_buf_pool **tx_data);
1497
1498 /** @cond INTERNAL_HIDDEN */
1499
1500 #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC)
1501 /**
1502 * @brief Debug helper to print out the buffer allocations
1503 */
1504 void net_pkt_print(void);
1505
1506 typedef void (*net_pkt_allocs_cb_t)(struct net_pkt *pkt,
1507 struct net_buf *buf,
1508 const char *func_alloc,
1509 int line_alloc,
1510 const char *func_free,
1511 int line_free,
1512 bool in_use,
1513 void *user_data);
1514
1515 void net_pkt_allocs_foreach(net_pkt_allocs_cb_t cb, void *user_data);
1516
1517 const char *net_pkt_slab2str(struct k_mem_slab *slab);
1518 const char *net_pkt_pool2str(struct net_buf_pool *pool);
1519
1520 #else
1521 #define net_pkt_print(...)
1522 #endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */
1523
1524 /* New allocator, and API are defined below.
1525 * This will be simpler when time will come to get rid of former API above.
1526 */
1527 #if defined(NET_PKT_DEBUG_ENABLED)
1528
1529 struct net_pkt *net_pkt_alloc_debug(k_timeout_t timeout,
1530 const char *caller, int line);
1531 #define net_pkt_alloc(_timeout) \
1532 net_pkt_alloc_debug(_timeout, __func__, __LINE__)
1533
1534 struct net_pkt *net_pkt_alloc_from_slab_debug(struct k_mem_slab *slab,
1535 k_timeout_t timeout,
1536 const char *caller, int line);
1537 #define net_pkt_alloc_from_slab(_slab, _timeout) \
1538 net_pkt_alloc_from_slab_debug(_slab, _timeout, __func__, __LINE__)
1539
1540 struct net_pkt *net_pkt_rx_alloc_debug(k_timeout_t timeout,
1541 const char *caller, int line);
1542 #define net_pkt_rx_alloc(_timeout) \
1543 net_pkt_rx_alloc_debug(_timeout, __func__, __LINE__)
1544
1545 struct net_pkt *net_pkt_alloc_on_iface_debug(struct net_if *iface,
1546 k_timeout_t timeout,
1547 const char *caller,
1548 int line);
1549 #define net_pkt_alloc_on_iface(_iface, _timeout) \
1550 net_pkt_alloc_on_iface_debug(_iface, _timeout, __func__, __LINE__)
1551
1552 struct net_pkt *net_pkt_rx_alloc_on_iface_debug(struct net_if *iface,
1553 k_timeout_t timeout,
1554 const char *caller,
1555 int line);
1556 #define net_pkt_rx_alloc_on_iface(_iface, _timeout) \
1557 net_pkt_rx_alloc_on_iface_debug(_iface, _timeout, \
1558 __func__, __LINE__)
1559
1560 int net_pkt_alloc_buffer_debug(struct net_pkt *pkt,
1561 size_t size,
1562 enum net_ip_protocol proto,
1563 k_timeout_t timeout,
1564 const char *caller, int line);
1565 #define net_pkt_alloc_buffer(_pkt, _size, _proto, _timeout) \
1566 net_pkt_alloc_buffer_debug(_pkt, _size, _proto, _timeout, \
1567 __func__, __LINE__)
1568
1569 struct net_pkt *net_pkt_alloc_with_buffer_debug(struct net_if *iface,
1570 size_t size,
1571 sa_family_t family,
1572 enum net_ip_protocol proto,
1573 k_timeout_t timeout,
1574 const char *caller,
1575 int line);
1576 #define net_pkt_alloc_with_buffer(_iface, _size, _family, \
1577 _proto, _timeout) \
1578 net_pkt_alloc_with_buffer_debug(_iface, _size, _family, \
1579 _proto, _timeout, \
1580 __func__, __LINE__)
1581
1582 struct net_pkt *net_pkt_rx_alloc_with_buffer_debug(struct net_if *iface,
1583 size_t size,
1584 sa_family_t family,
1585 enum net_ip_protocol proto,
1586 k_timeout_t timeout,
1587 const char *caller,
1588 int line);
1589 #define net_pkt_rx_alloc_with_buffer(_iface, _size, _family, \
1590 _proto, _timeout) \
1591 net_pkt_rx_alloc_with_buffer_debug(_iface, _size, _family, \
1592 _proto, _timeout, \
1593 __func__, __LINE__)
1594 #endif /* NET_PKT_DEBUG_ENABLED */
1595 /** @endcond */
1596
1597 /**
1598 * @brief Allocate an initialized net_pkt
1599 *
1600 * @details for the time being, 2 pools are used. One for TX and one for RX.
1601 * This allocator has to be used for TX.
1602 *
1603 * @param timeout Maximum time to wait for an allocation.
1604 *
1605 * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1606 */
1607 #if !defined(NET_PKT_DEBUG_ENABLED)
1608 struct net_pkt *net_pkt_alloc(k_timeout_t timeout);
1609 #endif
1610
1611 /**
1612 * @brief Allocate an initialized net_pkt from a specific slab
1613 *
1614 * @details unlike net_pkt_alloc() which uses core slabs, this one will use
1615 * an external slab (see NET_PKT_SLAB_DEFINE()).
1616 * Do _not_ use it unless you know what you are doing. Basically, only
1617 * net_context should be using this, in order to allocate packet and
1618 * then buffer on its local slab/pool (if any).
1619 *
1620 * @param slab The slab to use for allocating the packet
1621 * @param timeout Maximum time to wait for an allocation.
1622 *
1623 * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1624 */
1625 #if !defined(NET_PKT_DEBUG_ENABLED)
1626 struct net_pkt *net_pkt_alloc_from_slab(struct k_mem_slab *slab,
1627 k_timeout_t timeout);
1628 #endif
1629
1630 /**
1631 * @brief Allocate an initialized net_pkt for RX
1632 *
1633 * @details for the time being, 2 pools are used. One for TX and one for RX.
1634 * This allocator has to be used for RX.
1635 *
1636 * @param timeout Maximum time to wait for an allocation.
1637 *
1638 * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1639 */
1640 #if !defined(NET_PKT_DEBUG_ENABLED)
1641 struct net_pkt *net_pkt_rx_alloc(k_timeout_t timeout);
1642 #endif
1643
1644 /**
1645 * @brief Allocate a network packet for a specific network interface.
1646 *
1647 * @param iface The network interface the packet is supposed to go through.
1648 * @param timeout Maximum time to wait for an allocation.
1649 *
1650 * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1651 */
1652 #if !defined(NET_PKT_DEBUG_ENABLED)
1653 struct net_pkt *net_pkt_alloc_on_iface(struct net_if *iface,
1654 k_timeout_t timeout);
1655
1656 /* Same as above but specifically for RX packet */
1657 struct net_pkt *net_pkt_rx_alloc_on_iface(struct net_if *iface,
1658 k_timeout_t timeout);
1659 #endif
1660
1661 /**
1662 * @brief Allocate buffer for a net_pkt
1663 *
1664 * @details: such allocator will take into account space necessary for headers,
1665 * MTU, and existing buffer (if any). Beware that, due to all these
1666 * criteria, the allocated size might be smaller/bigger than
1667 * requested one.
1668 *
1669 * @param pkt The network packet requiring buffer to be allocated.
1670 * @param size The size of buffer being requested.
1671 * @param proto The IP protocol type (can be 0 for none).
1672 * @param timeout Maximum time to wait for an allocation.
1673 *
1674 * @return 0 on success, negative errno code otherwise.
1675 */
1676 #if !defined(NET_PKT_DEBUG_ENABLED)
1677 int net_pkt_alloc_buffer(struct net_pkt *pkt,
1678 size_t size,
1679 enum net_ip_protocol proto,
1680 k_timeout_t timeout);
1681 #endif
1682
1683 /**
1684 * @brief Allocate a network packet and buffer at once
1685 *
1686 * @param iface The network interface the packet is supposed to go through.
1687 * @param size The size of buffer.
1688 * @param family The family to which the packet belongs.
1689 * @param proto The IP protocol type (can be 0 for none).
1690 * @param timeout Maximum time to wait for an allocation.
1691 *
1692 * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1693 */
1694 #if !defined(NET_PKT_DEBUG_ENABLED)
1695 struct net_pkt *net_pkt_alloc_with_buffer(struct net_if *iface,
1696 size_t size,
1697 sa_family_t family,
1698 enum net_ip_protocol proto,
1699 k_timeout_t timeout);
1700
1701 /* Same as above but specifically for RX packet */
1702 struct net_pkt *net_pkt_rx_alloc_with_buffer(struct net_if *iface,
1703 size_t size,
1704 sa_family_t family,
1705 enum net_ip_protocol proto,
1706 k_timeout_t timeout);
1707 #endif
1708
1709 /**
1710 * @brief Append a buffer in packet
1711 *
1712 * @param pkt Network packet where to append the buffer
1713 * @param buffer Buffer to append
1714 */
1715 void net_pkt_append_buffer(struct net_pkt *pkt, struct net_buf *buffer);
1716
1717 /**
1718 * @brief Get available buffer space from a pkt
1719 *
1720 * @note Reserved bytes (headroom) in any of the fragments are not considered to
1721 * be available.
1722 *
1723 * @param pkt The net_pkt which buffer availability should be evaluated
1724 *
1725 * @return the amount of buffer available
1726 */
1727 size_t net_pkt_available_buffer(struct net_pkt *pkt);
1728
1729 /**
1730 * @brief Get available buffer space for payload from a pkt
1731 *
1732 * @note Reserved bytes (headroom) in any of the fragments are not considered to
1733 * be available.
1734 *
1735 * @details Unlike net_pkt_available_buffer(), this will take into account
1736 * the headers space.
1737 *
1738 * @param pkt The net_pkt which payload buffer availability should
1739 * be evaluated
1740 * @param proto The IP protocol type (can be 0 for none).
1741 *
1742 * @return the amount of buffer available for payload
1743 */
1744 size_t net_pkt_available_payload_buffer(struct net_pkt *pkt,
1745 enum net_ip_protocol proto);
1746
1747 /**
1748 * @brief Trim net_pkt buffer
1749 *
1750 * @details This will basically check for unused buffers and deallocates
1751 * them relevantly
1752 *
1753 * @param pkt The net_pkt which buffer will be trimmed
1754 */
1755 void net_pkt_trim_buffer(struct net_pkt *pkt);
1756
1757 /**
1758 * @brief Remove @a length bytes from tail of packet
1759 *
1760 * @details This function does not take packet cursor into account. It is a
1761 * helper to remove unneeded bytes from tail of packet (like appended
1762 * CRC). It takes care of buffer deallocation if removed bytes span
1763 * whole buffer(s).
1764 *
1765 * @param pkt Network packet
1766 * @param length Number of bytes to be removed
1767 *
1768 * @retval 0 On success.
1769 * @retval -EINVAL If packet length is shorter than @a length.
1770 */
1771 int net_pkt_remove_tail(struct net_pkt *pkt, size_t length);
1772
1773 /**
1774 * @brief Initialize net_pkt cursor
1775 *
1776 * @details This will initialize the net_pkt cursor from its buffer.
1777 *
1778 * @param pkt The net_pkt whose cursor is going to be initialized
1779 */
1780 void net_pkt_cursor_init(struct net_pkt *pkt);
1781
1782 /**
1783 * @brief Backup net_pkt cursor
1784 *
1785 * @param pkt The net_pkt whose cursor is going to be backed up
1786 * @param backup The cursor where to backup net_pkt cursor
1787 */
net_pkt_cursor_backup(struct net_pkt * pkt,struct net_pkt_cursor * backup)1788 static inline void net_pkt_cursor_backup(struct net_pkt *pkt,
1789 struct net_pkt_cursor *backup)
1790 {
1791 backup->buf = pkt->cursor.buf;
1792 backup->pos = pkt->cursor.pos;
1793 }
1794
1795 /**
1796 * @brief Restore net_pkt cursor from a backup
1797 *
1798 * @param pkt The net_pkt whose cursor is going to be restored
1799 * @param backup The cursor from where to restore net_pkt cursor
1800 */
net_pkt_cursor_restore(struct net_pkt * pkt,struct net_pkt_cursor * backup)1801 static inline void net_pkt_cursor_restore(struct net_pkt *pkt,
1802 struct net_pkt_cursor *backup)
1803 {
1804 pkt->cursor.buf = backup->buf;
1805 pkt->cursor.pos = backup->pos;
1806 }
1807
1808 /**
1809 * @brief Returns current position of the cursor
1810 *
1811 * @param pkt The net_pkt whose cursor position is going to be returned
1812 *
1813 * @return cursor's position
1814 */
net_pkt_cursor_get_pos(struct net_pkt * pkt)1815 static inline void *net_pkt_cursor_get_pos(struct net_pkt *pkt)
1816 {
1817 return pkt->cursor.pos;
1818 }
1819
1820 /**
1821 * @brief Skip some data from a net_pkt
1822 *
1823 * @details net_pkt's cursor should be properly initialized
1824 * Cursor position will be updated after the operation.
1825 * Depending on the value of pkt->overwrite bit, this function
1826 * will affect the buffer length or not. If it's true, it will
1827 * advance the cursor to the requested length. If it's false,
1828 * it will do the same but if the cursor was already also at the
1829 * end of existing data, it will increment the buffer length.
1830 * So in this case, its behavior is just like net_pkt_write or
1831 * net_pkt_memset, difference being that it will not affect the
1832 * buffer content itself (which may be just garbage then).
1833 *
1834 * @param pkt The net_pkt whose cursor will be updated to skip given
1835 * amount of data from the buffer.
1836 * @param length Amount of data to skip in the buffer
1837 *
1838 * @return 0 in success, negative errno code otherwise.
1839 */
1840 int net_pkt_skip(struct net_pkt *pkt, size_t length);
1841
1842 /**
1843 * @brief Memset some data in a net_pkt
1844 *
1845 * @details net_pkt's cursor should be properly initialized and,
1846 * if needed, positioned using net_pkt_skip.
1847 * Cursor position will be updated after the operation.
1848 *
1849 * @param pkt The net_pkt whose buffer to fill starting at the current
1850 * cursor position.
1851 * @param byte The byte to write in memory
1852 * @param length Amount of data to memset with given byte
1853 *
1854 * @return 0 in success, negative errno code otherwise.
1855 */
1856 int net_pkt_memset(struct net_pkt *pkt, int byte, size_t length);
1857
1858 /**
1859 * @brief Copy data from a packet into another one.
1860 *
1861 * @details Both net_pkt cursors should be properly initialized and,
1862 * if needed, positioned using net_pkt_skip.
1863 * The cursors will be updated after the operation.
1864 *
1865 * @param pkt_dst Destination network packet.
1866 * @param pkt_src Source network packet.
1867 * @param length Length of data to be copied.
1868 *
1869 * @return 0 on success, negative errno code otherwise.
1870 */
1871 int net_pkt_copy(struct net_pkt *pkt_dst,
1872 struct net_pkt *pkt_src,
1873 size_t length);
1874
1875 /**
1876 * @brief Clone pkt and its buffer.
1877 *
1878 * @param pkt Original pkt to be cloned
1879 * @param timeout Timeout to wait for free buffer
1880 *
1881 * @return NULL if error, cloned packet otherwise.
1882 */
1883 struct net_pkt *net_pkt_clone(struct net_pkt *pkt, k_timeout_t timeout);
1884
1885 /**
1886 * @brief Clone pkt and increase the refcount of its buffer.
1887 *
1888 * @param pkt Original pkt to be shallow cloned
1889 * @param timeout Timeout to wait for free packet
1890 *
1891 * @return NULL if error, cloned packet otherwise.
1892 */
1893 struct net_pkt *net_pkt_shallow_clone(struct net_pkt *pkt,
1894 k_timeout_t timeout);
1895
1896 /**
1897 * @brief Read some data from a net_pkt
1898 *
1899 * @details net_pkt's cursor should be properly initialized and,
1900 * if needed, positioned using net_pkt_skip.
1901 * Cursor position will be updated after the operation.
1902 *
1903 * @param pkt The network packet from where to read some data
1904 * @param data The destination buffer where to copy the data
1905 * @param length The amount of data to copy
1906 *
1907 * @return 0 on success, negative errno code otherwise.
1908 */
1909 int net_pkt_read(struct net_pkt *pkt, void *data, size_t length);
1910
1911 /* Read uint8_t data data a net_pkt */
net_pkt_read_u8(struct net_pkt * pkt,uint8_t * data)1912 static inline int net_pkt_read_u8(struct net_pkt *pkt, uint8_t *data)
1913 {
1914 return net_pkt_read(pkt, data, 1);
1915 }
1916
1917 /**
1918 * @brief Read uint16_t big endian data from a net_pkt
1919 *
1920 * @details net_pkt's cursor should be properly initialized and,
1921 * if needed, positioned using net_pkt_skip.
1922 * Cursor position will be updated after the operation.
1923 *
1924 * @param pkt The network packet from where to read
1925 * @param data The destination uint16_t where to copy the data
1926 *
1927 * @return 0 on success, negative errno code otherwise.
1928 */
1929 int net_pkt_read_be16(struct net_pkt *pkt, uint16_t *data);
1930
1931 /**
1932 * @brief Read uint16_t little endian data from a net_pkt
1933 *
1934 * @details net_pkt's cursor should be properly initialized and,
1935 * if needed, positioned using net_pkt_skip.
1936 * Cursor position will be updated after the operation.
1937 *
1938 * @param pkt The network packet from where to read
1939 * @param data The destination uint16_t where to copy the data
1940 *
1941 * @return 0 on success, negative errno code otherwise.
1942 */
1943 int net_pkt_read_le16(struct net_pkt *pkt, uint16_t *data);
1944
1945 /**
1946 * @brief Read uint32_t big endian data from a net_pkt
1947 *
1948 * @details net_pkt's cursor should be properly initialized and,
1949 * if needed, positioned using net_pkt_skip.
1950 * Cursor position will be updated after the operation.
1951 *
1952 * @param pkt The network packet from where to read
1953 * @param data The destination uint32_t where to copy the data
1954 *
1955 * @return 0 on success, negative errno code otherwise.
1956 */
1957 int net_pkt_read_be32(struct net_pkt *pkt, uint32_t *data);
1958
1959 /**
1960 * @brief Write data into a net_pkt
1961 *
1962 * @details net_pkt's cursor should be properly initialized and,
1963 * if needed, positioned using net_pkt_skip.
1964 * Cursor position will be updated after the operation.
1965 *
1966 * @param pkt The network packet where to write
1967 * @param data Data to be written
1968 * @param length Length of the data to be written
1969 *
1970 * @return 0 on success, negative errno code otherwise.
1971 */
1972 int net_pkt_write(struct net_pkt *pkt, const void *data, size_t length);
1973
1974 /* Write uint8_t data into a net_pkt. */
net_pkt_write_u8(struct net_pkt * pkt,uint8_t data)1975 static inline int net_pkt_write_u8(struct net_pkt *pkt, uint8_t data)
1976 {
1977 return net_pkt_write(pkt, &data, sizeof(uint8_t));
1978 }
1979
1980 /* Write uint16_t big endian data into a net_pkt. */
net_pkt_write_be16(struct net_pkt * pkt,uint16_t data)1981 static inline int net_pkt_write_be16(struct net_pkt *pkt, uint16_t data)
1982 {
1983 uint16_t data_be16 = htons(data);
1984
1985 return net_pkt_write(pkt, &data_be16, sizeof(uint16_t));
1986 }
1987
1988 /* Write uint32_t big endian data into a net_pkt. */
net_pkt_write_be32(struct net_pkt * pkt,uint32_t data)1989 static inline int net_pkt_write_be32(struct net_pkt *pkt, uint32_t data)
1990 {
1991 uint32_t data_be32 = htonl(data);
1992
1993 return net_pkt_write(pkt, &data_be32, sizeof(uint32_t));
1994 }
1995
1996 /* Write uint32_t little endian data into a net_pkt. */
net_pkt_write_le32(struct net_pkt * pkt,uint32_t data)1997 static inline int net_pkt_write_le32(struct net_pkt *pkt, uint32_t data)
1998 {
1999 uint32_t data_le32 = sys_cpu_to_le32(data);
2000
2001 return net_pkt_write(pkt, &data_le32, sizeof(uint32_t));
2002 }
2003
2004 /* Write uint16_t little endian data into a net_pkt. */
net_pkt_write_le16(struct net_pkt * pkt,uint16_t data)2005 static inline int net_pkt_write_le16(struct net_pkt *pkt, uint16_t data)
2006 {
2007 uint16_t data_le16 = sys_cpu_to_le16(data);
2008
2009 return net_pkt_write(pkt, &data_le16, sizeof(uint16_t));
2010 }
2011
2012 /**
2013 * @brief Get the amount of data which can be read from current cursor position
2014 *
2015 * @param pkt Network packet
2016 *
2017 * @return Amount of data which can be read from current pkt cursor
2018 */
2019 size_t net_pkt_remaining_data(struct net_pkt *pkt);
2020
2021 /**
2022 * @brief Update the overall length of a packet
2023 *
2024 * @details Unlike net_pkt_pull() below, this does not take packet cursor
2025 * into account. It's mainly a helper dedicated for ipv4 and ipv6
2026 * input functions. It shrinks the overall length by given parameter.
2027 *
2028 * @param pkt Network packet
2029 * @param length The new length of the packet
2030 *
2031 * @return 0 on success, negative errno code otherwise.
2032 */
2033 int net_pkt_update_length(struct net_pkt *pkt, size_t length);
2034
2035 /**
2036 * @brief Remove data from the packet at current location
2037 *
2038 * @details net_pkt's cursor should be properly initialized and,
2039 * eventually, properly positioned using net_pkt_skip/read/write.
2040 * Note that net_pkt's cursor is reset by this function.
2041 *
2042 * @param pkt Network packet
2043 * @param length Number of bytes to be removed
2044 *
2045 * @return 0 on success, negative errno code otherwise.
2046 */
2047 int net_pkt_pull(struct net_pkt *pkt, size_t length);
2048
2049 /**
2050 * @brief Get the actual offset in the packet from its cursor
2051 *
2052 * @param pkt Network packet.
2053 *
2054 * @return a valid offset on success, 0 otherwise as there is nothing that
2055 * can be done to evaluate the offset.
2056 */
2057 uint16_t net_pkt_get_current_offset(struct net_pkt *pkt);
2058
2059 /**
2060 * @brief Check if a data size could fit contiguously
2061 *
2062 * @details net_pkt's cursor should be properly initialized and,
2063 * if needed, positioned using net_pkt_skip.
2064 *
2065 * @param pkt Network packet.
2066 * @param size The size to check for contiguity
2067 *
2068 * @return true if that is the case, false otherwise.
2069 */
2070 bool net_pkt_is_contiguous(struct net_pkt *pkt, size_t size);
2071
2072 /**
2073 * Get the contiguous buffer space
2074 *
2075 * @param pkt Network packet
2076 *
2077 * @return The available contiguous buffer space in bytes starting from the
2078 * current cursor position. 0 in case of an error.
2079 */
2080 size_t net_pkt_get_contiguous_len(struct net_pkt *pkt);
2081
2082 struct net_pkt_data_access {
2083 #if !defined(CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS)
2084 void *data;
2085 #endif
2086 const size_t size;
2087 };
2088
2089 #if defined(CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS)
2090 #define NET_PKT_DATA_ACCESS_DEFINE(_name, _type) \
2091 struct net_pkt_data_access _name = { \
2092 .size = sizeof(_type), \
2093 }
2094
2095 #define NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(_name, _type) \
2096 NET_PKT_DATA_ACCESS_DEFINE(_name, _type)
2097
2098 #else
2099 #define NET_PKT_DATA_ACCESS_DEFINE(_name, _type) \
2100 _type _hdr_##_name; \
2101 struct net_pkt_data_access _name = { \
2102 .data = &_hdr_##_name, \
2103 .size = sizeof(_type), \
2104 }
2105
2106 #define NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(_name, _type) \
2107 struct net_pkt_data_access _name = { \
2108 .data = NULL, \
2109 .size = sizeof(_type), \
2110 }
2111
2112 #endif /* CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS */
2113
2114 /**
2115 * @brief Get data from a network packet in a contiguous way
2116 *
2117 * @details net_pkt's cursor should be properly initialized and,
2118 * if needed, positioned using net_pkt_skip.
2119 * Cursor position will be updated after the operation.
2120 *
2121 * @param pkt The network packet from where to get the data.
2122 * @param access A pointer to a valid net_pkt_data_access describing the
2123 * data to get in a contiguous way.
2124 *
2125 * @return a pointer to the requested contiguous data, NULL otherwise.
2126 */
2127 void *net_pkt_get_data(struct net_pkt *pkt,
2128 struct net_pkt_data_access *access);
2129
2130 /**
2131 * @brief Set contiguous data into a network packet
2132 *
2133 * @details net_pkt's cursor should be properly initialized and,
2134 * if needed, positioned using net_pkt_skip.
2135 * Cursor position will be updated after the operation.
2136 *
2137 * @param pkt The network packet to where the data should be set.
2138 * @param access A pointer to a valid net_pkt_data_access describing the
2139 * data to set.
2140 *
2141 * @return 0 on success, a negative errno otherwise.
2142 */
2143 int net_pkt_set_data(struct net_pkt *pkt,
2144 struct net_pkt_data_access *access);
2145
2146 /**
2147 * Acknowledge previously contiguous data taken from a network packet
2148 * Packet needs to be set to overwrite mode.
2149 */
net_pkt_acknowledge_data(struct net_pkt * pkt,struct net_pkt_data_access * access)2150 static inline int net_pkt_acknowledge_data(struct net_pkt *pkt,
2151 struct net_pkt_data_access *access)
2152 {
2153 return net_pkt_skip(pkt, access->size);
2154 }
2155
2156 /**
2157 * @}
2158 */
2159
2160 #ifdef __cplusplus
2161 }
2162 #endif
2163
2164 #endif /* ZEPHYR_INCLUDE_NET_NET_PKT_H_ */
2165