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