1 /* $NetBSD: ipsec_osdep.h,v 1.9.2.2 2007/12/01 17:33:16 bouyer Exp $ */
2 /* $FreeBSD: /repoman/r/ncvs/src/sys/netipsec/ipsec_osdep.h,v 1.1 2003/09/29 22:47:45 sam Exp $ */
3
4 /*
5 * Copyright (c) 2003 Jonathan Stone (jonathan@cs.stanford.edu)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef NETIPSEC_OSDEP_H
30 #define NETIPSEC_OSDEP_H
31
32 #ifdef _KERNEL
33 /*
34 * Hide porting differences across different 4.4BSD-derived platforms.
35 *
36 * 1. KASSERT() differences:
37 * 2. Kernel Random-number API differences.
38 * 3. Is packet data in an mbuf object writeable?
39 * 4. Packet-header semantics.
40 * 5. Fast mbuf-cluster allocation.
41 * 6. Network packet-output macros.
42 * 7. Elased time, in seconds.
43 * 8. Test if a socket object opened by a privileged (super) user.
44 * 9. Global SLIST of all open raw sockets.
45 * 10. Global SLIST of known interface addresses.
46 * 11. Type of initialization functions.
47 * 12. Byte order of ip_off
48 */
49
50 /*
51 * 1. KASSERT and spl differences
52 *
53 * FreeBSD takes an expression and parenthesized printf() argument-list.
54 * NetBSD takes one arg: the expression being asserted.
55 * FreeBSD's SPLASSERT() takes an SPL level as 1st arg and a
56 * parenthesized printf-format argument list as the second argument.
57 *
58 * This difference is hidden by two 2-argument macros and one 1-arg macro:
59 * IPSEC_ASSERT(expr, msg)
60 * IPSEC_SPLASSERT(spl, msg)
61 * One further difference is the spl names:
62 * NetBSD splsoftnet equates to FreeBSD splnet;
63 * NetBSD splnet equates to FreeBSD splimp.
64 * which is hidden by the macro IPSEC_SPLASSERT_SOFTNET(msg).
65 */
66 #ifdef __FreeBSD__
67 #define IPSEC_SPLASSERT(x,y) SPLASSERT(x, y)
68 #define IPSEC_ASSERT(c,m) KASSERT(c, m)
69 #define IPSEC_SPLASSERT_SOFTNET(m) SPLASSERT(splnet, m)
70 #endif /* __FreeBSD__ */
71
72 #ifdef __NetBSD__
73 #define IPSEC_SPLASSERT(x,y) (void)0
74 #define IPSEC_ASSERT(c,m) KASSERT(c)
75 #define IPSEC_SPLASSERT_SOFTNET(m) IPSEC_SPLASSERT(softnet, m)
76 #endif /* __NetBSD__ */
77
78 /*
79 * 2. Kernel Randomness API.
80 * FreeBSD uses:
81 * u_int read_random(void *outbuf, int nbytes).
82 */
83 #ifdef __FreeBSD__
84 #include <sys/random.h>
85 /* do nothing, use native random code. */
86 #endif /* __FreeBSD__ */
87
88 #ifdef __NetBSD__
89 #include <sys/rnd.h>
90 static __inline u_int read_random(void *p, u_int len);
91
92 static __inline u_int
93 read_random(void *bufp, u_int len)
94 {
95 return rnd_extract_data(bufp, len, RND_EXTRACT_ANY /*XXX FIXME */);
96 }
97 #endif /* __NetBSD__ */
98
99 /*
100 * 3. Test for mbuf mutability
101 * FreeBSD 4.x uses: M_EXT_WRITABLE
102 * NetBSD has M_READONLY(). Use !M_READONLY().
103 * Not an exact match to FreeBSD semantics, but adequate for IPsec purposes.
104 *
105 */
106 #ifdef __NetBSD__
107 /* XXX wrong, but close enough for restricted ipsec usage. */
108 #define M_EXT_WRITABLE(m) (!M_READONLY(m))
109 #endif /* __NetBSD__ */
110
111 /*
112 * 4. mbuf packet-header/packet-tag semantics.
113 * Sam Leffler explains, in private email, some problems with
114 * M_COPY_PKTHDR(), and why FreeBSD deprecated it and replaced it
115 * with new, explicit macros M_MOVE_PKTHDR()/M_DUP_PKTHDR().
116 * he original fast-ipsec source uses M_MOVE_PKTHDR.
117 * NetBSD currently still uses M_COPY_PKTHDR(), so we define
118 * M_MOVE_PKTHDR in terms of M_COPY_PKTHDR(). Fast-IPsec
119 * will delete the source mbuf shortly after copying packet tags,
120 * so we are safe for fast-ipsec but not in general..
121 */
122 #ifdef __NetBSD__
123 #define M_MOVE_PKTHDR(_f, _t) M_COPY_PKTHDR(_f, _t)
124 #endif /* __NetBSD__ */
125
126
127 /*
128 * 5. Fast mbuf-cluster allocation.
129 * FreeBSD 4.6 introduce m_getcl(), which performs `fast' allocation
130 * mbuf clusters from a cache of recently-freed clusters. (If the cache
131 * is empty, new clusters are allocated en-masse).
132 * On NetBSD, for now, implement the `cache' as an inline function
133 *using normal NetBSD mbuf/cluster allocation macros. Replace this
134 * with fast-cache code, if and when NetBSD implements one.
135 */
136 #ifdef __NetBSD__
137 static __inline struct mbuf *
138 m_getcl(int how, short type, int flags)
139 {
140 struct mbuf *mp;
141 if (flags & M_PKTHDR)
142 MGETHDR(mp, how, type);
143 else
144 MGET(mp, how, type);
145 if (mp == NULL)
146 return NULL;
147
148 MCLGET(mp, how);
149 if ((mp->m_flags & M_EXT) == 0) {
150 m_free(mp);
151 mp = NULL;
152 }
153 return mp;
154 }
155 #endif /* __NetBSD__ */
156
157 /*
158 * 6. Network output macros
159 * FreeBSD uses the IF_HANDOFF(), which raises SPL, enqueues
160 * a packet, and updates interface counters. NetBSD has IFQ_ENQUE(),
161 * which leaves SPL changes up to the caller.
162 * For now, we provide an emulation of IF_HANOOFF() which works
163 * for protocol input queues.
164 */
165 #ifdef __FreeBSD__
166 /* nothing to do */
167 #endif /* __FreeBSD__ */
168 #ifdef __NetBSD__
169 #define IF_HANDOFF(ifq, m, f) if_handoff(ifq, m, f, 0)
170
171 #include <net/if.h>
172
173 static __inline int
174 if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
175 {
176 int need_if_start = 0;
177 int s = splnet();
178
179 if (IF_QFULL(ifq)) {
180 IF_DROP(ifq);
181 splx(s);
182 m_freem(m);
183 return (0);
184 }
185 if (ifp != NULL) {
186 ifp->if_obytes += m->m_pkthdr.len + adjust;
187 if (m->m_flags & M_MCAST)
188 ifp->if_omcasts++;
189 need_if_start = !(ifp->if_flags & IFF_OACTIVE);
190 }
191 IF_ENQUEUE(ifq, m);
192 if (need_if_start)
193 (*ifp->if_start)(ifp);
194 splx(s);
195 return (1);
196 }
197 #endif /* __NetBSD__ */
198
199 /*
200 * 7. Elapsed Time: time_second as time in seconds.
201 * Original FreeBSD fast-ipsec code references a FreeBSD kernel global,
202 * time_second(). NetBSD: kludge #define to use time_mono_time.tv_sec.
203 */
204 #ifdef __NetBSD__
205 #include <sys/kernel.h>
206 #define time_second mono_time.tv_sec
207 #endif /* __NetBSD__ */
208
209 /* protosw glue */
210 #ifdef __NetBSD__
211 #include <sys/protosw.h>
212 #define ipprotosw protosw
213 #endif /* __NetBSD__ */
214
215 /*
216 * 8. Test for "privileged" socket opened by superuser.
217 * FreeBSD tests ((so)->so_cred && (so)->so_cred.cr_uid == 0),
218 * NetBSD (1.6N) tests (so)->so_uid == 0).
219 * This difference is wrapped inside the IPSEC_PRIVILEGED_SO() macro.
220 *
221 */
222 #ifdef __FreeBSD__
223 #define IPSEC_PRIVILEGED_SO(so) ((so)->so_cred && (so)->so_cred.cr_uid == 0)
224 #endif /* __FreeBSD__ */
225
226 #ifdef __NetBSD__
227 /* superuser opened socket? */
228 #define IPSEC_PRIVILEGED_SO(so) ((so)->so_uid == 0)
229 #endif /* __NetBSD__ */
230
231 /*
232 * 9. Raw socket list
233 * FreeBSD uses: listhead = rawcb_list, SLIST()-next field "list".
234 * NetBSD uses: listhead = rawcb, SLIST()-next field "list"
235 *
236 * This version of fast-ipsec source code uses rawcb_list as the head,
237 * and (to avoid namespace collisions) uses rcb_list as the "next" field.
238 */
239 #ifdef __FreeBSD__
240 #define rcb_list list
241 #endif /* __FreeBSD__ */
242 #ifdef __NetBSD__
243 #define rawcb_list rawcb
244 #endif /* __NetBSD__ */
245
246
247 /*
248 * 10. List of all known network interfaces.
249 * FreeBSD has listhead in_ifaddrhead, with ia_link as link.
250 * NetBSD has listhead in_ifaddr, with ia_list as link.
251 * No name-clahses, so just #define the appropriate names on NetBSD.
252 * NB: Is it worth introducing iterator (find-first-list/find-next-list)
253 * functions or macros to encapsulate these?
254 */
255 #ifdef __FreeBSD__
256 /* nothing to do for raw interface list */
257 #endif /* FreeBSD */
258 #ifdef __NetBSD__
259 #define ia_link ia_list
260 #endif /* __NetBSD__ */
261
262 /*
263 * 11. Type of initialization functions.
264 */
265 #ifdef __FreeBSD__
266 #define INITFN static
267 #endif
268 #ifdef __NetBSD__
269 #define INITFN extern
270 #endif
271
272 /* 12. On FreeBSD, ip_off assumed in host endian;
273 * it is converted (if necessary) by ip_input().
274 * On NetBSD, ip_off is in network byte order.
275 * We hide the difference with the macro IP_OFF_CONVERT
276 */
277
278 #ifdef __FreeBSD__
279 #define IP_OFF_CONVERT(x) (x)
280 #endif
281
282 #ifdef __NetBSD__
283 #define IP_OFF_CONVERT(x) (htons(x))
284 #endif
285
286 /*
287 * 13. IPv6 support, and "generic" inpcb vs. IPv4 pcb vs. IPv6 pcb.
288 * To IPv6 V4-mapped addresses (and the KAME-derived implementation
289 * of IPv6 v4-mapped addresses) we must support limited polymorphism:
290 * partway down the stack we detect an IPv6 protocol address is really
291 * a mapped V4 address, and then start dispatching that address to
292 * native IPv4 PCB lookup. In KAME-derived IPsec (including fas-ipsec)
293 * some functions must handle arguments which (dynamically) may be either
294 * a IPv4 pcb (struct inpcb *) or an IPv6 pcb (struct in6pcb *).
295 *
296 * In FreeBSD 4.x, sgtrucr in6pcb is syntactic sugar for struct inpcb,
297 * so punning between struct inpcb* and struct in6pcb* is trivial.
298 * NetBSD until recently used completely different structs for IPv4
299 * and IPv6 PCBs. To simplify fast-ipsec coexisting with IPv6,
300 * NetBSD's struct inpcb and struct in6pcb were changed to both have
301 * common struct, struct inpcb_hdr, as their first member. NetBSD can
302 * thus pass arguments as struct inpcb_hdr*, and dispatch on a v4/v6
303 * flag in the inpcb_hdr at runtime.
304 *
305 * We hide the NetBSD-vs-FreeBSD differences inside the following abstraction:
306 *
307 * PCB_T: a macro name for a struct type which is used as a "generic"
308 * argument for actual arguments an in4pcb or an in6pcb.
309 *
310 * PCB_FAMILY(p): given a "generic" pcb_t p, returns the protocol
311 * family (AF_INET, AF_INET6) of the unperlying inpcb/in6pcb.
312 *
313 * PCB_SOCKET(p): given a "generic" pcb_t p, returns the associated
314 * socket pointer
315 *
316 * PCB_TO_IN4PCB(p): given generic pcb_t *p, returns a struct inpcb *
317 * PCB_TO_IN6PCB(p): given generic pcb_t *p, returns a struct in6pcb *
318 *
319 * IN4PCB_TO_PCB(inp): given a struct inpcb *inp, returns a pcb_t *
320 * IN6PCB_TO_PCB(in6p): given a struct in6pcb *in6p, returns a pcb_t *
321 */
322 #ifdef __FreeBSD__
323 #define PCB_T struct inpcb
324 #define PCB_FAMILY(p) ((p)->inp_socket->so_proto->pr_domain->dom_family)
325 #define PCB_SOCKET(p) ((p)->inp_socket)
326
327 /* Convert generic pcb to IPv4/IPv6 pcb */
328 #define PCB_TO_IN4PCB(p) (p)
329 #define PCB_TO_IN6PCB(p) (p)
330
331 /* Convert IPv4/IPv6 pcb to generic pcb, for callers of fast-ipsec */
332 #define IN4PCB_TO_PCB(p) (p)
333 #define IN6PCB_TO_PCB(p) (p)
334 #endif /* __FreeBSD__ */
335
336 #ifdef __NetBSD__
337 #define PCB_T struct inpcb_hdr
338 #define PCB_FAMILY(p) ((p)->inph_af)
339 #define PCB_SOCKET(p) ((p)->inph_socket)
340
341 #define PCB_TO_IN4PCB(p) ((struct inpcb *)(p))
342 #define PCB_TO_IN6PCB(p) ((struct in6pcb *)(p))
343
344 #define IN4PCB_TO_PCB(p) ((PCB_T *)(&(p)->inp_head))
345 #define IN6PCB_TO_PCB(p) ((PCB_T *)(&(p)->in6p_head))
346 #endif /* __NetBSD__ */
347
348 /*
349 * Differences that we don't attempt to hide:
350 *
351 * A. Initialization code. This is the largest difference of all.
352 *
353 * FreeBSD uses compile/link-time perl hackery to generate special
354 * .o files with linker sections that give the moral equivalent of
355 * C++ file-level-object constructors. NetBSD has no such facility.
356 *
357 * Either we implement it (ideally, in a way that can emulate
358 * FreeBSD's SYSINIT() macros), or we must take other means
359 * to have the per-file init functions called at some appropriate time.
360 *
361 * In the absence of SYSINIT(), all the file-level init functions
362 * now have "extern" linkage. There is a new fast-ipsec init()
363 * function which calls each of the per-file in an appropriate order.
364 * init_main will arrange to call the fast-ipsec init function
365 * after the crypto framework has registered its transforms (including
366 * any autoconfigured hardware crypto accelerators) but before
367 * initializing the network stack to send or receive packet.
368 *
369 * B. Protosw() differences.
370 * CSRG-style BSD TCP/IP uses a generic protocol-dispatch-function
371 * where the specific request is identified by an enum argument.
372 * FreeBSD replaced that with an array of request-specific
373 * function pointers.
374 *
375 * These differences affect the handlers for key-protocol user requests
376 * so pervasively that I gave up on the fast-ipsec code, and re-worked the
377 * NetBSD KAME code to match the (relative few) API differences
378 * between NetBSD and FreeBSD's KAME netkey, and Fast-IPsec netkey.
379 *
380 * C. Timeout() versus callout(9):
381 * The FreeBSD 4.x netipsec/ code still uses timeout().
382 * FreeBSD 4.7 has callout(9), so I just replaced
383 * timeout_*() with the nearest callout_*() equivalents,
384 * and added a callout handle to the ipsec context.
385 *
386 * D. SPL name differences.
387 * FreeBSD splnet() equates directly to NetBSD's splsoftnet();
388 * FreeBSD uses splimp() where (for networking) NetBSD would use splnet().
389 */
390 #endif /* _KERNEL */
391 #endif /* NETIPSEC_OSDEP_H */
Cache object: 1e18dd602a2dd9ade41bb9d7a00e1f26
|