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.
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.
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]
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
36 #include <net/if_types.h>
37 #include <net/if_dl.h>
39 #include <libdladm_impl.h>
40 #include <libvrrpadm.h>
41 #include <libdllink.h>
42 #include <libdlbridge.h>
43 #include <libdlvnic.h>
46 * VNIC administration library.
50 * Default random MAC address prefix (locally administered).
52 static char dladm_vnic_def_prefix
[] = {0x02, 0x08, 0x20};
54 static dladm_status_t
dladm_vnic_persist_conf(dladm_handle_t
,
55 const char *name
, dladm_vnic_attr_t
*,
57 static const char *dladm_vnic_macaddr2str(const uchar_t
*, char *);
58 static dladm_status_t
dladm_vnic_str2macaddr(const char *, uchar_t
*);
61 * Convert a diagnostic returned by the kernel into a dladm_status_t.
64 dladm_vnic_diag2status(vnic_ioc_diag_t ioc_diag
)
67 case VNIC_IOC_DIAG_NONE
:
68 return (DLADM_STATUS_OK
);
69 case VNIC_IOC_DIAG_MACADDRLEN_INVALID
:
70 return (DLADM_STATUS_INVALIDMACADDRLEN
);
71 case VNIC_IOC_DIAG_MACADDR_NIC
:
72 return (DLADM_STATUS_INVALIDMACADDRNIC
);
73 case VNIC_IOC_DIAG_MACADDR_INUSE
:
74 return (DLADM_STATUS_INVALIDMACADDRINUSE
);
75 case VNIC_IOC_DIAG_MACFACTORYSLOTINVALID
:
76 return (DLADM_STATUS_MACFACTORYSLOTINVALID
);
77 case VNIC_IOC_DIAG_MACFACTORYSLOTUSED
:
78 return (DLADM_STATUS_MACFACTORYSLOTUSED
);
79 case VNIC_IOC_DIAG_MACFACTORYSLOTALLUSED
:
80 return (DLADM_STATUS_MACFACTORYSLOTALLUSED
);
81 case VNIC_IOC_DIAG_MACFACTORYNOTSUP
:
82 return (DLADM_STATUS_MACFACTORYNOTSUP
);
83 case VNIC_IOC_DIAG_MACPREFIX_INVALID
:
84 return (DLADM_STATUS_INVALIDMACPREFIX
);
85 case VNIC_IOC_DIAG_MACPREFIXLEN_INVALID
:
86 return (DLADM_STATUS_INVALIDMACPREFIXLEN
);
87 case VNIC_IOC_DIAG_MACMARGIN_INVALID
:
88 return (DLADM_STATUS_INVALID_MACMARGIN
);
89 case VNIC_IOC_DIAG_NO_HWRINGS
:
90 return (DLADM_STATUS_NO_HWRINGS
);
91 case VNIC_IOC_DIAG_MACADDR_INVALID
:
92 return (DLADM_STATUS_INVALIDMACADDR
);
93 case VNIC_IOC_DIAG_MACMTU_INVALID
:
94 return (DLADM_STATUS_INVALID_MTU
);
96 return (DLADM_STATUS_FAILED
);
101 * Send a create command to the VNIC driver.
104 i_dladm_vnic_create_sys(dladm_handle_t handle
, dladm_vnic_attr_t
*attr
)
107 vnic_ioc_create_t ioc
;
108 dladm_status_t status
= DLADM_STATUS_OK
;
110 bzero(&ioc
, sizeof (ioc
));
111 ioc
.vc_vnic_id
= attr
->va_vnic_id
;
112 ioc
.vc_link_id
= attr
->va_link_id
;
113 ioc
.vc_mac_addr_type
= attr
->va_mac_addr_type
;
114 ioc
.vc_mac_len
= attr
->va_mac_len
;
115 ioc
.vc_mac_slot
= attr
->va_mac_slot
;
116 ioc
.vc_mac_prefix_len
= attr
->va_mac_prefix_len
;
117 ioc
.vc_vid
= attr
->va_vid
;
118 ioc
.vc_vrid
= attr
->va_vrid
;
119 ioc
.vc_af
= attr
->va_af
;
120 ioc
.vc_flags
= attr
->va_force
? VNIC_IOC_CREATE_FORCE
: 0;
122 if (attr
->va_mac_len
> 0 || ioc
.vc_mac_prefix_len
> 0)
123 bcopy(attr
->va_mac_addr
, ioc
.vc_mac_addr
, MAXMACADDRLEN
);
124 bcopy(&attr
->va_resource_props
, &ioc
.vc_resource_props
,
125 sizeof (mac_resource_props_t
));
126 if (attr
->va_link_id
== DATALINK_INVALID_LINKID
)
127 ioc
.vc_flags
|= VNIC_IOC_CREATE_ANCHOR
;
129 rc
= ioctl(dladm_dld_fd(handle
), VNIC_IOC_CREATE
, &ioc
);
131 status
= dladm_errno2status(errno
);
133 if (status
!= DLADM_STATUS_OK
) {
134 if (ioc
.vc_diag
!= VNIC_IOC_DIAG_NONE
)
135 status
= dladm_vnic_diag2status(ioc
.vc_diag
);
137 if (status
!= DLADM_STATUS_OK
)
140 attr
->va_mac_addr_type
= ioc
.vc_mac_addr_type
;
141 switch (ioc
.vc_mac_addr_type
) {
142 case VNIC_MAC_ADDR_TYPE_FACTORY
:
143 attr
->va_mac_slot
= ioc
.vc_mac_slot
;
145 case VNIC_MAC_ADDR_TYPE_RANDOM
:
146 bcopy(ioc
.vc_mac_addr
, attr
->va_mac_addr
, MAXMACADDRLEN
);
147 attr
->va_mac_len
= ioc
.vc_mac_len
;
154 * Get the configuration information of the given VNIC.
156 static dladm_status_t
157 i_dladm_vnic_info_active(dladm_handle_t handle
, datalink_id_t linkid
,
158 dladm_vnic_attr_t
*attrp
)
163 dladm_status_t status
= DLADM_STATUS_OK
;
165 bzero(&ioc
, sizeof (ioc
));
167 vnic
->vn_vnic_id
= linkid
;
169 rc
= ioctl(dladm_dld_fd(handle
), VNIC_IOC_INFO
, &ioc
);
171 status
= dladm_errno2status(errno
);
175 attrp
->va_vnic_id
= vnic
->vn_vnic_id
;
176 attrp
->va_link_id
= vnic
->vn_link_id
;
177 attrp
->va_mac_addr_type
= vnic
->vn_mac_addr_type
;
178 bcopy(vnic
->vn_mac_addr
, attrp
->va_mac_addr
, MAXMACADDRLEN
);
179 attrp
->va_mac_len
= vnic
->vn_mac_len
;
180 attrp
->va_mac_slot
= vnic
->vn_mac_slot
;
181 attrp
->va_mac_prefix_len
= vnic
->vn_mac_prefix_len
;
182 attrp
->va_vid
= vnic
->vn_vid
;
183 attrp
->va_vrid
= vnic
->vn_vrid
;
184 attrp
->va_af
= vnic
->vn_af
;
185 attrp
->va_force
= vnic
->vn_force
;
191 static dladm_status_t
192 i_dladm_vnic_info_persist(dladm_handle_t handle
, datalink_id_t linkid
,
193 dladm_vnic_attr_t
*attrp
)
196 dladm_status_t status
;
197 char macstr
[ETHERADDRL
* 3];
198 char linkover
[MAXLINKNAMELEN
];
200 datalink_class_t
class;
202 attrp
->va_vnic_id
= linkid
;
203 if ((status
= dladm_getsnap_conf(handle
, linkid
, &conf
)) !=
207 status
= dladm_get_conf_field(handle
, conf
, FLINKOVER
, linkover
,
209 if (status
!= DLADM_STATUS_OK
) {
211 * This isn't an error, etherstubs don't have a FLINKOVER
214 attrp
->va_link_id
= DATALINK_INVALID_LINKID
;
216 if ((status
= dladm_name2info(handle
, linkover
,
217 &attrp
->va_link_id
, NULL
, NULL
, NULL
)) != DLADM_STATUS_OK
)
221 if ((status
= dladm_datalink_id2info(handle
, linkid
, NULL
, &class,
222 NULL
, NULL
, 0)) != DLADM_STATUS_OK
)
225 if (class == DATALINK_CLASS_VLAN
) {
226 if (attrp
->va_link_id
== DATALINK_INVALID_LINKID
) {
227 status
= DLADM_STATUS_BADARG
;
230 attrp
->va_mac_addr_type
= VNIC_MAC_ADDR_TYPE_PRIMARY
;
231 attrp
->va_mac_len
= 0;
233 status
= dladm_get_conf_field(handle
, conf
, FMADDRTYPE
, &u64
,
235 if (status
!= DLADM_STATUS_OK
)
238 attrp
->va_mac_addr_type
= (vnic_mac_addr_type_t
)u64
;
240 if ((status
= dladm_get_conf_field(handle
, conf
, FVRID
,
241 &u64
, sizeof (u64
))) != DLADM_STATUS_OK
) {
242 attrp
->va_vrid
= VRRP_VRID_NONE
;
244 attrp
->va_vrid
= (vrid_t
)u64
;
247 if ((status
= dladm_get_conf_field(handle
, conf
, FVRAF
,
248 &u64
, sizeof (u64
))) != DLADM_STATUS_OK
) {
249 attrp
->va_af
= AF_UNSPEC
;
251 attrp
->va_af
= (int)u64
;
254 status
= dladm_get_conf_field(handle
, conf
, FMADDRLEN
, &u64
,
256 attrp
->va_mac_len
= ((status
== DLADM_STATUS_OK
) ?
257 (uint_t
)u64
: ETHERADDRL
);
259 status
= dladm_get_conf_field(handle
, conf
, FMADDRSLOT
, &u64
,
261 attrp
->va_mac_slot
= ((status
== DLADM_STATUS_OK
) ?
264 status
= dladm_get_conf_field(handle
, conf
, FMADDRPREFIXLEN
,
266 attrp
->va_mac_prefix_len
= ((status
== DLADM_STATUS_OK
) ?
267 (uint_t
)u64
: sizeof (dladm_vnic_def_prefix
));
269 status
= dladm_get_conf_field(handle
, conf
, FMACADDR
, macstr
,
271 if (status
!= DLADM_STATUS_OK
)
274 status
= dladm_vnic_str2macaddr(macstr
, attrp
->va_mac_addr
);
275 if (status
!= DLADM_STATUS_OK
)
279 status
= dladm_get_conf_field(handle
, conf
, FVLANID
, &u64
,
281 attrp
->va_vid
= ((status
== DLADM_STATUS_OK
) ? (uint16_t)u64
: 0);
283 status
= DLADM_STATUS_OK
;
285 dladm_destroy_conf(handle
, conf
);
290 dladm_vnic_info(dladm_handle_t handle
, datalink_id_t linkid
,
291 dladm_vnic_attr_t
*attrp
, uint32_t flags
)
293 if (flags
== DLADM_OPT_ACTIVE
)
294 return (i_dladm_vnic_info_active(handle
, linkid
, attrp
));
295 else if (flags
== DLADM_OPT_PERSIST
)
296 return (i_dladm_vnic_info_persist(handle
, linkid
, attrp
));
298 return (DLADM_STATUS_BADARG
);
302 * Remove a VNIC from the kernel.
305 i_dladm_vnic_delete_sys(dladm_handle_t handle
, datalink_id_t linkid
)
307 vnic_ioc_delete_t ioc
;
308 dladm_status_t status
= DLADM_STATUS_OK
;
311 ioc
.vd_vnic_id
= linkid
;
313 rc
= ioctl(dladm_dld_fd(handle
), VNIC_IOC_DELETE
, &ioc
);
315 status
= dladm_errno2status(errno
);
321 * Convert between MAC address types and their string representations.
324 typedef struct dladm_vnic_addr_type_s
{
326 vnic_mac_addr_type_t va_type
;
327 } dladm_vnic_addr_type_t
;
329 static dladm_vnic_addr_type_t addr_types
[] = {
330 {"fixed", VNIC_MAC_ADDR_TYPE_FIXED
},
331 {"random", VNIC_MAC_ADDR_TYPE_RANDOM
},
332 {"factory", VNIC_MAC_ADDR_TYPE_FACTORY
},
333 {"auto", VNIC_MAC_ADDR_TYPE_AUTO
},
334 {"fixed", VNIC_MAC_ADDR_TYPE_PRIMARY
},
335 {"vrrp", VNIC_MAC_ADDR_TYPE_VRID
}
338 #define NADDR_TYPES (sizeof (addr_types) / sizeof (dladm_vnic_addr_type_t))
341 dladm_vnic_macaddrtype2str(vnic_mac_addr_type_t type
)
345 for (i
= 0; i
< NADDR_TYPES
; i
++) {
346 if (type
== addr_types
[i
].va_type
)
347 return (addr_types
[i
].va_str
);
353 dladm_vnic_str2macaddrtype(const char *str
, vnic_mac_addr_type_t
*val
)
356 dladm_vnic_addr_type_t
*type
;
358 for (i
= 0; i
< NADDR_TYPES
; i
++) {
359 type
= &addr_types
[i
];
360 if (strncmp(str
, type
->va_str
, strlen(type
->va_str
)) == 0) {
361 *val
= type
->va_type
;
362 return (DLADM_STATUS_OK
);
365 return (DLADM_STATUS_BADARG
);
369 * Based on the VRRP specification, the virtual router MAC address associated
370 * with a virtual router is an IEEE 802 MAC address in the following format:
372 * IPv4 case: 00-00-5E-00-01-{VRID} (in hex in internet standard bit-order)
374 * IPv6 case: 00-00-5E-00-02-{VRID} (in hex in internet standard bit-order)
376 static dladm_status_t
377 i_dladm_vnic_vrrp_mac(vrid_t vrid
, int af
, uint8_t *mac
, uint_t maclen
)
379 if (maclen
< ETHERADDRL
|| vrid
< VRRP_VRID_MIN
||
380 vrid
> VRRP_VRID_MAX
|| (af
!= AF_INET
&& af
!= AF_INET6
)) {
381 return (DLADM_STATUS_BADARG
);
384 mac
[0] = mac
[1] = mac
[3] = 0x0;
386 mac
[4] = (af
== AF_INET
) ? 0x01 : 0x02;
388 return (DLADM_STATUS_OK
);
392 * Create a new VNIC / VLAN. Update the configuration file and bring it up.
393 * The "vrid" and "af" arguments are only required if the mac_addr_type is
394 * VNIC_MAC_ADDR_TYPE_VRID. In that case, the MAC address will be caculated
395 * based on the above algorithm.
398 dladm_vnic_create(dladm_handle_t handle
, const char *vnic
, datalink_id_t linkid
,
399 vnic_mac_addr_type_t mac_addr_type
, uchar_t
*mac_addr
, uint_t mac_len
,
400 int *mac_slot
, uint_t mac_prefix_len
, uint16_t vid
, vrid_t vrid
,
401 int af
, datalink_id_t
*vnic_id_out
, dladm_arg_list_t
*proplist
,
404 dladm_vnic_attr_t attr
;
405 datalink_id_t vnic_id
;
406 datalink_class_t
class;
407 uint32_t media
= DL_ETHER
;
408 char name
[MAXLINKNAMELEN
];
409 uchar_t tmp_addr
[MAXMACADDRLEN
];
410 dladm_status_t status
;
412 boolean_t is_etherstub
;
414 boolean_t vnic_created
= B_FALSE
;
415 boolean_t conf_set
= B_FALSE
;
418 * Sanity test arguments.
420 if ((flags
& DLADM_OPT_ACTIVE
) == 0)
421 return (DLADM_STATUS_NOTSUP
);
423 is_vlan
= ((flags
& DLADM_OPT_VLAN
) != 0);
424 if (is_vlan
&& ((vid
< 1 || vid
> 4094)))
425 return (DLADM_STATUS_VIDINVAL
);
427 is_etherstub
= (linkid
== DATALINK_INVALID_LINKID
);
429 if (!dladm_vnic_macaddrtype2str(mac_addr_type
))
430 return (DLADM_STATUS_INVALIDMACADDRTYPE
);
432 if ((flags
& DLADM_OPT_ANCHOR
) == 0) {
433 if ((status
= dladm_datalink_id2info(handle
, linkid
, NULL
,
434 &class, &media
, NULL
, 0)) != DLADM_STATUS_OK
)
437 if (class == DATALINK_CLASS_VNIC
||
438 class == DATALINK_CLASS_VLAN
)
439 return (DLADM_STATUS_BADARG
);
441 /* it's an anchor VNIC */
442 if (linkid
!= DATALINK_INVALID_LINKID
|| vid
!= 0)
443 return (DLADM_STATUS_BADARG
);
447 * Only VRRP VNIC need VRID and address family specified.
449 if (mac_addr_type
!= VNIC_MAC_ADDR_TYPE_VRID
&&
450 (af
!= AF_UNSPEC
|| vrid
!= VRRP_VRID_NONE
)) {
451 return (DLADM_STATUS_BADARG
);
455 * If a random address might be generated, but no prefix
456 * was specified by the caller, use the default MAC address
459 if ((mac_addr_type
== VNIC_MAC_ADDR_TYPE_RANDOM
||
460 mac_addr_type
== VNIC_MAC_ADDR_TYPE_AUTO
) &&
461 mac_prefix_len
== 0) {
462 mac_prefix_len
= sizeof (dladm_vnic_def_prefix
);
464 bcopy(dladm_vnic_def_prefix
, mac_addr
, mac_prefix_len
);
468 * If this is a VRRP VNIC, generate its MAC address using the given
469 * VRID and address family.
471 if (mac_addr_type
== VNIC_MAC_ADDR_TYPE_VRID
) {
473 * VRRP VNICs must be created over ethernet data-links.
475 if (vrid
< VRRP_VRID_MIN
|| vrid
> VRRP_VRID_MAX
||
476 (af
!= AF_INET
&& af
!= AF_INET6
) || mac_addr
!= NULL
||
477 mac_len
!= 0 || mac_prefix_len
!= 0 ||
478 (mac_slot
!= NULL
&& *mac_slot
!= -1) || is_etherstub
||
480 return (DLADM_STATUS_BADARG
);
482 mac_len
= ETHERADDRL
;
484 status
= i_dladm_vnic_vrrp_mac(vrid
, af
, mac_addr
, mac_len
);
485 if (status
!= DLADM_STATUS_OK
)
489 if (mac_len
> MAXMACADDRLEN
)
490 return (DLADM_STATUS_INVALIDMACADDRLEN
);
493 flags
|= DLADM_OPT_PREFIX
;
494 (void) strlcpy(name
, "vnic", sizeof (name
));
496 (void) strlcpy(name
, vnic
, sizeof (name
));
499 class = is_vlan
? DATALINK_CLASS_VLAN
:
500 (is_etherstub
? DATALINK_CLASS_ETHERSTUB
: DATALINK_CLASS_VNIC
);
501 if ((status
= dladm_create_datalink_id(handle
, name
, class,
502 media
, flags
, &vnic_id
)) != DLADM_STATUS_OK
)
505 if ((flags
& DLADM_OPT_PREFIX
) != 0) {
506 (void) snprintf(name
+ 4, sizeof (name
), "%llu", vnic_id
);
507 flags
&= ~DLADM_OPT_PREFIX
;
510 bzero(&attr
, sizeof (attr
));
512 /* Extract resource_ctl and cpu_list from proplist */
513 if (proplist
!= NULL
) {
514 status
= dladm_link_proplist_extract(handle
, proplist
,
515 &attr
.va_resource_props
, 0);
516 if (status
!= DLADM_STATUS_OK
)
520 attr
.va_vnic_id
= vnic_id
;
521 attr
.va_link_id
= linkid
;
522 attr
.va_mac_addr_type
= mac_addr_type
;
523 attr
.va_mac_len
= mac_len
;
524 if (mac_slot
!= NULL
)
525 attr
.va_mac_slot
= *mac_slot
;
527 bcopy(mac_addr
, attr
.va_mac_addr
, mac_len
);
528 else if (mac_prefix_len
> 0)
529 bcopy(mac_addr
, attr
.va_mac_addr
, mac_prefix_len
);
530 attr
.va_mac_prefix_len
= mac_prefix_len
;
534 attr
.va_force
= (flags
& DLADM_OPT_FORCE
) != 0;
536 status
= i_dladm_vnic_create_sys(handle
, &attr
);
537 if (status
!= DLADM_STATUS_OK
)
539 vnic_created
= B_TRUE
;
541 /* Save vnic configuration and its properties */
542 if (!(flags
& DLADM_OPT_PERSIST
))
545 status
= dladm_vnic_persist_conf(handle
, name
, &attr
, class);
546 if (status
!= DLADM_STATUS_OK
)
550 if (proplist
!= NULL
) {
551 for (i
= 0; i
< proplist
->al_count
; i
++) {
552 dladm_arg_info_t
*aip
= &proplist
->al_info
[i
];
554 status
= dladm_set_linkprop(handle
, vnic_id
,
555 aip
->ai_name
, aip
->ai_val
, aip
->ai_count
,
557 if (status
!= DLADM_STATUS_OK
)
563 if (status
!= DLADM_STATUS_OK
) {
565 (void) dladm_remove_conf(handle
, vnic_id
);
567 (void) i_dladm_vnic_delete_sys(handle
, vnic_id
);
568 (void) dladm_destroy_datalink_id(handle
, vnic_id
, flags
);
570 if (vnic_id_out
!= NULL
)
571 *vnic_id_out
= vnic_id
;
572 if (mac_slot
!= NULL
)
573 *mac_slot
= attr
.va_mac_slot
;
577 dladm_status_t stat2
;
579 stat2
= dladm_bridge_refresh(handle
, linkid
);
580 if (status
== DLADM_STATUS_OK
&& stat2
!= DLADM_STATUS_OK
)
587 * Delete a VNIC / VLAN.
590 dladm_vnic_delete(dladm_handle_t handle
, datalink_id_t linkid
, uint32_t flags
)
592 dladm_status_t status
;
593 datalink_class_t
class;
596 return (DLADM_STATUS_BADARG
);
598 if ((dladm_datalink_id2info(handle
, linkid
, NULL
, &class, NULL
, NULL
, 0)
600 return (DLADM_STATUS_BADARG
);
602 if ((flags
& DLADM_OPT_VLAN
) != 0) {
603 if (class != DATALINK_CLASS_VLAN
)
604 return (DLADM_STATUS_BADARG
);
606 if (class != DATALINK_CLASS_VNIC
&&
607 class != DATALINK_CLASS_ETHERSTUB
)
608 return (DLADM_STATUS_BADARG
);
611 if ((flags
& DLADM_OPT_ACTIVE
) != 0) {
612 status
= i_dladm_vnic_delete_sys(handle
, linkid
);
613 if (status
== DLADM_STATUS_OK
) {
614 (void) dladm_set_linkprop(handle
, linkid
, NULL
, NULL
, 0,
616 (void) dladm_destroy_datalink_id(handle
, linkid
,
618 } else if (status
!= DLADM_STATUS_NOTFOUND
||
619 !(flags
& DLADM_OPT_PERSIST
)) {
623 if ((flags
& DLADM_OPT_PERSIST
) != 0) {
624 (void) dladm_remove_conf(handle
, linkid
);
625 (void) dladm_destroy_datalink_id(handle
, linkid
,
628 return (dladm_bridge_refresh(handle
, linkid
));
632 dladm_vnic_macaddr2str(const uchar_t
*mac
, char *buf
)
634 static char unknown_mac
[] = {0, 0, 0, 0, 0, 0};
639 if (bcmp(unknown_mac
, mac
, ETHERADDRL
) == 0)
640 (void) strlcpy(buf
, "unknown", DLADM_STRSIZE
);
642 return (_link_ntoa(mac
, buf
, ETHERADDRL
, IFT_OTHER
));
647 static dladm_status_t
648 dladm_vnic_str2macaddr(const char *str
, uchar_t
*buf
)
651 uchar_t
*b
= _link_aton(str
, &len
);
653 if (b
== NULL
|| len
>= MAXMACADDRLEN
)
654 return (DLADM_STATUS_BADARG
);
658 return (DLADM_STATUS_OK
);
662 static dladm_status_t
663 dladm_vnic_persist_conf(dladm_handle_t handle
, const char *name
,
664 dladm_vnic_attr_t
*attrp
, datalink_class_t
class)
667 dladm_status_t status
;
668 char macstr
[ETHERADDRL
* 3];
669 char linkover
[MAXLINKNAMELEN
];
672 if ((status
= dladm_create_conf(handle
, name
, attrp
->va_vnic_id
,
673 class, DL_ETHER
, &conf
)) != DLADM_STATUS_OK
)
676 if (attrp
->va_link_id
!= DATALINK_INVALID_LINKID
) {
677 status
= dladm_datalink_id2info(handle
, attrp
->va_link_id
, NULL
,
678 NULL
, NULL
, linkover
, sizeof (linkover
));
679 if (status
!= DLADM_STATUS_OK
)
681 status
= dladm_set_conf_field(handle
, conf
, FLINKOVER
,
682 DLADM_TYPE_STR
, linkover
);
683 if (status
!= DLADM_STATUS_OK
)
687 if (class != DATALINK_CLASS_VLAN
) {
688 u64
= attrp
->va_mac_addr_type
;
689 status
= dladm_set_conf_field(handle
, conf
, FMADDRTYPE
,
690 DLADM_TYPE_UINT64
, &u64
);
691 if (status
!= DLADM_STATUS_OK
)
694 u64
= attrp
->va_vrid
;
695 status
= dladm_set_conf_field(handle
, conf
, FVRID
,
696 DLADM_TYPE_UINT64
, &u64
);
697 if (status
!= DLADM_STATUS_OK
)
701 status
= dladm_set_conf_field(handle
, conf
, FVRAF
,
702 DLADM_TYPE_UINT64
, &u64
);
703 if (status
!= DLADM_STATUS_OK
)
706 if (attrp
->va_mac_len
!= ETHERADDRL
) {
707 u64
= attrp
->va_mac_len
;
708 status
= dladm_set_conf_field(handle
, conf
, FMADDRLEN
,
709 DLADM_TYPE_UINT64
, &u64
);
710 if (status
!= DLADM_STATUS_OK
)
714 if (attrp
->va_mac_slot
!= -1) {
715 u64
= attrp
->va_mac_slot
;
716 status
= dladm_set_conf_field(handle
, conf
,
717 FMADDRSLOT
, DLADM_TYPE_UINT64
, &u64
);
718 if (status
!= DLADM_STATUS_OK
)
722 if (attrp
->va_mac_prefix_len
!=
723 sizeof (dladm_vnic_def_prefix
)) {
724 u64
= attrp
->va_mac_prefix_len
;
725 status
= dladm_set_conf_field(handle
, conf
,
726 FMADDRPREFIXLEN
, DLADM_TYPE_UINT64
, &u64
);
727 if (status
!= DLADM_STATUS_OK
)
731 (void) dladm_vnic_macaddr2str(attrp
->va_mac_addr
, macstr
);
732 status
= dladm_set_conf_field(handle
, conf
, FMACADDR
,
733 DLADM_TYPE_STR
, macstr
);
734 if (status
!= DLADM_STATUS_OK
)
738 if (attrp
->va_vid
!= 0) {
740 status
= dladm_set_conf_field(handle
, conf
, FVLANID
,
741 DLADM_TYPE_UINT64
, &u64
);
742 if (status
!= DLADM_STATUS_OK
)
747 * Commit the link configuration.
749 status
= dladm_write_conf(handle
, conf
);
752 dladm_destroy_conf(handle
, conf
);
756 typedef struct dladm_vnic_up_arg_s
{
758 dladm_status_t status
;
759 } dladm_vnic_up_arg_t
;
762 i_dladm_vnic_up(dladm_handle_t handle
, datalink_id_t linkid
, void *arg
)
764 dladm_status_t
*statusp
= &(((dladm_vnic_up_arg_t
*)arg
)->status
);
765 dladm_vnic_attr_t attr
;
766 dladm_status_t status
;
767 dladm_arg_list_t
*proplist
;
769 bzero(&attr
, sizeof (attr
));
771 status
= dladm_vnic_info(handle
, linkid
, &attr
, DLADM_OPT_PERSIST
);
772 if (status
!= DLADM_STATUS_OK
)
775 /* Get all properties for this vnic */
776 status
= dladm_link_get_proplist(handle
, linkid
, &proplist
);
777 if (status
!= DLADM_STATUS_OK
)
780 if (proplist
!= NULL
) {
781 status
= dladm_link_proplist_extract(handle
, proplist
,
782 &attr
.va_resource_props
, DLADM_OPT_BOOT
);
785 status
= i_dladm_vnic_create_sys(handle
, &attr
);
786 if (status
== DLADM_STATUS_OK
) {
787 status
= dladm_up_datalink_id(handle
, linkid
);
788 if (status
!= DLADM_STATUS_OK
)
789 (void) i_dladm_vnic_delete_sys(handle
, linkid
);
794 return (DLADM_WALK_CONTINUE
);
798 dladm_vnic_up(dladm_handle_t handle
, datalink_id_t linkid
, uint32_t flags
)
800 dladm_vnic_up_arg_t vnic_arg
;
801 datalink_class_t
class;
803 class = ((flags
& DLADM_OPT_VLAN
) != 0) ? DATALINK_CLASS_VLAN
:
804 (DATALINK_CLASS_VNIC
| DATALINK_CLASS_ETHERSTUB
);
806 if (linkid
== DATALINK_ALL_LINKID
) {
807 (void) dladm_walk_datalink_id(i_dladm_vnic_up
, handle
,
808 &vnic_arg
, class, DATALINK_ANY_MEDIATYPE
,
810 return (DLADM_STATUS_OK
);
812 (void) i_dladm_vnic_up(handle
, linkid
, &vnic_arg
);
813 return (vnic_arg
.status
);