110616SSebastien.Roy@Sun.COM /*
210616SSebastien.Roy@Sun.COM * CDDL HEADER START
310616SSebastien.Roy@Sun.COM *
410616SSebastien.Roy@Sun.COM * The contents of this file are subject to the terms of the
510616SSebastien.Roy@Sun.COM * Common Development and Distribution License (the "License").
610616SSebastien.Roy@Sun.COM * You may not use this file except in compliance with the License.
710616SSebastien.Roy@Sun.COM *
810616SSebastien.Roy@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910616SSebastien.Roy@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010616SSebastien.Roy@Sun.COM * See the License for the specific language governing permissions
1110616SSebastien.Roy@Sun.COM * and limitations under the License.
1210616SSebastien.Roy@Sun.COM *
1310616SSebastien.Roy@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410616SSebastien.Roy@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510616SSebastien.Roy@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610616SSebastien.Roy@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710616SSebastien.Roy@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810616SSebastien.Roy@Sun.COM *
1910616SSebastien.Roy@Sun.COM * CDDL HEADER END
2010616SSebastien.Roy@Sun.COM */
2110616SSebastien.Roy@Sun.COM /*
22*12824SCathy.Zhou@Sun.COM * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2310616SSebastien.Roy@Sun.COM */
2410616SSebastien.Roy@Sun.COM
2510616SSebastien.Roy@Sun.COM #include <assert.h>
2610616SSebastien.Roy@Sun.COM #include <stdio.h>
2710616SSebastien.Roy@Sun.COM #include <errno.h>
2810616SSebastien.Roy@Sun.COM #include <stdlib.h>
2910616SSebastien.Roy@Sun.COM #include <unistd.h>
3010616SSebastien.Roy@Sun.COM #include <sys/types.h>
3110616SSebastien.Roy@Sun.COM #include <fcntl.h>
3210616SSebastien.Roy@Sun.COM #include <stropts.h>
3310616SSebastien.Roy@Sun.COM #include <string.h>
3410616SSebastien.Roy@Sun.COM #include <netdb.h>
3510616SSebastien.Roy@Sun.COM #include <sys/conf.h>
3610616SSebastien.Roy@Sun.COM #include <sys/socket.h>
3710616SSebastien.Roy@Sun.COM #include <netinet/in.h>
3810616SSebastien.Roy@Sun.COM #include <inet/iptun.h>
3910616SSebastien.Roy@Sun.COM #include <sys/dls.h>
4010616SSebastien.Roy@Sun.COM #include <libdlpi.h>
4110616SSebastien.Roy@Sun.COM #include <libdladm_impl.h>
4210616SSebastien.Roy@Sun.COM #include <libdllink.h>
4310616SSebastien.Roy@Sun.COM #include <libdliptun.h>
4410616SSebastien.Roy@Sun.COM
4510616SSebastien.Roy@Sun.COM /*
4610616SSebastien.Roy@Sun.COM * IP Tunneling Administration Library.
4710616SSebastien.Roy@Sun.COM * This library is used by dladm(1M) and to configure IP tunnel links.
4810616SSebastien.Roy@Sun.COM */
4910616SSebastien.Roy@Sun.COM
5010616SSebastien.Roy@Sun.COM #define IPTUN_CONF_TYPE "type"
5110616SSebastien.Roy@Sun.COM #define IPTUN_CONF_LADDR "laddr"
5210616SSebastien.Roy@Sun.COM #define IPTUN_CONF_RADDR "raddr"
5310616SSebastien.Roy@Sun.COM
5410616SSebastien.Roy@Sun.COM /*
5510616SSebastien.Roy@Sun.COM * If IPTUN_CREATE and IPTUN_MODIFY include IPsec policy and IPsec hasn't
5610616SSebastien.Roy@Sun.COM * loaded yet, the ioctls may return EAGAIN. We try the ioctl
5710616SSebastien.Roy@Sun.COM * IPTUN_IOCTL_ATTEMPT_LIMIT times and wait IPTUN_IOCTL_ATTEMPT_INTERVAL
5810616SSebastien.Roy@Sun.COM * microseconds between attempts.
5910616SSebastien.Roy@Sun.COM */
6010616SSebastien.Roy@Sun.COM #define IPTUN_IOCTL_ATTEMPT_LIMIT 3
6110616SSebastien.Roy@Sun.COM #define IPTUN_IOCTL_ATTEMPT_INTERVAL 10000
6210616SSebastien.Roy@Sun.COM
6310616SSebastien.Roy@Sun.COM dladm_status_t
i_iptun_ioctl(dladm_handle_t handle,int cmd,void * dp)6410616SSebastien.Roy@Sun.COM i_iptun_ioctl(dladm_handle_t handle, int cmd, void *dp)
6510616SSebastien.Roy@Sun.COM {
6610616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
6710616SSebastien.Roy@Sun.COM uint_t attempt;
6810616SSebastien.Roy@Sun.COM
6910616SSebastien.Roy@Sun.COM for (attempt = 0; attempt < IPTUN_IOCTL_ATTEMPT_LIMIT; attempt++) {
7010616SSebastien.Roy@Sun.COM if (attempt != 0)
7110616SSebastien.Roy@Sun.COM (void) usleep(IPTUN_IOCTL_ATTEMPT_INTERVAL);
7210616SSebastien.Roy@Sun.COM status = (ioctl(dladm_dld_fd(handle), cmd, dp) == 0) ?
7310616SSebastien.Roy@Sun.COM DLADM_STATUS_OK : dladm_errno2status(errno);
7410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_TRYAGAIN)
7510616SSebastien.Roy@Sun.COM break;
7610616SSebastien.Roy@Sun.COM }
7710616SSebastien.Roy@Sun.COM return (status);
7810616SSebastien.Roy@Sun.COM }
7910616SSebastien.Roy@Sun.COM
8010616SSebastien.Roy@Sun.COM /*
8110616SSebastien.Roy@Sun.COM * Given tunnel paramaters as supplied by a library consumer, fill in kernel
8210616SSebastien.Roy@Sun.COM * parameters to be passed down to the iptun control device.
8310616SSebastien.Roy@Sun.COM */
8410616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_kparams(dladm_handle_t handle,const iptun_params_t * params,iptun_kparams_t * ik)8510616SSebastien.Roy@Sun.COM i_iptun_kparams(dladm_handle_t handle, const iptun_params_t *params,
8610616SSebastien.Roy@Sun.COM iptun_kparams_t *ik)
8710616SSebastien.Roy@Sun.COM {
8810616SSebastien.Roy@Sun.COM dladm_status_t status;
8910616SSebastien.Roy@Sun.COM struct addrinfo *ai, hints;
9010616SSebastien.Roy@Sun.COM iptun_kparams_t tmpik;
9110616SSebastien.Roy@Sun.COM iptun_type_t iptuntype = IPTUN_TYPE_UNKNOWN;
9210616SSebastien.Roy@Sun.COM
9310616SSebastien.Roy@Sun.COM (void) memset(ik, 0, sizeof (*ik));
9410616SSebastien.Roy@Sun.COM
9510616SSebastien.Roy@Sun.COM ik->iptun_kparam_linkid = params->iptun_param_linkid;
9610616SSebastien.Roy@Sun.COM
9710616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_TYPE) {
9810616SSebastien.Roy@Sun.COM ik->iptun_kparam_type = iptuntype = params->iptun_param_type;
9910616SSebastien.Roy@Sun.COM ik->iptun_kparam_flags |= IPTUN_KPARAM_TYPE;
10010616SSebastien.Roy@Sun.COM }
10110616SSebastien.Roy@Sun.COM
10210616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR)) {
10310616SSebastien.Roy@Sun.COM if (iptuntype == IPTUN_TYPE_UNKNOWN) {
10410616SSebastien.Roy@Sun.COM /*
10510616SSebastien.Roy@Sun.COM * We need to get the type of this existing tunnel in
10610616SSebastien.Roy@Sun.COM * order to validate and/or look up the right kind of
10710616SSebastien.Roy@Sun.COM * IP address.
10810616SSebastien.Roy@Sun.COM */
10910616SSebastien.Roy@Sun.COM tmpik.iptun_kparam_linkid = params->iptun_param_linkid;
11010616SSebastien.Roy@Sun.COM status = i_iptun_ioctl(handle, IPTUN_INFO, &tmpik);
11110616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
11210616SSebastien.Roy@Sun.COM return (status);
11310616SSebastien.Roy@Sun.COM iptuntype = tmpik.iptun_kparam_type;
11410616SSebastien.Roy@Sun.COM }
11510616SSebastien.Roy@Sun.COM
11610616SSebastien.Roy@Sun.COM (void) memset(&hints, 0, sizeof (hints));
11710616SSebastien.Roy@Sun.COM switch (iptuntype) {
11810616SSebastien.Roy@Sun.COM case IPTUN_TYPE_IPV4:
11910616SSebastien.Roy@Sun.COM case IPTUN_TYPE_6TO4:
12010616SSebastien.Roy@Sun.COM hints.ai_family = AF_INET;
12110616SSebastien.Roy@Sun.COM break;
12210616SSebastien.Roy@Sun.COM case IPTUN_TYPE_IPV6:
12310616SSebastien.Roy@Sun.COM hints.ai_family = AF_INET6;
12410616SSebastien.Roy@Sun.COM break;
12510616SSebastien.Roy@Sun.COM }
12610616SSebastien.Roy@Sun.COM }
12710616SSebastien.Roy@Sun.COM
12810616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
12910616SSebastien.Roy@Sun.COM if (getaddrinfo(params->iptun_param_laddr, NULL, &hints, &ai) !=
13010616SSebastien.Roy@Sun.COM 0)
13110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNLADDR);
13210616SSebastien.Roy@Sun.COM if (ai->ai_next != NULL) {
13310616SSebastien.Roy@Sun.COM freeaddrinfo(ai);
13410616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNLADDR);
13510616SSebastien.Roy@Sun.COM }
13610616SSebastien.Roy@Sun.COM (void) memcpy(&ik->iptun_kparam_laddr, ai->ai_addr,
13710616SSebastien.Roy@Sun.COM ai->ai_addrlen);
13810616SSebastien.Roy@Sun.COM ik->iptun_kparam_flags |= IPTUN_KPARAM_LADDR;
13910616SSebastien.Roy@Sun.COM freeaddrinfo(ai);
14010616SSebastien.Roy@Sun.COM }
14110616SSebastien.Roy@Sun.COM
14210616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
14310616SSebastien.Roy@Sun.COM if (getaddrinfo(params->iptun_param_raddr, NULL, &hints, &ai) !=
14410616SSebastien.Roy@Sun.COM 0)
14510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNRADDR);
14610616SSebastien.Roy@Sun.COM if (ai->ai_next != NULL) {
14710616SSebastien.Roy@Sun.COM freeaddrinfo(ai);
14810616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNRADDR);
14910616SSebastien.Roy@Sun.COM }
15010616SSebastien.Roy@Sun.COM (void) memcpy(&ik->iptun_kparam_raddr, ai->ai_addr,
15110616SSebastien.Roy@Sun.COM ai->ai_addrlen);
15210616SSebastien.Roy@Sun.COM ik->iptun_kparam_flags |= IPTUN_KPARAM_RADDR;
15310616SSebastien.Roy@Sun.COM freeaddrinfo(ai);
15410616SSebastien.Roy@Sun.COM }
15510616SSebastien.Roy@Sun.COM
15610616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_SECINFO) {
15710616SSebastien.Roy@Sun.COM ik->iptun_kparam_secinfo = params->iptun_param_secinfo;
15810616SSebastien.Roy@Sun.COM ik->iptun_kparam_flags |= IPTUN_KPARAM_SECINFO;
15910616SSebastien.Roy@Sun.COM }
16010616SSebastien.Roy@Sun.COM
16110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK);
16210616SSebastien.Roy@Sun.COM }
16310616SSebastien.Roy@Sun.COM
16410616SSebastien.Roy@Sun.COM /*
16510616SSebastien.Roy@Sun.COM * The inverse of i_iptun_kparams(). Given kernel tunnel paramaters as
16610616SSebastien.Roy@Sun.COM * returned from an IPTUN_INFO ioctl, fill in tunnel parameters.
16710616SSebastien.Roy@Sun.COM */
16810616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_params(const iptun_kparams_t * ik,iptun_params_t * params)16910616SSebastien.Roy@Sun.COM i_iptun_params(const iptun_kparams_t *ik, iptun_params_t *params)
17010616SSebastien.Roy@Sun.COM {
17110616SSebastien.Roy@Sun.COM socklen_t salen;
17210616SSebastien.Roy@Sun.COM
17310616SSebastien.Roy@Sun.COM (void) memset(params, 0, sizeof (*params));
17410616SSebastien.Roy@Sun.COM
17510616SSebastien.Roy@Sun.COM params->iptun_param_linkid = ik->iptun_kparam_linkid;
17610616SSebastien.Roy@Sun.COM
17710616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_TYPE) {
17810616SSebastien.Roy@Sun.COM params->iptun_param_type = ik->iptun_kparam_type;
17910616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_TYPE;
18010616SSebastien.Roy@Sun.COM }
18110616SSebastien.Roy@Sun.COM
18210616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_LADDR) {
18310616SSebastien.Roy@Sun.COM salen = ik->iptun_kparam_laddr.ss_family == AF_INET ?
18410616SSebastien.Roy@Sun.COM sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6);
18510616SSebastien.Roy@Sun.COM if (getnameinfo((const struct sockaddr *)
18610616SSebastien.Roy@Sun.COM &ik->iptun_kparam_laddr, salen, params->iptun_param_laddr,
18710616SSebastien.Roy@Sun.COM sizeof (params->iptun_param_laddr), NULL, 0,
18810616SSebastien.Roy@Sun.COM NI_NUMERICHOST) != 0) {
18910616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNLADDR);
19010616SSebastien.Roy@Sun.COM }
19110616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_LADDR;
19210616SSebastien.Roy@Sun.COM }
19310616SSebastien.Roy@Sun.COM
19410616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_RADDR) {
19510616SSebastien.Roy@Sun.COM salen = ik->iptun_kparam_raddr.ss_family == AF_INET ?
19610616SSebastien.Roy@Sun.COM sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6);
19710616SSebastien.Roy@Sun.COM if (getnameinfo((const struct sockaddr *)
19810616SSebastien.Roy@Sun.COM &ik->iptun_kparam_raddr, salen, params->iptun_param_raddr,
19910616SSebastien.Roy@Sun.COM sizeof (params->iptun_param_raddr), NULL, 0,
20010616SSebastien.Roy@Sun.COM NI_NUMERICHOST) != 0) {
20110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADIPTUNRADDR);
20210616SSebastien.Roy@Sun.COM }
20310616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_RADDR;
20410616SSebastien.Roy@Sun.COM }
20510616SSebastien.Roy@Sun.COM
20610616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_SECINFO) {
20710616SSebastien.Roy@Sun.COM params->iptun_param_secinfo = ik->iptun_kparam_secinfo;
20810616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_SECINFO;
20910616SSebastien.Roy@Sun.COM }
21010616SSebastien.Roy@Sun.COM
21110616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_IMPLICIT)
21210616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_IMPLICIT;
21310616SSebastien.Roy@Sun.COM
21410616SSebastien.Roy@Sun.COM if (ik->iptun_kparam_flags & IPTUN_KPARAM_IPSECPOL)
21510616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_IPSECPOL;
21610616SSebastien.Roy@Sun.COM
21710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK);
21810616SSebastien.Roy@Sun.COM }
21910616SSebastien.Roy@Sun.COM
22010616SSebastien.Roy@Sun.COM dladm_status_t
i_iptun_get_sysparams(dladm_handle_t handle,iptun_params_t * params)22110616SSebastien.Roy@Sun.COM i_iptun_get_sysparams(dladm_handle_t handle, iptun_params_t *params)
22210616SSebastien.Roy@Sun.COM {
22310616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
22410616SSebastien.Roy@Sun.COM iptun_kparams_t ik;
22510616SSebastien.Roy@Sun.COM
22610616SSebastien.Roy@Sun.COM ik.iptun_kparam_linkid = params->iptun_param_linkid;
22710616SSebastien.Roy@Sun.COM status = i_iptun_ioctl(handle, IPTUN_INFO, &ik);
22810616SSebastien.Roy@Sun.COM if (status == DLADM_STATUS_OK)
22910616SSebastien.Roy@Sun.COM status = i_iptun_params(&ik, params);
23010616SSebastien.Roy@Sun.COM return (status);
23110616SSebastien.Roy@Sun.COM }
23210616SSebastien.Roy@Sun.COM
23310616SSebastien.Roy@Sun.COM /*
23410616SSebastien.Roy@Sun.COM * Read tunnel parameters from persistent storage. Note that the tunnel type
23510616SSebastien.Roy@Sun.COM * is the only thing which must always be in the configuratioh. All other
23610616SSebastien.Roy@Sun.COM * parameters (currently the source and destination addresses) may or may not
23710616SSebastien.Roy@Sun.COM * have been configured, and therefore may not have been set.
23810616SSebastien.Roy@Sun.COM */
23910616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_get_dbparams(dladm_handle_t handle,iptun_params_t * params)24010616SSebastien.Roy@Sun.COM i_iptun_get_dbparams(dladm_handle_t handle, iptun_params_t *params)
24110616SSebastien.Roy@Sun.COM {
24210616SSebastien.Roy@Sun.COM dladm_status_t status;
24310616SSebastien.Roy@Sun.COM dladm_conf_t conf;
24410616SSebastien.Roy@Sun.COM datalink_class_t class;
24510616SSebastien.Roy@Sun.COM uint64_t temp;
24610616SSebastien.Roy@Sun.COM
24710616SSebastien.Roy@Sun.COM /* First, make sure that this is an IP tunnel. */
24810616SSebastien.Roy@Sun.COM if ((status = dladm_datalink_id2info(handle, params->iptun_param_linkid,
24910616SSebastien.Roy@Sun.COM NULL, &class, NULL, NULL, 0)) != DLADM_STATUS_OK)
25010616SSebastien.Roy@Sun.COM return (status);
25110616SSebastien.Roy@Sun.COM if (class != DATALINK_CLASS_IPTUN)
25210616SSebastien.Roy@Sun.COM return (DLADM_STATUS_LINKINVAL);
25310616SSebastien.Roy@Sun.COM
254*12824SCathy.Zhou@Sun.COM if ((status = dladm_getsnap_conf(handle, params->iptun_param_linkid,
255*12824SCathy.Zhou@Sun.COM &conf)) != DLADM_STATUS_OK) {
25610616SSebastien.Roy@Sun.COM return (status);
257*12824SCathy.Zhou@Sun.COM }
25810616SSebastien.Roy@Sun.COM
25910616SSebastien.Roy@Sun.COM params->iptun_param_flags = 0;
26010616SSebastien.Roy@Sun.COM
26110616SSebastien.Roy@Sun.COM if ((status = dladm_get_conf_field(handle, conf, IPTUN_CONF_TYPE, &temp,
26210616SSebastien.Roy@Sun.COM sizeof (temp))) != DLADM_STATUS_OK)
26310616SSebastien.Roy@Sun.COM goto done;
26410616SSebastien.Roy@Sun.COM params->iptun_param_type = (iptun_type_t)temp;
26510616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_TYPE;
26610616SSebastien.Roy@Sun.COM
26710616SSebastien.Roy@Sun.COM if (dladm_get_conf_field(handle, conf, IPTUN_CONF_LADDR,
26810616SSebastien.Roy@Sun.COM params->iptun_param_laddr, sizeof (params->iptun_param_laddr)) ==
26910616SSebastien.Roy@Sun.COM DLADM_STATUS_OK)
27010616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_LADDR;
27110616SSebastien.Roy@Sun.COM
27210616SSebastien.Roy@Sun.COM if (dladm_get_conf_field(handle, conf, IPTUN_CONF_RADDR,
27310616SSebastien.Roy@Sun.COM params->iptun_param_raddr, sizeof (params->iptun_param_raddr)) ==
27410616SSebastien.Roy@Sun.COM DLADM_STATUS_OK)
27510616SSebastien.Roy@Sun.COM params->iptun_param_flags |= IPTUN_PARAM_RADDR;
27610616SSebastien.Roy@Sun.COM
27710616SSebastien.Roy@Sun.COM done:
27810616SSebastien.Roy@Sun.COM dladm_destroy_conf(handle, conf);
27910616SSebastien.Roy@Sun.COM return (status);
28010616SSebastien.Roy@Sun.COM }
28110616SSebastien.Roy@Sun.COM
28210616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_create_sys(dladm_handle_t handle,iptun_params_t * params)28310616SSebastien.Roy@Sun.COM i_iptun_create_sys(dladm_handle_t handle, iptun_params_t *params)
28410616SSebastien.Roy@Sun.COM {
28510616SSebastien.Roy@Sun.COM iptun_kparams_t ik;
28610616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
28710616SSebastien.Roy@Sun.COM
28810616SSebastien.Roy@Sun.COM /* The tunnel type is required for creation. */
28910616SSebastien.Roy@Sun.COM if (!(params->iptun_param_flags & IPTUN_PARAM_TYPE))
29010616SSebastien.Roy@Sun.COM return (DLADM_STATUS_IPTUNTYPEREQD);
29110616SSebastien.Roy@Sun.COM
29210616SSebastien.Roy@Sun.COM if ((status = i_iptun_kparams(handle, params, &ik)) == DLADM_STATUS_OK)
29310616SSebastien.Roy@Sun.COM status = i_iptun_ioctl(handle, IPTUN_CREATE, &ik);
29410616SSebastien.Roy@Sun.COM return (status);
29510616SSebastien.Roy@Sun.COM }
29610616SSebastien.Roy@Sun.COM
29710616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_create_db(dladm_handle_t handle,const char * name,iptun_params_t * params,uint32_t media)29810616SSebastien.Roy@Sun.COM i_iptun_create_db(dladm_handle_t handle, const char *name,
29910616SSebastien.Roy@Sun.COM iptun_params_t *params, uint32_t media)
30010616SSebastien.Roy@Sun.COM {
30110616SSebastien.Roy@Sun.COM dladm_conf_t conf;
30210616SSebastien.Roy@Sun.COM dladm_status_t status;
30310616SSebastien.Roy@Sun.COM uint64_t storage;
30410616SSebastien.Roy@Sun.COM
30510616SSebastien.Roy@Sun.COM status = dladm_create_conf(handle, name, params->iptun_param_linkid,
30610616SSebastien.Roy@Sun.COM DATALINK_CLASS_IPTUN, media, &conf);
30710616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
30810616SSebastien.Roy@Sun.COM return (status);
30910616SSebastien.Roy@Sun.COM
31010616SSebastien.Roy@Sun.COM assert(params->iptun_param_flags & IPTUN_PARAM_TYPE);
31110616SSebastien.Roy@Sun.COM storage = params->iptun_param_type;
31210616SSebastien.Roy@Sun.COM status = dladm_set_conf_field(handle, conf, IPTUN_CONF_TYPE,
31310616SSebastien.Roy@Sun.COM DLADM_TYPE_UINT64, &storage);
31410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
31510616SSebastien.Roy@Sun.COM goto done;
31610616SSebastien.Roy@Sun.COM
31710616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
31810616SSebastien.Roy@Sun.COM status = dladm_set_conf_field(handle, conf, IPTUN_CONF_LADDR,
31910616SSebastien.Roy@Sun.COM DLADM_TYPE_STR, params->iptun_param_laddr);
32010616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
32110616SSebastien.Roy@Sun.COM goto done;
32210616SSebastien.Roy@Sun.COM }
32310616SSebastien.Roy@Sun.COM
32410616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
32510616SSebastien.Roy@Sun.COM status = dladm_set_conf_field(handle, conf, IPTUN_CONF_RADDR,
32610616SSebastien.Roy@Sun.COM DLADM_TYPE_STR, params->iptun_param_raddr);
32710616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
32810616SSebastien.Roy@Sun.COM goto done;
32910616SSebastien.Roy@Sun.COM }
33010616SSebastien.Roy@Sun.COM
33110616SSebastien.Roy@Sun.COM status = dladm_write_conf(handle, conf);
33210616SSebastien.Roy@Sun.COM
33310616SSebastien.Roy@Sun.COM done:
33410616SSebastien.Roy@Sun.COM dladm_destroy_conf(handle, conf);
33510616SSebastien.Roy@Sun.COM return (status);
33610616SSebastien.Roy@Sun.COM }
33710616SSebastien.Roy@Sun.COM
33810616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_delete_sys(dladm_handle_t handle,datalink_id_t linkid)33910616SSebastien.Roy@Sun.COM i_iptun_delete_sys(dladm_handle_t handle, datalink_id_t linkid)
34010616SSebastien.Roy@Sun.COM {
34110616SSebastien.Roy@Sun.COM dladm_status_t status;
34210616SSebastien.Roy@Sun.COM
34310616SSebastien.Roy@Sun.COM status = i_iptun_ioctl(handle, IPTUN_DELETE, &linkid);
34410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
34510616SSebastien.Roy@Sun.COM return (status);
34610616SSebastien.Roy@Sun.COM (void) dladm_destroy_datalink_id(handle, linkid, DLADM_OPT_ACTIVE);
34710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK);
34810616SSebastien.Roy@Sun.COM }
34910616SSebastien.Roy@Sun.COM
35010616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_modify_sys(dladm_handle_t handle,const iptun_params_t * params)35110616SSebastien.Roy@Sun.COM i_iptun_modify_sys(dladm_handle_t handle, const iptun_params_t *params)
35210616SSebastien.Roy@Sun.COM {
35310616SSebastien.Roy@Sun.COM iptun_kparams_t ik;
35410616SSebastien.Roy@Sun.COM dladm_status_t status;
35510616SSebastien.Roy@Sun.COM
35610616SSebastien.Roy@Sun.COM if ((status = i_iptun_kparams(handle, params, &ik)) == DLADM_STATUS_OK)
35710616SSebastien.Roy@Sun.COM status = i_iptun_ioctl(handle, IPTUN_MODIFY, &ik);
35810616SSebastien.Roy@Sun.COM return (status);
35910616SSebastien.Roy@Sun.COM }
36010616SSebastien.Roy@Sun.COM
36110616SSebastien.Roy@Sun.COM static dladm_status_t
i_iptun_modify_db(dladm_handle_t handle,const iptun_params_t * params)36210616SSebastien.Roy@Sun.COM i_iptun_modify_db(dladm_handle_t handle, const iptun_params_t *params)
36310616SSebastien.Roy@Sun.COM {
36410616SSebastien.Roy@Sun.COM dladm_conf_t conf;
36510616SSebastien.Roy@Sun.COM dladm_status_t status;
36610616SSebastien.Roy@Sun.COM
36710616SSebastien.Roy@Sun.COM assert(params->iptun_param_flags &
36810616SSebastien.Roy@Sun.COM (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR));
36910616SSebastien.Roy@Sun.COM
37010616SSebastien.Roy@Sun.COM /*
37110616SSebastien.Roy@Sun.COM * The only parameters that can be modified persistently are the local
37210616SSebastien.Roy@Sun.COM * and remote addresses.
37310616SSebastien.Roy@Sun.COM */
37410616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & ~(IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR))
37510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG);
37610616SSebastien.Roy@Sun.COM
377*12824SCathy.Zhou@Sun.COM status = dladm_open_conf(handle, params->iptun_param_linkid, &conf);
37810616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
37910616SSebastien.Roy@Sun.COM return (status);
38010616SSebastien.Roy@Sun.COM
38110616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_LADDR) {
38210616SSebastien.Roy@Sun.COM status = dladm_set_conf_field(handle, conf, IPTUN_CONF_LADDR,
38310616SSebastien.Roy@Sun.COM DLADM_TYPE_STR, (void *)params->iptun_param_laddr);
38410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
38510616SSebastien.Roy@Sun.COM goto done;
38610616SSebastien.Roy@Sun.COM }
38710616SSebastien.Roy@Sun.COM
38810616SSebastien.Roy@Sun.COM if (params->iptun_param_flags & IPTUN_PARAM_RADDR) {
38910616SSebastien.Roy@Sun.COM status = dladm_set_conf_field(handle, conf, IPTUN_CONF_RADDR,
39010616SSebastien.Roy@Sun.COM DLADM_TYPE_STR, (void *)params->iptun_param_raddr);
39110616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
39210616SSebastien.Roy@Sun.COM goto done;
39310616SSebastien.Roy@Sun.COM }
39410616SSebastien.Roy@Sun.COM
39510616SSebastien.Roy@Sun.COM status = dladm_write_conf(handle, conf);
39610616SSebastien.Roy@Sun.COM
39710616SSebastien.Roy@Sun.COM done:
39810616SSebastien.Roy@Sun.COM dladm_destroy_conf(handle, conf);
39910616SSebastien.Roy@Sun.COM return (status);
40010616SSebastien.Roy@Sun.COM }
40110616SSebastien.Roy@Sun.COM
40210616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_create(dladm_handle_t handle,const char * name,iptun_params_t * params,uint32_t flags)40310616SSebastien.Roy@Sun.COM dladm_iptun_create(dladm_handle_t handle, const char *name,
40410616SSebastien.Roy@Sun.COM iptun_params_t *params, uint32_t flags)
40510616SSebastien.Roy@Sun.COM {
40610616SSebastien.Roy@Sun.COM dladm_status_t status;
40710616SSebastien.Roy@Sun.COM uint32_t linkmgmt_flags = flags;
40810616SSebastien.Roy@Sun.COM uint32_t media;
40910616SSebastien.Roy@Sun.COM
41010616SSebastien.Roy@Sun.COM if (!(params->iptun_param_flags & IPTUN_PARAM_TYPE))
41110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_IPTUNTYPEREQD);
41210616SSebastien.Roy@Sun.COM
41310616SSebastien.Roy@Sun.COM switch (params->iptun_param_type) {
41410616SSebastien.Roy@Sun.COM case IPTUN_TYPE_IPV4:
41510616SSebastien.Roy@Sun.COM media = DL_IPV4;
41610616SSebastien.Roy@Sun.COM break;
41710616SSebastien.Roy@Sun.COM case IPTUN_TYPE_IPV6:
41810616SSebastien.Roy@Sun.COM media = DL_IPV6;
41910616SSebastien.Roy@Sun.COM break;
42010616SSebastien.Roy@Sun.COM case IPTUN_TYPE_6TO4:
42110616SSebastien.Roy@Sun.COM media = DL_6TO4;
42210616SSebastien.Roy@Sun.COM break;
42310616SSebastien.Roy@Sun.COM default:
42410616SSebastien.Roy@Sun.COM return (DLADM_STATUS_IPTUNTYPE);
42510616SSebastien.Roy@Sun.COM }
42610616SSebastien.Roy@Sun.COM
42710616SSebastien.Roy@Sun.COM status = dladm_create_datalink_id(handle, name, DATALINK_CLASS_IPTUN,
42810616SSebastien.Roy@Sun.COM media, linkmgmt_flags, ¶ms->iptun_param_linkid);
42910616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
43010616SSebastien.Roy@Sun.COM return (status);
43110616SSebastien.Roy@Sun.COM
43210616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_PERSIST) {
43310616SSebastien.Roy@Sun.COM status = i_iptun_create_db(handle, name, params, media);
43410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
43510616SSebastien.Roy@Sun.COM goto done;
43610616SSebastien.Roy@Sun.COM }
43710616SSebastien.Roy@Sun.COM
43810616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_ACTIVE) {
43910616SSebastien.Roy@Sun.COM status = i_iptun_create_sys(handle, params);
44010616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK && (flags & DLADM_OPT_PERSIST)) {
44110616SSebastien.Roy@Sun.COM (void) dladm_remove_conf(handle,
44210616SSebastien.Roy@Sun.COM params->iptun_param_linkid);
44310616SSebastien.Roy@Sun.COM }
44410616SSebastien.Roy@Sun.COM }
44510616SSebastien.Roy@Sun.COM
44610616SSebastien.Roy@Sun.COM done:
44710616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK) {
44810616SSebastien.Roy@Sun.COM (void) dladm_destroy_datalink_id(handle,
44910616SSebastien.Roy@Sun.COM params->iptun_param_linkid, flags);
45010616SSebastien.Roy@Sun.COM }
45110616SSebastien.Roy@Sun.COM return (status);
45210616SSebastien.Roy@Sun.COM }
45310616SSebastien.Roy@Sun.COM
45410616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_delete(dladm_handle_t handle,datalink_id_t linkid,uint32_t flags)45510616SSebastien.Roy@Sun.COM dladm_iptun_delete(dladm_handle_t handle, datalink_id_t linkid, uint32_t flags)
45610616SSebastien.Roy@Sun.COM {
45710616SSebastien.Roy@Sun.COM dladm_status_t status;
45810616SSebastien.Roy@Sun.COM datalink_class_t class;
45910616SSebastien.Roy@Sun.COM
46010616SSebastien.Roy@Sun.COM /* First, make sure that this is an IP tunnel. */
46110616SSebastien.Roy@Sun.COM if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class, NULL,
46210616SSebastien.Roy@Sun.COM NULL, 0)) != DLADM_STATUS_OK)
46310616SSebastien.Roy@Sun.COM return (status);
46410616SSebastien.Roy@Sun.COM if (class != DATALINK_CLASS_IPTUN)
46510616SSebastien.Roy@Sun.COM return (DLADM_STATUS_LINKINVAL);
46610616SSebastien.Roy@Sun.COM
46710616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_ACTIVE) {
46810616SSebastien.Roy@Sun.COM /*
46910616SSebastien.Roy@Sun.COM * Note that if i_iptun_delete_sys() fails with
47010616SSebastien.Roy@Sun.COM * DLADM_STATUS_NOTFOUND and the caller also wishes to delete
47110616SSebastien.Roy@Sun.COM * the persistent configuration, we still fall through to the
47210616SSebastien.Roy@Sun.COM * DLADM_OPT_PERSIST case in case the tunnel only exists
47310616SSebastien.Roy@Sun.COM * persistently.
47410616SSebastien.Roy@Sun.COM */
47510616SSebastien.Roy@Sun.COM status = i_iptun_delete_sys(handle, linkid);
47610616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK &&
47710616SSebastien.Roy@Sun.COM (status != DLADM_STATUS_NOTFOUND ||
47810616SSebastien.Roy@Sun.COM !(flags & DLADM_OPT_PERSIST)))
47910616SSebastien.Roy@Sun.COM return (status);
48010616SSebastien.Roy@Sun.COM }
48110616SSebastien.Roy@Sun.COM
48210616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_PERSIST) {
48310616SSebastien.Roy@Sun.COM (void) dladm_remove_conf(handle, linkid);
48410616SSebastien.Roy@Sun.COM (void) dladm_destroy_datalink_id(handle, linkid,
48510616SSebastien.Roy@Sun.COM DLADM_OPT_PERSIST);
48610616SSebastien.Roy@Sun.COM }
48710616SSebastien.Roy@Sun.COM return (DLADM_STATUS_OK);
48810616SSebastien.Roy@Sun.COM }
48910616SSebastien.Roy@Sun.COM
49010616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_modify(dladm_handle_t handle,const iptun_params_t * params,uint32_t flags)49110616SSebastien.Roy@Sun.COM dladm_iptun_modify(dladm_handle_t handle, const iptun_params_t *params,
49210616SSebastien.Roy@Sun.COM uint32_t flags)
49310616SSebastien.Roy@Sun.COM {
49410616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
49510616SSebastien.Roy@Sun.COM iptun_params_t old_params;
49610616SSebastien.Roy@Sun.COM
49710616SSebastien.Roy@Sun.COM /*
49810616SSebastien.Roy@Sun.COM * We can only modify the tunnel source, tunnel destination, or IPsec
49910616SSebastien.Roy@Sun.COM * policy.
50010616SSebastien.Roy@Sun.COM */
50110616SSebastien.Roy@Sun.COM if (!(params->iptun_param_flags &
50210616SSebastien.Roy@Sun.COM (IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR|IPTUN_PARAM_SECINFO)))
50310616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG);
50410616SSebastien.Roy@Sun.COM
50510616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_PERSIST) {
50610616SSebastien.Roy@Sun.COM /*
50710616SSebastien.Roy@Sun.COM * Before we change the database, save the old configuration
50810616SSebastien.Roy@Sun.COM * so that we can revert back if an error occurs.
50910616SSebastien.Roy@Sun.COM */
51010616SSebastien.Roy@Sun.COM old_params.iptun_param_linkid = params->iptun_param_linkid;
51110616SSebastien.Roy@Sun.COM status = i_iptun_get_dbparams(handle, &old_params);
51210616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
51310616SSebastien.Roy@Sun.COM return (status);
51410616SSebastien.Roy@Sun.COM /* we'll only need to revert the parameters being modified */
51510616SSebastien.Roy@Sun.COM old_params.iptun_param_flags = params->iptun_param_flags;
51610616SSebastien.Roy@Sun.COM
51710616SSebastien.Roy@Sun.COM status = i_iptun_modify_db(handle, params);
51810616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
51910616SSebastien.Roy@Sun.COM return (status);
52010616SSebastien.Roy@Sun.COM }
52110616SSebastien.Roy@Sun.COM
52210616SSebastien.Roy@Sun.COM if (flags & DLADM_OPT_ACTIVE) {
52310616SSebastien.Roy@Sun.COM status = i_iptun_modify_sys(handle, params);
52410616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK && (flags & DLADM_OPT_PERSIST)) {
52510616SSebastien.Roy@Sun.COM (void) i_iptun_modify_db(handle, &old_params);
52610616SSebastien.Roy@Sun.COM }
52710616SSebastien.Roy@Sun.COM }
52810616SSebastien.Roy@Sun.COM
52910616SSebastien.Roy@Sun.COM return (status);
53010616SSebastien.Roy@Sun.COM }
53110616SSebastien.Roy@Sun.COM
53210616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_getparams(dladm_handle_t handle,iptun_params_t * params,uint32_t flags)53310616SSebastien.Roy@Sun.COM dladm_iptun_getparams(dladm_handle_t handle, iptun_params_t *params,
53410616SSebastien.Roy@Sun.COM uint32_t flags)
53510616SSebastien.Roy@Sun.COM {
53610616SSebastien.Roy@Sun.COM if (flags == DLADM_OPT_ACTIVE)
53710616SSebastien.Roy@Sun.COM return (i_iptun_get_sysparams(handle, params));
53810616SSebastien.Roy@Sun.COM else if (flags == DLADM_OPT_PERSIST)
53910616SSebastien.Roy@Sun.COM return (i_iptun_get_dbparams(handle, params));
54010616SSebastien.Roy@Sun.COM else
54110616SSebastien.Roy@Sun.COM return (DLADM_STATUS_BADARG);
54210616SSebastien.Roy@Sun.COM }
54310616SSebastien.Roy@Sun.COM
54410616SSebastien.Roy@Sun.COM static int
i_iptun_up(dladm_handle_t handle,datalink_id_t linkid,void * arg)54510616SSebastien.Roy@Sun.COM i_iptun_up(dladm_handle_t handle, datalink_id_t linkid, void *arg)
54610616SSebastien.Roy@Sun.COM {
54710616SSebastien.Roy@Sun.COM dladm_status_t *statusp = arg;
54810616SSebastien.Roy@Sun.COM dladm_status_t status;
54910616SSebastien.Roy@Sun.COM iptun_params_t params;
55010616SSebastien.Roy@Sun.COM boolean_t id_up = B_FALSE;
55110616SSebastien.Roy@Sun.COM
55210616SSebastien.Roy@Sun.COM status = dladm_up_datalink_id(handle, linkid);
55310616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK)
55410616SSebastien.Roy@Sun.COM goto done;
55510616SSebastien.Roy@Sun.COM id_up = B_TRUE;
55610616SSebastien.Roy@Sun.COM
55710616SSebastien.Roy@Sun.COM (void) memset(¶ms, 0, sizeof (params));
55810616SSebastien.Roy@Sun.COM
55910616SSebastien.Roy@Sun.COM params.iptun_param_linkid = linkid;
56010616SSebastien.Roy@Sun.COM if ((status = i_iptun_get_dbparams(handle, ¶ms)) == DLADM_STATUS_OK)
56110616SSebastien.Roy@Sun.COM status = i_iptun_create_sys(handle, ¶ms);
56210616SSebastien.Roy@Sun.COM done:
56310616SSebastien.Roy@Sun.COM if (statusp != NULL)
56410616SSebastien.Roy@Sun.COM *statusp = status;
56510616SSebastien.Roy@Sun.COM if (status != DLADM_STATUS_OK && id_up) {
56610616SSebastien.Roy@Sun.COM (void) dladm_destroy_datalink_id(handle, linkid,
56710616SSebastien.Roy@Sun.COM DLADM_OPT_ACTIVE);
56810616SSebastien.Roy@Sun.COM }
56910616SSebastien.Roy@Sun.COM return (DLADM_WALK_CONTINUE);
57010616SSebastien.Roy@Sun.COM }
57110616SSebastien.Roy@Sun.COM
57210616SSebastien.Roy@Sun.COM static int
i_iptun_down(dladm_handle_t handle,datalink_id_t linkid,void * arg)57310616SSebastien.Roy@Sun.COM i_iptun_down(dladm_handle_t handle, datalink_id_t linkid, void *arg)
57410616SSebastien.Roy@Sun.COM {
57510616SSebastien.Roy@Sun.COM dladm_status_t *statusp = arg;
57610616SSebastien.Roy@Sun.COM dladm_status_t status;
57710616SSebastien.Roy@Sun.COM
57810616SSebastien.Roy@Sun.COM status = i_iptun_delete_sys(handle, linkid);
57910616SSebastien.Roy@Sun.COM if (statusp != NULL)
58010616SSebastien.Roy@Sun.COM *statusp = status;
58110616SSebastien.Roy@Sun.COM return (DLADM_WALK_CONTINUE);
58210616SSebastien.Roy@Sun.COM }
58310616SSebastien.Roy@Sun.COM
58410616SSebastien.Roy@Sun.COM /* ARGSUSED */
58510616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_up(dladm_handle_t handle,datalink_id_t linkid)58610616SSebastien.Roy@Sun.COM dladm_iptun_up(dladm_handle_t handle, datalink_id_t linkid)
58710616SSebastien.Roy@Sun.COM {
58810616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
58910616SSebastien.Roy@Sun.COM
59010616SSebastien.Roy@Sun.COM if (linkid == DATALINK_ALL_LINKID) {
59110616SSebastien.Roy@Sun.COM (void) dladm_walk_datalink_id(i_iptun_up, handle, NULL,
59210616SSebastien.Roy@Sun.COM DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE,
59310616SSebastien.Roy@Sun.COM DLADM_OPT_PERSIST);
59410616SSebastien.Roy@Sun.COM } else {
59510616SSebastien.Roy@Sun.COM (void) i_iptun_up(handle, linkid, &status);
59610616SSebastien.Roy@Sun.COM }
59710616SSebastien.Roy@Sun.COM return (status);
59810616SSebastien.Roy@Sun.COM }
59910616SSebastien.Roy@Sun.COM
60010616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_down(dladm_handle_t handle,datalink_id_t linkid)60110616SSebastien.Roy@Sun.COM dladm_iptun_down(dladm_handle_t handle, datalink_id_t linkid)
60210616SSebastien.Roy@Sun.COM {
60310616SSebastien.Roy@Sun.COM dladm_status_t status = DLADM_STATUS_OK;
60410616SSebastien.Roy@Sun.COM
60510616SSebastien.Roy@Sun.COM if (linkid == DATALINK_ALL_LINKID) {
60610616SSebastien.Roy@Sun.COM (void) dladm_walk_datalink_id(i_iptun_down, handle, NULL,
60710616SSebastien.Roy@Sun.COM DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE,
60810616SSebastien.Roy@Sun.COM DLADM_OPT_ACTIVE);
60910616SSebastien.Roy@Sun.COM } else {
61010616SSebastien.Roy@Sun.COM (void) i_iptun_down(handle, linkid, &status);
61110616SSebastien.Roy@Sun.COM }
61210616SSebastien.Roy@Sun.COM return (status);
61310616SSebastien.Roy@Sun.COM }
61410616SSebastien.Roy@Sun.COM
61510616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_set6to4relay(dladm_handle_t handle,struct in_addr * relay)61610616SSebastien.Roy@Sun.COM dladm_iptun_set6to4relay(dladm_handle_t handle, struct in_addr *relay)
61710616SSebastien.Roy@Sun.COM {
61810616SSebastien.Roy@Sun.COM return (i_iptun_ioctl(handle, IPTUN_SET_6TO4RELAY, relay));
61910616SSebastien.Roy@Sun.COM }
62010616SSebastien.Roy@Sun.COM
62110616SSebastien.Roy@Sun.COM dladm_status_t
dladm_iptun_get6to4relay(dladm_handle_t handle,struct in_addr * relay)62210616SSebastien.Roy@Sun.COM dladm_iptun_get6to4relay(dladm_handle_t handle, struct in_addr *relay)
62310616SSebastien.Roy@Sun.COM {
62410616SSebastien.Roy@Sun.COM return (i_iptun_ioctl(handle, IPTUN_GET_6TO4RELAY, relay));
62510616SSebastien.Roy@Sun.COM }
626