initial version, corresponding to ipfw3-2012
[ipfw-google.git] / sys / sys / mbuf.h
1 /*
2  * Copyright (C) 2009 Luigi Rizzo, Universita` di Pisa
3  *
4  * BSD copyright.
5  *
6  * A simple compatibility interface to map mbufs onto sk_buff
7  */
8
9 #ifndef _SYS_MBUF_H_
10 #define _SYS_MBUF_H_
11
12 #include <sys/malloc.h>         /* we use free() */
13 /* hopefully queue.h is already included by someone else */
14 #include <sys/queue.h>
15 #ifdef _KERNEL
16
17 /* bzero not present on linux, but this should go in glue.h */
18 // #define bzero(s, n) memset(s, 0, n)
19
20 /*
21  * We implement a very simplified UMA allocator where the backend
22  * is simply malloc, and uma_zone only stores the length of the components.
23  */
24 typedef int uma_zone_t;         /* the zone size */
25
26 #define uma_zcreate(name, len, _3, _4, _5, _6, _7, _8)  (len)
27
28
29 #define uma_zfree(zone, item)   free(item, M_IPFW)
30 #define uma_zalloc(zone, flags) malloc(zone, M_IPFW, flags)
31 #define uma_zdestroy(zone)      do {} while (0)
32
33 /*-
34  * Macros for type conversion:
35  * mtod(m, t)   -- Convert mbuf pointer to data pointer of correct type.
36  */
37 #define mtod(m, t)      ((t)((m)->m_data))
38
39 #endif /* _KERNEL */
40
41 /*
42  * Packet tag structure (see below for details).
43  */
44 struct m_tag {
45         SLIST_ENTRY(m_tag)      m_tag_link;     /* List of packet tags */
46         u_int16_t               m_tag_id;       /* Tag ID */
47         u_int16_t               m_tag_len;      /* Length of data */
48         u_int32_t               m_tag_cookie;   /* ABI/Module ID */
49         void                    (*m_tag_free)(struct m_tag *);
50 };
51
52 #if defined(__linux__) || defined( _WIN32 )
53
54 /*
55  * Auxiliary structure to store values from the sk_buf.
56  * Note that we should not alter the sk_buff, and if we do
57  * so make sure to keep the values in sync between the mbuf
58  * and the sk_buff (especially m_len and m_pkthdr.len).
59  */
60
61 struct mbuf {
62         struct mbuf *m_next;
63         struct mbuf *m_nextpkt;
64         char *m_data; // XXX was void *
65         int m_len;      /* length in this mbuf */
66         int m_flags;
67 #ifdef __linux__
68 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
69         struct nf_info *queue_entry;
70 #else
71         struct nf_queue_entry *queue_entry;
72 #endif
73 #else /* _WIN32 */
74         int             direction;      /* could go in rcvif */
75         NDIS_HANDLE     context;        /* replaces queue_entry or skb ?*/
76         PNDIS_PACKET    pkt;
77 #endif
78         struct sk_buff *m_skb;
79         struct {
80 #ifdef __linux__
81                 struct net_device *rcvif;
82 #else
83                 struct ifnet *rcvif;
84 #endif
85                 int len;        /* total packet len */
86                 SLIST_HEAD (packet_tags, m_tag) tags;
87         } m_pkthdr;
88 };
89
90 #define M_SKIP_FIREWALL 0x01            /* skip firewall processing */
91 #define M_BCAST         0x02 /* send/received as link-level broadcast */
92 #define M_MCAST         0x04 /* send/received as link-level multicast */
93
94 #define M_DONTWAIT      M_NOWAIT        /* should not be here... */
95
96
97 /*
98  * m_dup() is used in the TEE case, currently unsupported so we
99  * just return.
100  */
101 static __inline struct mbuf     *m_dup(struct mbuf *m, int n)
102 {
103         (void)m; (void)n;
104         return NULL;
105 };
106
107 #define MTAG_ABI_COMPAT         0               /* compatibility ABI */
108 static __inline struct m_tag *
109 m_tag_find(struct mbuf *m, int type, struct m_tag *start)
110 {
111         (void)m; (void)type; (void)start;
112         return NULL;
113 };
114
115
116 static __inline void
117 m_tag_prepend(struct mbuf *m, struct m_tag *t)
118 {
119         SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
120 }
121
122 /*
123  * Return the next tag in the list of tags associated with an mbuf.
124  */
125 static __inline struct m_tag *
126 m_tag_next(struct mbuf *m, struct m_tag *t)
127 {
128  
129         return (SLIST_NEXT(t, m_tag_link));
130 }
131
132 /*
133  * Create an mtag of the given type
134  */
135 static __inline struct m_tag *
136 m_tag_alloc(uint32_t cookie, int type, int length, int wait)
137 {
138         int l = length + sizeof(struct m_tag);
139         struct m_tag *m = malloc(l, 0, M_NOWAIT);
140         if (m) {
141                 memset(m, 0, l);
142                 m->m_tag_id = type;
143                 m->m_tag_len = length;
144                 m->m_tag_cookie = cookie;
145         }
146         return m;
147 };
148
149 static __inline struct m_tag *
150 m_tag_get(int type, int length, int wait)
151 {
152         return m_tag_alloc(MTAG_ABI_COMPAT, type, length, wait);
153 }
154
155 static __inline struct m_tag *
156 m_tag_first(struct mbuf *m)
157 {
158         return SLIST_FIRST(&m->m_pkthdr.tags);
159 };
160
161 static __inline void
162 m_tag_delete(struct mbuf *m, struct m_tag *t)
163 {
164 };
165
166 static __inline struct m_tag *
167 m_tag_locate(struct mbuf *m, u_int32_t n, int x, struct m_tag *t)
168 {
169         struct m_tag *tag;
170
171         tag = m_tag_first(m);
172         if (tag == NULL)
173                 return NULL;
174
175         if (tag->m_tag_cookie != n || tag->m_tag_id != x)
176                 return NULL;
177         else
178                 return tag;
179 };
180
181 #define M_SETFIB(_m, _fib)      /* nothing on linux */
182
183 static __inline void
184 m_freem(struct mbuf *m)
185 {
186         struct m_tag *t;
187
188         /* free the m_tag chain */
189         while ( (t = SLIST_FIRST(&m->m_pkthdr.tags) ) ) {
190                 SLIST_REMOVE_HEAD(&m->m_pkthdr.tags, m_tag_link);
191                 free(t, 0);
192         }
193
194         /* free the mbuf */
195         free(m, M_IPFW);
196 };
197
198 /* m_pullup is not supported, there is a macro in missing.h */
199
200 #define M_GETFIB(_m)    0
201
202 /* macro used to create a new mbuf */
203 #define MT_DATA         1       /* dynamic (data) allocation */
204 #define MSIZE           256     /* size of an mbuf */
205 #define MGETHDR(_m, _how, _type)   ((_m) = m_gethdr((_how), (_type)))
206
207 /* allocate and init a new mbuf using the same structure of FreeBSD */
208 static __inline struct mbuf *
209 m_gethdr(int how, short type)
210 {
211         struct mbuf *m;
212
213         m = malloc(MSIZE, M_IPFW, M_NOWAIT);
214
215         if (m == NULL) {
216                 return m;
217         }
218
219         /* here we have MSIZE - sizeof(struct mbuf) available */
220         m->m_data = (char *)(m + 1);
221
222         return m;
223 }
224
225 #endif /* __linux__ || _WIN32 */
226
227 /*
228  * Persistent tags stay with an mbuf until the mbuf is reclaimed.  Otherwise
229  * tags are expected to ``vanish'' when they pass through a network
230  * interface.  For most interfaces this happens normally as the tags are
231  * reclaimed when the mbuf is free'd.  However in some special cases
232  * reclaiming must be done manually.  An example is packets that pass through
233  * the loopback interface.  Also, one must be careful to do this when
234  * ``turning around'' packets (e.g., icmp_reflect).
235  *
236  * To mark a tag persistent bit-or this flag in when defining the tag id.
237  * The tag will then be treated as described above.
238  */
239 #define MTAG_PERSISTENT                         0x800
240
241 #define PACKET_TAG_NONE                         0  /* Nadda */
242
243 /* Packet tags for use with PACKET_ABI_COMPAT. */
244 #define PACKET_TAG_IPSEC_IN_DONE                1  /* IPsec applied, in */
245 #define PACKET_TAG_IPSEC_OUT_DONE               2  /* IPsec applied, out */
246 #define PACKET_TAG_IPSEC_IN_CRYPTO_DONE         3  /* NIC IPsec crypto done */
247 #define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED      4  /* NIC IPsec crypto req'ed */
248 #define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO     5  /* NIC notifies IPsec */
249 #define PACKET_TAG_IPSEC_PENDING_TDB            6  /* Reminder to do IPsec */
250 #define PACKET_TAG_BRIDGE                       7  /* Bridge processing done */
251 #define PACKET_TAG_GIF                          8  /* GIF processing done */
252 #define PACKET_TAG_GRE                          9  /* GRE processing done */
253 #define PACKET_TAG_IN_PACKET_CHECKSUM           10 /* NIC checksumming done */
254 #define PACKET_TAG_ENCAP                        11 /* Encap.  processing */
255 #define PACKET_TAG_IPSEC_SOCKET                 12 /* IPSEC socket ref */
256 #define PACKET_TAG_IPSEC_HISTORY                13 /* IPSEC history */
257 #define PACKET_TAG_IPV6_INPUT                   14 /* IPV6 input processing */
258 #define PACKET_TAG_DUMMYNET                     15 /* dummynet info */
259 #define PACKET_TAG_DIVERT                       17 /* divert info */
260 #define PACKET_TAG_IPFORWARD                    18 /* ipforward info */
261 #define PACKET_TAG_MACLABEL     (19 | MTAG_PERSISTENT) /* MAC label */
262 #define PACKET_TAG_PF                           21 /* PF + ALTQ information */
263 #define PACKET_TAG_RTSOCKFAM                    25 /* rtsock sa family */
264 #define PACKET_TAG_IPOPTIONS                    27 /* Saved IP options */
265 #define PACKET_TAG_CARP                         28 /* CARP info */
266
267 #endif /* !_SYS_MBUF_H_ */