1 | /* $NetBSD: ipsec_osdep.h,v 1.26 2016/06/22 10:44:32 knakahara 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/cprng.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 cprng_fast(bufp, len); |
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 | */ |
114 | /* |
115 | * nothing. |
116 | */ |
117 | |
118 | /* |
119 | * 5. Fast mbuf-cluster allocation. |
120 | */ |
121 | /* |
122 | * nothing. |
123 | */ |
124 | |
125 | /* |
126 | * 6. Network output macros |
127 | * FreeBSD uses the IF_HANDOFF(), which raises SPL, enqueues |
128 | * a packet, and updates interface counters. NetBSD has IFQ_ENQUE(), |
129 | * which leaves SPL changes up to the caller. |
130 | * For now, we provide an emulation of IF_HANOOFF() which works |
131 | * for protocol input queues. |
132 | */ |
133 | #ifdef __FreeBSD__ |
134 | /* nothing to do */ |
135 | #endif /* __FreeBSD__ */ |
136 | #ifdef __NetBSD__ |
137 | #define IF_HANDOFF(ifq, m, f) if_handoff(ifq, m, f, 0) |
138 | |
139 | #include <net/if.h> |
140 | |
141 | static __inline int |
142 | if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) |
143 | { |
144 | int s = splnet(); |
145 | |
146 | KERNEL_LOCK(1, NULL); |
147 | if (IF_QFULL(ifq)) { |
148 | IF_DROP(ifq); |
149 | KERNEL_UNLOCK_ONE(NULL); |
150 | splx(s); |
151 | m_freem(m); |
152 | return (0); |
153 | } |
154 | if (ifp != NULL) |
155 | (void)if_transmit_lock(ifp, m); |
156 | |
157 | KERNEL_UNLOCK_ONE(NULL); |
158 | splx(s); |
159 | return (1); |
160 | } |
161 | #endif /* __NetBSD__ */ |
162 | |
163 | /* |
164 | * 7. Elapsed Time: time_second as time in seconds. |
165 | * Original FreeBSD fast-ipsec code references a FreeBSD kernel global, |
166 | * time_second(). |
167 | * XXX is this the right time scale - shouldn't we measure timeout/life times |
168 | * using a monotonic time scale (time_uptime, mono_time) - why if the FreeBSD |
169 | * base code using UTC based time for this ? |
170 | */ |
171 | |
172 | /* protosw glue */ |
173 | #ifdef __NetBSD__ |
174 | #include <sys/protosw.h> |
175 | #define ipprotosw protosw |
176 | #endif /* __NetBSD__ */ |
177 | |
178 | /* |
179 | * 8. Test for "privileged" socket opened by superuser. |
180 | * FreeBSD tests ((so)->so_cred && (so)->so_cred.cr_uid == 0), |
181 | * NetBSD (1.6N) tests (so)->so_uid == 0). |
182 | * This difference is wrapped inside the IPSEC_PRIVILEGED_SO() macro. |
183 | * |
184 | */ |
185 | #ifdef __FreeBSD__ |
186 | #define IPSEC_PRIVILEGED_SO(so) ((so)->so_cred && (so)->so_cred.cr_uid == 0) |
187 | #endif /* __FreeBSD__ */ |
188 | |
189 | #ifdef __NetBSD__ |
190 | /* superuser opened socket? */ |
191 | #define IPSEC_PRIVILEGED_SO(so) ((so)->so_uidinfo->ui_uid == 0) |
192 | #endif /* __NetBSD__ */ |
193 | |
194 | /* |
195 | * 9. Raw socket list |
196 | * FreeBSD uses: listhead = rawcb_list, SLIST()-next field "list". |
197 | * NetBSD uses: listhead = rawcb, SLIST()-next field "list" |
198 | * |
199 | * This version of fast-ipsec source code uses rawcb_list as the head, |
200 | * and (to avoid namespace collisions) uses rcb_list as the "next" field. |
201 | */ |
202 | #ifdef __FreeBSD__ |
203 | #define rcb_list list |
204 | #endif /* __FreeBSD__ */ |
205 | #ifdef __NetBSD__ |
206 | #define rawcb_list rawcb |
207 | #endif /* __NetBSD__ */ |
208 | |
209 | |
210 | /* |
211 | * 10. List of all known network interfaces. |
212 | * FreeBSD has listhead in_ifaddrhead, with ia_link as link. |
213 | * NetBSD has listhead in_ifaddr, with ia_list as link. |
214 | * No name-clahses, so just #define the appropriate names on NetBSD. |
215 | * NB: Is it worth introducing iterator (find-first-list/find-next-list) |
216 | * functions or macros to encapsulate these? |
217 | */ |
218 | #ifdef __FreeBSD__ |
219 | /* nothing to do for raw interface list */ |
220 | #endif /* FreeBSD */ |
221 | #ifdef __NetBSD__ |
222 | #define ia_link ia_list |
223 | #endif /* __NetBSD__ */ |
224 | |
225 | /* |
226 | * 11. Type of initialization functions. |
227 | */ |
228 | #ifdef __FreeBSD__ |
229 | #define INITFN static |
230 | #endif |
231 | #ifdef __NetBSD__ |
232 | #define INITFN extern |
233 | #endif |
234 | |
235 | /* 12. On FreeBSD, ip_off assumed in host endian; |
236 | * it is converted (if necessary) by ip_input(). |
237 | * On NetBSD, ip_off is in network byte order. |
238 | * We hide the difference with the macro IP_OFF_CONVERT |
239 | */ |
240 | |
241 | #ifdef __FreeBSD__ |
242 | #define IP_OFF_CONVERT(x) (x) |
243 | #endif |
244 | |
245 | #ifdef __NetBSD__ |
246 | #define IP_OFF_CONVERT(x) (htons(x)) |
247 | #endif |
248 | |
249 | /* |
250 | * 13. IPv6 support, and "generic" inpcb vs. IPv4 pcb vs. IPv6 pcb. |
251 | * To IPv6 V4-mapped addresses (and the KAME-derived implementation |
252 | * of IPv6 v4-mapped addresses) we must support limited polymorphism: |
253 | * partway down the stack we detect an IPv6 protocol address is really |
254 | * a mapped V4 address, and then start dispatching that address to |
255 | * native IPv4 PCB lookup. In KAME-derived IPsec (including fas-ipsec) |
256 | * some functions must handle arguments which (dynamically) may be either |
257 | * a IPv4 pcb (struct inpcb *) or an IPv6 pcb (struct in6pcb *). |
258 | * |
259 | * In FreeBSD 4.x, sgtrucr in6pcb is syntactic sugar for struct inpcb, |
260 | * so punning between struct inpcb* and struct in6pcb* is trivial. |
261 | * NetBSD until recently used completely different structs for IPv4 |
262 | * and IPv6 PCBs. To simplify fast-ipsec coexisting with IPv6, |
263 | * NetBSD's struct inpcb and struct in6pcb were changed to both have |
264 | * common struct, struct inpcb_hdr, as their first member. NetBSD can |
265 | * thus pass arguments as struct inpcb_hdr*, and dispatch on a v4/v6 |
266 | * flag in the inpcb_hdr at runtime. |
267 | * |
268 | * We hide the NetBSD-vs-FreeBSD differences inside the following abstraction: |
269 | * |
270 | * PCB_T: a macro name for a struct type which is used as a "generic" |
271 | * argument for actual arguments an in4pcb or an in6pcb. |
272 | * |
273 | * PCB_FAMILY(p): given a "generic" pcb_t p, returns the protocol |
274 | * family (AF_INET, AF_INET6) of the unperlying inpcb/in6pcb. |
275 | * |
276 | * PCB_SOCKET(p): given a "generic" pcb_t p, returns the associated |
277 | * socket pointer |
278 | * |
279 | * PCB_TO_IN4PCB(p): given generic pcb_t *p, returns a struct inpcb * |
280 | * PCB_TO_IN6PCB(p): given generic pcb_t *p, returns a struct in6pcb * |
281 | * |
282 | * IN4PCB_TO_PCB(inp): given a struct inpcb *inp, returns a pcb_t * |
283 | * IN6PCB_TO_PCB(in6p): given a struct in6pcb *in6p, returns a pcb_t * |
284 | */ |
285 | #ifdef __FreeBSD__ |
286 | #define PCB_T struct inpcb |
287 | #define PCB_FAMILY(p) ((p)->inp_socket->so_proto->pr_domain->dom_family) |
288 | #define PCB_SOCKET(p) ((p)->inp_socket) |
289 | |
290 | /* Convert generic pcb to IPv4/IPv6 pcb */ |
291 | #define PCB_TO_IN4PCB(p) (p) |
292 | #define PCB_TO_IN6PCB(p) (p) |
293 | |
294 | /* Convert IPv4/IPv6 pcb to generic pcb, for callers of fast-ipsec */ |
295 | #define IN4PCB_TO_PCB(p) (p) |
296 | #define IN6PCB_TO_PCB(p) (p) |
297 | #endif /* __FreeBSD__ */ |
298 | |
299 | #ifdef __NetBSD__ |
300 | #define PCB_T struct inpcb_hdr |
301 | #define PCB_FAMILY(p) ((p)->inph_af) |
302 | #define PCB_SOCKET(p) ((p)->inph_socket) |
303 | |
304 | #define PCB_TO_IN4PCB(p) ((struct inpcb *)(p)) |
305 | #define PCB_TO_IN6PCB(p) ((struct in6pcb *)(p)) |
306 | |
307 | #define IN4PCB_TO_PCB(p) ((PCB_T *)(&(p)->inp_head)) |
308 | #define IN6PCB_TO_PCB(p) ((PCB_T *)(&(p)->in6p_head)) |
309 | #endif /* __NetBSD__ */ |
310 | |
311 | /* |
312 | * Differences that we don't attempt to hide: |
313 | * |
314 | * A. Initialization code. This is the largest difference of all. |
315 | * |
316 | * FreeBSD uses compile/link-time perl hackery to generate special |
317 | * .o files with linker sections that give the moral equivalent of |
318 | * C++ file-level-object constructors. NetBSD has no such facility. |
319 | * |
320 | * Either we implement it (ideally, in a way that can emulate |
321 | * FreeBSD's SYSINIT() macros), or we must take other means |
322 | * to have the per-file init functions called at some appropriate time. |
323 | * |
324 | * In the absence of SYSINIT(), all the file-level init functions |
325 | * now have "extern" linkage. There is a new fast-ipsec init() |
326 | * function which calls each of the per-file in an appropriate order. |
327 | * init_main will arrange to call the fast-ipsec init function |
328 | * after the crypto framework has registered its transforms (including |
329 | * any autoconfigured hardware crypto accelerators) but before |
330 | * initializing the network stack to send or receive packet. |
331 | * |
332 | * B. Protosw() differences. |
333 | * CSRG-style BSD TCP/IP uses a generic protocol-dispatch-function |
334 | * where the specific request is identified by an enum argument. |
335 | * FreeBSD replaced that with an array of request-specific |
336 | * function pointers. |
337 | * |
338 | * These differences affect the handlers for key-protocol user requests |
339 | * so pervasively that I gave up on the fast-ipsec code, and re-worked the |
340 | * NetBSD KAME code to match the (relative few) API differences |
341 | * between NetBSD and FreeBSD's KAME netkey, and Fast-IPsec netkey. |
342 | * |
343 | * C. Timeout() versus callout(9): |
344 | * The FreeBSD 4.x netipsec/ code still uses timeout(). |
345 | * FreeBSD 4.7 has callout(9), so I just replaced |
346 | * timeout_*() with the nearest callout_*() equivalents, |
347 | * and added a callout handle to the ipsec context. |
348 | * |
349 | * D. SPL name differences. |
350 | * FreeBSD splnet() equates directly to NetBSD's splsoftnet(); |
351 | * FreeBSD uses splimp() where (for networking) NetBSD would use splnet(). |
352 | */ |
353 | #endif /* _KERNEL */ |
354 | #endif /* !_NETIPSEC_OSDEP_H_ */ |
355 | |