Home | History | Annotate | Line # | Download | only in sys
      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 
     60 struct mbuf;
     61 struct ifnet;
     62 struct sockaddr;
     63 struct socket;
     64 struct sockopt;
     65 struct stat;
     66 struct domain;
     67 struct proc;
     68 struct lwp;
     69 struct pr_usrreqs;
     70 
     71 struct 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
    164 static 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
    207 static 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
    231 static const char * const prcorequests[] = {
    232 	"GETOPT", "SETOPT",
    233 };
    234 #endif
    235 
    236 #ifdef _KERNEL
    237 
    238 struct 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  */
    264 extern	u_int pfslowtimo_now;
    265 extern	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 
    279 struct sockaddr;
    280 const struct protosw *pffindproto(int, int, int);
    281 const struct protosw *pffindtype(int, int);
    282 struct domain *pffinddomain(int);
    283 void pfctlinput(int, const struct sockaddr *);
    284 void 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)				\
    292 static int						\
    293 name##_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 }							\
    301 static void						\
    302 name##_detach_wrapper(struct socket *a)			\
    303 {							\
    304 	KERNEL_LOCK(1, NULL);				\
    305 	name##_detach(a);				\
    306 	KERNEL_UNLOCK_ONE(NULL);			\
    307 }							\
    308 static int						\
    309 name##_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 }							\
    318 static int						\
    319 name##_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 }							\
    328 static int						\
    329 name##_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 }							\
    338 static int						\
    339 name##_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 }							\
    348 static int						\
    349 name##_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 }							\
    357 static int						\
    358 name##_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 }							\
    366 static int						\
    367 name##_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 }							\
    375 static int						\
    376 name##_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 }							\
    384 static int						\
    385 name##_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 }							\
    394 static int						\
    395 name##_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 }							\
    403 static int						\
    404 name##_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 }							\
    413 static int						\
    414 name##_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 }							\
    423 static int						\
    424 name##_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 }							\
    433 static int						\
    434 name##_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 }							\
    443 static int						\
    444 name##_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 }							\
    453 static int						\
    454 name##_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 }							\
    463 static int						\
    464 name##_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)				\
    475 static int						\
    476 name##_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)				\
    487 static void *						\
    488 name##_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)				\
    500 static void						\
    501 name##_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_ */
    511