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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <fcntl.h>
32 #include <stropts.h>
33 #include <string.h>
34 #include <netdb.h>
35 #include <sys/conf.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <inet/iptun.h>
39 #include <sys/dls.h>
40 #include <libdlpi.h>
41 #include <libdladm_impl.h>
42 #include <libdllink.h>
43 #include <libdliptun.h>
44
45 /*
46 * IP Tunneling Administration Library.
47 * This library is used by dladm(1M) and to configure IP tunnel links.
48 */
49
50 #define IPTUN_CONF_TYPE "type"
51 #define IPTUN_CONF_LADDR "laddr"
52 #define IPTUN_CONF_RADDR "raddr"
53
54 /*
55 * If IPTUN_CREATE and IPTUN_MODIFY include IPsec policy and IPsec hasn't
56 * loaded yet, the ioctls may return EAGAIN. We try the ioctl
57 * IPTUN_IOCTL_ATTEMPT_LIMIT times and wait IPTUN_IOCTL_ATTEMPT_INTERVAL
58 * microseconds between attempts.
59 */
60 #define IPTUN_IOCTL_ATTEMPT_LIMIT 3
61 #define IPTUN_IOCTL_ATTEMPT_INTERVAL 10000
62
63 dladm_status_t
i_iptun_ioctl(dladm_handle_t handle,int cmd,void * dp)64 i_iptun_ioctl(dladm_handle_t handle, int cmd, void *dp)
65 {
66 dladm_status_t status = DLADM_STATUS_OK;
67 uint_t attempt;
68
69 for (attempt = 0; attempt < IPTUN_IOCTL_ATTEMPT_LIMIT; attempt++) {
70 if (attempt != 0)
71 (void) usleep(IPTUN_IOCTL_ATTEMPT_INTERVAL);
72 status = (ioctl(dladm_dld_fd(handle), cmd, dp) == 0) ?
73 DLADM_STATUS_OK : dladm_errno2status(errno);
74 if (status != DLADM_STATUS_TRYAGAIN)
75 break;
76 }
77 return (status);
78 }
79
80 /*
81 * Given tunnel paramaters as supplied by a library consumer, fill in kernel
82 * parameters to be passed down to the iptun control device.
83 */
84 static dladm_status_t
i_iptun_kparams(dladm_handle_t handle,const iptun_params_t * params,iptun_kparams_t * ik)85 i_iptun_kparams(dladm_handle_t handle, const iptun_params_t *params,
86 iptun_kparams_t *ik)
87 {
88 dladm_status_t status;
89 struct addrinfo *ai, hints;
90 iptun_kparams_t tmpik;
91 iptun_type_t iptuntype = IPTUN_TYPE_UNKNOWN;
92
93 (void) memset(ik, 0, sizeof (*ik));
94
95 ik->iptun_kparam_linkid = params->iptun_param_linkid;
96
97 if (params->iptun_param_flags & IPTUN_PARAM_TYPE) {
98 ik->iptun_kparam_type = iptuntype = params->iptun_param_type;
99 ik->iptun_kparam_flags |= IPTUN_KPARAM_TYPE;
100 }
101
102 if (params->iptun_param_flags & (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR)) {
103 if (iptuntype == IPTUN_TYPE_UNKNOWN) {
104 /*
105 * We need to get the type of this existing tunnel in
106 * order to validate and/or look up the right kind of
107 * IP address.
108 */
109 tmpik.iptun_kparam_linkid = params->iptun_param_linkid;
110 status = i_iptun_ioctl(handle, IPTUN_INFO, &tmpik);
111 if (status != DLADM_STATUS_OK)
112 return (status);
113 iptuntype = tmpik.iptun_kparam_type;
114 }
115
116 (void) memset(&hints, 0, sizeof (hints));
117 switch (iptuntype) {
118 case IPTUN_TYPE_IPV4:
119 case IPTUN_TYPE_6TO4:
120 hints.ai_family = AF_INET;
121 break;
122 case IPTUN_TYPE_IPV6:
123 hints.ai_family = AF_INET6;
124 break;
125 }
126 }
127
128 if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
129 if (getaddrinfo(params->iptun_param_laddr, NULL, &hints, &ai) !=
130 0)
131 return (DLADM_STATUS_BADIPTUNLADDR);
132 if (ai->ai_next != NULL) {
133 freeaddrinfo(ai);
134 return (DLADM_STATUS_BADIPTUNLADDR);
135 }
136 (void) memcpy(&ik->iptun_kparam_laddr, ai->ai_addr,
137 ai->ai_addrlen);
138 ik->iptun_kparam_flags |= IPTUN_KPARAM_LADDR;
139 freeaddrinfo(ai);
140 }
141
142 if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
143 if (getaddrinfo(params->iptun_param_raddr, NULL, &hints, &ai) !=
144 0)
145 return (DLADM_STATUS_BADIPTUNRADDR);
146 if (ai->ai_next != NULL) {
147 freeaddrinfo(ai);
148 return (DLADM_STATUS_BADIPTUNRADDR);
149 }
150 (void) memcpy(&ik->iptun_kparam_raddr, ai->ai_addr,
151 ai->ai_addrlen);
152 ik->iptun_kparam_flags |= IPTUN_KPARAM_RADDR;
153 freeaddrinfo(ai);
154 }
155
156 if (params->iptun_param_flags & IPTUN_PARAM_SECINFO) {
157 ik->iptun_kparam_secinfo = params->iptun_param_secinfo;
158 ik->iptun_kparam_flags |= IPTUN_KPARAM_SECINFO;
159 }
160
161 return (DLADM_STATUS_OK);
162 }
163
164 /*
165 * The inverse of i_iptun_kparams(). Given kernel tunnel paramaters as
166 * returned from an IPTUN_INFO ioctl, fill in tunnel parameters.
167 */
168 static dladm_status_t
i_iptun_params(const iptun_kparams_t * ik,iptun_params_t * params)169 i_iptun_params(const iptun_kparams_t *ik, iptun_params_t *params)
170 {
171 socklen_t salen;
172
173 (void) memset(params, 0, sizeof (*params));
174
175 params->iptun_param_linkid = ik->iptun_kparam_linkid;
176
177 if (ik->iptun_kparam_flags & IPTUN_KPARAM_TYPE) {
178 params->iptun_param_type = ik->iptun_kparam_type;
179 params->iptun_param_flags |= IPTUN_PARAM_TYPE;
180 }
181
182 if (ik->iptun_kparam_flags & IPTUN_KPARAM_LADDR) {
183 salen = ik->iptun_kparam_laddr.ss_family == AF_INET ?
184 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6);
185 if (getnameinfo((const struct sockaddr *)
186 &ik->iptun_kparam_laddr, salen, params->iptun_param_laddr,
187 sizeof (params->iptun_param_laddr), NULL, 0,
188 NI_NUMERICHOST) != 0) {
189 return (DLADM_STATUS_BADIPTUNLADDR);
190 }
191 params->iptun_param_flags |= IPTUN_PARAM_LADDR;
192 }
193
194 if (ik->iptun_kparam_flags & IPTUN_KPARAM_RADDR) {
195 salen = ik->iptun_kparam_raddr.ss_family == AF_INET ?
196 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6);
197 if (getnameinfo((const struct sockaddr *)
198 &ik->iptun_kparam_raddr, salen, params->iptun_param_raddr,
199 sizeof (params->iptun_param_raddr), NULL, 0,
200 NI_NUMERICHOST) != 0) {
201 return (DLADM_STATUS_BADIPTUNRADDR);
202 }
203 params->iptun_param_flags |= IPTUN_PARAM_RADDR;
204 }
205
206 if (ik->iptun_kparam_flags & IPTUN_KPARAM_SECINFO) {
207 params->iptun_param_secinfo = ik->iptun_kparam_secinfo;
208 params->iptun_param_flags |= IPTUN_PARAM_SECINFO;
209 }
210
211 if (ik->iptun_kparam_flags & IPTUN_KPARAM_IMPLICIT)
212 params->iptun_param_flags |= IPTUN_PARAM_IMPLICIT;
213
214 if (ik->iptun_kparam_flags & IPTUN_KPARAM_IPSECPOL)
215 params->iptun_param_flags |= IPTUN_PARAM_IPSECPOL;
216
217 return (DLADM_STATUS_OK);
218 }
219
220 dladm_status_t
i_iptun_get_sysparams(dladm_handle_t handle,iptun_params_t * params)221 i_iptun_get_sysparams(dladm_handle_t handle, iptun_params_t *params)
222 {
223 dladm_status_t status = DLADM_STATUS_OK;
224 iptun_kparams_t ik;
225
226 ik.iptun_kparam_linkid = params->iptun_param_linkid;
227 status = i_iptun_ioctl(handle, IPTUN_INFO, &ik);
228 if (status == DLADM_STATUS_OK)
229 status = i_iptun_params(&ik, params);
230 return (status);
231 }
232
233 /*
234 * Read tunnel parameters from persistent storage. Note that the tunnel type
235 * is the only thing which must always be in the configuratioh. All other
236 * parameters (currently the source and destination addresses) may or may not
237 * have been configured, and therefore may not have been set.
238 */
239 static dladm_status_t
i_iptun_get_dbparams(dladm_handle_t handle,iptun_params_t * params)240 i_iptun_get_dbparams(dladm_handle_t handle, iptun_params_t *params)
241 {
242 dladm_status_t status;
243 dladm_conf_t conf;
244 datalink_class_t class;
245 uint64_t temp;
246
247 /* First, make sure that this is an IP tunnel. */
248 if ((status = dladm_datalink_id2info(handle, params->iptun_param_linkid,
249 NULL, &class, NULL, NULL, 0)) != DLADM_STATUS_OK)
250 return (status);
251 if (class != DATALINK_CLASS_IPTUN)
252 return (DLADM_STATUS_LINKINVAL);
253
254 if ((status = dladm_getsnap_conf(handle, params->iptun_param_linkid,
255 &conf)) != DLADM_STATUS_OK) {
256 return (status);
257 }
258
259 params->iptun_param_flags = 0;
260
261 if ((status = dladm_get_conf_field(handle, conf, IPTUN_CONF_TYPE, &temp,
262 sizeof (temp))) != DLADM_STATUS_OK)
263 goto done;
264 params->iptun_param_type = (iptun_type_t)temp;
265 params->iptun_param_flags |= IPTUN_PARAM_TYPE;
266
267 if (dladm_get_conf_field(handle, conf, IPTUN_CONF_LADDR,
268 params->iptun_param_laddr, sizeof (params->iptun_param_laddr)) ==
269 DLADM_STATUS_OK)
270 params->iptun_param_flags |= IPTUN_PARAM_LADDR;
271
272 if (dladm_get_conf_field(handle, conf, IPTUN_CONF_RADDR,
273 params->iptun_param_raddr, sizeof (params->iptun_param_raddr)) ==
274 DLADM_STATUS_OK)
275 params->iptun_param_flags |= IPTUN_PARAM_RADDR;
276
277 done:
278 dladm_destroy_conf(handle, conf);
279 return (status);
280 }
281
282 static dladm_status_t
i_iptun_create_sys(dladm_handle_t handle,iptun_params_t * params)283 i_iptun_create_sys(dladm_handle_t handle, iptun_params_t *params)
284 {
285 iptun_kparams_t ik;
286 dladm_status_t status = DLADM_STATUS_OK;
287
288 /* The tunnel type is required for creation. */
289 if (!(params->iptun_param_flags & IPTUN_PARAM_TYPE))
290 return (DLADM_STATUS_IPTUNTYPEREQD);
291
292 if ((status = i_iptun_kparams(handle, params, &ik)) == DLADM_STATUS_OK)
293 status = i_iptun_ioctl(handle, IPTUN_CREATE, &ik);
294 return (status);
295 }
296
297 static dladm_status_t
i_iptun_create_db(dladm_handle_t handle,const char * name,iptun_params_t * params,uint32_t media)298 i_iptun_create_db(dladm_handle_t handle, const char *name,
299 iptun_params_t *params, uint32_t media)
300 {
301 dladm_conf_t conf;
302 dladm_status_t status;
303 uint64_t storage;
304
305 status = dladm_create_conf(handle, name, params->iptun_param_linkid,
306 DATALINK_CLASS_IPTUN, media, &conf);
307 if (status != DLADM_STATUS_OK)
308 return (status);
309
310 assert(params->iptun_param_flags & IPTUN_PARAM_TYPE);
311 storage = params->iptun_param_type;
312 status = dladm_set_conf_field(handle, conf, IPTUN_CONF_TYPE,
313 DLADM_TYPE_UINT64, &storage);
314 if (status != DLADM_STATUS_OK)
315 goto done;
316
317 if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
318 status = dladm_set_conf_field(handle, conf, IPTUN_CONF_LADDR,
319 DLADM_TYPE_STR, params->iptun_param_laddr);
320 if (status != DLADM_STATUS_OK)
321 goto done;
322 }
323
324 if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
325 status = dladm_set_conf_field(handle, conf, IPTUN_CONF_RADDR,
326 DLADM_TYPE_STR, params->iptun_param_raddr);
327 if (status != DLADM_STATUS_OK)
328 goto done;
329 }
330
331 status = dladm_write_conf(handle, conf);
332
333 done:
334 dladm_destroy_conf(handle, conf);
335 return (status);
336 }
337
338 static dladm_status_t
i_iptun_delete_sys(dladm_handle_t handle,datalink_id_t linkid)339 i_iptun_delete_sys(dladm_handle_t handle, datalink_id_t linkid)
340 {
341 dladm_status_t status;
342
343 status = i_iptun_ioctl(handle, IPTUN_DELETE, &linkid);
344 if (status != DLADM_STATUS_OK)
345 return (status);
346 (void) dladm_destroy_datalink_id(handle, linkid, DLADM_OPT_ACTIVE);
347 return (DLADM_STATUS_OK);
348 }
349
350 static dladm_status_t
i_iptun_modify_sys(dladm_handle_t handle,const iptun_params_t * params)351 i_iptun_modify_sys(dladm_handle_t handle, const iptun_params_t *params)
352 {
353 iptun_kparams_t ik;
354 dladm_status_t status;
355
356 if ((status = i_iptun_kparams(handle, params, &ik)) == DLADM_STATUS_OK)
357 status = i_iptun_ioctl(handle, IPTUN_MODIFY, &ik);
358 return (status);
359 }
360
361 static dladm_status_t
i_iptun_modify_db(dladm_handle_t handle,const iptun_params_t * params)362 i_iptun_modify_db(dladm_handle_t handle, const iptun_params_t *params)
363 {
364 dladm_conf_t conf;
365 dladm_status_t status;
366
367 assert(params->iptun_param_flags &
368 (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR));
369
370 /*
371 * The only parameters that can be modified persistently are the local
372 * and remote addresses.
373 */
374 if (params->iptun_param_flags & ~(IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR))
375 return (DLADM_STATUS_BADARG);
376
377 status = dladm_open_conf(handle, params->iptun_param_linkid, &conf);
378 if (status != DLADM_STATUS_OK)
379 return (status);
380
381 if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
382 status = dladm_set_conf_field(handle, conf, IPTUN_CONF_LADDR,
383 DLADM_TYPE_STR, (void *)params->iptun_param_laddr);
384 if (status != DLADM_STATUS_OK)
385 goto done;
386 }
387
388 if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
389 status = dladm_set_conf_field(handle, conf, IPTUN_CONF_RADDR,
390 DLADM_TYPE_STR, (void *)params->iptun_param_raddr);
391 if (status != DLADM_STATUS_OK)
392 goto done;
393 }
394
395 status = dladm_write_conf(handle, conf);
396
397 done:
398 dladm_destroy_conf(handle, conf);
399 return (status);
400 }
401
402 dladm_status_t
dladm_iptun_create(dladm_handle_t handle,const char * name,iptun_params_t * params,uint32_t flags)403 dladm_iptun_create(dladm_handle_t handle, const char *name,
404 iptun_params_t *params, uint32_t flags)
405 {
406 dladm_status_t status;
407 uint32_t linkmgmt_flags = flags;
408 uint32_t media;
409
410 if (!(params->iptun_param_flags & IPTUN_PARAM_TYPE))
411 return (DLADM_STATUS_IPTUNTYPEREQD);
412
413 switch (params->iptun_param_type) {
414 case IPTUN_TYPE_IPV4:
415 media = DL_IPV4;
416 break;
417 case IPTUN_TYPE_IPV6:
418 media = DL_IPV6;
419 break;
420 case IPTUN_TYPE_6TO4:
421 media = DL_6TO4;
422 break;
423 default:
424 return (DLADM_STATUS_IPTUNTYPE);
425 }
426
427 status = dladm_create_datalink_id(handle, name, DATALINK_CLASS_IPTUN,
428 media, linkmgmt_flags, ¶ms->iptun_param_linkid);
429 if (status != DLADM_STATUS_OK)
430 return (status);
431
432 if (flags & DLADM_OPT_PERSIST) {
433 status = i_iptun_create_db(handle, name, params, media);
434 if (status != DLADM_STATUS_OK)
435 goto done;
436 }
437
438 if (flags & DLADM_OPT_ACTIVE) {
439 status = i_iptun_create_sys(handle, params);
440 if (status != DLADM_STATUS_OK && (flags & DLADM_OPT_PERSIST)) {
441 (void) dladm_remove_conf(handle,
442 params->iptun_param_linkid);
443 }
444 }
445
446 done:
447 if (status != DLADM_STATUS_OK) {
448 (void) dladm_destroy_datalink_id(handle,
449 params->iptun_param_linkid, flags);
450 }
451 return (status);
452 }
453
454 dladm_status_t
dladm_iptun_delete(dladm_handle_t handle,datalink_id_t linkid,uint32_t flags)455 dladm_iptun_delete(dladm_handle_t handle, datalink_id_t linkid, uint32_t flags)
456 {
457 dladm_status_t status;
458 datalink_class_t class;
459
460 /* First, make sure that this is an IP tunnel. */
461 if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL,
462 NULL, 0)) != DLADM_STATUS_OK)
463 return (status);
464 if (class != DATALINK_CLASS_IPTUN)
465 return (DLADM_STATUS_LINKINVAL);
466
467 if (flags & DLADM_OPT_ACTIVE) {
468 /*
469 * Note that if i_iptun_delete_sys() fails with
470 * DLADM_STATUS_NOTFOUND and the caller also wishes to delete
471 * the persistent configuration, we still fall through to the
472 * DLADM_OPT_PERSIST case in case the tunnel only exists
473 * persistently.
474 */
475 status = i_iptun_delete_sys(handle, linkid);
476 if (status != DLADM_STATUS_OK &&
477 (status != DLADM_STATUS_NOTFOUND ||
478 !(flags & DLADM_OPT_PERSIST)))
479 return (status);
480 }
481
482 if (flags & DLADM_OPT_PERSIST) {
483 (void) dladm_remove_conf(handle, linkid);
484 (void) dladm_destroy_datalink_id(handle, linkid,
485 DLADM_OPT_PERSIST);
486 }
487 return (DLADM_STATUS_OK);
488 }
489
490 dladm_status_t
dladm_iptun_modify(dladm_handle_t handle,const iptun_params_t * params,uint32_t flags)491 dladm_iptun_modify(dladm_handle_t handle, const iptun_params_t *params,
492 uint32_t flags)
493 {
494 dladm_status_t status = DLADM_STATUS_OK;
495 iptun_params_t old_params;
496
497 /*
498 * We can only modify the tunnel source, tunnel destination, or IPsec
499 * policy.
500 */
501 if (!(params->iptun_param_flags &
502 (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR|IPTUN_PARAM_SECINFO)))
503 return (DLADM_STATUS_BADARG);
504
505 if (flags & DLADM_OPT_PERSIST) {
506 /*
507 * Before we change the database, save the old configuration
508 * so that we can revert back if an error occurs.
509 */
510 old_params.iptun_param_linkid = params->iptun_param_linkid;
511 status = i_iptun_get_dbparams(handle, &old_params);
512 if (status != DLADM_STATUS_OK)
513 return (status);
514 /* we'll only need to revert the parameters being modified */
515 old_params.iptun_param_flags = params->iptun_param_flags;
516
517 status = i_iptun_modify_db(handle, params);
518 if (status != DLADM_STATUS_OK)
519 return (status);
520 }
521
522 if (flags & DLADM_OPT_ACTIVE) {
523 status = i_iptun_modify_sys(handle, params);
524 if (status != DLADM_STATUS_OK && (flags & DLADM_OPT_PERSIST)) {
525 (void) i_iptun_modify_db(handle, &old_params);
526 }
527 }
528
529 return (status);
530 }
531
532 dladm_status_t
dladm_iptun_getparams(dladm_handle_t handle,iptun_params_t * params,uint32_t flags)533 dladm_iptun_getparams(dladm_handle_t handle, iptun_params_t *params,
534 uint32_t flags)
535 {
536 if (flags == DLADM_OPT_ACTIVE)
537 return (i_iptun_get_sysparams(handle, params));
538 else if (flags == DLADM_OPT_PERSIST)
539 return (i_iptun_get_dbparams(handle, params));
540 else
541 return (DLADM_STATUS_BADARG);
542 }
543
544 static int
i_iptun_up(dladm_handle_t handle,datalink_id_t linkid,void * arg)545 i_iptun_up(dladm_handle_t handle, datalink_id_t linkid, void *arg)
546 {
547 dladm_status_t *statusp = arg;
548 dladm_status_t status;
549 iptun_params_t params;
550 boolean_t id_up = B_FALSE;
551
552 status = dladm_up_datalink_id(handle, linkid);
553 if (status != DLADM_STATUS_OK)
554 goto done;
555 id_up = B_TRUE;
556
557 (void) memset(¶ms, 0, sizeof (params));
558
559 params.iptun_param_linkid = linkid;
560 if ((status = i_iptun_get_dbparams(handle, ¶ms)) == DLADM_STATUS_OK)
561 status = i_iptun_create_sys(handle, ¶ms);
562 done:
563 if (statusp != NULL)
564 *statusp = status;
565 if (status != DLADM_STATUS_OK && id_up) {
566 (void) dladm_destroy_datalink_id(handle, linkid,
567 DLADM_OPT_ACTIVE);
568 }
569 return (DLADM_WALK_CONTINUE);
570 }
571
572 static int
i_iptun_down(dladm_handle_t handle,datalink_id_t linkid,void * arg)573 i_iptun_down(dladm_handle_t handle, datalink_id_t linkid, void *arg)
574 {
575 dladm_status_t *statusp = arg;
576 dladm_status_t status;
577
578 status = i_iptun_delete_sys(handle, linkid);
579 if (statusp != NULL)
580 *statusp = status;
581 return (DLADM_WALK_CONTINUE);
582 }
583
584 /* ARGSUSED */
585 dladm_status_t
dladm_iptun_up(dladm_handle_t handle,datalink_id_t linkid)586 dladm_iptun_up(dladm_handle_t handle, datalink_id_t linkid)
587 {
588 dladm_status_t status = DLADM_STATUS_OK;
589
590 if (linkid == DATALINK_ALL_LINKID) {
591 (void) dladm_walk_datalink_id(i_iptun_up, handle, NULL,
592 DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE,
593 DLADM_OPT_PERSIST);
594 } else {
595 (void) i_iptun_up(handle, linkid, &status);
596 }
597 return (status);
598 }
599
600 dladm_status_t
dladm_iptun_down(dladm_handle_t handle,datalink_id_t linkid)601 dladm_iptun_down(dladm_handle_t handle, datalink_id_t linkid)
602 {
603 dladm_status_t status = DLADM_STATUS_OK;
604
605 if (linkid == DATALINK_ALL_LINKID) {
606 (void) dladm_walk_datalink_id(i_iptun_down, handle, NULL,
607 DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE,
608 DLADM_OPT_ACTIVE);
609 } else {
610 (void) i_iptun_down(handle, linkid, &status);
611 }
612 return (status);
613 }
614
615 dladm_status_t
dladm_iptun_set6to4relay(dladm_handle_t handle,struct in_addr * relay)616 dladm_iptun_set6to4relay(dladm_handle_t handle, struct in_addr *relay)
617 {
618 return (i_iptun_ioctl(handle, IPTUN_SET_6TO4RELAY, relay));
619 }
620
621 dladm_status_t
dladm_iptun_get6to4relay(dladm_handle_t handle,struct in_addr * relay)622 dladm_iptun_get6to4relay(dladm_handle_t handle, struct in_addr *relay)
623 {
624 return (i_iptun_ioctl(handle, IPTUN_GET_6TO4RELAY, relay));
625 }
626