master
  1/*	$NetBSD: protosw.h,v 1.69 2018/09/14 05:09:51 maxv Exp $	*/
  2
  3/*-
  4 * Copyright (c) 1982, 1986, 1993
  5 *	The Regents of the University of California.  All rights reserved.
  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 * 3. Neither the name of the University nor the names of its contributors
 16 *    may be used to endorse or promote products derived from this software
 17 *    without specific prior written permission.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 29 * SUCH DAMAGE.
 30 *
 31 *	@(#)protosw.h	8.1 (Berkeley) 6/2/93
 32 */
 33
 34#ifndef _SYS_PROTOSW_H_
 35#define _SYS_PROTOSW_H_
 36
 37/*
 38 * Protocol switch table.
 39 *
 40 * Each protocol has a handle initializing one of these structures,
 41 * which is used for protocol-protocol and system-protocol communication.
 42 *
 43 * A protocol is called through the pr_init entry before any other.
 44 * Thereafter it is called every 200ms through the pr_fasttimo entry and
 45 * every 500ms through the pr_slowtimo for timer based actions.
 46 * The system will call the pr_drain entry if it is low on space and
 47 * this should throw away any non-critical data.
 48 *
 49 * Protocols pass data between themselves as chains of mbufs using
 50 * the pr_input and pr_output hooks.  Pr_input passes data up (towards
 51 * UNIX) and pr_output passes it down (towards the imps); control
 52 * information passes up and down on pr_ctlinput and pr_ctloutput.
 53 * The protocol is responsible for the space occupied by any the
 54 * arguments to these entries and must dispose it.
 55 *
 56 * The userreq routine interfaces protocols to the system and is
 57 * described below.
 58 */
 59
 60struct mbuf;
 61struct ifnet;
 62struct sockaddr;
 63struct socket;
 64struct sockopt;
 65struct stat;
 66struct domain;
 67struct proc;
 68struct lwp;
 69struct pr_usrreqs;
 70
 71struct protosw {
 72	int 	pr_type;		/* socket type used for */
 73	struct	domain *pr_domain;	/* domain protocol a member of */
 74	short	pr_protocol;		/* protocol number */
 75	short	pr_flags;		/* see below */
 76
 77/* protocol-protocol hooks */
 78	void	(*pr_input)		/* input to protocol (from below) */
 79			(struct mbuf *, int, int);
 80	void	*(*pr_ctlinput)		/* control input (from below) */
 81			(int, const struct sockaddr *, void *);
 82	int	(*pr_ctloutput)		/* control output (from above) */
 83			(int, struct socket *, struct sockopt *);
 84
 85/* user-protocol hooks */
 86	const struct pr_usrreqs *pr_usrreqs;
 87
 88/* utility hooks */
 89	void	(*pr_init)		/* initialization hook */
 90			(void);
 91
 92	void	(*pr_fasttimo)		/* fast timeout (200ms) */
 93			(void);
 94	void	(*pr_slowtimo)		/* slow timeout (500ms) */
 95			(void);
 96	void	(*pr_drain)		/* flush any excess space possible */
 97			(void);
 98};
 99
100#define	PR_SLOWHZ	2		/* 2 slow timeouts per second */
101#define	PR_FASTHZ	5		/* 5 fast timeouts per second */
102
103/*
104 * Values for pr_flags.
105 * PR_ADDR requires PR_ATOMIC;
106 * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
107 */
108#define	PR_ATOMIC	0x01		/* exchange atomic messages only */
109#define	PR_ADDR		0x02		/* addresses given with messages */
110#define	PR_CONNREQUIRED	0x04		/* connection required by protocol */
111#define	PR_WANTRCVD	0x08		/* want pr_rcvd() calls */
112#define	PR_RIGHTS	0x10		/* passes capabilities */
113#define	PR_LISTEN	0x20		/* supports listen(2) and accept(2) */
114#define	PR_LASTHDR	0x40		/* enforce ipsec policy; last header */
115#define	PR_ABRTACPTDIS	0x80		/* abort on accept(2) to disconnected
116					   socket */
117#define PR_PURGEIF	0x100		/* might store struct ifnet pointer;
118					   pr_purgeif() must be called on ifnet
119					   deletion */
120#define	PR_ADDR_OPT	0x200		/* Allow address during delivery */
121
122
123/*
124 * The arguments to usrreq are:
125 *	(*protosw[].pr_usrreq)(up, req, m, nam, opt, p);
126 * where up is a (struct socket *), req is one of these requests,
127 * m is a optional mbuf chain containing a message,
128 * nam is an optional mbuf chain containing an address,
129 * opt is an optional mbuf containing socket options,
130 * and p is a pointer to the process requesting the action (if any).
131 * The protocol is responsible for disposal of the mbuf chains m and opt,
132 * the caller is responsible for any space held by nam.
133 * A non-zero return from usrreq gives an
134 * UNIX error number which should be passed to higher level software.
135 */
136#define	PRU_ATTACH		0	/* attach protocol to up */
137#define	PRU_DETACH		1	/* detach protocol from up */
138#define	PRU_BIND		2	/* bind socket to address */
139#define	PRU_LISTEN		3	/* listen for connection */
140#define	PRU_CONNECT		4	/* establish connection to peer */
141#define	PRU_ACCEPT		5	/* accept connection from peer */
142#define	PRU_DISCONNECT		6	/* disconnect from peer */
143#define	PRU_SHUTDOWN		7	/* won't send any more data */
144#define	PRU_RCVD		8	/* have taken data; more room now */
145#define	PRU_SEND		9	/* send this data */
146#define	PRU_ABORT		10	/* abort (fast DISCONNECT, DETACH) */
147#define	PRU_CONTROL		11	/* control operations on protocol */
148#define	PRU_SENSE		12	/* return status into m */
149#define	PRU_RCVOOB		13	/* retrieve out of band data */
150#define	PRU_SENDOOB		14	/* send out of band data */
151#define	PRU_SOCKADDR		15	/* fetch socket's address */
152#define	PRU_PEERADDR		16	/* fetch peer's address */
153#define	PRU_CONNECT2		17	/* connect two sockets */
154/* begin for protocols internal use */
155#define	PRU_FASTTIMO		18	/* 200ms timeout */
156#define	PRU_SLOWTIMO		19	/* 500ms timeout */
157#define	PRU_PROTORCV		20	/* receive from below */
158#define	PRU_PROTOSEND		21	/* send to below */
159#define	PRU_PURGEIF		22	/* purge specified if */
160
161#define	PRU_NREQ		23
162
163#ifdef PRUREQUESTS
164static const char * const prurequests[] = {
165	"ATTACH",	"DETACH",	"BIND",		"LISTEN",
166	"CONNECT",	"ACCEPT",	"DISCONNECT",	"SHUTDOWN",
167	"RCVD",		"SEND",		"ABORT",	"CONTROL",
168	"SENSE",	"RCVOOB",	"SENDOOB",	"SOCKADDR",
169	"PEERADDR",	"CONNECT2",	"FASTTIMO",	"SLOWTIMO",
170	"PROTORCV",	"PROTOSEND",	"PURGEIF",
171};
172#endif
173
174/*
175 * The arguments to the ctlinput routine are
176 *	(*protosw[].pr_ctlinput)(cmd, sa, arg);
177 * where cmd is one of the commands below, sa is a pointer to a sockaddr,
178 * and arg is an optional void *argument used within a protocol family.
179 */
180#define	PRC_IFDOWN		0	/* interface transition */
181#define	PRC_ROUTEDEAD		1	/* select new route if possible ??? */
182#define	PRC_QUENCH2		3	/* DEC congestion bit says slow down */
183#define	PRC_QUENCH		4	/* some one said to slow down */
184#define	PRC_MSGSIZE		5	/* message size forced drop */
185#define	PRC_HOSTDEAD		6	/* host appears to be down */
186#define	PRC_HOSTUNREACH		7	/* deprecated (use PRC_UNREACH_HOST) */
187#define	PRC_UNREACH_NET		8	/* no route to network */
188#define	PRC_UNREACH_HOST	9	/* no route to host */
189#define	PRC_UNREACH_PROTOCOL	10	/* dst says bad protocol */
190#define	PRC_UNREACH_PORT	11	/* bad port # */
191/* was	PRC_UNREACH_NEEDFRAG	12	   (use PRC_MSGSIZE) */
192#define	PRC_UNREACH_SRCFAIL	13	/* source route failed */
193#define	PRC_REDIRECT_NET	14	/* net routing redirect */
194#define	PRC_REDIRECT_HOST	15	/* host routing redirect */
195#define	PRC_REDIRECT_TOSNET	16	/* redirect for type of service & net */
196#define	PRC_REDIRECT_TOSHOST	17	/* redirect for tos & host */
197#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
198#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
199#define	PRC_PARAMPROB		20	/* header incorrect */
200
201#define	PRC_NCMDS		21
202
203#define	PRC_IS_REDIRECT(cmd)	\
204	((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
205
206#ifdef PRCREQUESTS
207static const char * const prcrequests[] = {
208	"IFDOWN", "ROUTEDEAD", "#2", "DEC-BIT-QUENCH2",
209	"QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
210	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
211	"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
212	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
213	"PARAMPROB"
214};
215#endif
216
217/*
218 * The arguments to ctloutput are:
219 *	(*protosw[].pr_ctloutput)(req, so, sopt);
220 * req is one of the actions listed below, so is a (struct socket *),
221 * sopt is a (struct sockopt *)
222 * A non-zero return from usrreq gives an
223 * UNIX error number which should be passed to higher level software.
224 */
225#define	PRCO_GETOPT	0
226#define	PRCO_SETOPT	1
227
228#define	PRCO_NCMDS	2
229
230#ifdef PRCOREQUESTS
231static const char * const prcorequests[] = {
232	"GETOPT", "SETOPT",
233};
234#endif
235
236#ifdef _KERNEL
237
238struct pr_usrreqs {
239	int	(*pr_attach)(struct socket *, int);
240	void	(*pr_detach)(struct socket *);
241	int	(*pr_accept)(struct socket *, struct sockaddr *);
242	int	(*pr_connect)(struct socket *, struct sockaddr *, struct lwp *);
243	int	(*pr_connect2)(struct socket *, struct socket *);
244	int	(*pr_bind)(struct socket *, struct sockaddr *, struct lwp *);
245	int	(*pr_listen)(struct socket *, struct lwp *);
246	int	(*pr_disconnect)(struct socket *);
247	int	(*pr_shutdown)(struct socket *);
248	int	(*pr_abort)(struct socket *);
249	int	(*pr_ioctl)(struct socket *, u_long, void *, struct ifnet *);
250	int	(*pr_stat)(struct socket *, struct stat *);
251	int	(*pr_peeraddr)(struct socket *, struct sockaddr *);
252	int	(*pr_sockaddr)(struct socket *, struct sockaddr *);
253	int	(*pr_rcvd)(struct socket *, int, struct lwp *);
254	int	(*pr_recvoob)(struct socket *, struct mbuf *, int);
255	int	(*pr_send)(struct socket *, struct mbuf *, struct sockaddr *,
256	    struct mbuf *, struct lwp *);
257	int	(*pr_sendoob)(struct socket *, struct mbuf *, struct mbuf *);
258	int	(*pr_purgeif)(struct socket *, struct ifnet *);
259};
260
261/*
262 * Monotonically increasing time values for slow and fast timers.
263 */
264extern	u_int pfslowtimo_now;
265extern	u_int pffasttimo_now;
266
267#define	PRT_SLOW_ARM(t, nticks)	(t) = (pfslowtimo_now + (nticks))
268#define	PRT_FAST_ARM(t, nticks)	(t) = (pffasttimo_now + (nticks))
269
270#define	PRT_SLOW_DISARM(t)	(t) = 0
271#define	PRT_FAST_DISARM(t)	(t) = 0
272
273#define	PRT_SLOW_ISARMED(t)	((t) != 0)
274#define	PRT_FAST_ISARMED(t)	((t) != 0)
275
276#define	PRT_SLOW_ISEXPIRED(t)	(PRT_SLOW_ISARMED((t)) && (t) <= pfslowtimo_now)
277#define	PRT_FAST_ISEXPIRED(t)	(PRT_FAST_ISARMED((t)) && (t) <= pffasttimo_now)
278
279struct sockaddr;
280const struct protosw *pffindproto(int, int, int);
281const struct protosw *pffindtype(int, int);
282struct domain *pffinddomain(int);
283void pfctlinput(int, const struct sockaddr *);
284void pfctlinput2(int, const struct sockaddr *, void *);
285
286/*
287 * Wrappers for non-MPSAFE protocols
288 */
289#include <sys/systm.h>	/* kernel_lock */
290
291#define	PR_WRAP_USRREQS(name)				\
292static int						\
293name##_attach_wrapper(struct socket *a, int b)		\
294{							\
295	int rv;						\
296	KERNEL_LOCK(1, NULL);				\
297	rv = name##_attach(a, b);			\
298	KERNEL_UNLOCK_ONE(NULL);			\
299	return rv;					\
300}							\
301static void						\
302name##_detach_wrapper(struct socket *a)			\
303{							\
304	KERNEL_LOCK(1, NULL);				\
305	name##_detach(a);				\
306	KERNEL_UNLOCK_ONE(NULL);			\
307}							\
308static int						\
309name##_accept_wrapper(struct socket *a,			\
310    struct sockaddr *b)					\
311{							\
312	int rv;						\
313	KERNEL_LOCK(1, NULL);				\
314	rv = name##_accept(a, b);			\
315	KERNEL_UNLOCK_ONE(NULL);			\
316	return rv;					\
317}							\
318static int						\
319name##_bind_wrapper(struct socket *a,			\
320    struct sockaddr *b,	struct lwp *c)			\
321{							\
322	int rv;						\
323	KERNEL_LOCK(1, NULL);				\
324	rv = name##_bind(a, b, c);			\
325	KERNEL_UNLOCK_ONE(NULL);			\
326	return rv;					\
327}							\
328static int						\
329name##_connect_wrapper(struct socket *a,		\
330    struct sockaddr *b, struct lwp *c)			\
331{							\
332	int rv;						\
333	KERNEL_LOCK(1, NULL);				\
334	rv = name##_connect(a, b, c);			\
335	KERNEL_UNLOCK_ONE(NULL);			\
336	return rv;					\
337}							\
338static int						\
339name##_connect2_wrapper(struct socket *a,		\
340    struct socket *b)					\
341{							\
342	int rv;						\
343	KERNEL_LOCK(1, NULL);				\
344	rv = name##_connect2(a, b);			\
345	KERNEL_UNLOCK_ONE(NULL);			\
346	return rv;					\
347}							\
348static int						\
349name##_listen_wrapper(struct socket *a, struct lwp *b)	\
350{							\
351	int rv;						\
352	KERNEL_LOCK(1, NULL);				\
353	rv = name##_listen(a, b);			\
354	KERNEL_UNLOCK_ONE(NULL);			\
355	return rv;					\
356}							\
357static int						\
358name##_disconnect_wrapper(struct socket *a)		\
359{							\
360	int rv;						\
361	KERNEL_LOCK(1, NULL);				\
362	rv = name##_disconnect(a);			\
363	KERNEL_UNLOCK_ONE(NULL);			\
364	return rv;					\
365}							\
366static int						\
367name##_shutdown_wrapper(struct socket *a)		\
368{							\
369	int rv;						\
370	KERNEL_LOCK(1, NULL);				\
371	rv = name##_shutdown(a);			\
372	KERNEL_UNLOCK_ONE(NULL);			\
373	return rv;					\
374}							\
375static int						\
376name##_abort_wrapper(struct socket *a)			\
377{							\
378	int rv;						\
379	KERNEL_LOCK(1, NULL);				\
380	rv = name##_abort(a);				\
381	KERNEL_UNLOCK_ONE(NULL);			\
382	return rv;					\
383}							\
384static int						\
385name##_ioctl_wrapper(struct socket *a, u_long b,	\
386    void *c, struct ifnet *d)				\
387{							\
388	int rv;						\
389	KERNEL_LOCK(1, NULL);				\
390	rv = name##_ioctl(a, b, c, d);			\
391	KERNEL_UNLOCK_ONE(NULL);			\
392	return rv;					\
393}							\
394static int						\
395name##_stat_wrapper(struct socket *a, struct stat *b)	\
396{							\
397	int rv;						\
398	KERNEL_LOCK(1, NULL);				\
399	rv = name##_stat(a, b);				\
400	KERNEL_UNLOCK_ONE(NULL);			\
401	return rv;					\
402}							\
403static int						\
404name##_peeraddr_wrapper(struct socket *a,		\
405    struct sockaddr *b)					\
406{							\
407	int rv;						\
408	KERNEL_LOCK(1, NULL);				\
409	rv = name##_peeraddr(a, b);			\
410	KERNEL_UNLOCK_ONE(NULL);			\
411	return rv;					\
412}							\
413static int						\
414name##_sockaddr_wrapper(struct socket *a,		\
415    struct sockaddr *b)					\
416{							\
417	int rv;						\
418	KERNEL_LOCK(1, NULL);				\
419	rv = name##_sockaddr(a, b);			\
420	KERNEL_UNLOCK_ONE(NULL);			\
421	return rv;					\
422}							\
423static int						\
424name##_rcvd_wrapper(struct socket *a, int b,		\
425    struct lwp *c)					\
426{							\
427	int rv;						\
428	KERNEL_LOCK(1, NULL);				\
429	rv = name##_rcvd(a, b, c);			\
430	KERNEL_UNLOCK_ONE(NULL);			\
431	return rv;					\
432}							\
433static int						\
434name##_recvoob_wrapper(struct socket *a,		\
435    struct mbuf *b, int c)				\
436{							\
437	int rv;						\
438	KERNEL_LOCK(1, NULL);				\
439	rv = name##_recvoob(a, b, c);			\
440	KERNEL_UNLOCK_ONE(NULL);			\
441	return rv;					\
442}							\
443static int						\
444name##_send_wrapper(struct socket *a, struct mbuf *b,	\
445    struct sockaddr *c, struct mbuf *d, struct lwp *e)	\
446{							\
447	int rv;						\
448	KERNEL_LOCK(1, NULL);				\
449	rv = name##_send(a, b, c, d, e);		\
450	KERNEL_UNLOCK_ONE(NULL);			\
451	return rv;					\
452}							\
453static int						\
454name##_sendoob_wrapper(struct socket *a,		\
455    struct mbuf *b, struct mbuf *c)			\
456{							\
457	int rv;						\
458	KERNEL_LOCK(1, NULL);				\
459	rv = name##_sendoob(a, b, c);			\
460	KERNEL_UNLOCK_ONE(NULL);			\
461	return rv;					\
462}							\
463static int						\
464name##_purgeif_wrapper(struct socket *a,		\
465    struct ifnet *b)					\
466{							\
467	int rv;						\
468	KERNEL_LOCK(1, NULL);				\
469	rv = name##_purgeif(a, b);			\
470	KERNEL_UNLOCK_ONE(NULL);			\
471	return rv;					\
472}
473
474#define	PR_WRAP_CTLOUTPUT(name)				\
475static int						\
476name##_wrapper(int a, struct socket *b,			\
477    struct sockopt *c)					\
478{							\
479	int rv;						\
480	KERNEL_LOCK(1, NULL);				\
481	rv = name(a, b, c);				\
482	KERNEL_UNLOCK_ONE(NULL);			\
483	return rv;					\
484}
485
486#define	PR_WRAP_CTLINPUT(name)				\
487static void *						\
488name##_wrapper(int a, const struct sockaddr *b, void *c)\
489{							\
490	void *rv;					\
491	KERNEL_LOCK(1, NULL);				\
492	rv = name(a, b, c);				\
493	KERNEL_UNLOCK_ONE(NULL);			\
494	return rv;					\
495}
496
497#include <sys/socketvar.h> /* for softnet_lock */
498
499#define	PR_WRAP_INPUT(name)				\
500static void						\
501name##_wrapper(struct mbuf *m, int off, int proto)	\
502{							\
503	mutex_enter(softnet_lock);			\
504	name(m, off, proto);				\
505	mutex_exit(softnet_lock);			\
506}
507
508#endif /* _KERNEL */
509
510#endif /* !_SYS_PROTOSW_H_ */