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
13 /* PAGE_SIZE minus 16 bytes of metadata in pktbuf_buf */
14 #ifndef PKTBUF_POOL_SIZE
15 #define PKTBUF_POOL_SIZE 256
16 #endif
17
18 #ifndef PKTBUF_SIZE
19 #define PKTBUF_SIZE 1536
20 #endif
21
22 /* How much space pktbuf_alloc should save for IP headers in the front of the buffer */
23 #define PKTBUF_MAX_HDR 64
24 /* The remaining space in the buffer */
25 #define PKTBUF_MAX_DATA (PKTBUF_SIZE - PKTBUF_MAX_HDR)
26
27 typedef void (*pktbuf_free_callback)(void *buf, void *arg);
28 typedef struct pktbuf {
29 u8 *data;
30 u32 blen;
31 u32 dlen;
32 paddr_t phys_base;
33 struct list_node list;
34 u32 flags;
35 pktbuf_free_callback cb;
36 void *cb_args;
37 u8 *buffer;
38 } pktbuf_t;
39
40 typedef struct pktbuf_pool_object {
41 union {
42 pktbuf_t p;
43 uint8_t b[PKTBUF_SIZE];
44 };
45 } pktbuf_pool_object_t;
46
47 #define PKTBUF_FLAG_CKSUM_IP_GOOD (1<<0)
48 #define PKTBUF_FLAG_CKSUM_TCP_GOOD (1<<1)
49 #define PKTBUF_FLAG_CKSUM_UDP_GOOD (1<<2)
50 #define PKTBUF_FLAG_EOF (1<<3)
51 #define PKTBUF_FLAG_CACHED (1<<4)
52
53 /* Return the physical address offset of data in the packet */
pktbuf_data_phys(pktbuf_t * p)54 static inline u32 pktbuf_data_phys(pktbuf_t *p) {
55 return p->phys_base + (p->data - p->buffer);
56 }
57
58 // number of bytes available for _prepend
pktbuf_avail_head(pktbuf_t * p)59 static inline u32 pktbuf_avail_head(pktbuf_t *p) {
60 return p->data - p->buffer;
61 }
62
63 // number of bytes available for _append or _append_data
pktbuf_avail_tail(pktbuf_t * p)64 static inline u32 pktbuf_avail_tail(pktbuf_t *p) {
65 return p->blen - (p->data - p->buffer) - p->dlen;
66 }
67
68 // allocate packet buffer from buffer pool
69 pktbuf_t *pktbuf_alloc(void);
70 pktbuf_t *pktbuf_alloc_empty(void);
71
72 /* Add a buffer to an existing packet buffer */
73 void pktbuf_add_buffer(pktbuf_t *p, u8 *buf, u32 len, uint32_t header_sz,
74 uint32_t flags, pktbuf_free_callback cb, void *cb_args);
75 // return packet buffer to buffer pool
76 // returns number of threads woken up
77 int pktbuf_free(pktbuf_t *p, bool reschedule);
78
79 // extend buffer by sz bytes, copied from data
80 void pktbuf_append_data(pktbuf_t *p, const void *data, size_t sz);
81
82 // extend buffer by sz bytes, returning a pointer to the
83 // start of the newly appended region
84 void *pktbuf_append(pktbuf_t *p, size_t sz);
85
86 // grow the front of the buffer and return a pointer
87 // to the new start of packet
88 void *pktbuf_prepend(pktbuf_t *p, size_t sz);
89
90 // shrink the buffer by discarding the first sz bytes
91 // returning a pointer to the discarded bytes (which
92 // will remain untouched until the next _prepend),
93 // or NULL if there were not enough bytes to consume
94 void *pktbuf_consume(pktbuf_t *p, size_t sz);
95
96 // remove sz bytes from the end of the pktbuf
97 void pktbuf_consume_tail(pktbuf_t *p, size_t sz);
98
99 // create a new packet buffer from raw memory and add
100 // it to the free pool
101 void pktbuf_create(void *ptr, size_t size);
102
103 // Create buffers for pktbufs of size PKTBUF_BUF_SIZE out of size
104 void pktbuf_create_bufs(void *ptr, size_t size);
105
106 void pktbuf_dump(pktbuf_t *p);
107