xref: /illumos-gate/usr/src/uts/common/inet/optcom.h (revision 8c067cfd3aea0c49a166f9fb38114b56a9160ac6)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1990 Mentat Inc. */
26 
27 #ifndef	_INET_OPTCOM_H
28 #define	_INET_OPTCOM_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 #if defined(_KERNEL) && defined(__STDC__)
35 
36 #include <inet/ipclassifier.h>
37 /* Options Description Structure */
38 typedef struct opdes_s {
39 	t_uscalar_t	opdes_name;	/* option name */
40 	t_uscalar_t	opdes_level;	/* option "level" */
41 	int	opdes_access_nopriv;	/* permissions for non-privileged */
42 	int	opdes_access_priv;	/* permissions for privileged */
43 	int	opdes_access_req_priv;	/* required privilege, OP_NP if none */
44 	int	opdes_props;	/* properties of associated with option */
45 	t_uscalar_t	opdes_size;	/* length of option */
46 					/* [ or maxlen if variable */
47 			/* length(OP_VARLEN) property set for option] */
48 	union {
49 		/*
50 		 *
51 		 * Note: C semantics:
52 		 * static initializer of "union" type assume
53 		 * the constant on RHS is of the type of the
54 		 * first member of the union. So what comes first
55 		 * is important.
56 		 */
57 #define	OPDES_DEFSZ_MAX		64
58 		int64_t  opdes_def_int64;
59 		char	opdes_def_charbuf[OPDES_DEFSZ_MAX];
60 	} opdes_def;
61 } opdes_t;
62 
63 #define	opdes_default	opdes_def.opdes_def_int64
64 #define	opdes_defbuf	opdes_def.opdes_def_charbuf
65 /*
66  * Flags to set in opdes_acces_{all,priv} fields in opdes_t
67  *
68  *	OA_R	read access
69  *	OA_W	write access
70  *	OA_RW	read-write access
71  *	OA_X	execute access
72  *
73  * Note: - semantics "execute" access used for operations excuted using
74  *		option management interface
75  *	- no bits set means this option is not visible. Some options may not
76  *	  even be visible to all but priviliged users.
77  */
78 #define	OA_R	0x1
79 #define	OA_W	0x2
80 #define	OA_X	0x4
81 
82 /*
83  * Utility macros to test permissions needed to compose more
84  * complex ones. (Only a few really used directly in code).
85  */
86 #define	OA_RW	(OA_R|OA_W)
87 #define	OA_WX	(OA_W|OA_X)
88 #define	OA_RX	(OA_R|OA_X)
89 #define	OA_RWX	(OA_R|OA_W|OA_X)
90 
91 #define	OA_ANY_ACCESS(x) ((x)->opdes_access_nopriv|(x)->opdes_access_priv)
92 #define	OA_R_NOPRIV(x)	((x)->opdes_access_nopriv & OA_R)
93 #define	OA_R_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_R)
94 #define	OA_W_NOPRIV(x)	((x)->opdes_access_nopriv & OA_W)
95 #define	OA_X_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_X)
96 #define	OA_X_NOPRIV(x)	((x)->opdes_access_nopriv & OA_X)
97 #define	OA_W_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_W)
98 #define	OA_WX_NOPRIV(x)	((x)->opdes_access_nopriv & OA_WX)
99 #define	OA_WX_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_WX)
100 #define	OA_RWX_ANYPRIV(x)	(OA_ANY_ACCESS(x) & OA_RWX)
101 #define	OA_RONLY_NOPRIV(x)	(((x)->opdes_access_nopriv & OA_RWX) == OA_R)
102 #define	OA_RONLY_ANYPRIV(x)	((OA_ANY_ACCESS(x) & OA_RWX) == OA_R)
103 
104 #define	OP_NP		(-1)			/* No privilege required */
105 #define	OP_CONFIG	(0)			/* Network configuration */
106 #define	OP_RAW		(1)			/* Raw packets */
107 #define	OP_PRIVPORT	(2)			/* Privileged ports */
108 
109 
110 /*
111  * Following macros supply the option and their privilege and
112  * are used to determine permissions.
113  */
114 #define	OA_POLICY_OK(x, c) \
115 		(secpolicy_ip((c), (x)->opdes_access_req_priv, B_FALSE) == 0)
116 
117 #define	OA_POLICY_ONLY_OK(x, c) \
118 		(secpolicy_ip((c), (x)->opdes_access_req_priv, B_TRUE) == 0)
119 
120 #define	OA_MATCHED_PRIV(x, c)	((x)->opdes_access_req_priv != OP_NP && \
121 		OA_POLICY_ONLY_OK((x), (c)))
122 
123 #define	OA_READ_PERMISSION(x, c)	(OA_R_NOPRIV(x) || \
124 		(OA_R_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
125 
126 #define	OA_WRITE_OR_EXECUTE(x, c)	(OA_WX_NOPRIV(x) || \
127 		(OA_WX_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
128 
129 #define	OA_READONLY_PERMISSION(x, c)	(OA_RONLY_NOPRIV(x) || \
130 		(OA_RONLY_ANYPRIV(x) && OA_POLICY_OK((x), (c))))
131 
132 #define	OA_WRITE_PERMISSION(x, c)	(OA_W_NOPRIV(x) || \
133 		(OA_W_ANYPRIV(x) && OA_POLICY_ONLY_OK((x), (c))))
134 
135 #define	OA_EXECUTE_PERMISSION(x, c)	(OA_X_NOPRIV(x) || \
136 		(OA_X_ANYPRIV(x) && OA_POLICY_ONLY_OK((x), (c))))
137 
138 #define	OA_NO_PERMISSION(x, c)		(OA_MATCHED_PRIV((x), (c)) ? \
139 		((x)->opdes_access_priv == 0) : ((x)->opdes_access_nopriv == 0))
140 
141 #define	PASS_OPT_TO_IP(connp)		\
142 	if (IPCL_IS_NONSTR(connp))	\
143 		return (-EINVAL)
144 
145 /*
146  * Other properties set in opdes_props field.
147  */
148 #define	OP_PASSNEXT	0x1	/* to pass option to next module or not */
149 #define	OP_VARLEN	0x2	/* option is varible length  */
150 #define	OP_NOT_ABSREQ	0x4	/* option is not a "absolute requirement" */
151 				/* i.e. failure to negotiate does not */
152 				/* abort primitive ("ignore" semantics ok) */
153 #define	OP_NODEFAULT	0x8	/* no concept of "default value"  */
154 #define	OP_DEF_FN	0x10	/* call a "default function" to get default */
155 				/* value, not from static table  */
156 
157 
158 /*
159  * Structure to represent attributed of option management specific
160  * to one particular layer of "transport".
161  */
162 
163 typedef	t_uscalar_t optlevel_t;
164 
165 typedef int (*opt_def_fn)(queue_t *, int, int, uchar_t *);
166 typedef int (*opt_get_fn)(queue_t *, int, int, uchar_t *);
167 typedef int (*opt_set_fn)(queue_t *, uint_t, int, int, uint_t, uchar_t *,
168     uint_t *, uchar_t *, void *, cred_t *, mblk_t *);
169 
170 typedef struct optdb_obj {
171 	opt_def_fn	odb_deffn;	/* default value function */
172 	opt_get_fn	odb_getfn;	/* get function */
173 	opt_set_fn	odb_setfn;	/* set function */
174 	boolean_t	odb_topmost_tpiprovider; /* whether topmost tpi */
175 					/* provider or downstream */
176 	uint_t		odb_opt_arr_cnt; /* count of number of options in db */
177 	opdes_t		*odb_opt_des_arr; /* option descriptors in db */
178 	uint_t		odb_valid_levels_arr_cnt;
179 					/* count of option levels supported */
180 	optlevel_t	*odb_valid_levels_arr;
181 					/* array of option levels supported */
182 } optdb_obj_t;
183 
184 /*
185  * This is used to restart option processing. This goes inside an M_CTL
186  * which is prepended to the packet. IP may need to become exclusive on
187  * an ill for setting some options. For dg. IP_ADD_MEMBERSHIP. Since
188  * there can be more than 1 option packed in an option buffer, we need to
189  * remember where to restart option processing after resuming from a wait
190  * for exclusive condition in IP.
191  */
192 typedef struct opt_restart_s {
193 	struct	opthdr	*or_start;		/* start of option buffer */
194 	struct	opthdr	*or_end;		/* end of option buffer */
195 	struct	opthdr	*or_ropt;		/* restart option here */
196 	t_uscalar_t	or_worst_status;	/* Used by tpi_optcom_req */
197 	t_uscalar_t	or_type;		/* svr4 or tpi optcom variant */
198 	int		or_private;		/* currently used by CGTP */
199 } opt_restart_t;
200 /*
201  * Values for "optset_context" parameter passed to
202  * transport specific "setfn()" routines
203  */
204 #define	SETFN_OPTCOM_CHECKONLY		1 /* "checkonly" semantics T_CHECK */
205 #define	SETFN_OPTCOM_NEGOTIATE		2 /* semantics for T_*_OPTCOM_REQ */
206 #define	SETFN_UD_NEGOTIATE		3 /* semantics for T_UNITDATA_REQ */
207 #define	SETFN_CONN_NEGOTIATE		4 /* semantics for T_CONN_*_REQ */
208 
209 /*
210  * Function prototypes
211  */
212 extern void optcom_err_ack(queue_t *, mblk_t *, t_scalar_t, int);
213 extern int svr4_optcom_req(queue_t *, mblk_t *, cred_t *, optdb_obj_t *,
214     boolean_t);
215 extern int tpi_optcom_req(queue_t *, mblk_t *, cred_t *, optdb_obj_t *,
216     boolean_t);
217 extern int  tpi_optcom_buf(queue_t *, mblk_t *, t_scalar_t *, t_scalar_t,
218     cred_t *, optdb_obj_t *, void *, int *);
219 extern t_uscalar_t optcom_max_optsize(opdes_t *, uint_t);
220 extern int optcom_pkt_set(uchar_t *, uint_t, boolean_t, uchar_t **, uint_t *,
221     uint_t);
222 
223 extern int process_auxiliary_options(conn_t *, void *, t_uscalar_t,
224     void *, optdb_obj_t *, int (*)(conn_t *, uint_t, int, int, uint_t,
225     uchar_t *, uint_t *, uchar_t *, void *, cred_t *));
226 
227 #endif	/* defined(_KERNEL) && defined(__STDC__) */
228 
229 #ifdef	__cplusplus
230 }
231 #endif
232 
233 #endif	/* _INET_OPTCOM_H */
234