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