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