xref: /titanic_53/usr/src/uts/common/inet/optcom.h (revision 0f1702c5201310f0529cd5abb77652e5e9b241b6)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*0f1702c5SYu Xiangning  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate /* Copyright (c) 1990 Mentat Inc. */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #ifndef	_INET_OPTCOM_H
287c478bd9Sstevel@tonic-gate #define	_INET_OPTCOM_H
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
317c478bd9Sstevel@tonic-gate extern "C" {
327c478bd9Sstevel@tonic-gate #endif
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #if defined(_KERNEL) && defined(__STDC__)
357c478bd9Sstevel@tonic-gate 
36*0f1702c5SYu Xiangning #include <inet/ipclassifier.h>
377c478bd9Sstevel@tonic-gate /* Options Description Structure */
387c478bd9Sstevel@tonic-gate typedef struct opdes_s {
397c478bd9Sstevel@tonic-gate 	t_uscalar_t	opdes_name;	/* option name */
407c478bd9Sstevel@tonic-gate 	t_uscalar_t	opdes_level;	/* option "level" */
417c478bd9Sstevel@tonic-gate 	int	opdes_access_nopriv;	/* permissions for non-privileged */
427c478bd9Sstevel@tonic-gate 	int	opdes_access_priv;	/* permissions for privileged */
437c478bd9Sstevel@tonic-gate 	int	opdes_access_req_priv;	/* required privilege, OP_NP if none */
447c478bd9Sstevel@tonic-gate 	int	opdes_props;	/* properties of associated with option */
457c478bd9Sstevel@tonic-gate 	t_uscalar_t	opdes_size;	/* length of option */
467c478bd9Sstevel@tonic-gate 					/* [ or maxlen if variable */
477c478bd9Sstevel@tonic-gate 			/* length(OP_VARLEN) property set for option] */
487c478bd9Sstevel@tonic-gate 	union {
497c478bd9Sstevel@tonic-gate 		/*
507c478bd9Sstevel@tonic-gate 		 *
517c478bd9Sstevel@tonic-gate 		 * Note: C semantics:
527c478bd9Sstevel@tonic-gate 		 * static initializer of "union" type assume
537c478bd9Sstevel@tonic-gate 		 * the constant on RHS is of the type of the
547c478bd9Sstevel@tonic-gate 		 * first member of the union. So what comes first
557c478bd9Sstevel@tonic-gate 		 * is important.
567c478bd9Sstevel@tonic-gate 		 */
577c478bd9Sstevel@tonic-gate #define	OPDES_DEFSZ_MAX		64
587c478bd9Sstevel@tonic-gate 		int64_t  opdes_def_int64;
597c478bd9Sstevel@tonic-gate 		char	opdes_def_charbuf[OPDES_DEFSZ_MAX];
607c478bd9Sstevel@tonic-gate 	} opdes_def;
617c478bd9Sstevel@tonic-gate } opdes_t;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate #define	opdes_default	opdes_def.opdes_def_int64
647c478bd9Sstevel@tonic-gate #define	opdes_defbuf	opdes_def.opdes_def_charbuf
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * Flags to set in opdes_acces_{all,priv} fields in opdes_t
677c478bd9Sstevel@tonic-gate  *
687c478bd9Sstevel@tonic-gate  *	OA_R	read access
697c478bd9Sstevel@tonic-gate  *	OA_W	write access
707c478bd9Sstevel@tonic-gate  *	OA_RW	read-write access
717c478bd9Sstevel@tonic-gate  *	OA_X	execute access
727c478bd9Sstevel@tonic-gate  *
737c478bd9Sstevel@tonic-gate  * Note: - semantics "execute" access used for operations excuted using
747c478bd9Sstevel@tonic-gate  *		option management interface
757c478bd9Sstevel@tonic-gate  *	- no bits set means this option is not visible. Some options may not
767c478bd9Sstevel@tonic-gate  *	  even be visible to all but priviliged users.
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate #define	OA_R	0x1
797c478bd9Sstevel@tonic-gate #define	OA_W	0x2
807c478bd9Sstevel@tonic-gate #define	OA_X	0x4
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * Utility macros to test permissions needed to compose more
847c478bd9Sstevel@tonic-gate  * complex ones. (Only a few really used directly in code).
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate #define	OA_RW	(OA_R|OA_W)
877c478bd9Sstevel@tonic-gate #define	OA_WX	(OA_W|OA_X)
887c478bd9Sstevel@tonic-gate #define	OA_RX	(OA_R|OA_X)
897c478bd9Sstevel@tonic-gate #define	OA_RWX	(OA_R|OA_W|OA_X)
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #define	OA_ANY_ACCESS(x) ((x)->opdes_access_nopriv|(x)->opdes_access_priv)
927c478bd9Sstevel@tonic-gate #define	OA_R_NOPRIV(x)	((x)->opdes_access_nopriv & OA_R)
937c478bd9Sstevel@tonic-gate #define	OA_R_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_R)
947c478bd9Sstevel@tonic-gate #define	OA_W_NOPRIV(x)	((x)->opdes_access_nopriv & OA_W)
957c478bd9Sstevel@tonic-gate #define	OA_X_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_X)
967c478bd9Sstevel@tonic-gate #define	OA_X_NOPRIV(x)	((x)->opdes_access_nopriv & OA_X)
977c478bd9Sstevel@tonic-gate #define	OA_W_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_W)
987c478bd9Sstevel@tonic-gate #define	OA_WX_NOPRIV(x)	((x)->opdes_access_nopriv & OA_WX)
997c478bd9Sstevel@tonic-gate #define	OA_WX_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_WX)
1007c478bd9Sstevel@tonic-gate #define	OA_RWX_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_RWX)
1017c478bd9Sstevel@tonic-gate #define	OA_RONLY_NOPRIV(x)	(((x)->opdes_access_nopriv & OA_RWX) == OA_R)
1027c478bd9Sstevel@tonic-gate #define	OA_RONLY_ANYPRIV(x)	((OA_ANY_ACCESS(x) & OA_RWX) == OA_R)
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate #define	OP_NP		(-1)			/* No privilege required */
1057c478bd9Sstevel@tonic-gate #define	OP_CONFIG	(0)			/* Network configuration */
1067c478bd9Sstevel@tonic-gate #define	OP_RAW		(1)			/* Raw packets */
1077c478bd9Sstevel@tonic-gate #define	OP_PRIVPORT	(2)			/* Privileged ports */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate  * Following macros supply the option and their privilege and
1127c478bd9Sstevel@tonic-gate  * are used to determine permissions.
1137c478bd9Sstevel@tonic-gate  */
1147c478bd9Sstevel@tonic-gate #define	OA_POLICY_OK(x, c) \
115f4b3ec61Sdh155122 		(secpolicy_ip((c), (x)->opdes_access_req_priv, B_FALSE) == 0)
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate #define	OA_POLICY_ONLY_OK(x, c) \
118f4b3ec61Sdh155122 		(secpolicy_ip((c), (x)->opdes_access_req_priv, B_TRUE) == 0)
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate #define	OA_MATCHED_PRIV(x, c)	((x)->opdes_access_req_priv != OP_NP && \
1217c478bd9Sstevel@tonic-gate 		OA_POLICY_ONLY_OK((x), (c)))
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate #define	OA_READ_PERMISSION(x, c)	(OA_R_NOPRIV(x) || \
1247c478bd9Sstevel@tonic-gate 		(OA_R_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate #define	OA_WRITE_OR_EXECUTE(x, c)	(OA_WX_NOPRIV(x) || \
1277c478bd9Sstevel@tonic-gate 		(OA_WX_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate #define	OA_READONLY_PERMISSION(x, c)	(OA_RONLY_NOPRIV(x) || \
1307c478bd9Sstevel@tonic-gate 		(OA_RONLY_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate #define	OA_WRITE_PERMISSION(x, c)	(OA_W_NOPRIV(x) || \
1337c478bd9Sstevel@tonic-gate 		(OA_W_ANYPRIV(x) && OA_POLICY_ONLY_OK((x), (c))))
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate #define	OA_EXECUTE_PERMISSION(x, c)	(OA_X_NOPRIV(x) || \
1367c478bd9Sstevel@tonic-gate 		(OA_X_ANYPRIV(x) && OA_POLICY_ONLY_OK((x), (c))))
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate #define	OA_NO_PERMISSION(x, c)		(OA_MATCHED_PRIV((x), (c)) ? \
1397c478bd9Sstevel@tonic-gate 		((x)->opdes_access_priv == 0) : ((x)->opdes_access_nopriv == 0))
1407c478bd9Sstevel@tonic-gate 
141*0f1702c5SYu Xiangning #define	PASS_OPT_TO_IP(connp)		\
142*0f1702c5SYu Xiangning 	if (IPCL_IS_NONSTR(connp))	\
143*0f1702c5SYu Xiangning 		return (-EINVAL)
144*0f1702c5SYu Xiangning 
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate  * Other properties set in opdes_props field.
1477c478bd9Sstevel@tonic-gate  */
1487c478bd9Sstevel@tonic-gate #define	OP_PASSNEXT	0x1	/* to pass option to next module or not */
1497c478bd9Sstevel@tonic-gate #define	OP_VARLEN	0x2	/* option is varible length  */
1507c478bd9Sstevel@tonic-gate #define	OP_NOT_ABSREQ	0x4	/* option is not a "absolute requirement" */
1517c478bd9Sstevel@tonic-gate 				/* i.e. failure to negotiate does not */
1527c478bd9Sstevel@tonic-gate 				/* abort primitive ("ignore" semantics ok) */
1537c478bd9Sstevel@tonic-gate #define	OP_NODEFAULT	0x8	/* no concept of "default value"  */
1547c478bd9Sstevel@tonic-gate #define	OP_DEF_FN	0x10	/* call a "default function" to get default */
1557c478bd9Sstevel@tonic-gate 				/* value, not from static table  */
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate /*
1597c478bd9Sstevel@tonic-gate  * Structure to represent attributed of option management specific
1607c478bd9Sstevel@tonic-gate  * to one particular layer of "transport".
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate typedef	t_uscalar_t optlevel_t;
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate typedef int (*opt_def_fn)(queue_t *, int, int, uchar_t *);
1667c478bd9Sstevel@tonic-gate typedef int (*opt_get_fn)(queue_t *, int, int, uchar_t *);
1677c478bd9Sstevel@tonic-gate typedef int (*opt_set_fn)(queue_t *, uint_t, int, int, uint_t, uchar_t *,
1687c478bd9Sstevel@tonic-gate     uint_t *, uchar_t *, void *, cred_t *, mblk_t *);
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate typedef struct optdb_obj {
1717c478bd9Sstevel@tonic-gate 	opt_def_fn	odb_deffn;	/* default value function */
1727c478bd9Sstevel@tonic-gate 	opt_get_fn	odb_getfn;	/* get function */
1737c478bd9Sstevel@tonic-gate 	opt_set_fn	odb_setfn;	/* set function */
1747c478bd9Sstevel@tonic-gate 	boolean_t	odb_topmost_tpiprovider; /* whether topmost tpi */
1757c478bd9Sstevel@tonic-gate 					/* provider or downstream */
1767c478bd9Sstevel@tonic-gate 	uint_t		odb_opt_arr_cnt; /* count of number of options in db */
1777c478bd9Sstevel@tonic-gate 	opdes_t		*odb_opt_des_arr; /* option descriptors in db */
1787c478bd9Sstevel@tonic-gate 	uint_t		odb_valid_levels_arr_cnt;
1797c478bd9Sstevel@tonic-gate 					/* count of option levels supported */
1807c478bd9Sstevel@tonic-gate 	optlevel_t	*odb_valid_levels_arr;
1817c478bd9Sstevel@tonic-gate 					/* array of option levels supported */
1827c478bd9Sstevel@tonic-gate } optdb_obj_t;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate  * This is used to restart option processing. This goes inside an M_CTL
1867c478bd9Sstevel@tonic-gate  * which is prepended to the packet. IP may need to become exclusive on
1877c478bd9Sstevel@tonic-gate  * an ill for setting some options. For dg. IP_ADD_MEMBERSHIP. Since
1887c478bd9Sstevel@tonic-gate  * there can be more than 1 option packed in an option buffer, we need to
1897c478bd9Sstevel@tonic-gate  * remember where to restart option processing after resuming from a wait
1907c478bd9Sstevel@tonic-gate  * for exclusive condition in IP.
1917c478bd9Sstevel@tonic-gate  */
1927c478bd9Sstevel@tonic-gate typedef struct opt_restart_s {
1937c478bd9Sstevel@tonic-gate 	struct	opthdr	*or_start;		/* start of option buffer */
1947c478bd9Sstevel@tonic-gate 	struct	opthdr	*or_end;		/* end of option buffer */
1957c478bd9Sstevel@tonic-gate 	struct	opthdr	*or_ropt;		/* restart option here */
1967c478bd9Sstevel@tonic-gate 	t_uscalar_t	or_worst_status;	/* Used by tpi_optcom_req */
1977c478bd9Sstevel@tonic-gate 	t_uscalar_t	or_type;		/* svr4 or tpi optcom variant */
1987c478bd9Sstevel@tonic-gate 	int		or_private;		/* currently used by CGTP */
1997c478bd9Sstevel@tonic-gate } opt_restart_t;
2007c478bd9Sstevel@tonic-gate /*
2017c478bd9Sstevel@tonic-gate  * Values for "optset_context" parameter passed to
2027c478bd9Sstevel@tonic-gate  * transport specific "setfn()" routines
2037c478bd9Sstevel@tonic-gate  */
2047c478bd9Sstevel@tonic-gate #define	SETFN_OPTCOM_CHECKONLY		1 /* "checkonly" semantics T_CHECK */
2057c478bd9Sstevel@tonic-gate #define	SETFN_OPTCOM_NEGOTIATE		2 /* semantics for T_*_OPTCOM_REQ */
2067c478bd9Sstevel@tonic-gate #define	SETFN_UD_NEGOTIATE		3 /* semantics for T_UNITDATA_REQ */
2077c478bd9Sstevel@tonic-gate #define	SETFN_CONN_NEGOTIATE		4 /* semantics for T_CONN_*_REQ */
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate /*
2107c478bd9Sstevel@tonic-gate  * Function prototypes
2117c478bd9Sstevel@tonic-gate  */
2127c478bd9Sstevel@tonic-gate extern void optcom_err_ack(queue_t *, mblk_t *, t_scalar_t, int);
213fc80c0dfSnordmark extern int svr4_optcom_req(queue_t *, mblk_t *, cred_t *, optdb_obj_t *,
214fc80c0dfSnordmark     boolean_t);
215fc80c0dfSnordmark extern int tpi_optcom_req(queue_t *, mblk_t *, cred_t *, optdb_obj_t *,
216fc80c0dfSnordmark     boolean_t);
2177c478bd9Sstevel@tonic-gate extern int  tpi_optcom_buf(queue_t *, mblk_t *, t_scalar_t *, t_scalar_t,
2187c478bd9Sstevel@tonic-gate     cred_t *, optdb_obj_t *, void *, int *);
2197c478bd9Sstevel@tonic-gate extern t_uscalar_t optcom_max_optsize(opdes_t *, uint_t);
22045916cd2Sjpk extern int optcom_pkt_set(uchar_t *, uint_t, boolean_t, uchar_t **, uint_t *,
22145916cd2Sjpk     uint_t);
2227c478bd9Sstevel@tonic-gate 
223*0f1702c5SYu Xiangning extern int process_auxiliary_options(conn_t *, void *, t_uscalar_t,
224*0f1702c5SYu Xiangning     void *, optdb_obj_t *, int (*)(conn_t *, uint_t, int, int, uint_t,
225*0f1702c5SYu Xiangning     uchar_t *, uint_t *, uchar_t *, void *, cred_t *));
226*0f1702c5SYu Xiangning 
2277c478bd9Sstevel@tonic-gate #endif	/* defined(_KERNEL) && defined(__STDC__) */
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate #endif
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate #endif	/* _INET_OPTCOM_H */
234