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