summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/ipsec_osdep.h
blob: c1e11b49ca133d708877a8b9b4af06ace677c0a3 (plain)
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*	$FreeBSD$	*/
/*	$NetBSD: ipsec_osdep.h,v 1.1 2003/08/13 20:06:51 jonathan Exp $	*/

/*-
 * Copyright (c) 2003 Jonathan Stone (jonathan@cs.stanford.edu)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef NETIPSEC_OSDEP_H
#define NETIPSEC_OSDEP_H

/* 
 *  Hide porting differences across different 4.4BSD-derived platforms.
 * 
 * 1.  KASSERT() differences: 
 * 2.  Kernel  Random-number API differences.
 * 3.  Is packet data in an mbuf object writeable?
 * 4.  Packet-header semantics.
 * 5.  Fast mbuf-cluster allocation.
 * 6.  Network packet-output macros.
 * 7.  Elased time, in seconds.
 * 8.  Test if a  socket object opened by  a privileged (super) user.
 * 9.  Global SLIST of all open raw sockets.
 * 10. Global SLIST of known interface addresses.
 */

/*
 *  1. KASSERT and spl differences 
 *
 * FreeBSD takes an expression and  parenthesized printf() argument-list.
 * NetBSD takes one arg: the expression being asserted.
 * FreeBSD's SPLASSERT() takes an SPL level as 1st arg and a
 * parenthesized printf-format argument list as the second argument.
 *
 * This difference is hidden by two 2-argument macros and one 1-arg macro:
 *    IPSEC_ASSERT(expr, msg)
 *    IPSEC_SPLASSERT(spl, msg)
 * One further difference is the spl names:
 *    NetBSD splsoftnet equates to FreeBSD splnet;
 *    NetBSD splnet equates to FreeBSD splimp.
 * which is hidden by the macro IPSEC_SPLASSERT_SOFTNET(msg).
 */
#ifdef __FreeBSD__
#if __FreeBSD_version < 500000
#define IPSEC_SPLASSERT(_x,_y) SPLASSERT(_x, _y)
#else
#define IPSEC_SPLASSERT(_x,_y)
#endif
#define IPSEC_SPLASSERT_SOFTNET(_m) IPSEC_SPLASSERT(net,_m)
#define IPSEC_ASSERT(_c,_m) KASSERT(_c, _m)
#endif	/* __FreeBSD__ */

#ifdef	__NetBSD__
#define IPSEC_SPLASSERT(x,y) (void)0
#define IPSEC_ASSERT(c,m) KASSERT(c)
#define IPSEC_SPLASSERT_SOFTNET(m) IPSEC_SPLASSERT(softnet, m)
#endif	/* __NetBSD__ */

/*
 * 2. Kernel Randomness API.
 * FreeBSD uses:
 *    u_int read_random(void *outbuf, int nbytes).
 */
#ifdef __FreeBSD__
#include <sys/random.h>
/* do nothing, use native random code. */
#endif /* __FreeBSD__ */

#ifdef	__NetBSD__
#include <sys/rnd.h>
static __inline u_int read_random(void *p, u_int len);

static __inline u_int
read_random(void *bufp, u_int len) 
{ 
	return rnd_extract_data(bufp, len, RND_EXTRACT_ANY /*XXX FIXME */);
}
#endif	/* __NetBSD__ */

/*
 * 3. Test for mbuf mutability
 * FreeBSD 4.x uses: M_EXT_WRITABLE
 * NetBSD has M_READONLY(). Use !M_READONLY().
 * Not an exact match to FreeBSD semantics, but adequate for IPsec purposes.
 * 
 */
#ifdef __NetBSD__
/* XXX wrong, but close enough for restricted ipsec usage. */
#define M_EXT_WRITABLE(m) (!M_READONLY(m))
#endif	/* __NetBSD__ */

/*
 * 4. mbuf packet-header/packet-tag semantics.
 * Sam Leffler explains, in private email, some problems with
 * M_COPY_PKTHDR(), and why FreeBSD deprecated it and replaced it
 * with new, explicit macros M_MOVE_PKTHDR()/M_DUP_PKTHDR().
 * he original fast-ipsec source uses M_MOVE_PKTHDR.
 * NetBSD currently still uses M_COPY_PKTHDR(), so we define
 * M_MOVE_PKTHDR in terms of M_COPY_PKTHDR().  Fast-IPsec
 * will delete the source mbuf shortly after copying packet tags,
 * so we are safe for fast-ipsec but not in general..
 */
#ifdef __NetBSD__
#define M_MOVE_PKTHDR(_f, _t) M_COPY_PKTHDR(_f, _t)
#endif /* __NetBSD__ */


/*
 * 5. Fast mbuf-cluster allocation.
 * FreeBSD 4.6 introduce m_getcl(), which performs `fast' allocation
 * mbuf clusters from a cache of recently-freed clusters. (If the  cache
 * is empty, new clusters are allocated en-masse).
 *   On NetBSD, for now, implement the `cache' as an inline  function
 *using normal NetBSD mbuf/cluster allocation macros. Replace this
 * with fast-cache code, if and when netBSD  implements one.
 */
#ifdef __NetBSD__
static __inline struct mbuf *
m_getcl(int how, short type, int flags)
{
	struct mbuf *mp;
	if (flags & M_PKTHDR) 
		MGETHDR(mp, how, type);
	else
		MGET(mp, how,  type);
	if (mp == NULL)
		return NULL;

	MCLGET(mp, how);
	return mp;
}
#endif /* __NetBSD__ */

/*
 * 6. Network output macros
 * FreeBSD uses the  IF_HANDOFF(), which raises SPL, enqueues
 * a packet, and updates interface counters. NetBSD has IFQ_ENQUE(),
 * which leaves SPL changes up to the caller. 
 * For now, we provide an emulation of IF_HANOOFF() which works
 * for protocol input queues.
 */
#ifdef __FreeBSD__ 
/* nothing to do */
#endif /* __FreeBSD__ */
#ifdef __NetBSD__
#define IF_HANDOFF(ifq, m, f) if_handoff(ifq, m, f, 0)
  
#include <net/if.h>

static __inline int
if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
{
	int need_if_start = 0;
	int s = splnet();

	if (IF_QFULL(ifq)) {
		IF_DROP(ifq);
		splx(s);
		m_freem(m);
		return (0);
	}
	if (ifp != NULL) {
		ifp->if_obytes += m->m_pkthdr.len + adjust;
		if (m->m_flags & M_MCAST)
			ifp->if_omcasts++;
		need_if_start = !(ifp->if_flags & IFF_OACTIVE);
	}
	IF_ENQUEUE(ifq, m);
	if (need_if_start)
		(*ifp->if_start)(ifp);
	splx(s);
	return (1);
}
#endif /* __NetBSD__ */

/*
 * 7. Elapsed Time: time_second as time in seconds.
 * Original FreeBSD fast-ipsec code references a FreeBSD kernel global,
 * time_second().  NetBSD: kludge #define to use time_mono_time.tv_sec.
 */
#ifdef __NetBSD__
#include <sys/kernel.h>
#define time_second mono_time.tv_sec
#endif	/* __NetBSD__ */

/* protosw glue */
#ifdef __NetBSD__
#include <sys/protosw.h>
#define ipprotosw protosw
#endif	/* __NetBSD__ */

/*
 * 8. Test for "privileged" socket opened by superuser.
 * FreeBSD tests  ((so)->so_cred != NULL && priv_check_cred((so)->so_cred,
 * PRIV_NETINET_IPSEC, SUSER_ALLOWJAIL) == 0).
 * NetBSD (1.6N) tests (so)->so_uid == 0).
 * This difference is wrapped inside  the IPSEC_PRIVILEGED_SO() macro.
 *
 * XXXRW: Why was this suser_allowjail?
 */
#ifdef __FreeBSD__ 
#define IPSEC_IS_PRIVILEGED_SO(_so) \
	((_so)->so_cred != NULL && \
	 priv_check_cred((_so)->so_cred, PRIV_NETINET_IPSEC, 0) \
	 == 0)
#endif	/* __FreeBSD__ */

#ifdef __NetBSD__
/* superuser opened socket? */
#define IPSEC_IS_PRIVILEGED_SO(so) ((so)->so_uid == 0)
#endif	/* __NetBSD__ */

/*
 * 9. Raw socket list
 * FreeBSD uses: listhead = rawcb_list, SLIST()-next field "list".
 * NetBSD  uses: listhead = rawcb, SLIST()-next field "list"
 *
 * This version of fast-ipsec source code  uses rawcb_list as the head,
 *  and (to avoid namespace collisions) uses rcb_list as the "next" field.
 */
#ifdef __FreeBSD__
#define rcb_list list
#endif /* __FreeBSD__ */
#ifdef __NetBSD__
#define rawcb_list rawcb
#endif	/* __NetBSD__ */


/*
 * 10. List of all known network interfaces.
 * FreeBSD has listhead in_ifaddread, with ia_link as link.
 * NetBSD has listhead in_ifaddr, with ia_list as link.
 * No name-clahses, so just #define the appropriate names on NetBSD.
 * NB: Is it worth introducing iterator (find-first-list/find-next-list)
 * functions or macros to encapsulate these?
 */
#ifdef __FreeBSD__
/* nothing to do for raw interface list */
#endif	/* FreeBSD */
#ifdef __NetBSD__
/* For now, use FreeBSD-compatible names for raw interface list. */
#define in_ifaddrhead in_ifaddr
#define ia_link ia_list
#endif	/* __NetBSD__ */




/*
 * Differences that we don't attempt to hide:
 *
 * A. Initialization code.  This  is the largest difference of all.
 *
 *   FreeBSD uses compile/link-time perl hackery to generate special 
 * .o files  with linker sections  that give the moral equivalent of
 * C++ file-level-object constructors. NetBSD has no such facility.
 *
 * Either we implement it (ideally, in a way that can emulate
 * FreeBSD's SYSINIT() macros), or we must take other means
 * to have the per-file init functions called at some appropriate time.
 *
 * In the absence of SYSINIT(), all the file-level init functions
 * now have "extern" linkage. There is a new fast-ipsec init()
 * function which calls each of the per-file in an appropriate order. 
 * init_main will arrange to call the fast-ipsec init function
 * after the crypto framework has registered its transforms (including
 * any autoconfigured hardware crypto  accelerators) but before
 * initializing the network stack to send or receive  packet.
 *
 * B. Protosw() differences. 
 * CSRG-style BSD TCP/IP uses a generic protocol-dispatch-function
 * where the specific request is identified by an enum argument.
 * FreeBSD replaced that with an array of request-specific
 * function pointers.
 *
 * These differences affect the handlers for key-protocol user requests
 * so pervasively that I gave up on the fast-ipsec code, and re-worked the
 * NetBSD KAME code to match the (relative few) API differences
 * between NetBSD and FreeBSD's KAME netkey, and Fast-IPsec netkey.
 *
 * C. Timeout() versus callout(9):
 * The FreeBSD 4.x netipsec/ code still uses timeout().
 * FreeBSD 4.7 has callout(9), so I just replaced 
 * timeout_*() with the nearest callout_*() equivalents,
 * and added a callout handle to the ipsec context.
 *
 * D. SPL name differences.
 * FreeBSD splnet() equates directly to NetBSD's splsoftnet();
 * FreeBSD uses splimp() where (for networking) NetBSD would use splnet().
 */
#endif /* NETIPSEC_OSDEP_H */
OpenPOWER on IntegriCloud