1 /*
2  * Copyright (c) 2014 Brian Swetland
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <sys/types.h>
11 #include <lk/list.h>
12 #include <lk/compiler.h>
13 
14 __BEGIN_CDECLS
15 
16 /* PAGE_SIZE minus 16 bytes of metadata in pktbuf_buf */
17 #ifndef PKTBUF_POOL_SIZE
18 #define PKTBUF_POOL_SIZE 256
19 #endif
20 
21 #ifndef PKTBUF_SIZE
22 #define PKTBUF_SIZE     1536
23 #endif
24 
25 /* How much space pktbuf_alloc should save for IP headers in the front of the buffer */
26 #define PKTBUF_MAX_HDR  64
27 /* The remaining space in the buffer */
28 #define PKTBUF_MAX_DATA (PKTBUF_SIZE - PKTBUF_MAX_HDR)
29 
30 typedef void (*pktbuf_free_callback)(void *buf, void *arg);
31 typedef struct pktbuf {
32     u8 *data;
33     u32 blen;
34     u32 dlen;
35     paddr_t phys_base;
36     struct list_node list;
37     u32 flags;
38     pktbuf_free_callback cb;
39     void *cb_args;
40     u8 *buffer;
41 } pktbuf_t;
42 
43 typedef struct pktbuf_pool_object {
44     union {
45         pktbuf_t p;
46         uint8_t b[PKTBUF_SIZE];
47     };
48 } pktbuf_pool_object_t;
49 
50 #define PKTBUF_FLAG_CKSUM_IP_GOOD  (1<<0)
51 #define PKTBUF_FLAG_CKSUM_TCP_GOOD (1<<1)
52 #define PKTBUF_FLAG_CKSUM_UDP_GOOD (1<<2)
53 #define PKTBUF_FLAG_EOF            (1<<3)
54 #define PKTBUF_FLAG_CACHED         (1<<4)
55 
56 /* Return the physical address offset of data in the packet */
pktbuf_data_phys(pktbuf_t * p)57 static inline u32 pktbuf_data_phys(pktbuf_t *p) {
58     return p->phys_base + (p->data - p->buffer);
59 }
60 
61 // number of bytes available for _prepend
pktbuf_avail_head(pktbuf_t * p)62 static inline u32 pktbuf_avail_head(pktbuf_t *p) {
63     return p->data - p->buffer;
64 }
65 
66 // number of bytes available for _append or _append_data
pktbuf_avail_tail(pktbuf_t * p)67 static inline u32 pktbuf_avail_tail(pktbuf_t *p) {
68     return p->blen - (p->data - p->buffer) - p->dlen;
69 }
70 
71 // allocate packet buffer from buffer pool
72 pktbuf_t *pktbuf_alloc(void);
73 pktbuf_t *pktbuf_alloc_empty(void);
74 
75 /* Add a buffer to an existing packet buffer */
76 void pktbuf_add_buffer(pktbuf_t *p, u8 *buf, u32 len, uint32_t header_sz,
77                        uint32_t flags, pktbuf_free_callback cb, void *cb_args);
78 
79 // return packet buffer to buffer pool
80 // returns number of threads woken up
81 int pktbuf_free(pktbuf_t *p, bool reschedule);
82 
83 // extend buffer by sz bytes, copied from data
84 void pktbuf_append_data(pktbuf_t *p, const void *data, size_t sz);
85 
86 // extend buffer by sz bytes, returning a pointer to the
87 // start of the newly appended region
88 void *pktbuf_append(pktbuf_t *p, size_t sz);
89 
90 // grow the front of the buffer and return a pointer
91 // to the new start of packet
92 void *pktbuf_prepend(pktbuf_t *p, size_t sz);
93 
94 // shrink the buffer by discarding the first sz bytes
95 // returning a pointer to the discarded bytes (which
96 // will remain untouched until the next _prepend),
97 // or NULL if there were not enough bytes to consume
98 void *pktbuf_consume(pktbuf_t *p, size_t sz);
99 
100 // remove sz bytes from the end of the pktbuf
101 void pktbuf_consume_tail(pktbuf_t *p, size_t sz);
102 
103 // reset the header size to header_sz into the underlying buffer.
104 // p->dlen is also set to 0.
105 // pktbuf must have a buffer with a valid blen and header_sz must
106 // be within the buffer.
107 void pktbuf_reset(pktbuf_t *p, uint32_t header_sz);
108 
109 // create a new packet buffer from raw memory and add
110 // it to the free pool
111 void pktbuf_create(void *ptr, size_t size);
112 
113 // Create buffers for pktbufs of size PKTBUF_BUF_SIZE out of size
114 void pktbuf_create_bufs(void *ptr, size_t size);
115 
116 void pktbuf_dump(pktbuf_t *p);
117 
118 __END_CDECLS
119