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/*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#include <stdio.h>
27#include <door.h>
28#include <errno.h>
29#include <strings.h>
30#include <sys/mman.h>
31#include <libdladm.h>
32#include <libdlib.h>
33#include <libdllink.h>
34
35extern dladm_status_t	dladm_door_fd(dladm_handle_t, int *);
36
37static dladm_status_t
38ibd_dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf,
39    size_t rsize)
40{
41	door_arg_t	darg;
42	int		door_fd;
43	dladm_status_t	status = DLADM_STATUS_OK;
44
45	darg.data_ptr	= arg;
46	darg.data_size	= asize;
47	darg.desc_ptr	= NULL;
48	darg.desc_num	= 0;
49	darg.rbuf	= rbuf;
50	darg.rsize	= rsize;
51
52	/* The door descriptor is opened if it isn't already */
53	if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK)
54		return (status);
55
56	if (door_call(door_fd, &darg) == -1)
57		return (DLADM_STATUS_FAILED);
58
59	if (darg.rbuf != rbuf) {
60		/*
61		 * The size of the input rbuf is not big enough so that
62		 * the door allocate the rbuf itself. In this case, simply
63		 * think something wrong with the door call.
64		 */
65		(void) munmap(darg.rbuf, darg.rsize);
66		return (DLADM_STATUS_TOOSMALL);
67	}
68
69	if (darg.rsize != rsize)
70		return (DLADM_STATUS_FAILED);
71
72	if ((((dlmgmt_retval_t *)rbuf)->lr_err) == 0)
73		return (DLADM_STATUS_OK);
74	else
75		return (DLADM_STATUS_FAILED);
76}
77
78static int
79ibd_delete_link(dladm_handle_t dlh, char *link)
80{
81	dlmgmt_door_getlinkid_t		getlinkid;
82	dlmgmt_getlinkid_retval_t	retval;
83	datalink_id_t			linkid;
84	dladm_status_t			status;
85	char				errmsg[DLADM_STRSIZE];
86
87	getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID;
88	(void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN);
89
90	if ((status = ibd_dladm_door_call(dlh, &getlinkid, sizeof (getlinkid),
91	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
92		(void) fprintf(stderr,
93		    "dladm_door_call failed: %s; linkname = %s\n",
94		    dladm_status2str(status, errmsg), link);
95		return (status);
96	}
97
98	if (retval.lr_class != DATALINK_CLASS_PHYS) {
99		(void) fprintf(stderr,
100		    "Not a physical link: linkname = %s, class = 0x%x\n",
101		    link, (uint_t)retval.lr_class);
102		return (status);
103	}
104
105	linkid = retval.lr_linkid;
106
107	if ((status = dladm_remove_conf(dlh, linkid)) != DLADM_STATUS_OK) {
108		(void) fprintf(stderr, "dladm_remove_conf failed: %s\n",
109		    dladm_status2str(status, errmsg));
110		return (status);
111	}
112
113	if ((status = dladm_destroy_datalink_id(dlh, linkid,
114	    DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) != DLADM_STATUS_OK) {
115		(void) fprintf(stderr, "dladm_destroy_datalink_id failed: %s\n",
116		    dladm_status2str(status, errmsg));
117	}
118
119	return (status);
120}
121
122int
123main(int argc, char *argv[])
124{
125	dladm_handle_t	dlh;
126	int		i;
127	dladm_status_t	status;
128	char		errmsg[DLADM_STRSIZE];
129
130	if (argc < 2) {
131		(void) fprintf(stderr,
132		    "Usage: ibd_delete_link linkname ...\n");
133		return (2);
134	}
135
136	if ((status = dladm_open(&dlh)) != DLADM_STATUS_OK) {
137		(void) fprintf(stderr, "Failed to open dladm handle: %s\n",
138		    dladm_status2str(status, errmsg));
139		return (1);
140	}
141
142	for (i = 1; i < argc; i++) {
143		if (ibd_delete_link(dlh, argv[i]) != DLADM_STATUS_OK) {
144			dladm_close(dlh);
145			return (1);
146		}
147	}
148
149	dladm_close(dlh);
150	return (0);
151}
152