xref: /titanic_41/usr/src/uts/common/avs/ns/rdc/rdc_subr.c (revision 3270659f55e0928d6edec3d26217cc29398a8149)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/ksynch.h>
28 #include <sys/errno.h>
29 #include <sys/debug.h>
30 #include <sys/cmn_err.h>
31 #include <sys/kmem.h>
32 #include <sys/errno.h>
33 
34 #ifdef _SunOS_2_6
35 /*
36  * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we
37  * define enum_t here as it is all we need from rpc/types.h
38  * anyway and make it look like we included it. Yuck.
39  */
40 #define	_RPC_TYPES_H
41 typedef int enum_t;
42 #else
43 #ifndef DS_DDICT
44 #include <rpc/types.h>
45 #endif
46 #endif /* _SunOS_2_6 */
47 
48 #include <sys/nsc_thread.h>
49 #include <sys/nsctl/nsctl.h>
50 #include "rdc_io.h"
51 #include "rdc_ioctl.h"
52 #include "rdc_prot.h"
53 
54 /*
55  * Initialize a netbuf suitable for
56  * describing an address
57  */
58 
59 void
init_rdc_netbuf(struct netbuf * nbuf)60 init_rdc_netbuf(struct netbuf *nbuf)
61 {
62 	nbuf->buf = kmem_zalloc(RDC_MAXADDR, KM_SLEEP);
63 	nbuf->maxlen = RDC_MAXADDR;
64 	nbuf->len = 0;
65 }
66 
67 /*
68  * Free a netbuf
69  */
70 
71 void
free_rdc_netbuf(struct netbuf * nbuf)72 free_rdc_netbuf(struct netbuf *nbuf)
73 {
74 	if (!(nbuf) || !(nbuf->buf)) {
75 #ifdef DEBUG
76 		cmn_err(CE_PANIC, "Null netbuf in free_rdc_netbuf");
77 #endif
78 		return;
79 	}
80 	kmem_free(nbuf->buf, nbuf->maxlen);
81 	nbuf->buf = NULL;
82 	nbuf->maxlen = 0;
83 	nbuf->len = 0;
84 }
85 
86 
87 /*
88  * Duplicate a netbuf, must be followed by a free_rdc_netbuf().
89  */
90 void
dup_rdc_netbuf(const struct netbuf * from,struct netbuf * to)91 dup_rdc_netbuf(const struct netbuf *from, struct netbuf *to)
92 {
93 	init_rdc_netbuf(to);
94 	to->len = from->len;
95 
96 	if (from->len > to->maxlen) {
97 		cmn_err(CE_WARN, "!dup_rdc_netbuf: from->len %d, to->maxlen %d",
98 		    from->len, to->maxlen);
99 	}
100 
101 	bcopy(from->buf, to->buf, (size_t)from->len);
102 }
103 
104 
105 #ifdef DEBUG
106 void
rdc_print_svinfo(rdc_srv_t * svp,char * str)107 rdc_print_svinfo(rdc_srv_t *svp, char *str)
108 {
109 	int i;
110 
111 	if (svp == NULL)
112 		return;
113 
114 	cmn_err(CE_NOTE, "!rdc %s servinfo: %p\n", str, (void *) svp);
115 
116 	if (svp->ri_knconf != NULL) {
117 		cmn_err(CE_NOTE, "!knconf: semantics %d",
118 		    svp->ri_knconf->knc_semantics);
119 		cmn_err(CE_NOTE, "!	protofmly %s",
120 		    svp->ri_knconf->knc_protofmly);
121 		cmn_err(CE_NOTE, "!	proto	  %s",
122 		    svp->ri_knconf->knc_proto);
123 		cmn_err(CE_NOTE, "!	rdev	  %lx",
124 		    svp->ri_knconf->knc_rdev);
125 	}
126 
127 	for (i = 0; i < svp->ri_addr.len; i++)
128 		printf("%u ", svp->ri_addr.buf[i]);
129 
130 	cmn_err(CE_NOTE, "!\naddr:	len %d buf %p\n",
131 	    svp->ri_addr.len, (void *) svp->ri_addr.buf);
132 	cmn_err(CE_NOTE, "!host:	%s\n", svp->ri_hostname);
133 }
134 #endif /* DEBUG */
135 
136 /*
137  * Initialize an rdc servinfo
138  * Contains all the protocol we need to do a client rpc
139  * A chain of rdc_srv_t indicates a one to many
140  */
141 
142 rdc_srv_t *
rdc_create_svinfo(char * host,struct netbuf * svaddr,struct knetconfig * conf)143 rdc_create_svinfo(char *host, struct netbuf *svaddr, struct knetconfig *conf)
144 {
145 	rdc_srv_t *nvp;
146 	int hlen = strlen(host) + 1;
147 
148 	if (conf == NULL) {
149 		return (NULL);
150 	}
151 
152 	if (host == NULL) {
153 		return (NULL);
154 	}
155 
156 	nvp = kmem_zalloc(sizeof (*nvp), KM_SLEEP);
157 	nvp->ri_knconf = kmem_alloc(sizeof (*nvp->ri_knconf), KM_SLEEP);
158 	nvp->ri_hostname = kmem_zalloc(hlen, KM_SLEEP);
159 
160 	if (nvp == NULL || nvp->ri_hostname == NULL || nvp->ri_knconf == NULL) {
161 		rdc_destroy_svinfo(nvp);
162 		return (NULL);
163 	}
164 
165 	nvp->ri_hostnamelen = hlen;
166 
167 	bcopy((void *)conf, (void *)nvp->ri_knconf, sizeof (*nvp->ri_knconf));
168 	nvp->ri_knconf->knc_protofmly = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP);
169 	nvp->ri_knconf->knc_proto = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP);
170 
171 	if (nvp->ri_knconf->knc_protofmly == NULL ||
172 	    nvp->ri_knconf->knc_proto == NULL) {
173 		rdc_destroy_svinfo(nvp);
174 		return (NULL);
175 
176 	}
177 
178 	(void) strncpy(nvp->ri_knconf->knc_protofmly, conf->knc_protofmly,
179 	    KNC_STRSIZE);
180 	(void) strncpy(nvp->ri_knconf->knc_proto, conf->knc_proto, KNC_STRSIZE);
181 
182 	dup_rdc_netbuf(svaddr, &nvp->ri_addr);
183 
184 	nvp->ri_secdata = NULL;		/* For now */
185 	(void) strncpy(nvp->ri_hostname, host, hlen);
186 #ifdef DEBUG_IP
187 	rdc_print_svinfo(nvp, "!create");
188 #endif
189 	return (nvp);
190 }
191 
192 void
rdc_destroy_svinfo(rdc_srv_t * svp)193 rdc_destroy_svinfo(rdc_srv_t *svp)
194 {
195 	if (svp == NULL)
196 		return;
197 
198 	if (svp->ri_addr.buf && svp->ri_addr.maxlen)
199 		free_rdc_netbuf(&(svp->ri_addr));
200 
201 	if (svp->ri_knconf->knc_protofmly)
202 		kmem_free(svp->ri_knconf->knc_protofmly, KNC_STRSIZE + 1);
203 
204 	if (svp->ri_knconf->knc_proto)
205 		kmem_free(svp->ri_knconf->knc_proto, KNC_STRSIZE + 1);
206 
207 	if (svp->ri_knconf)
208 		kmem_free(svp->ri_knconf, sizeof (*svp->ri_knconf));
209 
210 	kmem_free(svp, sizeof (*svp));
211 }
212 
213 /*
214  * rdc_netbuf_toint
215  * Returns oldsytle ipv4 RDC ver 3 addresses for RPC protocol from netbuf
216  * Note: This would never be called in the case of IPv6 and a program
217  * mismatch ie ver 3 to ver 4
218  */
219 int
rdc_netbuf_toint(struct netbuf * nb)220 rdc_netbuf_toint(struct netbuf *nb)
221 {
222 	int ret;
223 	if (nb->len > RDC_MAXADDR)
224 		cmn_err(CE_NOTE, "!rdc_netbuf_toint: bad size %d", nb->len);
225 
226 	switch (nb->len) {
227 		case 4:
228 			bcopy(nb->buf, (char *)&ret, sizeof (int));
229 			return (ret);
230 
231 		case 8:
232 		case 16:
233 		case 32:
234 			bcopy(&nb->buf[4], (char *)&ret, sizeof (int));
235 			return (ret);
236 
237 		default:
238 			cmn_err(CE_NOTE, "!rdc_netbuf_toint: size %d", nb->len);
239 		}
240 	return (0);
241 }
242