1b86efd96Sagiri /*
2b86efd96Sagiri * CDDL HEADER START
3b86efd96Sagiri *
4b86efd96Sagiri * The contents of this file are subject to the terms of the
5b86efd96Sagiri * Common Development and Distribution License (the "License").
6b86efd96Sagiri * You may not use this file except in compliance with the License.
7b86efd96Sagiri *
8b86efd96Sagiri * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9b86efd96Sagiri * or http://www.opensolaris.org/os/licensing.
10b86efd96Sagiri * See the License for the specific language governing permissions
11b86efd96Sagiri * and limitations under the License.
12b86efd96Sagiri *
13b86efd96Sagiri * When distributing Covered Code, include this CDDL HEADER in each
14b86efd96Sagiri * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15b86efd96Sagiri * If applicable, add the following below this CDDL HEADER, with the
16b86efd96Sagiri * fields enclosed by brackets "[]" replaced with your own identifying
17b86efd96Sagiri * information: Portions Copyright [yyyy] [name of copyright owner]
18b86efd96Sagiri *
19b86efd96Sagiri * CDDL HEADER END
20b86efd96Sagiri */
21b86efd96Sagiri /*
22*a69cdccdSRavi Chandra Nallan * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
23*a69cdccdSRavi Chandra Nallan * Copyright (c) 1990 Mentat Inc.
24b86efd96Sagiri */
25b86efd96Sagiri
26b86efd96Sagiri #include <sys/ib/clients/rds/rds.h>
270f1702c5SYu Xiangning #include <inet/proto_set.h>
28b86efd96Sagiri
29b86efd96Sagiri #define rds_max_buf 2097152
30b86efd96Sagiri opdes_t rds_opt_arr[] = {
31b86efd96Sagiri
32bd670b35SErik Nordmark { SO_TYPE, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
33bd670b35SErik Nordmark { SO_SNDBUF, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
34bd670b35SErik Nordmark { SO_RCVBUF, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
35b86efd96Sagiri };
36b86efd96Sagiri
37b86efd96Sagiri /* ARGSUSED */
38b86efd96Sagiri int
rds_opt_default(queue_t * q,t_scalar_t level,t_scalar_t name,uchar_t * ptr)39b86efd96Sagiri rds_opt_default(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr)
40b86efd96Sagiri {
41b86efd96Sagiri /* no default value processed by protocol specific code currently */
42b86efd96Sagiri return (-1);
43b86efd96Sagiri }
44b86efd96Sagiri
45b86efd96Sagiri /*
46b86efd96Sagiri * This routine retrieves the current status of socket options.
47b86efd96Sagiri * It returns the size of the option retrieved.
48b86efd96Sagiri */
49b86efd96Sagiri int
rds_opt_get(queue_t * q,t_scalar_t level,t_scalar_t name,uchar_t * ptr)50b86efd96Sagiri rds_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr)
51b86efd96Sagiri {
52b86efd96Sagiri int *i1 = (int *)(uintptr_t)ptr;
53b86efd96Sagiri
54b86efd96Sagiri switch (level) {
55b86efd96Sagiri case SOL_SOCKET:
56b86efd96Sagiri switch (name) {
57b86efd96Sagiri case SO_TYPE:
58b86efd96Sagiri *i1 = SOCK_DGRAM;
59b86efd96Sagiri break; /* goto sizeof (int) option return */
60b86efd96Sagiri
61b86efd96Sagiri case SO_SNDBUF:
62b86efd96Sagiri *i1 = q->q_hiwat;
63b86efd96Sagiri break; /* goto sizeof (int) option return */
64b86efd96Sagiri case SO_RCVBUF:
65b86efd96Sagiri *i1 = RD(q)->q_hiwat;
66b86efd96Sagiri break; /* goto sizeof (int) option return */
67b86efd96Sagiri default:
68b86efd96Sagiri return (-1);
69b86efd96Sagiri }
70b86efd96Sagiri break;
71b86efd96Sagiri default:
72b86efd96Sagiri return (-1);
73b86efd96Sagiri }
74b86efd96Sagiri return (sizeof (int));
75b86efd96Sagiri }
76b86efd96Sagiri
77b86efd96Sagiri /* This routine sets socket options. */
78b86efd96Sagiri /* ARGSUSED */
79b86efd96Sagiri int
rds_opt_set(queue_t * q,uint_t optset_context,int level,int name,uint_t inlen,uchar_t * invalp,uint_t * outlenp,uchar_t * outvalp,void * thisdg_attrs,cred_t * cr)80b86efd96Sagiri rds_opt_set(queue_t *q, uint_t optset_context, int level,
81b86efd96Sagiri int name, uint_t inlen, uchar_t *invalp, uint_t *outlenp,
82bd670b35SErik Nordmark uchar_t *outvalp, void *thisdg_attrs, cred_t *cr)
83b86efd96Sagiri {
84b86efd96Sagiri int *i1 = (int *)(uintptr_t)invalp;
85b86efd96Sagiri boolean_t checkonly;
86b86efd96Sagiri
87b86efd96Sagiri switch (optset_context) {
88b86efd96Sagiri case SETFN_OPTCOM_CHECKONLY:
89b86efd96Sagiri checkonly = B_TRUE;
90b86efd96Sagiri /*
91b86efd96Sagiri * Note: Implies T_CHECK semantics for T_OPTCOM_REQ
92b86efd96Sagiri * inlen != 0 implies value supplied and
93b86efd96Sagiri * we have to "pretend" to set it.
94b86efd96Sagiri * inlen == 0 implies that there is no
95b86efd96Sagiri * value part in T_CHECK request and just validation
96b86efd96Sagiri * done elsewhere should be enough, we just return here.
97b86efd96Sagiri */
98b86efd96Sagiri if (inlen == 0) {
99b86efd96Sagiri *outlenp = 0;
100b86efd96Sagiri return (0);
101b86efd96Sagiri }
102b86efd96Sagiri break;
103b86efd96Sagiri case SETFN_OPTCOM_NEGOTIATE:
104b86efd96Sagiri checkonly = B_FALSE;
105b86efd96Sagiri break;
106b86efd96Sagiri default:
107b86efd96Sagiri /*
108b86efd96Sagiri * We should never get here
109b86efd96Sagiri */
110b86efd96Sagiri *outlenp = 0;
111b86efd96Sagiri return (EINVAL);
112b86efd96Sagiri }
113b86efd96Sagiri
114b86efd96Sagiri ASSERT((optset_context != SETFN_OPTCOM_CHECKONLY) ||
115b86efd96Sagiri (optset_context == SETFN_OPTCOM_CHECKONLY && inlen != 0));
116b86efd96Sagiri
117b86efd96Sagiri /*
118b86efd96Sagiri * For fixed length options, no sanity check
119b86efd96Sagiri * of passed in length is done. It is assumed *_optcom_req()
120b86efd96Sagiri * routines do the right thing.
121b86efd96Sagiri */
122b86efd96Sagiri
123b86efd96Sagiri switch (level) {
124b86efd96Sagiri case SOL_SOCKET:
125b86efd96Sagiri switch (name) {
126b86efd96Sagiri
127b86efd96Sagiri case SO_SNDBUF:
128b86efd96Sagiri if (*i1 > rds_max_buf) {
129b86efd96Sagiri *outlenp = 0;
130b86efd96Sagiri return (ENOBUFS);
131b86efd96Sagiri }
132b86efd96Sagiri if (!checkonly) {
133b86efd96Sagiri q->q_hiwat = *i1;
134b86efd96Sagiri }
135b86efd96Sagiri break;
136b86efd96Sagiri case SO_RCVBUF:
137b86efd96Sagiri if (*i1 > rds_max_buf) {
138b86efd96Sagiri *outlenp = 0;
139b86efd96Sagiri return (ENOBUFS);
140b86efd96Sagiri }
141b86efd96Sagiri if (!checkonly) {
142b86efd96Sagiri RD(q)->q_hiwat = *i1;
1430f1702c5SYu Xiangning (void) proto_set_rx_hiwat(RD(q), NULL, *i1);
144b86efd96Sagiri }
145b86efd96Sagiri break;
146b86efd96Sagiri default:
147b86efd96Sagiri *outlenp = 0;
148b86efd96Sagiri return (EINVAL);
149b86efd96Sagiri }
150b86efd96Sagiri break;
151b86efd96Sagiri default:
152b86efd96Sagiri *outlenp = 0;
153b86efd96Sagiri return (EINVAL);
154b86efd96Sagiri }
155b86efd96Sagiri /*
156b86efd96Sagiri * Common case of OK return with outval same as inval.
157b86efd96Sagiri */
158b86efd96Sagiri if (invalp != outvalp) {
159b86efd96Sagiri /* don't trust bcopy for identical src/dst */
160b86efd96Sagiri (void) bcopy(invalp, outvalp, inlen);
161b86efd96Sagiri }
162b86efd96Sagiri *outlenp = inlen;
163b86efd96Sagiri return (0);
164b86efd96Sagiri }
165b86efd96Sagiri
166b86efd96Sagiri uint_t rds_max_optsize; /* initialized when RDS driver is loaded */
167b86efd96Sagiri
168b86efd96Sagiri #define RDS_VALID_LEVELS_CNT A_CNT(rds_valid_levels_arr)
169b86efd96Sagiri
170b86efd96Sagiri #define RDS_OPT_ARR_CNT A_CNT(rds_opt_arr)
171b86efd96Sagiri
172b86efd96Sagiri
173b86efd96Sagiri optlevel_t rds_valid_levels_arr[] = {
174b86efd96Sagiri SOL_SOCKET,
175b86efd96Sagiri };
176b86efd96Sagiri
177b86efd96Sagiri /*
178b86efd96Sagiri * Initialize option database object for RDS
179b86efd96Sagiri *
180b86efd96Sagiri * This object represents database of options to search passed to
181b86efd96Sagiri * {sock,tpi}optcom_req() interface routine to take care of option
182b86efd96Sagiri * management and associated methods.
183b86efd96Sagiri */
184b86efd96Sagiri
185b86efd96Sagiri optdb_obj_t rds_opt_obj = {
186b86efd96Sagiri rds_opt_default, /* RDS default value function pointer */
187b86efd96Sagiri rds_opt_get, /* RDS get function pointer */
188b86efd96Sagiri rds_opt_set, /* RDS set function pointer */
189b86efd96Sagiri RDS_OPT_ARR_CNT, /* RDS option database count of entries */
190b86efd96Sagiri rds_opt_arr, /* RDS option database */
191b86efd96Sagiri RDS_VALID_LEVELS_CNT, /* RDS valid level count of entries */
192b86efd96Sagiri rds_valid_levels_arr /* RDS valid level array */
193b86efd96Sagiri };
194