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