-
Notifications
You must be signed in to change notification settings - Fork 1
/
mbuf.h
196 lines (162 loc) · 3.88 KB
/
mbuf.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#ifndef MBUF_H_
#define MBUF_H_
#ifndef MBUF_POOL_LEN
#define MBUF_POOL_LEN 16
#endif
#include <sys/uio.h>
#include <stddef.h>
#include <stdint.h>
#if !(MBUF_POOL_LEN)
#include <stdlib.h>
#endif
#define MTU_SIZE 1500
#define _howmany(x, y) (((x) + ((y) - 1)) / (y))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#ifndef MSIZE
#define MSIZE 256
#endif
#define MLEN (MSIZE - sizeof(struct m_hdr))
struct mbuf;
/* Header present at the beginning of every mbuf */
struct m_hdr {
struct mbuf *mh_next;
uint8_t *mh_head;
uint8_t *mh_tail;
};
struct mbuf {
struct m_hdr m_hdr;
uint8_t m_data[MLEN];
};
#define m_next m_hdr.mh_next
#define m_head m_hdr.mh_head
#define m_tail m_hdr.mh_tail
#define MB_IP_ALIGN 2
/*
* Following ascii diagram illustrates the layout of mbuf data structure.
*
* +--+-------------+
* m_hdr | | |
* | | |
* +--------------------> &m_data[0]
* | | |
* | | |
* | | +---> m_head
* | | |
* + | |
* m_data[MLEN] | |
* + | |
* | | |
* | | |
* | | +---> m_tail
* | | |
* +--+-------------+---> &m_data[MLEN]
*/
struct mbuf_iovec {
struct mbuf *buffs[_howmany(MTU_SIZE, MLEN)];
struct iovec iov[_howmany(MTU_SIZE, MLEN)];
};
struct mbuf *mb_pool_alloc(void);
void mb_pool_free(struct mbuf *m);
struct mbuf *mb_pool_chain_alloc(unsigned int nrbufs);
void mb_pool_chain_free(struct mbuf *m);
static inline void mb_init(struct mbuf *m);
static inline struct mbuf *mb_alloc(void)
{
struct mbuf *m;
#if MBUF_POOL_LEN
m = mb_pool_alloc();
#else
m = malloc(sizeof(struct mbuf));
mb_init(m);
#endif
return m;
}
static inline void mb_free(struct mbuf *m)
{
#if MBUF_POOL_LEN
mb_pool_free(m);
#else
free(m);
#endif
}
void mb_pool_init(void);
/*
* Allocate @num_mbuffs number of mbufs. Returns a pointer to
* the head of the mbuf chain.
*/
static inline struct mbuf *mb_alloc_chain(unsigned int num_mbuffs)
{
return mb_pool_chain_alloc(num_mbuffs);
}
#define mb_alloc_mtu() mb_alloc_chain(_howmany(MTU_SIZE, MLEN))
int mb_pool_sg_alloc(struct mbuf_iovec *miov);
void mb_pool_sg_free_excess(struct mbuf_iovec *mi, unsigned int bytes_in_use);
/*
* Free an entire mbuf chain pointed to by @m
*/
static inline void mb_chain_free(struct mbuf *m)
{
mb_pool_chain_free(m);
}
static inline void mb_init(struct mbuf *m)
{
m->m_next = NULL;
m->m_head = m->m_data;
m->m_tail = m->m_data;
}
static inline void *mb_head(const struct mbuf *m)
{
return m->m_head;
}
static inline struct mbuf *mb_last(struct mbuf *m)
{
while (m->m_next)
m = m->m_next;
return m;
}
static inline struct mbuf **mb_lastpp(struct mbuf **m)
{
while (*m)
m = &(*m)->m_next;
return m;
}
static inline unsigned int mb_datalen(const struct mbuf *m)
{
return m->m_tail - m->m_head;
}
/*
* Increase the headroom of an empty mbuf by reducing the tail room.
* This is only allowed for an empty buffer. This function roughly
* does the same thing as skb_reserve of Linux kernel.
*/
static inline void mb_reserve(struct mbuf *m, unsigned int len)
{
m->m_head += len;
m->m_tail += len;
}
static inline unsigned int mb_headroom(struct mbuf *m)
{
return m->m_head - m->m_data;
}
static inline unsigned int mb_tailroom(struct mbuf *m)
{
return &m->m_data[MLEN] - m->m_tail;
}
static inline void *mb_push(struct mbuf *m, unsigned int len)
{
m->m_head -= len;
return m->m_head;
}
static inline void *mb_put(struct mbuf *m, unsigned int len)
{
uint8_t *oldtail = m->m_tail;
m->m_tail += len;
return oldtail;
}
static inline void *mb_htrim(struct mbuf *m, unsigned int len)
{
uint8_t *oldhead = m->m_head;
m->m_head += len;
return oldhead;
}
#endif /* end of include guard: MBUF_H_ */