Line data Source code
1 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 <zephyr/net_buf.h>
23 :
24 : #if defined(CONFIG_IEEE802154)
25 : #include <zephyr/net/ieee802154_pkt.h>
26 : #endif
27 : #include <zephyr/net/net_core.h>
28 : #include <zephyr/net/net_linkaddr.h>
29 : #include <zephyr/net/net_ip.h>
30 : #include <zephyr/net/net_if.h>
31 : #include <zephyr/net/net_context.h>
32 : #include <zephyr/net/net_time.h>
33 : #include <zephyr/net/ethernet_vlan.h>
34 : #include <zephyr/net/ptp_time.h>
35 :
36 : #ifdef __cplusplus
37 : extern "C" {
38 : #endif
39 :
40 : /**
41 : * @brief Network packet management library
42 : * @defgroup net_pkt Network Packet Library
43 : * @since 1.5
44 : * @version 0.8.0
45 : * @ingroup networking
46 : * @{
47 : */
48 :
49 : struct net_context;
50 :
51 : /** @cond INTERNAL_HIDDEN */
52 :
53 : #if defined(CONFIG_NET_PKT_ALLOC_STATS)
54 : struct net_pkt_alloc_stats {
55 : uint64_t alloc_sum;
56 : uint64_t time_sum;
57 : uint32_t count;
58 : };
59 :
60 : struct net_pkt_alloc_stats_slab {
61 : struct net_pkt_alloc_stats ok;
62 : struct net_pkt_alloc_stats fail;
63 : struct k_mem_slab *slab;
64 : };
65 :
66 : #define NET_PKT_ALLOC_STATS_DEFINE(alloc_name, slab_name) \
67 : STRUCT_SECTION_ITERABLE(net_pkt_alloc_stats_slab, alloc_name) = { \
68 : .slab = &slab_name, \
69 : }
70 :
71 : #else
72 : #define NET_PKT_ALLOC_STATS_DEFINE(name, slab)
73 : #endif /* CONFIG_NET_PKT_ALLOC_STATS */
74 :
75 : /* buffer cursor used in net_pkt */
76 : struct net_pkt_cursor {
77 : /** Current net_buf pointer by the cursor */
78 : struct net_buf *buf;
79 : /** Current position in the data buffer of the net_buf */
80 : uint8_t *pos;
81 : };
82 :
83 : /** @endcond */
84 :
85 : /**
86 : * @brief Network packet.
87 : *
88 : * Note that if you add new fields into net_pkt, remember to update
89 : * net_pkt_clone() function.
90 : */
91 1 : struct net_pkt {
92 : /**
93 : * The fifo is used by RX/TX threads and by socket layer. The net_pkt
94 : * is queued via fifo to the processing thread.
95 : */
96 1 : intptr_t fifo;
97 :
98 : /** Slab pointer from where it belongs to */
99 1 : struct k_mem_slab *slab;
100 :
101 : /** buffer holding the packet */
102 : union {
103 1 : struct net_buf *frags; /**< buffer fragment */
104 1 : struct net_buf *buffer; /**< alias to a buffer fragment */
105 1 : };
106 :
107 : /** Internal buffer iterator used for reading/writing */
108 1 : struct net_pkt_cursor cursor;
109 :
110 : /** Network connection context */
111 1 : struct net_context *context;
112 :
113 : /** Network interface */
114 1 : struct net_if *iface;
115 :
116 : /** @cond ignore */
117 :
118 : #if defined(CONFIG_NET_TCP)
119 : /** Allow placing the packet into sys_slist_t */
120 : sys_snode_t next;
121 : #endif
122 : #if defined(CONFIG_NET_ROUTING) || defined(CONFIG_NET_ETHERNET_BRIDGE)
123 : struct net_if *orig_iface; /* Original network interface */
124 : #endif
125 :
126 : #if defined(CONFIG_NET_VPN)
127 : struct {
128 : /** Original network interface */
129 : struct net_if *iface;
130 : /** Pointer to IP header of the encrypted pkt */
131 : union net_ip_header ip_hdr;
132 : /** Pointer to UDP header of the encrypted pkt */
133 : union net_proto_header proto_hdr;
134 : /** Peer id */
135 : int peer_id;
136 : } vpn;
137 : #endif
138 :
139 : #if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME)
140 : /**
141 : * TX or RX timestamp if available
142 : *
143 : * For packets that have been sent over the medium, the timestamp refers
144 : * to the time the message timestamp point was encountered at the
145 : * reference plane.
146 : *
147 : * Unsent packages can be scheduled by setting the timestamp to a future
148 : * point in time.
149 : *
150 : * All timestamps refer to the network subsystem's local clock.
151 : *
152 : * See @ref net_ptp_time for definitions of local clock, message
153 : * timestamp point and reference plane. See @ref net_time_t for
154 : * semantics of the network reference clock.
155 : *
156 : * TODO: Replace with net_time_t to decouple from PTP.
157 : */
158 : struct net_ptp_time timestamp;
159 : #endif
160 :
161 : #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS) || \
162 : defined(CONFIG_TRACING_NET_CORE)
163 : struct {
164 : /** Create time in cycles */
165 : uint32_t create_time;
166 :
167 : #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \
168 : defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
169 : /** Collect extra statistics for net_pkt processing
170 : * from various points in the IP stack. See networking
171 : * documentation where these points are located and how
172 : * to interpret the results.
173 : */
174 : struct {
175 : uint32_t stat[NET_PKT_DETAIL_STATS_COUNT];
176 : int count;
177 : } detail;
178 : #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL ||
179 : CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
180 : };
181 : #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS */
182 :
183 : #if defined(CONFIG_NET_PKT_ALLOC_STATS)
184 : struct net_pkt_alloc_stats_slab *alloc_stats;
185 : #endif /* CONFIG_NET_PKT_ALLOC_STATS */
186 :
187 : /** Reference counter */
188 : atomic_t atomic_ref;
189 :
190 : /* Filled by layer 2 when network packet is received. */
191 : struct net_linkaddr lladdr_src;
192 : struct net_linkaddr lladdr_dst;
193 : uint16_t ll_proto_type;
194 :
195 : #if defined(CONFIG_NET_IP)
196 : uint8_t ip_hdr_len; /* pre-filled in order to avoid func call */
197 : #endif
198 :
199 : uint8_t overwrite : 1; /* Is packet content being overwritten? */
200 : uint8_t eof : 1; /* Last packet before EOF */
201 : uint8_t ptp_pkt : 1; /* For outgoing packet: is this packet
202 : * a L2 PTP packet.
203 : * Used only if defined (CONFIG_NET_L2_PTP)
204 : */
205 : uint8_t forwarding : 1; /* Are we forwarding this pkt
206 : * Used only if defined(CONFIG_NET_ROUTE)
207 : */
208 : uint8_t family : 3; /* Address family, see net_ip.h */
209 :
210 : /* bitfield byte alignment boundary */
211 :
212 : #if defined(CONFIG_NET_IPV4_ACD)
213 : uint8_t ipv4_acd_arp_msg : 1; /* Is this pkt IPv4 conflict detection ARP
214 : * message.
215 : * Note: family needs to be
216 : * AF_INET.
217 : */
218 : #endif
219 : #if defined(CONFIG_NET_LLDP)
220 : uint8_t lldp_pkt : 1; /* Is this pkt an LLDP message.
221 : * Note: family needs to be
222 : * AF_UNSPEC.
223 : */
224 : #endif
225 : uint8_t ppp_msg : 1; /* This is a PPP message */
226 : uint8_t captured : 1; /* Set to 1 if this packet is already being
227 : * captured
228 : */
229 : uint8_t l2_bridged : 1; /* set to 1 if this packet comes from a bridge
230 : * and already contains its L2 header to be
231 : * preserved. Useful only if
232 : * defined(CONFIG_NET_ETHERNET_BRIDGE).
233 : */
234 : uint8_t l2_processed : 1; /* Set to 1 if this packet has already been
235 : * processed by the L2
236 : */
237 : uint8_t chksum_done : 1; /* Checksum has already been computed for
238 : * the packet.
239 : */
240 : #if defined(CONFIG_NET_IP_FRAGMENT)
241 : uint8_t ip_reassembled : 1; /* Packet is a reassembled IP packet. */
242 : #endif
243 : #if defined(CONFIG_NET_PKT_TIMESTAMP)
244 : uint8_t tx_timestamping : 1; /** Timestamp transmitted packet */
245 : uint8_t rx_timestamping : 1; /** Timestamp received packet */
246 : #endif
247 : /* bitfield byte alignment boundary */
248 :
249 : #if defined(CONFIG_NET_IP)
250 : union {
251 : /* IPv6 hop limit or IPv4 ttl for this network packet.
252 : * The value is shared between IPv6 and IPv4.
253 : */
254 : #if defined(CONFIG_NET_IPV6)
255 : uint8_t ipv6_hop_limit;
256 : #endif
257 : #if defined(CONFIG_NET_IPV4)
258 : uint8_t ipv4_ttl;
259 : #endif
260 : };
261 :
262 : union {
263 : #if defined(CONFIG_NET_IPV4)
264 : uint8_t ipv4_opts_len; /* length of IPv4 header options */
265 : #endif
266 : #if defined(CONFIG_NET_IPV6)
267 : uint16_t ipv6_ext_len; /* length of extension headers */
268 : #endif
269 : };
270 :
271 : #if defined(CONFIG_NET_IP_FRAGMENT)
272 : union {
273 : #if defined(CONFIG_NET_IPV4_FRAGMENT)
274 : struct {
275 : uint16_t flags; /* Fragment offset and M (More Fragment) flag */
276 : uint16_t id; /* Fragment ID */
277 : } ipv4_fragment;
278 : #endif /* CONFIG_NET_IPV4_FRAGMENT */
279 : #if defined(CONFIG_NET_IPV6_FRAGMENT)
280 : struct {
281 : uint16_t flags; /* Fragment offset and M (More Fragment) flag */
282 : uint32_t id; /* Fragment id */
283 : uint16_t hdr_start; /* Where starts the fragment header */
284 : } ipv6_fragment;
285 : #endif /* CONFIG_NET_IPV6_FRAGMENT */
286 : };
287 : #endif /* CONFIG_NET_IP_FRAGMENT */
288 :
289 : #if defined(CONFIG_NET_IPV6)
290 : /* Where is the start of the last header before payload data
291 : * in IPv6 packet. This is offset value from start of the IPv6
292 : * packet. Note that this value should be updated by who ever
293 : * adds IPv6 extension headers to the network packet.
294 : */
295 : uint16_t ipv6_prev_hdr_start;
296 :
297 : uint8_t ipv6_ext_opt_len; /* IPv6 ND option length */
298 : uint8_t ipv6_next_hdr; /* What is the very first next header */
299 : #endif /* CONFIG_NET_IPV6 */
300 :
301 : #if defined(CONFIG_NET_IP_DSCP_ECN)
302 : /** IPv4/IPv6 Differentiated Services Code Point value. */
303 : uint8_t ip_dscp : 6;
304 :
305 : /** IPv4/IPv6 Explicit Congestion Notification value. */
306 : uint8_t ip_ecn : 2;
307 : #endif /* CONFIG_NET_IP_DSCP_ECN */
308 : #endif /* CONFIG_NET_IP */
309 :
310 : #if defined(CONFIG_NET_VLAN)
311 : /* VLAN TCI (Tag Control Information). This contains the Priority
312 : * Code Point (PCP), Drop Eligible Indicator (DEI) and VLAN
313 : * Identifier (VID, called more commonly VLAN tag). This value is
314 : * kept in host byte order.
315 : */
316 : uint16_t vlan_tci;
317 : #endif /* CONFIG_NET_VLAN */
318 :
319 : #if defined(NET_PKT_HAS_CONTROL_BLOCK)
320 : /* TODO: Evolve this into a union of orthogonal
321 : * control block declarations if further L2
322 : * stacks require L2-specific attributes.
323 : */
324 : #if defined(CONFIG_IEEE802154)
325 : /* The following structure requires a 4-byte alignment
326 : * boundary to avoid padding.
327 : */
328 : struct net_pkt_cb_ieee802154 cb;
329 : #endif /* CONFIG_IEEE802154 */
330 : #endif /* NET_PKT_HAS_CONTROL_BLOCK */
331 :
332 : /** Network packet priority, can be left out in which case packet
333 : * is not prioritised.
334 : */
335 : uint8_t priority;
336 :
337 : #if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_L2_IPIP)
338 : /* Remote address of the received packet. This is only used by
339 : * network interfaces with an offloaded TCP/IP stack, or if we
340 : * have network tunneling in use.
341 : */
342 : union {
343 : struct sockaddr remote;
344 :
345 : /* This will make sure that there is enough storage to store
346 : * the address struct. The access to value is via remote
347 : * address.
348 : */
349 : struct sockaddr_storage remote_storage;
350 : };
351 : #endif /* CONFIG_NET_OFFLOAD */
352 :
353 : #if defined(CONFIG_NET_CAPTURE_COOKED_MODE)
354 : /* Tell the capture api that this is a captured packet */
355 : uint8_t cooked_mode_pkt : 1;
356 : #endif /* CONFIG_NET_CAPTURE_COOKED_MODE */
357 :
358 : #if defined(CONFIG_NET_IPV4_PMTU)
359 : /* Path MTU needed for this destination address */
360 : uint8_t ipv4_pmtu : 1;
361 : #endif /* CONFIG_NET_IPV4_PMTU */
362 :
363 : /* @endcond */
364 : };
365 :
366 : /** @cond ignore */
367 :
368 : /* The interface real ll address */
369 : static inline struct net_linkaddr *net_pkt_lladdr_if(struct net_pkt *pkt)
370 : {
371 : return net_if_get_link_addr(pkt->iface);
372 : }
373 :
374 : static inline struct net_context *net_pkt_context(struct net_pkt *pkt)
375 : {
376 : return pkt->context;
377 : }
378 :
379 : static inline void net_pkt_set_context(struct net_pkt *pkt,
380 : struct net_context *ctx)
381 : {
382 : pkt->context = ctx;
383 : }
384 :
385 : static inline struct net_if *net_pkt_iface(struct net_pkt *pkt)
386 : {
387 : return pkt->iface;
388 : }
389 :
390 : static inline void net_pkt_set_iface(struct net_pkt *pkt, struct net_if *iface)
391 : {
392 : pkt->iface = iface;
393 :
394 : /* If the network interface is set in pkt, then also set the type of
395 : * the network address that is stored in pkt. This is done here so
396 : * that the address type is properly set and is not forgotten.
397 : */
398 : if (iface) {
399 : uint8_t type = net_if_get_link_addr(iface)->type;
400 :
401 : pkt->lladdr_src.type = type;
402 : pkt->lladdr_dst.type = type;
403 : }
404 : }
405 :
406 : static inline struct net_if *net_pkt_orig_iface(struct net_pkt *pkt)
407 : {
408 : #if defined(CONFIG_NET_ROUTING) || defined(CONFIG_NET_ETHERNET_BRIDGE)
409 : return pkt->orig_iface;
410 : #else
411 : return pkt->iface;
412 : #endif
413 : }
414 :
415 : static inline void net_pkt_set_orig_iface(struct net_pkt *pkt,
416 : struct net_if *iface)
417 : {
418 : #if defined(CONFIG_NET_ROUTING) || defined(CONFIG_NET_ETHERNET_BRIDGE)
419 : pkt->orig_iface = iface;
420 : #else
421 : ARG_UNUSED(pkt);
422 : ARG_UNUSED(iface);
423 : #endif
424 : }
425 :
426 : #if defined(CONFIG_NET_VPN)
427 : static inline struct net_if *net_pkt_vpn_iface(struct net_pkt *pkt)
428 : {
429 : return pkt->vpn.iface;
430 : }
431 :
432 : static inline void net_pkt_set_vpn_iface(struct net_pkt *pkt,
433 : struct net_if *iface)
434 : {
435 : pkt->vpn.iface = iface;
436 : }
437 :
438 : static inline union net_ip_header *net_pkt_vpn_ip_hdr(struct net_pkt *pkt)
439 : {
440 : return &pkt->vpn.ip_hdr;
441 : }
442 :
443 : static inline void net_pkt_set_vpn_ip_hdr(struct net_pkt *pkt,
444 : union net_ip_header *ip_hdr)
445 : {
446 : pkt->vpn.ip_hdr = *ip_hdr;
447 : }
448 :
449 : static inline union net_proto_header *net_pkt_vpn_udp_hdr(struct net_pkt *pkt)
450 : {
451 : return &pkt->vpn.proto_hdr;
452 : }
453 :
454 : static inline void net_pkt_set_vpn_udp_hdr(struct net_pkt *pkt,
455 : union net_proto_header *proto_hdr)
456 : {
457 : pkt->vpn.proto_hdr = *proto_hdr;
458 : }
459 :
460 : static inline int net_pkt_vpn_peer_id(struct net_pkt *pkt)
461 : {
462 : return pkt->vpn.peer_id;
463 : }
464 :
465 : static inline void net_pkt_set_vpn_peer_id(struct net_pkt *pkt,
466 : int peer_id)
467 : {
468 : pkt->vpn.peer_id = peer_id;
469 : }
470 : #endif /* CONFIG_NET_VPN */
471 :
472 : static inline uint8_t net_pkt_family(struct net_pkt *pkt)
473 : {
474 : return pkt->family;
475 : }
476 :
477 : static inline void net_pkt_set_family(struct net_pkt *pkt, uint8_t family)
478 : {
479 : pkt->family = family;
480 : }
481 :
482 : static inline bool net_pkt_is_ptp(struct net_pkt *pkt)
483 : {
484 : return !!(pkt->ptp_pkt);
485 : }
486 :
487 : static inline void net_pkt_set_ptp(struct net_pkt *pkt, bool is_ptp)
488 : {
489 : pkt->ptp_pkt = is_ptp;
490 : }
491 :
492 : static inline bool net_pkt_is_tx_timestamping(struct net_pkt *pkt)
493 : {
494 : #if defined(CONFIG_NET_PKT_TIMESTAMP)
495 : return !!(pkt->tx_timestamping);
496 : #else
497 : ARG_UNUSED(pkt);
498 :
499 : return false;
500 : #endif
501 : }
502 :
503 : static inline void net_pkt_set_tx_timestamping(struct net_pkt *pkt, bool is_timestamping)
504 : {
505 : #if defined(CONFIG_NET_PKT_TIMESTAMP)
506 : pkt->tx_timestamping = is_timestamping;
507 : #else
508 : ARG_UNUSED(pkt);
509 : ARG_UNUSED(is_timestamping);
510 : #endif
511 : }
512 :
513 : static inline bool net_pkt_is_rx_timestamping(struct net_pkt *pkt)
514 : {
515 : #if defined(CONFIG_NET_PKT_TIMESTAMP)
516 : return !!(pkt->rx_timestamping);
517 : #else
518 : ARG_UNUSED(pkt);
519 :
520 : return false;
521 : #endif
522 : }
523 :
524 : static inline void net_pkt_set_rx_timestamping(struct net_pkt *pkt, bool is_timestamping)
525 : {
526 : #if defined(CONFIG_NET_PKT_TIMESTAMP)
527 : pkt->rx_timestamping = is_timestamping;
528 : #else
529 : ARG_UNUSED(pkt);
530 : ARG_UNUSED(is_timestamping);
531 : #endif
532 : }
533 :
534 : static inline bool net_pkt_is_captured(struct net_pkt *pkt)
535 : {
536 : return !!(pkt->captured);
537 : }
538 :
539 : static inline void net_pkt_set_captured(struct net_pkt *pkt, bool is_captured)
540 : {
541 : pkt->captured = is_captured;
542 : }
543 :
544 : static inline bool net_pkt_is_l2_bridged(struct net_pkt *pkt)
545 : {
546 : return IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE) ? !!(pkt->l2_bridged) : 0;
547 : }
548 :
549 : static inline void net_pkt_set_l2_bridged(struct net_pkt *pkt, bool is_l2_bridged)
550 : {
551 : if (IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE)) {
552 : pkt->l2_bridged = is_l2_bridged;
553 : }
554 : }
555 :
556 : static inline bool net_pkt_is_l2_processed(struct net_pkt *pkt)
557 : {
558 : return !!(pkt->l2_processed);
559 : }
560 :
561 : static inline void net_pkt_set_l2_processed(struct net_pkt *pkt,
562 : bool is_l2_processed)
563 : {
564 : pkt->l2_processed = is_l2_processed;
565 : }
566 :
567 : static inline bool net_pkt_is_chksum_done(struct net_pkt *pkt)
568 : {
569 : return !!(pkt->chksum_done);
570 : }
571 :
572 : static inline void net_pkt_set_chksum_done(struct net_pkt *pkt,
573 : bool is_chksum_done)
574 : {
575 : pkt->chksum_done = is_chksum_done;
576 : }
577 :
578 : static inline uint8_t net_pkt_ip_hdr_len(struct net_pkt *pkt)
579 : {
580 : #if defined(CONFIG_NET_IP)
581 : return pkt->ip_hdr_len;
582 : #else
583 : ARG_UNUSED(pkt);
584 :
585 : return 0;
586 : #endif
587 : }
588 :
589 : static inline void net_pkt_set_ip_hdr_len(struct net_pkt *pkt, uint8_t len)
590 : {
591 : #if defined(CONFIG_NET_IP)
592 : pkt->ip_hdr_len = len;
593 : #else
594 : ARG_UNUSED(pkt);
595 : ARG_UNUSED(len);
596 : #endif
597 : }
598 :
599 : static inline uint8_t net_pkt_ip_dscp(struct net_pkt *pkt)
600 : {
601 : #if defined(CONFIG_NET_IP_DSCP_ECN)
602 : return pkt->ip_dscp;
603 : #else
604 : ARG_UNUSED(pkt);
605 :
606 : return 0;
607 : #endif
608 : }
609 :
610 : static inline void net_pkt_set_ip_dscp(struct net_pkt *pkt, uint8_t dscp)
611 : {
612 : #if defined(CONFIG_NET_IP_DSCP_ECN)
613 : pkt->ip_dscp = dscp;
614 : #else
615 : ARG_UNUSED(pkt);
616 : ARG_UNUSED(dscp);
617 : #endif
618 : }
619 :
620 : static inline uint8_t net_pkt_ip_ecn(struct net_pkt *pkt)
621 : {
622 : #if defined(CONFIG_NET_IP_DSCP_ECN)
623 : return pkt->ip_ecn;
624 : #else
625 : ARG_UNUSED(pkt);
626 :
627 : return 0;
628 : #endif
629 : }
630 :
631 : static inline void net_pkt_set_ip_ecn(struct net_pkt *pkt, uint8_t ecn)
632 : {
633 : #if defined(CONFIG_NET_IP_DSCP_ECN)
634 : pkt->ip_ecn = ecn;
635 : #else
636 : ARG_UNUSED(pkt);
637 : ARG_UNUSED(ecn);
638 : #endif
639 : }
640 :
641 : static inline uint8_t net_pkt_eof(struct net_pkt *pkt)
642 : {
643 : return pkt->eof;
644 : }
645 :
646 : static inline void net_pkt_set_eof(struct net_pkt *pkt, bool eof)
647 : {
648 : pkt->eof = eof;
649 : }
650 :
651 : static inline bool net_pkt_forwarding(struct net_pkt *pkt)
652 : {
653 : return !!(pkt->forwarding);
654 : }
655 :
656 : static inline void net_pkt_set_forwarding(struct net_pkt *pkt, bool forward)
657 : {
658 : pkt->forwarding = forward;
659 : }
660 :
661 : #if defined(CONFIG_NET_IPV4)
662 : static inline uint8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
663 : {
664 : return pkt->ipv4_ttl;
665 : }
666 :
667 : static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
668 : uint8_t ttl)
669 : {
670 : pkt->ipv4_ttl = ttl;
671 : }
672 :
673 : static inline uint8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
674 : {
675 : return pkt->ipv4_opts_len;
676 : }
677 :
678 : static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
679 : uint8_t opts_len)
680 : {
681 : pkt->ipv4_opts_len = opts_len;
682 : }
683 : #else
684 : static inline uint8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
685 : {
686 : ARG_UNUSED(pkt);
687 :
688 : return 0;
689 : }
690 :
691 : static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
692 : uint8_t ttl)
693 : {
694 : ARG_UNUSED(pkt);
695 : ARG_UNUSED(ttl);
696 : }
697 :
698 : static inline uint8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
699 : {
700 : ARG_UNUSED(pkt);
701 : return 0;
702 : }
703 :
704 : static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
705 : uint8_t opts_len)
706 : {
707 : ARG_UNUSED(pkt);
708 : ARG_UNUSED(opts_len);
709 : }
710 : #endif
711 :
712 : #if defined(CONFIG_NET_IPV6)
713 : static inline uint8_t net_pkt_ipv6_ext_opt_len(struct net_pkt *pkt)
714 : {
715 : return pkt->ipv6_ext_opt_len;
716 : }
717 :
718 : static inline void net_pkt_set_ipv6_ext_opt_len(struct net_pkt *pkt,
719 : uint8_t len)
720 : {
721 : pkt->ipv6_ext_opt_len = len;
722 : }
723 :
724 : static inline uint8_t net_pkt_ipv6_next_hdr(struct net_pkt *pkt)
725 : {
726 : return pkt->ipv6_next_hdr;
727 : }
728 :
729 : static inline void net_pkt_set_ipv6_next_hdr(struct net_pkt *pkt,
730 : uint8_t next_hdr)
731 : {
732 : pkt->ipv6_next_hdr = next_hdr;
733 : }
734 :
735 : static inline uint16_t net_pkt_ipv6_ext_len(struct net_pkt *pkt)
736 : {
737 : return pkt->ipv6_ext_len;
738 : }
739 :
740 : static inline void net_pkt_set_ipv6_ext_len(struct net_pkt *pkt, uint16_t len)
741 : {
742 : pkt->ipv6_ext_len = len;
743 : }
744 :
745 : static inline uint16_t net_pkt_ipv6_hdr_prev(struct net_pkt *pkt)
746 : {
747 : return pkt->ipv6_prev_hdr_start;
748 : }
749 :
750 : static inline void net_pkt_set_ipv6_hdr_prev(struct net_pkt *pkt,
751 : uint16_t offset)
752 : {
753 : pkt->ipv6_prev_hdr_start = offset;
754 : }
755 :
756 : static inline uint8_t net_pkt_ipv6_hop_limit(struct net_pkt *pkt)
757 : {
758 : return pkt->ipv6_hop_limit;
759 : }
760 :
761 : static inline void net_pkt_set_ipv6_hop_limit(struct net_pkt *pkt,
762 : uint8_t hop_limit)
763 : {
764 : pkt->ipv6_hop_limit = hop_limit;
765 : }
766 : #else /* CONFIG_NET_IPV6 */
767 : static inline uint8_t net_pkt_ipv6_ext_opt_len(struct net_pkt *pkt)
768 : {
769 : ARG_UNUSED(pkt);
770 :
771 : return 0;
772 : }
773 :
774 : static inline void net_pkt_set_ipv6_ext_opt_len(struct net_pkt *pkt,
775 : uint8_t len)
776 : {
777 : ARG_UNUSED(pkt);
778 : ARG_UNUSED(len);
779 : }
780 :
781 : static inline uint8_t net_pkt_ipv6_next_hdr(struct net_pkt *pkt)
782 : {
783 : ARG_UNUSED(pkt);
784 :
785 : return 0;
786 : }
787 :
788 : static inline void net_pkt_set_ipv6_next_hdr(struct net_pkt *pkt,
789 : uint8_t next_hdr)
790 : {
791 : ARG_UNUSED(pkt);
792 : ARG_UNUSED(next_hdr);
793 : }
794 :
795 : static inline uint16_t net_pkt_ipv6_ext_len(struct net_pkt *pkt)
796 : {
797 : ARG_UNUSED(pkt);
798 :
799 : return 0;
800 : }
801 :
802 : static inline void net_pkt_set_ipv6_ext_len(struct net_pkt *pkt, uint16_t len)
803 : {
804 : ARG_UNUSED(pkt);
805 : ARG_UNUSED(len);
806 : }
807 :
808 : static inline uint16_t net_pkt_ipv6_hdr_prev(struct net_pkt *pkt)
809 : {
810 : ARG_UNUSED(pkt);
811 :
812 : return 0;
813 : }
814 :
815 : static inline void net_pkt_set_ipv6_hdr_prev(struct net_pkt *pkt,
816 : uint16_t offset)
817 : {
818 : ARG_UNUSED(pkt);
819 : ARG_UNUSED(offset);
820 : }
821 :
822 : static inline uint8_t net_pkt_ipv6_hop_limit(struct net_pkt *pkt)
823 : {
824 : ARG_UNUSED(pkt);
825 :
826 : return 0;
827 : }
828 :
829 : static inline void net_pkt_set_ipv6_hop_limit(struct net_pkt *pkt,
830 : uint8_t hop_limit)
831 : {
832 : ARG_UNUSED(pkt);
833 : ARG_UNUSED(hop_limit);
834 : }
835 : #endif /* CONFIG_NET_IPV6 */
836 :
837 : static inline uint16_t net_pkt_ip_opts_len(struct net_pkt *pkt)
838 : {
839 : #if defined(CONFIG_NET_IPV6)
840 : return pkt->ipv6_ext_len;
841 : #elif defined(CONFIG_NET_IPV4)
842 : return pkt->ipv4_opts_len;
843 : #else
844 : ARG_UNUSED(pkt);
845 :
846 : return 0;
847 : #endif
848 : }
849 :
850 : #if defined(CONFIG_NET_IPV4_PMTU)
851 : static inline bool net_pkt_ipv4_pmtu(struct net_pkt *pkt)
852 : {
853 : return !!pkt->ipv4_pmtu;
854 : }
855 :
856 : static inline void net_pkt_set_ipv4_pmtu(struct net_pkt *pkt, bool value)
857 : {
858 : pkt->ipv4_pmtu = value;
859 : }
860 : #else
861 : static inline bool net_pkt_ipv4_pmtu(struct net_pkt *pkt)
862 : {
863 : ARG_UNUSED(pkt);
864 :
865 : return false;
866 : }
867 :
868 : static inline void net_pkt_set_ipv4_pmtu(struct net_pkt *pkt, bool value)
869 : {
870 : ARG_UNUSED(pkt);
871 : ARG_UNUSED(value);
872 : }
873 : #endif /* CONFIG_NET_IPV4_PMTU */
874 :
875 : #if defined(CONFIG_NET_IPV4_FRAGMENT)
876 : static inline uint16_t net_pkt_ipv4_fragment_offset(struct net_pkt *pkt)
877 : {
878 : return (pkt->ipv4_fragment.flags & NET_IPV4_FRAGH_OFFSET_MASK) * 8;
879 : }
880 :
881 : static inline bool net_pkt_ipv4_fragment_more(struct net_pkt *pkt)
882 : {
883 : return (pkt->ipv4_fragment.flags & NET_IPV4_MORE_FRAG_MASK) != 0;
884 : }
885 :
886 : static inline void net_pkt_set_ipv4_fragment_flags(struct net_pkt *pkt, uint16_t flags)
887 : {
888 : pkt->ipv4_fragment.flags = flags;
889 : }
890 :
891 : static inline uint32_t net_pkt_ipv4_fragment_id(struct net_pkt *pkt)
892 : {
893 : return pkt->ipv4_fragment.id;
894 : }
895 :
896 : static inline void net_pkt_set_ipv4_fragment_id(struct net_pkt *pkt, uint32_t id)
897 : {
898 : pkt->ipv4_fragment.id = id;
899 : }
900 : #else /* CONFIG_NET_IPV4_FRAGMENT */
901 : static inline uint16_t net_pkt_ipv4_fragment_offset(struct net_pkt *pkt)
902 : {
903 : ARG_UNUSED(pkt);
904 :
905 : return 0;
906 : }
907 :
908 : static inline bool net_pkt_ipv4_fragment_more(struct net_pkt *pkt)
909 : {
910 : ARG_UNUSED(pkt);
911 :
912 : return 0;
913 : }
914 :
915 : static inline void net_pkt_set_ipv4_fragment_flags(struct net_pkt *pkt, uint16_t flags)
916 : {
917 : ARG_UNUSED(pkt);
918 : ARG_UNUSED(flags);
919 : }
920 :
921 : static inline uint32_t net_pkt_ipv4_fragment_id(struct net_pkt *pkt)
922 : {
923 : ARG_UNUSED(pkt);
924 :
925 : return 0;
926 : }
927 :
928 : static inline void net_pkt_set_ipv4_fragment_id(struct net_pkt *pkt, uint32_t id)
929 : {
930 : ARG_UNUSED(pkt);
931 : ARG_UNUSED(id);
932 : }
933 : #endif /* CONFIG_NET_IPV4_FRAGMENT */
934 :
935 : #if defined(CONFIG_NET_IPV6_FRAGMENT)
936 : static inline uint16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
937 : {
938 : return pkt->ipv6_fragment.hdr_start;
939 : }
940 :
941 : static inline void net_pkt_set_ipv6_fragment_start(struct net_pkt *pkt,
942 : uint16_t start)
943 : {
944 : pkt->ipv6_fragment.hdr_start = start;
945 : }
946 :
947 : static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
948 : {
949 : return pkt->ipv6_fragment.flags & NET_IPV6_FRAGH_OFFSET_MASK;
950 : }
951 : static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
952 : {
953 : return (pkt->ipv6_fragment.flags & 0x01) != 0;
954 : }
955 :
956 : static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
957 : uint16_t flags)
958 : {
959 : pkt->ipv6_fragment.flags = flags;
960 : }
961 :
962 : static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)
963 : {
964 : return pkt->ipv6_fragment.id;
965 : }
966 :
967 : static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt,
968 : uint32_t id)
969 : {
970 : pkt->ipv6_fragment.id = id;
971 : }
972 : #else /* CONFIG_NET_IPV6_FRAGMENT */
973 : static inline uint16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
974 : {
975 : ARG_UNUSED(pkt);
976 :
977 : return 0;
978 : }
979 :
980 : static inline void net_pkt_set_ipv6_fragment_start(struct net_pkt *pkt,
981 : uint16_t start)
982 : {
983 : ARG_UNUSED(pkt);
984 : ARG_UNUSED(start);
985 : }
986 :
987 : static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
988 : {
989 : ARG_UNUSED(pkt);
990 :
991 : return 0;
992 : }
993 :
994 : static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
995 : {
996 : ARG_UNUSED(pkt);
997 :
998 : return 0;
999 : }
1000 :
1001 : static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
1002 : uint16_t flags)
1003 : {
1004 : ARG_UNUSED(pkt);
1005 : ARG_UNUSED(flags);
1006 : }
1007 :
1008 : static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)
1009 : {
1010 : ARG_UNUSED(pkt);
1011 :
1012 : return 0;
1013 : }
1014 :
1015 : static inline void net_pkt_set_ipv6_fragment_id(struct net_pkt *pkt,
1016 : uint32_t id)
1017 : {
1018 : ARG_UNUSED(pkt);
1019 : ARG_UNUSED(id);
1020 : }
1021 : #endif /* CONFIG_NET_IPV6_FRAGMENT */
1022 :
1023 : #if defined(CONFIG_NET_IP_FRAGMENT)
1024 : static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt)
1025 : {
1026 : return !!(pkt->ip_reassembled);
1027 : }
1028 :
1029 : static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt,
1030 : bool reassembled)
1031 : {
1032 : pkt->ip_reassembled = reassembled;
1033 : }
1034 : #else /* CONFIG_NET_IP_FRAGMENT */
1035 : static inline bool net_pkt_is_ip_reassembled(struct net_pkt *pkt)
1036 : {
1037 : ARG_UNUSED(pkt);
1038 :
1039 : return false;
1040 : }
1041 :
1042 : static inline void net_pkt_set_ip_reassembled(struct net_pkt *pkt,
1043 : bool reassembled)
1044 : {
1045 : ARG_UNUSED(pkt);
1046 : ARG_UNUSED(reassembled);
1047 : }
1048 : #endif /* CONFIG_NET_IP_FRAGMENT */
1049 :
1050 : static inline uint8_t net_pkt_priority(struct net_pkt *pkt)
1051 : {
1052 : return pkt->priority;
1053 : }
1054 :
1055 : static inline void net_pkt_set_priority(struct net_pkt *pkt,
1056 : uint8_t priority)
1057 : {
1058 : pkt->priority = priority;
1059 : }
1060 :
1061 : #if defined(CONFIG_NET_CAPTURE_COOKED_MODE)
1062 : static inline bool net_pkt_is_cooked_mode(struct net_pkt *pkt)
1063 : {
1064 : return pkt->cooked_mode_pkt;
1065 : }
1066 :
1067 : static inline void net_pkt_set_cooked_mode(struct net_pkt *pkt, bool value)
1068 : {
1069 : pkt->cooked_mode_pkt = value;
1070 : }
1071 : #else
1072 : static inline bool net_pkt_is_cooked_mode(struct net_pkt *pkt)
1073 : {
1074 : ARG_UNUSED(pkt);
1075 :
1076 : return false;
1077 : }
1078 :
1079 : static inline void net_pkt_set_cooked_mode(struct net_pkt *pkt, bool value)
1080 : {
1081 : ARG_UNUSED(pkt);
1082 : ARG_UNUSED(value);
1083 : }
1084 : #endif /* CONFIG_NET_CAPTURE_COOKED_MODE */
1085 :
1086 : #if defined(CONFIG_NET_VLAN)
1087 : static inline uint16_t net_pkt_vlan_tag(struct net_pkt *pkt)
1088 : {
1089 : return net_eth_vlan_get_vid(pkt->vlan_tci);
1090 : }
1091 :
1092 : static inline void net_pkt_set_vlan_tag(struct net_pkt *pkt, uint16_t tag)
1093 : {
1094 : pkt->vlan_tci = net_eth_vlan_set_vid(pkt->vlan_tci, tag);
1095 : }
1096 :
1097 : static inline uint8_t net_pkt_vlan_priority(struct net_pkt *pkt)
1098 : {
1099 : return net_eth_vlan_get_pcp(pkt->vlan_tci);
1100 : }
1101 :
1102 : static inline void net_pkt_set_vlan_priority(struct net_pkt *pkt,
1103 : uint8_t priority)
1104 : {
1105 : pkt->vlan_tci = net_eth_vlan_set_pcp(pkt->vlan_tci, priority);
1106 : }
1107 :
1108 : static inline bool net_pkt_vlan_dei(struct net_pkt *pkt)
1109 : {
1110 : return net_eth_vlan_get_dei(pkt->vlan_tci);
1111 : }
1112 :
1113 : static inline void net_pkt_set_vlan_dei(struct net_pkt *pkt, bool dei)
1114 : {
1115 : pkt->vlan_tci = net_eth_vlan_set_dei(pkt->vlan_tci, dei);
1116 : }
1117 :
1118 : static inline void net_pkt_set_vlan_tci(struct net_pkt *pkt, uint16_t tci)
1119 : {
1120 : pkt->vlan_tci = tci;
1121 : }
1122 :
1123 : static inline uint16_t net_pkt_vlan_tci(struct net_pkt *pkt)
1124 : {
1125 : return pkt->vlan_tci;
1126 : }
1127 : #else
1128 : static inline uint16_t net_pkt_vlan_tag(struct net_pkt *pkt)
1129 : {
1130 : ARG_UNUSED(pkt);
1131 :
1132 : return NET_VLAN_TAG_UNSPEC;
1133 : }
1134 :
1135 : static inline void net_pkt_set_vlan_tag(struct net_pkt *pkt, uint16_t tag)
1136 : {
1137 : ARG_UNUSED(pkt);
1138 : ARG_UNUSED(tag);
1139 : }
1140 :
1141 : static inline uint8_t net_pkt_vlan_priority(struct net_pkt *pkt)
1142 : {
1143 : ARG_UNUSED(pkt);
1144 :
1145 : return 0;
1146 : }
1147 :
1148 : static inline bool net_pkt_vlan_dei(struct net_pkt *pkt)
1149 : {
1150 : ARG_UNUSED(pkt);
1151 :
1152 : return false;
1153 : }
1154 :
1155 : static inline void net_pkt_set_vlan_dei(struct net_pkt *pkt, bool dei)
1156 : {
1157 : ARG_UNUSED(pkt);
1158 : ARG_UNUSED(dei);
1159 : }
1160 :
1161 : static inline uint16_t net_pkt_vlan_tci(struct net_pkt *pkt)
1162 : {
1163 : ARG_UNUSED(pkt);
1164 :
1165 : return NET_VLAN_TAG_UNSPEC; /* assumes priority is 0 */
1166 : }
1167 :
1168 : static inline void net_pkt_set_vlan_tci(struct net_pkt *pkt, uint16_t tci)
1169 : {
1170 : ARG_UNUSED(pkt);
1171 : ARG_UNUSED(tci);
1172 : }
1173 : #endif
1174 :
1175 : #if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME)
1176 : static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt)
1177 : {
1178 : return &pkt->timestamp;
1179 : }
1180 :
1181 : static inline void net_pkt_set_timestamp(struct net_pkt *pkt,
1182 : struct net_ptp_time *timestamp)
1183 : {
1184 : pkt->timestamp.second = timestamp->second;
1185 : pkt->timestamp.nanosecond = timestamp->nanosecond;
1186 : }
1187 :
1188 : static inline net_time_t net_pkt_timestamp_ns(struct net_pkt *pkt)
1189 : {
1190 : return net_ptp_time_to_ns(&pkt->timestamp);
1191 : }
1192 :
1193 : static inline void net_pkt_set_timestamp_ns(struct net_pkt *pkt, net_time_t timestamp)
1194 : {
1195 : pkt->timestamp = ns_to_net_ptp_time(timestamp);
1196 : }
1197 : #else
1198 : static inline struct net_ptp_time *net_pkt_timestamp(struct net_pkt *pkt)
1199 : {
1200 : ARG_UNUSED(pkt);
1201 :
1202 : return NULL;
1203 : }
1204 :
1205 : static inline void net_pkt_set_timestamp(struct net_pkt *pkt,
1206 : struct net_ptp_time *timestamp)
1207 : {
1208 : ARG_UNUSED(pkt);
1209 : ARG_UNUSED(timestamp);
1210 : }
1211 :
1212 : static inline net_time_t net_pkt_timestamp_ns(struct net_pkt *pkt)
1213 : {
1214 : ARG_UNUSED(pkt);
1215 :
1216 : return 0;
1217 : }
1218 :
1219 : static inline void net_pkt_set_timestamp_ns(struct net_pkt *pkt, net_time_t timestamp)
1220 : {
1221 : ARG_UNUSED(pkt);
1222 : ARG_UNUSED(timestamp);
1223 : }
1224 : #endif /* CONFIG_NET_PKT_TIMESTAMP || CONFIG_NET_PKT_TXTIME */
1225 :
1226 : #if defined(CONFIG_NET_PKT_RXTIME_STATS) || defined(CONFIG_NET_PKT_TXTIME_STATS) || \
1227 : defined(CONFIG_TRACING_NET_CORE)
1228 :
1229 : static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
1230 : {
1231 : return pkt->create_time;
1232 : }
1233 :
1234 : static inline void net_pkt_set_create_time(struct net_pkt *pkt,
1235 : uint32_t create_time)
1236 : {
1237 : pkt->create_time = create_time;
1238 : }
1239 : #else
1240 : static inline uint32_t net_pkt_create_time(struct net_pkt *pkt)
1241 : {
1242 : ARG_UNUSED(pkt);
1243 :
1244 : return 0U;
1245 : }
1246 :
1247 : static inline void net_pkt_set_create_time(struct net_pkt *pkt,
1248 : uint32_t create_time)
1249 : {
1250 : ARG_UNUSED(pkt);
1251 : ARG_UNUSED(create_time);
1252 : }
1253 : #endif /* CONFIG_NET_PKT_RXTIME_STATS || CONFIG_NET_PKT_TXTIME_STATS ||
1254 : * CONFIG_TRACING_NET_CORE
1255 : */
1256 :
1257 : #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL) || \
1258 : defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
1259 : static inline uint32_t *net_pkt_stats_tick(struct net_pkt *pkt)
1260 : {
1261 : return pkt->detail.stat;
1262 : }
1263 :
1264 : static inline int net_pkt_stats_tick_count(struct net_pkt *pkt)
1265 : {
1266 : return pkt->detail.count;
1267 : }
1268 :
1269 : static inline void net_pkt_stats_tick_reset(struct net_pkt *pkt)
1270 : {
1271 : memset(&pkt->detail, 0, sizeof(pkt->detail));
1272 : }
1273 :
1274 : static ALWAYS_INLINE void net_pkt_set_stats_tick(struct net_pkt *pkt,
1275 : uint32_t tick)
1276 : {
1277 : if (pkt->detail.count >= NET_PKT_DETAIL_STATS_COUNT) {
1278 : NET_ERR("Detail stats count overflow (%d >= %d)",
1279 : pkt->detail.count, NET_PKT_DETAIL_STATS_COUNT);
1280 : return;
1281 : }
1282 :
1283 : pkt->detail.stat[pkt->detail.count++] = tick;
1284 : }
1285 :
1286 : #define net_pkt_set_tx_stats_tick(pkt, tick) net_pkt_set_stats_tick(pkt, tick)
1287 : #define net_pkt_set_rx_stats_tick(pkt, tick) net_pkt_set_stats_tick(pkt, tick)
1288 : #else
1289 : static inline uint32_t *net_pkt_stats_tick(struct net_pkt *pkt)
1290 : {
1291 : ARG_UNUSED(pkt);
1292 :
1293 : return NULL;
1294 : }
1295 :
1296 : static inline int net_pkt_stats_tick_count(struct net_pkt *pkt)
1297 : {
1298 : ARG_UNUSED(pkt);
1299 :
1300 : return 0;
1301 : }
1302 :
1303 : static inline void net_pkt_stats_tick_reset(struct net_pkt *pkt)
1304 : {
1305 : ARG_UNUSED(pkt);
1306 : }
1307 :
1308 : static inline void net_pkt_set_stats_tick(struct net_pkt *pkt, uint32_t tick)
1309 : {
1310 : ARG_UNUSED(pkt);
1311 : ARG_UNUSED(tick);
1312 : }
1313 :
1314 : #define net_pkt_set_tx_stats_tick(pkt, tick)
1315 : #define net_pkt_set_rx_stats_tick(pkt, tick)
1316 : #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL ||
1317 : CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
1318 :
1319 : static inline uint8_t *net_pkt_data(struct net_pkt *pkt)
1320 : {
1321 : return pkt->frags->data;
1322 : }
1323 :
1324 : static inline uint8_t *net_pkt_ip_data(struct net_pkt *pkt)
1325 : {
1326 : return pkt->frags->data;
1327 : }
1328 :
1329 : static inline bool net_pkt_is_empty(struct net_pkt *pkt)
1330 : {
1331 : return !pkt->buffer || !net_pkt_data(pkt) || pkt->buffer->len == 0;
1332 : }
1333 :
1334 : static inline struct net_linkaddr *net_pkt_lladdr_src(struct net_pkt *pkt)
1335 : {
1336 : return &pkt->lladdr_src;
1337 : }
1338 :
1339 : static inline struct net_linkaddr *net_pkt_lladdr_dst(struct net_pkt *pkt)
1340 : {
1341 : return &pkt->lladdr_dst;
1342 : }
1343 :
1344 : static inline void net_pkt_lladdr_swap(struct net_pkt *pkt)
1345 : {
1346 : struct net_linkaddr tmp;
1347 :
1348 : memcpy(tmp.addr,
1349 : net_pkt_lladdr_src(pkt)->addr,
1350 : net_pkt_lladdr_src(pkt)->len);
1351 : memcpy(net_pkt_lladdr_src(pkt)->addr,
1352 : net_pkt_lladdr_dst(pkt)->addr,
1353 : net_pkt_lladdr_dst(pkt)->len);
1354 : memcpy(net_pkt_lladdr_dst(pkt)->addr,
1355 : tmp.addr,
1356 : net_pkt_lladdr_src(pkt)->len);
1357 : }
1358 :
1359 : static inline void net_pkt_lladdr_clear(struct net_pkt *pkt)
1360 : {
1361 : (void)net_linkaddr_clear(net_pkt_lladdr_src(pkt));
1362 : (void)net_linkaddr_clear(net_pkt_lladdr_dst(pkt));
1363 : }
1364 :
1365 : static inline uint16_t net_pkt_ll_proto_type(struct net_pkt *pkt)
1366 : {
1367 : return pkt->ll_proto_type;
1368 : }
1369 :
1370 : static inline void net_pkt_set_ll_proto_type(struct net_pkt *pkt, uint16_t type)
1371 : {
1372 : pkt->ll_proto_type = type;
1373 : }
1374 :
1375 : #if defined(CONFIG_NET_IPV4_ACD)
1376 : static inline bool net_pkt_ipv4_acd(struct net_pkt *pkt)
1377 : {
1378 : return !!(pkt->ipv4_acd_arp_msg);
1379 : }
1380 :
1381 : static inline void net_pkt_set_ipv4_acd(struct net_pkt *pkt,
1382 : bool is_acd_arp_msg)
1383 : {
1384 : pkt->ipv4_acd_arp_msg = is_acd_arp_msg;
1385 : }
1386 : #else /* CONFIG_NET_IPV4_ACD */
1387 : static inline bool net_pkt_ipv4_acd(struct net_pkt *pkt)
1388 : {
1389 : ARG_UNUSED(pkt);
1390 :
1391 : return false;
1392 : }
1393 :
1394 : static inline void net_pkt_set_ipv4_acd(struct net_pkt *pkt,
1395 : bool is_acd_arp_msg)
1396 : {
1397 : ARG_UNUSED(pkt);
1398 : ARG_UNUSED(is_acd_arp_msg);
1399 : }
1400 : #endif /* CONFIG_NET_IPV4_ACD */
1401 :
1402 : #if defined(CONFIG_NET_LLDP)
1403 : static inline bool net_pkt_is_lldp(struct net_pkt *pkt)
1404 : {
1405 : return !!(pkt->lldp_pkt);
1406 : }
1407 :
1408 : static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp)
1409 : {
1410 : pkt->lldp_pkt = is_lldp;
1411 : }
1412 : #else
1413 : static inline bool net_pkt_is_lldp(struct net_pkt *pkt)
1414 : {
1415 : ARG_UNUSED(pkt);
1416 :
1417 : return false;
1418 : }
1419 :
1420 : static inline void net_pkt_set_lldp(struct net_pkt *pkt, bool is_lldp)
1421 : {
1422 : ARG_UNUSED(pkt);
1423 : ARG_UNUSED(is_lldp);
1424 : }
1425 : #endif /* CONFIG_NET_LLDP */
1426 :
1427 : #if defined(CONFIG_NET_L2_PPP)
1428 : static inline bool net_pkt_is_ppp(struct net_pkt *pkt)
1429 : {
1430 : return !!(pkt->ppp_msg);
1431 : }
1432 :
1433 : static inline void net_pkt_set_ppp(struct net_pkt *pkt,
1434 : bool is_ppp_msg)
1435 : {
1436 : pkt->ppp_msg = is_ppp_msg;
1437 : }
1438 : #else /* CONFIG_NET_L2_PPP */
1439 : static inline bool net_pkt_is_ppp(struct net_pkt *pkt)
1440 : {
1441 : ARG_UNUSED(pkt);
1442 :
1443 : return false;
1444 : }
1445 :
1446 : static inline void net_pkt_set_ppp(struct net_pkt *pkt,
1447 : bool is_ppp_msg)
1448 : {
1449 : ARG_UNUSED(pkt);
1450 : ARG_UNUSED(is_ppp_msg);
1451 : }
1452 : #endif /* CONFIG_NET_L2_PPP */
1453 :
1454 : #if defined(NET_PKT_HAS_CONTROL_BLOCK)
1455 : static inline void *net_pkt_cb(struct net_pkt *pkt)
1456 : {
1457 : return &pkt->cb;
1458 : }
1459 : #else
1460 : static inline void *net_pkt_cb(struct net_pkt *pkt)
1461 : {
1462 : ARG_UNUSED(pkt);
1463 :
1464 : return NULL;
1465 : }
1466 : #endif
1467 :
1468 : #define NET_IPV6_HDR(pkt) ((struct net_ipv6_hdr *)net_pkt_ip_data(pkt))
1469 : #define NET_IPV4_HDR(pkt) ((struct net_ipv4_hdr *)net_pkt_ip_data(pkt))
1470 :
1471 : static inline void net_pkt_set_src_ipv6_addr(struct net_pkt *pkt)
1472 : {
1473 : net_if_ipv6_select_src_addr(net_context_get_iface(
1474 : net_pkt_context(pkt)),
1475 : (struct in6_addr *)NET_IPV6_HDR(pkt)->src);
1476 : }
1477 :
1478 : static inline void net_pkt_set_overwrite(struct net_pkt *pkt, bool overwrite)
1479 : {
1480 : pkt->overwrite = overwrite;
1481 : }
1482 :
1483 : static inline bool net_pkt_is_being_overwritten(struct net_pkt *pkt)
1484 : {
1485 : return !!(pkt->overwrite);
1486 : }
1487 :
1488 : #ifdef CONFIG_NET_PKT_FILTER
1489 :
1490 : bool net_pkt_filter_send_ok(struct net_pkt *pkt);
1491 : bool net_pkt_filter_recv_ok(struct net_pkt *pkt);
1492 :
1493 : #else
1494 :
1495 : static inline bool net_pkt_filter_send_ok(struct net_pkt *pkt)
1496 : {
1497 : ARG_UNUSED(pkt);
1498 :
1499 : return true;
1500 : }
1501 :
1502 : static inline bool net_pkt_filter_recv_ok(struct net_pkt *pkt)
1503 : {
1504 : ARG_UNUSED(pkt);
1505 :
1506 : return true;
1507 : }
1508 :
1509 : #endif /* CONFIG_NET_PKT_FILTER */
1510 :
1511 : #if defined(CONFIG_NET_PKT_FILTER) && \
1512 : (defined(CONFIG_NET_PKT_FILTER_IPV4_HOOK) || defined(CONFIG_NET_PKT_FILTER_IPV6_HOOK))
1513 :
1514 : bool net_pkt_filter_ip_recv_ok(struct net_pkt *pkt);
1515 :
1516 : #else
1517 :
1518 : static inline bool net_pkt_filter_ip_recv_ok(struct net_pkt *pkt)
1519 : {
1520 : ARG_UNUSED(pkt);
1521 :
1522 : return true;
1523 : }
1524 :
1525 : #endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK || CONFIG_NET_PKT_FILTER_IPV6_HOOK */
1526 :
1527 : #if defined(CONFIG_NET_PKT_FILTER) && defined(CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK)
1528 :
1529 : bool net_pkt_filter_local_in_recv_ok(struct net_pkt *pkt);
1530 :
1531 : #else
1532 :
1533 : static inline bool net_pkt_filter_local_in_recv_ok(struct net_pkt *pkt)
1534 : {
1535 : ARG_UNUSED(pkt);
1536 :
1537 : return true;
1538 : }
1539 :
1540 : #endif /* CONFIG_NET_PKT_FILTER && CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */
1541 :
1542 : #if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_L2_IPIP)
1543 : static inline struct sockaddr *net_pkt_remote_address(struct net_pkt *pkt)
1544 : {
1545 : return &pkt->remote;
1546 : }
1547 :
1548 : static inline void net_pkt_set_remote_address(struct net_pkt *pkt,
1549 : struct sockaddr *address,
1550 : socklen_t len)
1551 : {
1552 : memcpy(&pkt->remote, address, len);
1553 : }
1554 : #endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_L2_IPIP */
1555 :
1556 : /* @endcond */
1557 :
1558 : /**
1559 : * @brief Create a net_pkt slab
1560 : *
1561 : * A net_pkt slab is used to store meta-information about
1562 : * network packets. It must be coupled with a data fragment pool
1563 : * (@ref NET_PKT_DATA_POOL_DEFINE) used to store the actual
1564 : * packet data. The macro can be used by an application to define
1565 : * additional custom per-context TX packet slabs (see
1566 : * net_context_setup_pools()).
1567 : *
1568 : * @param name Name of the slab.
1569 : * @param count Number of net_pkt in this slab.
1570 : */
1571 1 : #define NET_PKT_SLAB_DEFINE(name, count) \
1572 : K_MEM_SLAB_DEFINE(name, sizeof(struct net_pkt), count, 4); \
1573 : NET_PKT_ALLOC_STATS_DEFINE(pkt_alloc_stats_##name, name)
1574 :
1575 : /** @cond INTERNAL_HIDDEN */
1576 :
1577 : /* Backward compatibility macro */
1578 : #define NET_PKT_TX_SLAB_DEFINE(name, count) NET_PKT_SLAB_DEFINE(name, count)
1579 :
1580 : /** @endcond */
1581 :
1582 : /**
1583 : * @brief Create a data fragment net_buf pool
1584 : *
1585 : * A net_buf pool is used to store actual data for
1586 : * network packets. It must be coupled with a net_pkt slab
1587 : * (@ref NET_PKT_SLAB_DEFINE) used to store the packet
1588 : * meta-information. The macro can be used by an application to
1589 : * define additional custom per-context TX packet pools (see
1590 : * net_context_setup_pools()).
1591 : *
1592 : * @param name Name of the pool.
1593 : * @param count Number of net_buf in this pool.
1594 : */
1595 1 : #define NET_PKT_DATA_POOL_DEFINE(name, count) \
1596 : NET_BUF_POOL_DEFINE(name, count, CONFIG_NET_BUF_DATA_SIZE, \
1597 : 0, NULL)
1598 :
1599 : /** @cond INTERNAL_HIDDEN */
1600 :
1601 : #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC) || \
1602 : (CONFIG_NET_PKT_LOG_LEVEL >= LOG_LEVEL_DBG)
1603 : #define NET_PKT_DEBUG_ENABLED
1604 : #endif
1605 :
1606 : #if defined(NET_PKT_DEBUG_ENABLED)
1607 :
1608 : /* Debug versions of the net_pkt functions that are used when tracking
1609 : * buffer usage.
1610 : */
1611 :
1612 : struct net_buf *net_pkt_get_reserve_data_debug(struct net_buf_pool *pool,
1613 : size_t min_len,
1614 : k_timeout_t timeout,
1615 : const char *caller,
1616 : int line);
1617 :
1618 : #define net_pkt_get_reserve_data(pool, min_len, timeout) \
1619 : net_pkt_get_reserve_data_debug(pool, min_len, timeout, __func__, __LINE__)
1620 :
1621 : struct net_buf *net_pkt_get_reserve_rx_data_debug(size_t min_len,
1622 : k_timeout_t timeout,
1623 : const char *caller,
1624 : int line);
1625 : #define net_pkt_get_reserve_rx_data(min_len, timeout) \
1626 : net_pkt_get_reserve_rx_data_debug(min_len, timeout, __func__, __LINE__)
1627 :
1628 : struct net_buf *net_pkt_get_reserve_tx_data_debug(size_t min_len,
1629 : k_timeout_t timeout,
1630 : const char *caller,
1631 : int line);
1632 : #define net_pkt_get_reserve_tx_data(min_len, timeout) \
1633 : net_pkt_get_reserve_tx_data_debug(min_len, timeout, __func__, __LINE__)
1634 :
1635 : struct net_buf *net_pkt_get_frag_debug(struct net_pkt *pkt, size_t min_len,
1636 : k_timeout_t timeout,
1637 : const char *caller, int line);
1638 : #define net_pkt_get_frag(pkt, min_len, timeout) \
1639 : net_pkt_get_frag_debug(pkt, min_len, timeout, __func__, __LINE__)
1640 :
1641 : void net_pkt_unref_debug(struct net_pkt *pkt, const char *caller, int line);
1642 : #define net_pkt_unref(pkt) net_pkt_unref_debug(pkt, __func__, __LINE__)
1643 :
1644 : struct net_pkt *net_pkt_ref_debug(struct net_pkt *pkt, const char *caller,
1645 : int line);
1646 : #define net_pkt_ref(pkt) net_pkt_ref_debug(pkt, __func__, __LINE__)
1647 :
1648 : struct net_buf *net_pkt_frag_ref_debug(struct net_buf *frag,
1649 : const char *caller, int line);
1650 : #define net_pkt_frag_ref(frag) net_pkt_frag_ref_debug(frag, __func__, __LINE__)
1651 :
1652 : void net_pkt_frag_unref_debug(struct net_buf *frag,
1653 : const char *caller, int line);
1654 : #define net_pkt_frag_unref(frag) \
1655 : net_pkt_frag_unref_debug(frag, __func__, __LINE__)
1656 :
1657 : struct net_buf *net_pkt_frag_del_debug(struct net_pkt *pkt,
1658 : struct net_buf *parent,
1659 : struct net_buf *frag,
1660 : const char *caller, int line);
1661 : #define net_pkt_frag_del(pkt, parent, frag) \
1662 : net_pkt_frag_del_debug(pkt, parent, frag, __func__, __LINE__)
1663 :
1664 : void net_pkt_frag_add_debug(struct net_pkt *pkt, struct net_buf *frag,
1665 : const char *caller, int line);
1666 : #define net_pkt_frag_add(pkt, frag) \
1667 : net_pkt_frag_add_debug(pkt, frag, __func__, __LINE__)
1668 :
1669 : void net_pkt_frag_insert_debug(struct net_pkt *pkt, struct net_buf *frag,
1670 : const char *caller, int line);
1671 : #define net_pkt_frag_insert(pkt, frag) \
1672 : net_pkt_frag_insert_debug(pkt, frag, __func__, __LINE__)
1673 : #endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC ||
1674 : * CONFIG_NET_PKT_LOG_LEVEL >= LOG_LEVEL_DBG
1675 : */
1676 : /** @endcond */
1677 :
1678 : #if defined(NET_PKT_DEBUG_ENABLED)
1679 : /**
1680 : * @brief Print fragment list and the fragment sizes
1681 : *
1682 : * @details Only available if debugging is activated.
1683 : *
1684 : * @param pkt Network pkt.
1685 : */
1686 : void net_pkt_print_frags(struct net_pkt *pkt);
1687 : #else
1688 0 : #define net_pkt_print_frags(pkt)
1689 : #endif
1690 :
1691 : #if !defined(NET_PKT_DEBUG_ENABLED)
1692 : /**
1693 : * @brief Get a data buffer from a given pool.
1694 : *
1695 : * @details Normally this version is not useful for applications
1696 : * but is mainly used by network fragmentation code.
1697 : *
1698 : * @param pool The net_buf pool to use.
1699 : * @param min_len Minimum length of the requested fragment.
1700 : * @param timeout Affects the action taken should the net buf pool be empty.
1701 : * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1702 : * wait as long as necessary. Otherwise, wait up to the specified time.
1703 : *
1704 : * @return Network buffer if successful, NULL otherwise.
1705 : */
1706 1 : struct net_buf *net_pkt_get_reserve_data(struct net_buf_pool *pool,
1707 : size_t min_len, k_timeout_t timeout);
1708 : #endif
1709 :
1710 : #if !defined(NET_PKT_DEBUG_ENABLED)
1711 : /**
1712 : * @brief Get RX DATA buffer from pool.
1713 : * Normally you should use net_pkt_get_frag() instead.
1714 : *
1715 : * @details Normally this version is not useful for applications
1716 : * but is mainly used by network fragmentation code.
1717 : *
1718 : * @param min_len Minimum length of the requested fragment.
1719 : * @param timeout Affects the action taken should the net buf pool be empty.
1720 : * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1721 : * wait as long as necessary. Otherwise, wait up to the specified time.
1722 : *
1723 : * @return Network buffer if successful, NULL otherwise.
1724 : */
1725 1 : struct net_buf *net_pkt_get_reserve_rx_data(size_t min_len, k_timeout_t timeout);
1726 : #endif
1727 :
1728 : #if !defined(NET_PKT_DEBUG_ENABLED)
1729 : /**
1730 : * @brief Get TX DATA buffer from pool.
1731 : * Normally you should use net_pkt_get_frag() instead.
1732 : *
1733 : * @details Normally this version is not useful for applications
1734 : * but is mainly used by network fragmentation code.
1735 : *
1736 : * @param min_len Minimum length of the requested fragment.
1737 : * @param timeout Affects the action taken should the net buf pool be empty.
1738 : * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1739 : * wait as long as necessary. Otherwise, wait up to the specified time.
1740 : *
1741 : * @return Network buffer if successful, NULL otherwise.
1742 : */
1743 1 : struct net_buf *net_pkt_get_reserve_tx_data(size_t min_len, k_timeout_t timeout);
1744 : #endif
1745 :
1746 : #if !defined(NET_PKT_DEBUG_ENABLED)
1747 : /**
1748 : * @brief Get a data fragment that might be from user specific
1749 : * buffer pool or from global DATA pool.
1750 : *
1751 : * @param pkt Network packet.
1752 : * @param min_len Minimum length of the requested fragment.
1753 : * @param timeout Affects the action taken should the net buf pool be empty.
1754 : * If K_NO_WAIT, then return immediately. If K_FOREVER, then
1755 : * wait as long as necessary. Otherwise, wait up to the specified time.
1756 : *
1757 : * @return Network buffer if successful, NULL otherwise.
1758 : */
1759 1 : struct net_buf *net_pkt_get_frag(struct net_pkt *pkt, size_t min_len,
1760 : k_timeout_t timeout);
1761 : #endif
1762 :
1763 : #if !defined(NET_PKT_DEBUG_ENABLED)
1764 : /**
1765 : * @brief Place packet back into the available packets slab
1766 : *
1767 : * @details Releases the packet to other use. This needs to be
1768 : * called by application after it has finished with the packet.
1769 : *
1770 : * @param pkt Network packet to release.
1771 : *
1772 : */
1773 1 : void net_pkt_unref(struct net_pkt *pkt);
1774 : #endif
1775 :
1776 : #if !defined(NET_PKT_DEBUG_ENABLED)
1777 : /**
1778 : * @brief Increase the packet ref count
1779 : *
1780 : * @details Mark the packet to be used still.
1781 : *
1782 : * @param pkt Network packet to ref.
1783 : *
1784 : * @return Network packet if successful, NULL otherwise.
1785 : */
1786 1 : struct net_pkt *net_pkt_ref(struct net_pkt *pkt);
1787 : #endif
1788 :
1789 : #if !defined(NET_PKT_DEBUG_ENABLED)
1790 : /**
1791 : * @brief Increase the packet fragment ref count
1792 : *
1793 : * @details Mark the fragment to be used still.
1794 : *
1795 : * @param frag Network fragment to ref.
1796 : *
1797 : * @return a pointer on the referenced Network fragment.
1798 : */
1799 1 : struct net_buf *net_pkt_frag_ref(struct net_buf *frag);
1800 : #endif
1801 :
1802 : #if !defined(NET_PKT_DEBUG_ENABLED)
1803 : /**
1804 : * @brief Decrease the packet fragment ref count
1805 : *
1806 : * @param frag Network fragment to unref.
1807 : */
1808 1 : void net_pkt_frag_unref(struct net_buf *frag);
1809 : #endif
1810 :
1811 : #if !defined(NET_PKT_DEBUG_ENABLED)
1812 : /**
1813 : * @brief Delete existing fragment from a packet
1814 : *
1815 : * @param pkt Network packet from which frag belongs to.
1816 : * @param parent parent fragment of frag, or NULL if none.
1817 : * @param frag Fragment to delete.
1818 : *
1819 : * @return Pointer to the following fragment, or NULL if it had no
1820 : * further fragments.
1821 : */
1822 1 : struct net_buf *net_pkt_frag_del(struct net_pkt *pkt,
1823 : struct net_buf *parent,
1824 : struct net_buf *frag);
1825 : #endif
1826 :
1827 : #if !defined(NET_PKT_DEBUG_ENABLED)
1828 : /**
1829 : * @brief Add a fragment to a packet at the end of its fragment list
1830 : *
1831 : * @param pkt pkt Network packet where to add the fragment
1832 : * @param frag Fragment to add
1833 : */
1834 1 : void net_pkt_frag_add(struct net_pkt *pkt, struct net_buf *frag);
1835 : #endif
1836 :
1837 : #if !defined(NET_PKT_DEBUG_ENABLED)
1838 : /**
1839 : * @brief Insert a fragment to a packet at the beginning of its fragment list
1840 : *
1841 : * @param pkt pkt Network packet where to insert the fragment
1842 : * @param frag Fragment to insert
1843 : */
1844 1 : void net_pkt_frag_insert(struct net_pkt *pkt, struct net_buf *frag);
1845 : #endif
1846 :
1847 : /**
1848 : * @brief Compact the fragment list of a packet.
1849 : *
1850 : * @details After this there is no more any free space in individual fragments.
1851 : * @param pkt Network packet.
1852 : */
1853 1 : void net_pkt_compact(struct net_pkt *pkt);
1854 :
1855 : /**
1856 : * @brief Get information about predefined RX, TX and DATA pools.
1857 : *
1858 : * @param rx Pointer to RX pool is returned.
1859 : * @param tx Pointer to TX pool is returned.
1860 : * @param rx_data Pointer to RX DATA pool is returned.
1861 : * @param tx_data Pointer to TX DATA pool is returned.
1862 : */
1863 1 : void net_pkt_get_info(struct k_mem_slab **rx,
1864 : struct k_mem_slab **tx,
1865 : struct net_buf_pool **rx_data,
1866 : struct net_buf_pool **tx_data);
1867 :
1868 : /** @cond INTERNAL_HIDDEN */
1869 :
1870 : #if defined(CONFIG_NET_DEBUG_NET_PKT_ALLOC)
1871 : /**
1872 : * @brief Debug helper to print out the buffer allocations
1873 : */
1874 : void net_pkt_print(void);
1875 :
1876 : typedef void (*net_pkt_allocs_cb_t)(struct net_pkt *pkt,
1877 : struct net_buf *buf,
1878 : const char *func_alloc,
1879 : int line_alloc,
1880 : const char *func_free,
1881 : int line_free,
1882 : bool in_use,
1883 : void *user_data);
1884 :
1885 : void net_pkt_allocs_foreach(net_pkt_allocs_cb_t cb, void *user_data);
1886 :
1887 : const char *net_pkt_slab2str(struct k_mem_slab *slab);
1888 : const char *net_pkt_pool2str(struct net_buf_pool *pool);
1889 :
1890 : #else
1891 : #define net_pkt_print(...)
1892 : #endif /* CONFIG_NET_DEBUG_NET_PKT_ALLOC */
1893 :
1894 : /* New allocator, and API are defined below.
1895 : * This will be simpler when time will come to get rid of former API above.
1896 : */
1897 : #if defined(NET_PKT_DEBUG_ENABLED)
1898 :
1899 : struct net_pkt *net_pkt_alloc_debug(k_timeout_t timeout,
1900 : const char *caller, int line);
1901 : #define net_pkt_alloc(_timeout) \
1902 : net_pkt_alloc_debug(_timeout, __func__, __LINE__)
1903 :
1904 : struct net_pkt *net_pkt_alloc_from_slab_debug(struct k_mem_slab *slab,
1905 : k_timeout_t timeout,
1906 : const char *caller, int line);
1907 : #define net_pkt_alloc_from_slab(_slab, _timeout) \
1908 : net_pkt_alloc_from_slab_debug(_slab, _timeout, __func__, __LINE__)
1909 :
1910 : struct net_pkt *net_pkt_rx_alloc_debug(k_timeout_t timeout,
1911 : const char *caller, int line);
1912 : #define net_pkt_rx_alloc(_timeout) \
1913 : net_pkt_rx_alloc_debug(_timeout, __func__, __LINE__)
1914 :
1915 : struct net_pkt *net_pkt_alloc_on_iface_debug(struct net_if *iface,
1916 : k_timeout_t timeout,
1917 : const char *caller,
1918 : int line);
1919 : #define net_pkt_alloc_on_iface(_iface, _timeout) \
1920 : net_pkt_alloc_on_iface_debug(_iface, _timeout, __func__, __LINE__)
1921 :
1922 : struct net_pkt *net_pkt_rx_alloc_on_iface_debug(struct net_if *iface,
1923 : k_timeout_t timeout,
1924 : const char *caller,
1925 : int line);
1926 : #define net_pkt_rx_alloc_on_iface(_iface, _timeout) \
1927 : net_pkt_rx_alloc_on_iface_debug(_iface, _timeout, \
1928 : __func__, __LINE__)
1929 :
1930 : int net_pkt_alloc_buffer_debug(struct net_pkt *pkt,
1931 : size_t size,
1932 : enum net_ip_protocol proto,
1933 : k_timeout_t timeout,
1934 : const char *caller, int line);
1935 : #define net_pkt_alloc_buffer(_pkt, _size, _proto, _timeout) \
1936 : net_pkt_alloc_buffer_debug(_pkt, _size, _proto, _timeout, \
1937 : __func__, __LINE__)
1938 :
1939 : int net_pkt_alloc_buffer_raw_debug(struct net_pkt *pkt, size_t size,
1940 : k_timeout_t timeout,
1941 : const char *caller, int line);
1942 : #define net_pkt_alloc_buffer_raw(_pkt, _size, _timeout) \
1943 : net_pkt_alloc_buffer_raw_debug(_pkt, _size, _timeout, \
1944 : __func__, __LINE__)
1945 :
1946 : struct net_pkt *net_pkt_alloc_with_buffer_debug(struct net_if *iface,
1947 : size_t size,
1948 : sa_family_t family,
1949 : enum net_ip_protocol proto,
1950 : k_timeout_t timeout,
1951 : const char *caller,
1952 : int line);
1953 : #define net_pkt_alloc_with_buffer(_iface, _size, _family, \
1954 : _proto, _timeout) \
1955 : net_pkt_alloc_with_buffer_debug(_iface, _size, _family, \
1956 : _proto, _timeout, \
1957 : __func__, __LINE__)
1958 :
1959 : struct net_pkt *net_pkt_rx_alloc_with_buffer_debug(struct net_if *iface,
1960 : size_t size,
1961 : sa_family_t family,
1962 : enum net_ip_protocol proto,
1963 : k_timeout_t timeout,
1964 : const char *caller,
1965 : int line);
1966 : #define net_pkt_rx_alloc_with_buffer(_iface, _size, _family, \
1967 : _proto, _timeout) \
1968 : net_pkt_rx_alloc_with_buffer_debug(_iface, _size, _family, \
1969 : _proto, _timeout, \
1970 : __func__, __LINE__)
1971 :
1972 : int net_pkt_alloc_buffer_with_reserve_debug(struct net_pkt *pkt,
1973 : size_t size,
1974 : size_t reserve,
1975 : enum net_ip_protocol proto,
1976 : k_timeout_t timeout,
1977 : const char *caller,
1978 : int line);
1979 : #define net_pkt_alloc_buffer_with_reserve(_pkt, _size, _reserve, _proto, _timeout) \
1980 : net_pkt_alloc_buffer_with_reserve_debug(_pkt, _size, _reserve, _proto, \
1981 : _timeout, __func__, __LINE__)
1982 :
1983 : #endif /* NET_PKT_DEBUG_ENABLED */
1984 : /** @endcond */
1985 :
1986 : #if !defined(NET_PKT_DEBUG_ENABLED)
1987 : /**
1988 : * @brief Allocate an initialized net_pkt
1989 : *
1990 : * @details for the time being, 2 pools are used. One for TX and one for RX.
1991 : * This allocator has to be used for TX.
1992 : *
1993 : * @param timeout Maximum time to wait for an allocation.
1994 : *
1995 : * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
1996 : */
1997 1 : struct net_pkt *net_pkt_alloc(k_timeout_t timeout);
1998 : #endif
1999 :
2000 : #if !defined(NET_PKT_DEBUG_ENABLED)
2001 : /**
2002 : * @brief Allocate an initialized net_pkt from a specific slab
2003 : *
2004 : * @details unlike net_pkt_alloc() which uses core slabs, this one will use
2005 : * an external slab (see NET_PKT_SLAB_DEFINE()).
2006 : * Do _not_ use it unless you know what you are doing. Basically, only
2007 : * net_context should be using this, in order to allocate packet and
2008 : * then buffer on its local slab/pool (if any).
2009 : *
2010 : * @param slab The slab to use for allocating the packet
2011 : * @param timeout Maximum time to wait for an allocation.
2012 : *
2013 : * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
2014 : */
2015 1 : struct net_pkt *net_pkt_alloc_from_slab(struct k_mem_slab *slab,
2016 : k_timeout_t timeout);
2017 : #endif
2018 :
2019 : #if !defined(NET_PKT_DEBUG_ENABLED)
2020 : /**
2021 : * @brief Allocate an initialized net_pkt for RX
2022 : *
2023 : * @details for the time being, 2 pools are used. One for TX and one for RX.
2024 : * This allocator has to be used for RX.
2025 : *
2026 : * @param timeout Maximum time to wait for an allocation.
2027 : *
2028 : * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
2029 : */
2030 1 : struct net_pkt *net_pkt_rx_alloc(k_timeout_t timeout);
2031 : #endif
2032 :
2033 : #if !defined(NET_PKT_DEBUG_ENABLED)
2034 : /**
2035 : * @brief Allocate a network packet for a specific network interface.
2036 : *
2037 : * @param iface The network interface the packet is supposed to go through.
2038 : * @param timeout Maximum time to wait for an allocation.
2039 : *
2040 : * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
2041 : */
2042 1 : struct net_pkt *net_pkt_alloc_on_iface(struct net_if *iface,
2043 : k_timeout_t timeout);
2044 :
2045 : /** @cond INTERNAL_HIDDEN */
2046 :
2047 : /* Same as above but specifically for RX packet */
2048 : struct net_pkt *net_pkt_rx_alloc_on_iface(struct net_if *iface,
2049 : k_timeout_t timeout);
2050 : /** @endcond */
2051 :
2052 : #endif
2053 :
2054 : #if !defined(NET_PKT_DEBUG_ENABLED)
2055 : /**
2056 : * @brief Allocate buffer for a net_pkt
2057 : *
2058 : * @details: such allocator will take into account space necessary for headers,
2059 : * MTU, and existing buffer (if any). Beware that, due to all these
2060 : * criteria, the allocated size might be smaller/bigger than
2061 : * requested one.
2062 : *
2063 : * @param pkt The network packet requiring buffer to be allocated.
2064 : * @param size The size of buffer being requested.
2065 : * @param proto The IP protocol type (can be 0 for none).
2066 : * @param timeout Maximum time to wait for an allocation.
2067 : *
2068 : * @return 0 on success, negative errno code otherwise.
2069 : */
2070 1 : int net_pkt_alloc_buffer(struct net_pkt *pkt,
2071 : size_t size,
2072 : enum net_ip_protocol proto,
2073 : k_timeout_t timeout);
2074 : #endif
2075 :
2076 : #if !defined(NET_PKT_DEBUG_ENABLED)
2077 : /**
2078 : * @brief Allocate buffer for a net_pkt and reserve some space in the first net_buf.
2079 : *
2080 : * @details: such allocator will take into account space necessary for headers,
2081 : * MTU, and existing buffer (if any). Beware that, due to all these
2082 : * criteria, the allocated size might be smaller/bigger than
2083 : * requested one.
2084 : *
2085 : * @param pkt The network packet requiring buffer to be allocated.
2086 : * @param size The size of buffer being requested.
2087 : * @param reserve The L2 header size to reserve. This can be 0, in which case
2088 : * the L2 header is placed into a separate net_buf.
2089 : * @param proto The IP protocol type (can be 0 for none).
2090 : * @param timeout Maximum time to wait for an allocation.
2091 : *
2092 : * @return 0 on success, negative errno code otherwise.
2093 : */
2094 : #if !defined(NET_PKT_DEBUG_ENABLED)
2095 1 : int net_pkt_alloc_buffer_with_reserve(struct net_pkt *pkt,
2096 : size_t size,
2097 : size_t reserve,
2098 : enum net_ip_protocol proto,
2099 : k_timeout_t timeout);
2100 : #endif
2101 :
2102 : /**
2103 : * @brief Allocate buffer for a net_pkt, of specified size, w/o any additional
2104 : * preconditions
2105 : *
2106 : * @details: The actual buffer size may be larger than requested one if fixed
2107 : * size buffers are in use.
2108 : *
2109 : * @param pkt The network packet requiring buffer to be allocated.
2110 : * @param size The size of buffer being requested.
2111 : * @param timeout Maximum time to wait for an allocation.
2112 : *
2113 : * @return 0 on success, negative errno code otherwise.
2114 : */
2115 1 : int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size,
2116 : k_timeout_t timeout);
2117 : #endif
2118 :
2119 : #if !defined(NET_PKT_DEBUG_ENABLED)
2120 : /**
2121 : * @brief Allocate a network packet and buffer at once
2122 : *
2123 : * @param iface The network interface the packet is supposed to go through.
2124 : * @param size The size of buffer.
2125 : * @param family The family to which the packet belongs.
2126 : * @param proto The IP protocol type (can be 0 for none).
2127 : * @param timeout Maximum time to wait for an allocation.
2128 : *
2129 : * @return a pointer to a newly allocated net_pkt on success, NULL otherwise.
2130 : */
2131 1 : struct net_pkt *net_pkt_alloc_with_buffer(struct net_if *iface,
2132 : size_t size,
2133 : sa_family_t family,
2134 : enum net_ip_protocol proto,
2135 : k_timeout_t timeout);
2136 :
2137 : /** @cond INTERNAL_HIDDEN */
2138 :
2139 : /* Same as above but specifically for RX packet */
2140 : struct net_pkt *net_pkt_rx_alloc_with_buffer(struct net_if *iface,
2141 : size_t size,
2142 : sa_family_t family,
2143 : enum net_ip_protocol proto,
2144 : k_timeout_t timeout);
2145 :
2146 : /** @endcond */
2147 :
2148 : #endif
2149 :
2150 : /**
2151 : * @brief Append a buffer in packet
2152 : *
2153 : * @param pkt Network packet where to append the buffer
2154 : * @param buffer Buffer to append
2155 : */
2156 1 : void net_pkt_append_buffer(struct net_pkt *pkt, struct net_buf *buffer);
2157 :
2158 : /**
2159 : * @brief Get available buffer space from a pkt
2160 : *
2161 : * @note Reserved bytes (headroom) in any of the fragments are not considered to
2162 : * be available.
2163 : *
2164 : * @param pkt The net_pkt which buffer availability should be evaluated
2165 : *
2166 : * @return the amount of buffer available
2167 : */
2168 1 : size_t net_pkt_available_buffer(struct net_pkt *pkt);
2169 :
2170 : /**
2171 : * @brief Get available buffer space for payload from a pkt
2172 : *
2173 : * @note Reserved bytes (headroom) in any of the fragments are not considered to
2174 : * be available.
2175 : *
2176 : * @details Unlike net_pkt_available_buffer(), this will take into account
2177 : * the headers space.
2178 : *
2179 : * @param pkt The net_pkt which payload buffer availability should
2180 : * be evaluated
2181 : * @param proto The IP protocol type (can be 0 for none).
2182 : *
2183 : * @return the amount of buffer available for payload
2184 : */
2185 1 : size_t net_pkt_available_payload_buffer(struct net_pkt *pkt,
2186 : enum net_ip_protocol proto);
2187 :
2188 : /**
2189 : * @brief Trim net_pkt buffer
2190 : *
2191 : * @details This will basically check for unused buffers and deallocate
2192 : * them relevantly
2193 : *
2194 : * @param pkt The net_pkt which buffer will be trimmed
2195 : */
2196 1 : void net_pkt_trim_buffer(struct net_pkt *pkt);
2197 :
2198 : /**
2199 : * @brief Remove @a length bytes from tail of packet
2200 : *
2201 : * @details This function does not take packet cursor into account. It is a
2202 : * helper to remove unneeded bytes from tail of packet (like appended
2203 : * CRC). It takes care of buffer deallocation if removed bytes span
2204 : * whole buffer(s).
2205 : *
2206 : * @param pkt Network packet
2207 : * @param length Number of bytes to be removed
2208 : *
2209 : * @retval 0 On success.
2210 : * @retval -EINVAL If packet length is shorter than @a length.
2211 : */
2212 1 : int net_pkt_remove_tail(struct net_pkt *pkt, size_t length);
2213 :
2214 : /**
2215 : * @brief Initialize net_pkt cursor
2216 : *
2217 : * @details This will initialize the net_pkt cursor from its buffer.
2218 : *
2219 : * @param pkt The net_pkt whose cursor is going to be initialized
2220 : */
2221 1 : void net_pkt_cursor_init(struct net_pkt *pkt);
2222 :
2223 : /**
2224 : * @brief Backup net_pkt cursor
2225 : *
2226 : * @param pkt The net_pkt whose cursor is going to be backed up
2227 : * @param backup The cursor where to backup net_pkt cursor
2228 : */
2229 1 : static inline void net_pkt_cursor_backup(struct net_pkt *pkt,
2230 : struct net_pkt_cursor *backup)
2231 : {
2232 : backup->buf = pkt->cursor.buf;
2233 : backup->pos = pkt->cursor.pos;
2234 : }
2235 :
2236 : /**
2237 : * @brief Restore net_pkt cursor from a backup
2238 : *
2239 : * @param pkt The net_pkt whose cursor is going to be restored
2240 : * @param backup The cursor from where to restore net_pkt cursor
2241 : */
2242 1 : static inline void net_pkt_cursor_restore(struct net_pkt *pkt,
2243 : struct net_pkt_cursor *backup)
2244 : {
2245 : pkt->cursor.buf = backup->buf;
2246 : pkt->cursor.pos = backup->pos;
2247 : }
2248 :
2249 : /**
2250 : * @brief Returns current position of the cursor
2251 : *
2252 : * @param pkt The net_pkt whose cursor position is going to be returned
2253 : *
2254 : * @return cursor's position
2255 : */
2256 1 : static inline void *net_pkt_cursor_get_pos(struct net_pkt *pkt)
2257 : {
2258 : return pkt->cursor.pos;
2259 : }
2260 :
2261 : /**
2262 : * @brief Skip some data from a net_pkt
2263 : *
2264 : * @details net_pkt's cursor should be properly initialized
2265 : * Cursor position will be updated after the operation.
2266 : * Depending on the value of pkt->overwrite bit, this function
2267 : * will affect the buffer length or not. If it's true, it will
2268 : * advance the cursor to the requested length. If it's false,
2269 : * it will do the same but if the cursor was already also at the
2270 : * end of existing data, it will increment the buffer length.
2271 : * So in this case, its behavior is just like net_pkt_write or
2272 : * net_pkt_memset, difference being that it will not affect the
2273 : * buffer content itself (which may be just garbage then).
2274 : *
2275 : * @param pkt The net_pkt whose cursor will be updated to skip given
2276 : * amount of data from the buffer.
2277 : * @param length Amount of data to skip in the buffer
2278 : *
2279 : * @return 0 in success, negative errno code otherwise.
2280 : */
2281 1 : int net_pkt_skip(struct net_pkt *pkt, size_t length);
2282 :
2283 : /**
2284 : * @brief Memset some data in a net_pkt
2285 : *
2286 : * @details net_pkt's cursor should be properly initialized and,
2287 : * if needed, positioned using net_pkt_skip.
2288 : * Cursor position will be updated after the operation.
2289 : *
2290 : * @param pkt The net_pkt whose buffer to fill starting at the current
2291 : * cursor position.
2292 : * @param byte The byte to write in memory
2293 : * @param length Amount of data to memset with given byte
2294 : *
2295 : * @return 0 in success, negative errno code otherwise.
2296 : */
2297 1 : int net_pkt_memset(struct net_pkt *pkt, int byte, size_t length);
2298 :
2299 : /**
2300 : * @brief Copy data from a packet into another one.
2301 : *
2302 : * @details Both net_pkt cursors should be properly initialized and,
2303 : * if needed, positioned using net_pkt_skip.
2304 : * The cursors will be updated after the operation.
2305 : *
2306 : * @param pkt_dst Destination network packet.
2307 : * @param pkt_src Source network packet.
2308 : * @param length Length of data to be copied.
2309 : *
2310 : * @return 0 on success, negative errno code otherwise.
2311 : */
2312 1 : int net_pkt_copy(struct net_pkt *pkt_dst,
2313 : struct net_pkt *pkt_src,
2314 : size_t length);
2315 :
2316 : /**
2317 : * @brief Clone pkt and its buffer. The cloned packet will be allocated on
2318 : * the same pool as the original one.
2319 : *
2320 : * @param pkt Original pkt to be cloned
2321 : * @param timeout Timeout to wait for free buffer
2322 : *
2323 : * @return NULL if error, cloned packet otherwise.
2324 : */
2325 1 : struct net_pkt *net_pkt_clone(struct net_pkt *pkt, k_timeout_t timeout);
2326 :
2327 : /**
2328 : * @brief Clone pkt and its buffer. The cloned packet will be allocated on
2329 : * the RX packet poll.
2330 : *
2331 : * @param pkt Original pkt to be cloned
2332 : * @param timeout Timeout to wait for free buffer
2333 : *
2334 : * @return NULL if error, cloned packet otherwise.
2335 : */
2336 1 : struct net_pkt *net_pkt_rx_clone(struct net_pkt *pkt, k_timeout_t timeout);
2337 :
2338 : /**
2339 : * @brief Clone pkt and increase the refcount of its buffer.
2340 : *
2341 : * @param pkt Original pkt to be shallow cloned
2342 : * @param timeout Timeout to wait for free packet
2343 : *
2344 : * @return NULL if error, cloned packet otherwise.
2345 : */
2346 1 : struct net_pkt *net_pkt_shallow_clone(struct net_pkt *pkt,
2347 : k_timeout_t timeout);
2348 :
2349 : /**
2350 : * @brief Read some data from a net_pkt
2351 : *
2352 : * @details net_pkt's cursor should be properly initialized and,
2353 : * if needed, positioned using net_pkt_skip.
2354 : * Cursor position will be updated after the operation.
2355 : *
2356 : * @param pkt The network packet from where to read some data
2357 : * @param data The destination buffer where to copy the data
2358 : * @param length The amount of data to copy
2359 : *
2360 : * @return 0 on success, negative errno code otherwise.
2361 : */
2362 1 : int net_pkt_read(struct net_pkt *pkt, void *data, size_t length);
2363 :
2364 : /**
2365 : * @brief Read a byte (uint8_t) from a net_pkt
2366 : *
2367 : * @details net_pkt's cursor should be properly initialized and,
2368 : * if needed, positioned using net_pkt_skip.
2369 : * Cursor position will be updated after the operation.
2370 : *
2371 : * @param pkt The network packet from where to read
2372 : * @param data The destination uint8_t where to copy the data
2373 : *
2374 : * @return 0 on success, negative errno code otherwise.
2375 : */
2376 1 : static inline int net_pkt_read_u8(struct net_pkt *pkt, uint8_t *data)
2377 : {
2378 : return net_pkt_read(pkt, data, 1);
2379 : }
2380 :
2381 : /**
2382 : * @brief Read uint16_t big endian data from a net_pkt
2383 : *
2384 : * @details net_pkt's cursor should be properly initialized and,
2385 : * if needed, positioned using net_pkt_skip.
2386 : * Cursor position will be updated after the operation.
2387 : *
2388 : * @param pkt The network packet from where to read
2389 : * @param data The destination uint16_t where to copy the data
2390 : *
2391 : * @return 0 on success, negative errno code otherwise.
2392 : */
2393 1 : int net_pkt_read_be16(struct net_pkt *pkt, uint16_t *data);
2394 :
2395 : /**
2396 : * @brief Read uint16_t little endian data from a net_pkt
2397 : *
2398 : * @details net_pkt's cursor should be properly initialized and,
2399 : * if needed, positioned using net_pkt_skip.
2400 : * Cursor position will be updated after the operation.
2401 : *
2402 : * @param pkt The network packet from where to read
2403 : * @param data The destination uint16_t where to copy the data
2404 : *
2405 : * @return 0 on success, negative errno code otherwise.
2406 : */
2407 1 : int net_pkt_read_le16(struct net_pkt *pkt, uint16_t *data);
2408 :
2409 : /**
2410 : * @brief Read uint32_t big endian data from a net_pkt
2411 : *
2412 : * @details net_pkt's cursor should be properly initialized and,
2413 : * if needed, positioned using net_pkt_skip.
2414 : * Cursor position will be updated after the operation.
2415 : *
2416 : * @param pkt The network packet from where to read
2417 : * @param data The destination uint32_t where to copy the data
2418 : *
2419 : * @return 0 on success, negative errno code otherwise.
2420 : */
2421 1 : int net_pkt_read_be32(struct net_pkt *pkt, uint32_t *data);
2422 :
2423 : /**
2424 : * @brief Write data into a net_pkt
2425 : *
2426 : * @details net_pkt's cursor should be properly initialized and,
2427 : * if needed, positioned using net_pkt_skip.
2428 : * Cursor position will be updated after the operation.
2429 : *
2430 : * @param pkt The network packet where to write
2431 : * @param data Data to be written
2432 : * @param length Length of the data to be written
2433 : *
2434 : * @return 0 on success, negative errno code otherwise.
2435 : */
2436 1 : int net_pkt_write(struct net_pkt *pkt, const void *data, size_t length);
2437 :
2438 : /**
2439 : * @brief Write a byte (uint8_t) data to a net_pkt
2440 : *
2441 : * @details net_pkt's cursor should be properly initialized and,
2442 : * if needed, positioned using net_pkt_skip.
2443 : * Cursor position will be updated after the operation.
2444 : *
2445 : * @param pkt The network packet from where to read
2446 : * @param data The uint8_t value to write
2447 : *
2448 : * @return 0 on success, negative errno code otherwise.
2449 : */
2450 1 : static inline int net_pkt_write_u8(struct net_pkt *pkt, uint8_t data)
2451 : {
2452 : return net_pkt_write(pkt, &data, sizeof(uint8_t));
2453 : }
2454 :
2455 : /**
2456 : * @brief Write a uint16_t big endian data to a net_pkt
2457 : *
2458 : * @details net_pkt's cursor should be properly initialized and,
2459 : * if needed, positioned using net_pkt_skip.
2460 : * Cursor position will be updated after the operation.
2461 : *
2462 : * @param pkt The network packet from where to read
2463 : * @param data The uint16_t value in host byte order to write
2464 : *
2465 : * @return 0 on success, negative errno code otherwise.
2466 : */
2467 1 : static inline int net_pkt_write_be16(struct net_pkt *pkt, uint16_t data)
2468 : {
2469 : uint16_t data_be16 = htons(data);
2470 :
2471 : return net_pkt_write(pkt, &data_be16, sizeof(uint16_t));
2472 : }
2473 :
2474 : /**
2475 : * @brief Write a uint32_t big endian data to a net_pkt
2476 : *
2477 : * @details net_pkt's cursor should be properly initialized and,
2478 : * if needed, positioned using net_pkt_skip.
2479 : * Cursor position will be updated after the operation.
2480 : *
2481 : * @param pkt The network packet from where to read
2482 : * @param data The uint32_t value in host byte order to write
2483 : *
2484 : * @return 0 on success, negative errno code otherwise.
2485 : */
2486 1 : static inline int net_pkt_write_be32(struct net_pkt *pkt, uint32_t data)
2487 : {
2488 : uint32_t data_be32 = htonl(data);
2489 :
2490 : return net_pkt_write(pkt, &data_be32, sizeof(uint32_t));
2491 : }
2492 :
2493 : /**
2494 : * @brief Write a uint32_t little endian data to a net_pkt
2495 : *
2496 : * @details net_pkt's cursor should be properly initialized and,
2497 : * if needed, positioned using net_pkt_skip.
2498 : * Cursor position will be updated after the operation.
2499 : *
2500 : * @param pkt The network packet from where to read
2501 : * @param data The uint32_t value in host byte order to write
2502 : *
2503 : * @return 0 on success, negative errno code otherwise.
2504 : */
2505 1 : static inline int net_pkt_write_le32(struct net_pkt *pkt, uint32_t data)
2506 : {
2507 : uint32_t data_le32 = sys_cpu_to_le32(data);
2508 :
2509 : return net_pkt_write(pkt, &data_le32, sizeof(uint32_t));
2510 : }
2511 :
2512 : /**
2513 : * @brief Write a uint16_t little endian data to a net_pkt
2514 : *
2515 : * @details net_pkt's cursor should be properly initialized and,
2516 : * if needed, positioned using net_pkt_skip.
2517 : * Cursor position will be updated after the operation.
2518 : *
2519 : * @param pkt The network packet from where to read
2520 : * @param data The uint16_t value in host byte order to write
2521 : *
2522 : * @return 0 on success, negative errno code otherwise.
2523 : */
2524 1 : static inline int net_pkt_write_le16(struct net_pkt *pkt, uint16_t data)
2525 : {
2526 : uint16_t data_le16 = sys_cpu_to_le16(data);
2527 :
2528 : return net_pkt_write(pkt, &data_le16, sizeof(uint16_t));
2529 : }
2530 :
2531 : /**
2532 : * @brief Get the amount of data which can be read from current cursor position
2533 : *
2534 : * @param pkt Network packet
2535 : *
2536 : * @return Amount of data which can be read from current pkt cursor
2537 : */
2538 1 : size_t net_pkt_remaining_data(struct net_pkt *pkt);
2539 :
2540 : /**
2541 : * @brief Get the total amount of bytes stored in a packet.
2542 : *
2543 : * @param pkt Network packet
2544 : *
2545 : * @return Total amount of bytes stored in a packet.
2546 : */
2547 1 : static inline size_t net_pkt_get_len(struct net_pkt *pkt)
2548 : {
2549 : return net_buf_frags_len(pkt->frags);
2550 : }
2551 :
2552 : /**
2553 : * @brief Update the overall length of a packet
2554 : *
2555 : * @details Unlike net_pkt_pull() below, this does not take packet cursor
2556 : * into account. It's mainly a helper dedicated for ipv4 and ipv6
2557 : * input functions. It shrinks the overall length by given parameter.
2558 : *
2559 : * @param pkt Network packet
2560 : * @param length The new length of the packet
2561 : *
2562 : * @return 0 on success, negative errno code otherwise.
2563 : */
2564 1 : int net_pkt_update_length(struct net_pkt *pkt, size_t length);
2565 :
2566 : /**
2567 : * @brief Remove data from the start of the packet.
2568 : *
2569 : * @details net_pkt's cursor should be properly initialized.
2570 : * Note that net_pkt's cursor is reset by this function.
2571 : * This functions works in similar way as net_buf_pull(),
2572 : * but it can handle multiple net_buf fragments.
2573 : *
2574 : * @param pkt Network packet
2575 : * @param length Number of bytes to be removed
2576 : *
2577 : * @return 0 on success, negative errno code otherwise.
2578 : */
2579 1 : int net_pkt_pull(struct net_pkt *pkt, size_t length);
2580 :
2581 : /**
2582 : * @brief Get the actual offset in the packet from its cursor
2583 : *
2584 : * @param pkt Network packet.
2585 : *
2586 : * @return a valid offset on success, 0 otherwise as there is nothing that
2587 : * can be done to evaluate the offset.
2588 : */
2589 1 : uint16_t net_pkt_get_current_offset(struct net_pkt *pkt);
2590 :
2591 : /**
2592 : * @brief Check if a data size could fit contiguously
2593 : *
2594 : * @details net_pkt's cursor should be properly initialized and,
2595 : * if needed, positioned using net_pkt_skip.
2596 : *
2597 : * @param pkt Network packet.
2598 : * @param size The size to check for contiguity
2599 : *
2600 : * @return true if that is the case, false otherwise.
2601 : */
2602 1 : bool net_pkt_is_contiguous(struct net_pkt *pkt, size_t size);
2603 :
2604 : /**
2605 : * Get the contiguous buffer space
2606 : *
2607 : * @param pkt Network packet
2608 : *
2609 : * @return The available contiguous buffer space in bytes starting from the
2610 : * current cursor position. 0 in case of an error.
2611 : */
2612 1 : size_t net_pkt_get_contiguous_len(struct net_pkt *pkt);
2613 :
2614 : /** @cond INTERNAL_HIDDEN */
2615 :
2616 : struct net_pkt_data_access {
2617 : #if !defined(CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS)
2618 : void *data;
2619 : #endif
2620 : const size_t size;
2621 : };
2622 :
2623 : #if defined(CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS)
2624 : #define NET_PKT_DATA_ACCESS_DEFINE(_name, _type) \
2625 : struct net_pkt_data_access _name = { \
2626 : .size = sizeof(_type), \
2627 : }
2628 :
2629 : #define NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(_name, _type) \
2630 : NET_PKT_DATA_ACCESS_DEFINE(_name, _type)
2631 :
2632 : #else
2633 : #define NET_PKT_DATA_ACCESS_DEFINE(_name, _type) \
2634 : _type _hdr_##_name; \
2635 : struct net_pkt_data_access _name = { \
2636 : .data = &_hdr_##_name, \
2637 : .size = sizeof(_type), \
2638 : }
2639 :
2640 : #define NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(_name, _type) \
2641 : struct net_pkt_data_access _name = { \
2642 : .data = NULL, \
2643 : .size = sizeof(_type), \
2644 : }
2645 :
2646 : #endif /* CONFIG_NET_HEADERS_ALWAYS_CONTIGUOUS */
2647 :
2648 : /** @endcond */
2649 :
2650 : /**
2651 : * @brief Get data from a network packet in a contiguous way
2652 : *
2653 : * @details net_pkt's cursor should be properly initialized and,
2654 : * if needed, positioned using net_pkt_skip. Unlike other functions,
2655 : * cursor position will not be updated after the operation.
2656 : *
2657 : * @param pkt The network packet from where to get the data.
2658 : * @param access A pointer to a valid net_pkt_data_access describing the
2659 : * data to get in a contiguous way.
2660 : *
2661 : * @return a pointer to the requested contiguous data, NULL otherwise.
2662 : */
2663 1 : void *net_pkt_get_data(struct net_pkt *pkt,
2664 : struct net_pkt_data_access *access);
2665 :
2666 : /**
2667 : * @brief Set contiguous data into a network packet
2668 : *
2669 : * @details net_pkt's cursor should be properly initialized and,
2670 : * if needed, positioned using net_pkt_skip.
2671 : * Cursor position will be updated after the operation.
2672 : *
2673 : * @param pkt The network packet to where the data should be set.
2674 : * @param access A pointer to a valid net_pkt_data_access describing the
2675 : * data to set.
2676 : *
2677 : * @return 0 on success, a negative errno otherwise.
2678 : */
2679 1 : int net_pkt_set_data(struct net_pkt *pkt,
2680 : struct net_pkt_data_access *access);
2681 :
2682 : /**
2683 : * Acknowledge previously contiguous data taken from a network packet
2684 : * Packet needs to be set to overwrite mode.
2685 : */
2686 1 : static inline int net_pkt_acknowledge_data(struct net_pkt *pkt,
2687 : struct net_pkt_data_access *access)
2688 : {
2689 : return net_pkt_skip(pkt, access->size);
2690 : }
2691 :
2692 : /**
2693 : * @}
2694 : */
2695 :
2696 : #ifdef __cplusplus
2697 : }
2698 : #endif
2699 :
2700 : #endif /* ZEPHYR_INCLUDE_NET_NET_PKT_H_ */
|