843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER START
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The contents of this file are subject to the terms of the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Common Development and Distribution License (the "License").
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You may not use this file except in compliance with the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
843e19887f64dde75055cf8842fc4db2171eff45johnlev * or http://www.opensolaris.org/os/licensing.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * See the License for the specific language governing permissions
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and limitations under the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * When distributing Covered Code, include this CDDL HEADER in each
843e19887f64dde75055cf8842fc4db2171eff45johnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If applicable, add the following below this CDDL HEADER, with the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * fields enclosed by brackets "[]" replaced with your own identifying
843e19887f64dde75055cf8842fc4db2171eff45johnlev * information: Portions Copyright [yyyy] [name of copyright owner]
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER END
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi * Copyright 2015 Joyent, Inc.
238d8f47d92b5b99a374f9639e0704420d3aef77Dale Ghent * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/types.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <sys/cred.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/sysmacros.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/conf.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/cmn_err.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/list.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/ksynch.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/kmem.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/stream.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/modctl.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/ddi.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/sunddi.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/atomic.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/stat.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/modhash.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/strsubr.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/strsun.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/dlpi.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/mac.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_provider.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_client.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_client_priv.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/mac_ether.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/dls.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/pattr.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/time.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/vlan.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/vnic.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/vnic_impl.h>
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi#include <sys/mac_impl.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_flow_impl.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <inet/ip_impl.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Note that for best performance, the VNIC is a passthrough design.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * For each VNIC corresponds a MAC client of the underlying MAC (lower MAC).
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * This MAC client is opened by the VNIC driver at VNIC creation,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and closed when the VNIC is deleted.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * When a MAC client of the VNIC itself opens a VNIC, the MAC layer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * (upper MAC) detects that the MAC being opened is a VNIC. Instead
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * of allocating a new MAC client, it asks the VNIC driver to return
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the lower MAC client handle associated with the VNIC, and that handle
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * is returned to the upper MAC client directly. This allows access
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * by upper MAC clients of the VNIC to have direct access to the lower
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC client for the control path and data path.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Due to this passthrough, some of the entry points exported by the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * VNIC driver are never directly invoked. These entry points include
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vnic_m_start, vnic_m_stop, vnic_m_promisc, vnic_m_multicst, etc.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek *
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * VNICs support multiple upper mac clients to enable support for
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * multiple MAC addresses on the VNIC. When the VNIC is created the
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * initial mac client is the primary upper mac. Any additional mac
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * clients are secondary macs.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int vnic_m_start(void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void vnic_m_stop(void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int vnic_m_promisc(void *, boolean_t);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int vnic_m_multicst(void *, boolean_t, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int vnic_m_unicst(void *, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int vnic_m_stat(void *, uint_t, uint64_t *);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vnic_m_ioctl(void *, queue_t *, mblk_t *);
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbailstatic int vnic_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail const void *);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic int vnic_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic void vnic_m_propinfo(void *, const char *, mac_prop_id_t,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_handle_t);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic mblk_t *vnic_m_tx(void *, mblk_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic boolean_t vnic_m_capab_get(void *, mac_capab_t, void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void vnic_notify_cb(void *, mac_notify_type_t);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic void vnic_cleanup_secondary_macs(vnic_t *, int);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic kmem_cache_t *vnic_cache;
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic krwlock_t vnic_lock;
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic uint_t vnic_count;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail#define ANCHOR_VNIC_MIN_MTU 576
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail#define ANCHOR_VNIC_MAX_MTU 9000
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* hash of VNICs (vnic_t's), keyed by VNIC id */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic mod_hash_t *vnic_hash;
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define VNIC_HASHSZ 64
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define VNIC_HASH_KEY(vnic_id) ((mod_hash_key_t)(uintptr_t)vnic_id)
843e19887f64dde75055cf8842fc4db2171eff45johnlev
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail#define VNIC_M_CALLBACK_FLAGS \
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO)
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic mac_callbacks_t vnic_m_callbacks = {
843e19887f64dde75055cf8842fc4db2171eff45johnlev VNIC_M_CALLBACK_FLAGS,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_stat,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_start,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_stop,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_promisc,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_multicst,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_unicst,
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_m_tx,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer NULL,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_m_ioctl,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail vnic_m_capab_get,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail NULL,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail NULL,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail vnic_m_setprop,
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_m_getprop,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer vnic_m_propinfo
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevvoid
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_dev_init(void)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_cache = kmem_cache_create("vnic_cache",
843e19887f64dde75055cf8842fc4db2171eff45johnlev sizeof (vnic_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_hash = mod_hash_create_idhash("vnic_hash",
843e19887f64dde75055cf8842fc4db2171eff45johnlev VNIC_HASHSZ, mod_hash_null_valdtor);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_init(&vnic_lock, NULL, RW_DEFAULT, NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_count = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevvoid
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_dev_fini(void)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev ASSERT(vnic_count == 0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_destroy(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mod_hash_destroy_idhash(vnic_hash);
843e19887f64dde75055cf8842fc4db2171eff45johnlev kmem_cache_destroy(vnic_cache);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevuint_t
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_dev_count(void)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (vnic_count);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic vnic_ioc_diag_t
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_mac2vnic_diag(mac_diag_t diag)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng switch (diag) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACADDR_NIC:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACADDR_NIC);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACADDR_INUSE:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACADDR_INUSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACADDR_INVALID:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACADDR_INVALID);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACADDRLEN_INVALID:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACADDRLEN_INVALID);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACFACTORYSLOTINVALID:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACFACTORYSLOTINVALID);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACFACTORYSLOTUSED:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACFACTORYSLOTUSED);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACFACTORYSLOTALLUSED:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACFACTORYSLOTALLUSED);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACFACTORYNOTSUP:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACFACTORYNOTSUP);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACPREFIX_INVALID:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACPREFIX_INVALID);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACPREFIXLEN_INVALID:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_MACPREFIXLEN_INVALID);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_DIAG_MACNO_HWRINGS:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_NO_HWRINGS);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng default:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (VNIC_IOC_DIAG_NONE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_unicast_add(vnic_t *vnic, vnic_mac_addr_type_t vnic_addr_type,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int *addr_slot, uint_t prefix_len, int *addr_len_ptr_arg,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint8_t *mac_addr_arg, uint16_t flags, vnic_ioc_diag_t *diag,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer uint16_t vid, boolean_t req_hwgrp_flag)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_diag_t mac_diag;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t mac_flags = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int err;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint_t addr_len;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (flags & VNIC_IOC_CREATE_NODUPCHECK)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags |= MAC_UNICAST_NODUPCHECK;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng switch (vnic_addr_type) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case VNIC_MAC_ADDR_TYPE_FIXED:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case VNIC_MAC_ADDR_TYPE_VRID:
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * The MAC address value to assign to the VNIC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * is already provided in mac_addr_arg. addr_len_ptr_arg
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * already contains the MAC address length.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case VNIC_MAC_ADDR_TYPE_RANDOM:
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Random MAC address. There are two sub-cases:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 1 - If mac_len == 0, a new MAC address is generated.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * The length of the MAC address to generated depends
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * on the type of MAC used. The prefix to use for the MAC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * address is stored in the most significant bytes
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * of the mac_addr argument, and its length is specified
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * by the mac_prefix_len argument. This prefix can
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * correspond to a IEEE OUI in the case of Ethernet,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * for example.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 2 - If mac_len > 0, the address was already picked
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * randomly, and is now passed back during VNIC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * re-creation. The mac_addr argument contains the MAC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * address that was generated. We distinguish this
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * case from the fixed MAC address case, since we
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * want the user consumers to know, when they query
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the list of VNICs, that a VNIC was assigned a
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * random MAC address vs assigned a fixed address
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * specified by the user.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If it's a pre-generated address, we're done. mac_addr_arg
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and addr_len_ptr_arg already contain the MAC address
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * value and length.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*addr_len_ptr_arg > 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* generate a new random MAC address */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((err = mac_addr_random(vnic->vn_mch,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix_len, mac_addr_arg, &mac_diag)) != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = vnic_mac2vnic_diag(mac_diag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *addr_len_ptr_arg = mac_addr_len(vnic->vn_lower_mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case VNIC_MAC_ADDR_TYPE_FACTORY:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_addr_factory_reserve(vnic->vn_mch, addr_slot);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err == EINVAL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_MACFACTORYSLOTINVALID;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err == EBUSY)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_MACFACTORYSLOTUSED;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err == ENOSPC)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_MACFACTORYSLOTALLUSED;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_addr_factory_value(vnic->vn_lower_mh, *addr_slot,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_addr_arg, &addr_len, NULL, NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *addr_len_ptr_arg = addr_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case VNIC_MAC_ADDR_TYPE_AUTO:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* first try to allocate a factory MAC address */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_addr_factory_reserve(vnic->vn_mch, addr_slot);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_addr_factory_value(vnic->vn_lower_mh, *addr_slot,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_addr_arg, &addr_len, NULL, NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_addr_type = VNIC_MAC_ADDR_TYPE_FACTORY;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *addr_len_ptr_arg = addr_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Allocating a factory MAC address failed, generate a
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * random MAC address instead.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((err = mac_addr_random(vnic->vn_mch,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix_len, mac_addr_arg, &mac_diag)) != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = vnic_mac2vnic_diag(mac_diag);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *addr_len_ptr_arg = mac_addr_len(vnic->vn_lower_mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_addr_type = VNIC_MAC_ADDR_TYPE_RANDOM;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case VNIC_MAC_ADDR_TYPE_PRIMARY:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * We get the address here since we copy it in the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vnic's vn_addr.
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * We can't ask for hardware resources since we
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * don't currently support hardware classification
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * for these MAC clients.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (req_hwgrp_flag) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *diag = VNIC_IOC_DIAG_NO_HWRINGS;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer return (ENOTSUP);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicast_primary_get(vnic->vn_lower_mh, mac_addr_arg);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *addr_len_ptr_arg = mac_addr_len(vnic->vn_lower_mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags |= MAC_UNICAST_VNIC_PRIMARY;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_addr_type = vnic_addr_type;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_unicast_add(vnic->vn_mch, mac_addr_arg, mac_flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &vnic->vn_muh, vid, &mac_diag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic_addr_type == VNIC_MAC_ADDR_TYPE_FACTORY) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* release factory MAC address */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_addr_factory_release(vnic->vn_mch, *addr_slot);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = vnic_mac2vnic_diag(mac_diag);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Create a new VNIC upon request from administrator.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Returns 0 on success, an errno on failure.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_dev_create(datalink_id_t vnic_id, datalink_id_t linkid,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_mac_addr_type_t *vnic_addr_type, int *mac_len, uchar_t *mac_addr,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou int *mac_slot, uint_t mac_prefix_len, uint16_t vid, vrid_t vrid,
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou int af, mac_resource_props_t *mrp, uint32_t flags, vnic_ioc_diag_t *diag,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_t *vnic;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac_register_t *mac;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int err;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng boolean_t is_anchor = ((flags & VNIC_IOC_CREATE_ANCHOR) != 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng char vnic_name[MAXNAMELEN];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const mac_info_t *minfop;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer uint32_t req_hwgrp_flag = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_NONE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_enter(&vnic_lock, RW_WRITER);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* does a VNIC with the same id already exist? */
843e19887f64dde75055cf8842fc4db2171eff45johnlev err = mod_hash_find(vnic_hash, VNIC_HASH_KEY(vnic_id),
843e19887f64dde75055cf8842fc4db2171eff45johnlev (mod_hash_val_t *)&vnic);
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (err == 0) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (EEXIST);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic = kmem_cache_alloc(vnic_cache, KM_NOSLEEP);
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (vnic == NULL) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENOMEM);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev bzero(vnic, sizeof (*vnic));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_id = vnic_id;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_link_id = linkid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vnic->vn_vrid = vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vnic->vn_af = af;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!is_anchor) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (linkid == DATALINK_INVALID_LINKID) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = EINVAL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Open the lower MAC and assign its initial bandwidth and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC address. We do this here during VNIC creation and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * do not wait until the upper MAC client open so that we
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * can validate the VNIC creation parameters (bandwidth,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC address, etc) and reserve a factory MAC address if
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * one was requested.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_open_by_linkid(linkid, &vnic->vn_lower_mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * VNIC(vlan) over VNICs(vlans) is not supported.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mac_is_vnic(vnic->vn_lower_mh)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = EINVAL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* only ethernet support for now */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng minfop = mac_info(vnic->vn_lower_mh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (minfop->mi_nativemedia != DL_ETHER) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = ENOTSUP;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) dls_mgmt_get_linkinfo(vnic_id, vnic_name, NULL, NULL,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_client_open(vnic->vn_lower_mh, &vnic->vn_mch,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer vnic_name, MAC_OPEN_FLAGS_IS_VNIC);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* assign a MAC address to the VNIC */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = vnic_unicast_add(vnic, *vnic_addr_type, mac_slot,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prefix_len, mac_len, mac_addr, flags, diag, vid,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer req_hwgrp_flag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_muh = NULL;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (diag != NULL && req_hwgrp_flag)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_NO_HWRINGS;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* register to receive notification from underlying MAC */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_mnh = mac_notify_add(vnic->vn_lower_mh, vnic_notify_cb,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *vnic_addr_type = vnic->vn_addr_type;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_addr_len = *mac_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_vid = vid;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bcopy(mac_addr, vnic->vn_addr, vnic->vn_addr_len);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_addr_type == VNIC_MAC_ADDR_TYPE_FACTORY)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_slot_id = *mac_slot;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou /*
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * Set the initial VNIC capabilities. If the VNIC is created
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * over MACs which does not support nactive vlan, disable
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * VNIC's hardware checksum capability if its VID is not 0,
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * since the underlying MAC would get the hardware checksum
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou * offset wrong in case of VLAN packets.
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou */
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou if (vid == 0 || !mac_capab_get(vnic->vn_lower_mh,
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou MAC_CAPAB_NO_NATIVEVLAN, NULL)) {
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou if (!mac_capab_get(vnic->vn_lower_mh, MAC_CAPAB_HCKSUM,
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou &vnic->vn_hcksum_txflags))
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou vnic->vn_hcksum_txflags = 0;
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_hcksum_txflags = 0;
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* register with the MAC module */
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((mac = mac_alloc(MAC_VERSION)) == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev goto bail;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac->m_driver = vnic;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac->m_dip = vnic_get_dip();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mac->m_instance = (uint_t)-1;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac->m_src_addr = vnic->vn_addr;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac->m_callbacks = &vnic_m_callbacks;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!is_anchor) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If this is a VNIC based VLAN, then we check for the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * margin unless it has been created with the force
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * flag. If we are configuring a VLAN over an etherstub,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * we don't check the margin even if force is not set.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vid == 0 || (flags & VNIC_IOC_CREATE_FORCE) != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vid != VLAN_ID_NONE)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_force = B_TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * As the current margin size of the underlying mac is
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * used to determine the margin size of the VNIC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * itself, request the underlying mac not to change
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * to a smaller margin size.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_margin_add(vnic->vn_lower_mh,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &vnic->vn_margin, B_TRUE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(err == 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_margin = VLAN_TAGSZ;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mac_margin_add(vnic->vn_lower_mh,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &vnic->vn_margin, B_FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_free(mac);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (diag != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *diag = VNIC_IOC_DIAG_MACMARGIN_INVALID;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto bail;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_sdu_get(vnic->vn_lower_mh, &mac->m_min_sdu,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &mac->m_max_sdu);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi err = mac_mtu_add(vnic->vn_lower_mh, &mac->m_max_sdu, B_FALSE);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (err != 0) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_margin_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_margin) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_free(mac);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (diag != NULL)
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi *diag = VNIC_IOC_DIAG_MACMTU_INVALID;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi goto bail;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_mtu = mac->m_max_sdu;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_margin = VLAN_TAGSZ;
dcb12fb726d8dd4ff80ea255dc3f53b5692c75e5Robert Mustacchi mac->m_min_sdu = 1;
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail mac->m_max_sdu = ANCHOR_VNIC_MAX_MTU;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_mtu = ANCHOR_VNIC_MAX_MTU;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mac->m_margin = vnic->vn_margin;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
843e19887f64dde75055cf8842fc4db2171eff45johnlev err = mac_register(mac, &vnic->vn_mh);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mac_free(mac);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (err != 0) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (!is_anchor) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_mtu_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_mtu) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_margin_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_margin) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
843e19887f64dde75055cf8842fc4db2171eff45johnlev goto bail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Set the VNIC's MAC in the client */
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning if (!is_anchor) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_set_upper_mac(vnic->vn_mch, vnic->vn_mh, mrp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning if (mrp != NULL) {
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning if ((mrp->mrp_mask & MRP_RX_RINGS) != 0 ||
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning (mrp->mrp_mask & MRP_TX_RINGS) != 0) {
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning req_hwgrp_flag = B_TRUE;
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning }
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning err = mac_client_set_resources(vnic->vn_mch, mrp);
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning if (err != 0) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_mtu_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_mtu) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_margin_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_margin) == 0);
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning (void) mac_unregister(vnic->vn_mh);
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning goto bail;
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning }
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning }
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning }
54ba248100e7ebd2d552b955cf4eec0341b8b3a3Max Bruning
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = dls_devnet_create(vnic->vn_mh, vnic->vn_id, crgetzoneid(credp));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng VERIFY(is_anchor || mac_margin_remove(vnic->vn_lower_mh,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz vnic->vn_margin) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (!is_anchor) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_mtu_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_mtu) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_margin_remove(vnic->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vnic->vn_margin) == 0);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mac_unregister(vnic->vn_mh);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto bail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* add new VNIC to hash table */
843e19887f64dde75055cf8842fc4db2171eff45johnlev err = mod_hash_insert(vnic_hash, VNIC_HASH_KEY(vnic_id),
843e19887f64dde75055cf8842fc4db2171eff45johnlev (mod_hash_val_t)vnic);
843e19887f64dde75055cf8842fc4db2171eff45johnlev ASSERT(err == 0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_count++;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi /*
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi * Now that we've enabled this VNIC, we should go through and update the
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi * link state by setting it to our parents.
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi */
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng vnic->vn_enabled = B_TRUE;
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi if (is_anchor) {
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi mac_link_update(vnic->vn_mh, LINK_STATE_UP);
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi } else {
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi mac_link_update(vnic->vn_mh,
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi mac_client_stat_get(vnic->vn_mch, MAC_STAT_LINK_STATE));
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi }
bf773d37f3253ade20599b1f3df2732d1b2ae424Robert Mustacchi
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevbail:
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!is_anchor) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_mnh != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_notify_remove(vnic->vn_mnh, B_TRUE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_muh != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_unicast_remove(vnic->vn_mch, vnic->vn_muh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_mch != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_close(vnic->vn_mch, MAC_CLOSE_FLAGS_IS_VNIC);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_lower_mh != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_close(vnic->vn_lower_mh);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmem_cache_free(vnic_cache, vnic);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Modify the properties of an existing VNIC.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvnic_dev_modify(datalink_id_t vnic_id, uint_t modify_mask,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_mac_addr_type_t mac_addr_type, uint_t mac_len, uchar_t *mac_addr,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint_t mac_slot, mac_resource_props_t *mrp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_t *vnic = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_enter(&vnic_lock, RW_WRITER);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mod_hash_find(vnic_hash, VNIC_HASH_KEY(vnic_id),
843e19887f64dde75055cf8842fc4db2171eff45johnlev (mod_hash_val_t *)&vnic) != 0) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENOENT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Royvnic_dev_delete(datalink_id_t vnic_id, uint32_t flags, cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_t *vnic = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mod_hash_val_t val;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t tmpid;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int rc;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_enter(&vnic_lock, RW_WRITER);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mod_hash_find(vnic_hash, VNIC_HASH_KEY(vnic_id),
843e19887f64dde75055cf8842fc4db2171eff45johnlev (mod_hash_val_t *)&vnic) != 0) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENOENT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((rc = dls_devnet_destroy(vnic->vn_mh, &tmpid, B_TRUE)) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rw_exit(&vnic_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(vnic_id == tmpid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * We cannot unregister the MAC yet. Unregistering would
843e19887f64dde75055cf8842fc4db2171eff45johnlev * free up mac_impl_t which should not happen at this time.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * So disable mac_impl_t by calling mac_disable(). This will prevent
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * any new claims on mac_impl_t.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((rc = mac_disable(vnic->vn_mh)) != 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) dls_devnet_create(vnic->vn_mh, vnic_id,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy crgetzoneid(credp));
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (rc);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_cleanup_secondary_macs(vnic, vnic->vn_nhandles);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng vnic->vn_enabled = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev (void) mod_hash_remove(vnic_hash, VNIC_HASH_KEY(vnic_id), &val);
843e19887f64dde75055cf8842fc4db2171eff45johnlev ASSERT(vnic == (vnic_t *)val);
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_count--;
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * XXX-nicolas shouldn't have a void cast here, if it's
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * expected that the function will never fail, then we should
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * have an ASSERT().
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_unregister(vnic->vn_mh);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_lower_mh != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Check if MAC address for the vnic was obtained from the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * factory MAC addresses. If yes, release it.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_addr_type == VNIC_MAC_ADDR_TYPE_FACTORY) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_addr_factory_release(vnic->vn_mch,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic->vn_slot_id);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi (void) mac_mtu_remove(vnic->vn_lower_mh, vnic->vn_mtu);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_notify_remove(vnic->vn_mnh, B_TRUE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_unicast_remove(vnic->vn_mch, vnic->vn_muh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_close(vnic->vn_mch, MAC_CLOSE_FLAGS_IS_VNIC);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_close(vnic->vn_lower_mh);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmem_cache_free(vnic_cache, vnic);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevmblk_t *
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_tx(void *arg, mblk_t *mp_chain)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * This function could be invoked for an anchor VNIC when sending
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * broadcast and multicast packets, and unicast packets which did
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * not match any local known destination.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng freemsgchain(mp_chain);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng miocnak(q, mp, 0, ENOTSUP);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * This entry point cannot be passed-through, since it is invoked
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * for the per-VNIC kstats which must be exported independently
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * of the existence of VNIC MAC clients.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_stat(void *arg, uint_t stat, uint64_t *val)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_t *vnic = arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int rval = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_lower_mh == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * It's an anchor VNIC, which does not have any
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * statistics in itself.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (ENOTSUP);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * ENOTSUP must be reported for unsupported stats, the VNIC
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * driver reports a subset of the stats that would
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * be returned by a real piece of hardware.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev switch (stat) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_LINK_STATE:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_LINK_UP:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_PROMISC:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_IFSPEED:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_MULTIRCV:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_MULTIXMT:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_BRDCSTRCV:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_BRDCSTXMT:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_OPACKETS:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_STAT_OBYTES:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_IERRORS:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_OERRORS:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_RBYTES:
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_STAT_IPACKETS:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *val = mac_client_stat_get(vnic->vn_mch, stat);
843e19887f64dde75055cf8842fc4db2171eff45johnlev break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev default:
843e19887f64dde75055cf8842fc4db2171eff45johnlev rval = ENOTSUP;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (rval);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Invoked by the upper MAC to retrieve the lower MAC client handle
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * corresponding to a VNIC. A pointer to this function is obtained
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * by the upper MAC via capability query.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * XXX-nicolas Note: this currently causes all VNIC MAC clients to
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * receive the same MAC client handle for the same VNIC. This is ok
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * as long as we have only one VNIC MAC client which sends and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * receives data, but we don't currently enforce this at the MAC layer.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void *
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_mac_client_handle(void *vnic_arg)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_t *vnic = vnic_arg;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (vnic->vn_mch);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek/*
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Invoked when updating the primary MAC so that the secondary MACs are
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * kept in sync.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic void
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekvnic_mac_secondary_update(void *vnic_arg)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_t *vn = vnic_arg;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int i;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek for (i = 1; i <= vn->vn_nhandles; i++) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_secondary_dup(vn->vn_mc_handles[0], vn->vn_mc_handles[i]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Return information about the specified capability.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic boolean_t
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_capab_get(void *arg, mac_capab_t cap, void *cap_data)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_t *vnic = arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev switch (cap) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev case MAC_CAPAB_HCKSUM: {
843e19887f64dde75055cf8842fc4db2171eff45johnlev uint32_t *hcksum_txflags = cap_data;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev *hcksum_txflags = vnic->vn_hcksum_txflags &
843e19887f64dde75055cf8842fc4db2171eff45johnlev (HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM |
843e19887f64dde75055cf8842fc4db2171eff45johnlev HCKSUM_INET_PARTIAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_CAPAB_VNIC: {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_capab_vnic_t *vnic_capab = cap_data;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_lower_mh == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * It's an anchor VNIC, we don't have an underlying
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * NIC and MAC client handle.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (B_FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic_capab != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_capab->mcv_arg = vnic;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_capab->mcv_mac_client_handle =
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_mac_client_handle;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_capab->mcv_mac_secondary_update =
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_mac_secondary_update;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_CAPAB_ANCHOR_VNIC: {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* since it's an anchor VNIC we don't have lower mac handle */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_lower_mh == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(vnic->vn_link_id == 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (B_TRUE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (B_FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_CAPAB_NO_NATIVEVLAN:
9056fceb0248aaa677b3a3ca8a9cabbf9a1a542dCathy Zhou return (B_FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_CAPAB_NO_ZCOPY:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (B_TRUE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case MAC_CAPAB_VRRP: {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou mac_capab_vrrp_t *vrrp_capab = cap_data;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (vnic->vn_vrid != 0) {
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou if (vrrp_capab != NULL)
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou vrrp_capab->mcv_af = vnic->vn_af;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (B_TRUE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou return (B_FALSE);
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou }
843e19887f64dde75055cf8842fc4db2171eff45johnlev default:
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (B_FALSE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (B_TRUE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_start(void *arg)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_stop(void *arg)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_promisc(void *arg, boolean_t on)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
843e19887f64dde75055cf8842fc4db2171eff45johnlevvnic_m_multicst(void *arg, boolean_t add, const uint8_t *addrp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_m_unicst(void *arg, const uint8_t *macaddr)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vnic_t *vnic = arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (mac_vnic_unicast_set(vnic->vn_mch, macaddr));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic void
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekvnic_cleanup_secondary_macs(vnic_t *vn, int cnt)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int i;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* Remove existing secondaries (primary is at 0) */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek for (i = 1; i <= cnt; i++) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_rx_clear(vn->vn_mc_handles[i]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* unicast handle might not have been set yet */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek if (vn->vn_mu_handles[i] != NULL)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek (void) mac_unicast_remove(vn->vn_mc_handles[i],
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vn->vn_mu_handles[i]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_secondary_cleanup(vn->vn_mc_handles[i]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_client_close(vn->vn_mc_handles[i], MAC_CLOSE_FLAGS_IS_VNIC);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vn->vn_mu_handles[i] = NULL;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vn->vn_mc_handles[i] = NULL;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vn->vn_nhandles = 0;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek}
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek/*
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Setup secondary MAC addresses on the vnic. Due to limitations in the mac
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * code, each mac address must be associated with a mac_client (and the
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * flow that goes along with the client) so we need to create those clients
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * here.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic int
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekvnic_set_secondary_macs(vnic_t *vn, mac_secondary_addr_t *msa)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int i, err;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek char primary_name[MAXNAMELEN];
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* First, remove pre-existing secondaries */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek ASSERT(vn->vn_nhandles < MPT_MAXMACADDR);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_cleanup_secondary_macs(vn, vn->vn_nhandles);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek if (msa->ms_addrcnt == (uint32_t)-1)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek msa->ms_addrcnt = 0;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vn->vn_nhandles = msa->ms_addrcnt;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek (void) dls_mgmt_get_linkinfo(vn->vn_id, primary_name, NULL, NULL, NULL);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /*
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Now add the new secondary MACs
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Recall that the primary MAC address is the first element.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * The secondary clients are named after the primary with their
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * index to distinguish them.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek for (i = 1; i <= vn->vn_nhandles; i++) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek uint8_t *addr;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_diag_t mac_diag;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek char secondary_name[MAXNAMELEN];
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek (void) snprintf(secondary_name, sizeof (secondary_name),
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek "%s%02d", primary_name, i);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek err = mac_client_open(vn->vn_lower_mh, &vn->vn_mc_handles[i],
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek secondary_name, MAC_OPEN_FLAGS_IS_VNIC);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek if (err != 0) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* Remove any that we successfully added */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_cleanup_secondary_macs(vn, --i);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (err);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /*
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Assign a MAC address to the VNIC
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek *
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Normally this would be done with vnic_unicast_add but since
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * we know these are fixed adddresses, and since we need to
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * save this in the proper array slot, we bypass that function
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * and go direct.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek addr = msa->ms_addrs[i - 1];
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek err = mac_unicast_add(vn->vn_mc_handles[i], addr, 0,
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek &vn->vn_mu_handles[i], vn->vn_vid, &mac_diag);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek if (err != 0) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* Remove any that we successfully added */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_cleanup_secondary_macs(vn, i);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (err);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /*
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * Setup the secondary the same way as the primary (i.e.
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * receiver function/argument (e.g. i_dls_link_rx, mac_pkt_drop,
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek * etc.), the promisc list, and the resource controls).
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_secondary_dup(vn->vn_mc_handles[0], vn->vn_mc_handles[i]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (0);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek}
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic int
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekvnic_get_secondary_macs(vnic_t *vn, uint_t pr_valsize, void *pr_val)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int i;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_secondary_addr_t msa;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek if (pr_valsize < sizeof (msa))
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (EINVAL);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek /* Get existing addresses (primary is at 0) */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek ASSERT(vn->vn_nhandles < MPT_MAXMACADDR);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek for (i = 1; i <= vn->vn_nhandles; i++) {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek ASSERT(vn->vn_mc_handles[i] != NULL);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_unicast_secondary_get(vn->vn_mc_handles[i],
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek msa.ms_addrs[i - 1]);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek msa.ms_addrcnt = vn->vn_nhandles;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek bcopy(&msa, pr_val, sizeof (msa));
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (0);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek}
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail/*
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail * Callback functions for set/get of properties
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail */
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail/*ARGSUSED*/
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbailstatic int
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbailvnic_m_setprop(void *m_driver, const char *pr_name, mac_prop_id_t pr_num,
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail uint_t pr_valsize, const void *pr_val)
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int err = 0;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail vnic_t *vn = m_driver;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail switch (pr_num) {
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail case MAC_PROP_MTU: {
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail uint32_t mtu;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail if (pr_valsize < sizeof (mtu)) {
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail err = EINVAL;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail break;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail }
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail bcopy(pr_val, &mtu, sizeof (mtu));
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (vn->vn_link_id == DATALINK_INVALID_LINKID) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (mtu < ANCHOR_VNIC_MIN_MTU ||
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mtu > ANCHOR_VNIC_MAX_MTU) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi err = EINVAL;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi break;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi } else {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi err = mac_mtu_add(vn->vn_lower_mh, &mtu, B_FALSE);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi /*
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * If it's not supported to set a value here, translate
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * that to EINVAL, so user land gets a better idea of
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * what went wrong. This realistically means that they
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * violated the output of prop info.
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi */
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (err == ENOTSUP)
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi err = EINVAL;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (err != 0)
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi break;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi VERIFY(mac_mtu_remove(vn->vn_lower_mh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vn->vn_mtu) == 0);
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail }
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi vn->vn_mtu = mtu;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail err = mac_maxsdu_update(vn->vn_mh, mtu);
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail break;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail }
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi case MAC_PROP_VN_PROMISC_FILTERED: {
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi boolean_t filtered;
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi if (pr_valsize < sizeof (filtered)) {
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi err = EINVAL;
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi break;
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi }
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi bcopy(pr_val, &filtered, sizeof (filtered));
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi mac_set_promisc_filtered(vn->vn_mch, filtered);
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi break;
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek case MAC_PROP_SECONDARY_ADDRS: {
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_secondary_addr_t msa;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek bcopy(pr_val, &msa, sizeof (msa));
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek err = vnic_set_secondary_macs(vn, &msa);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek break;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail default:
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek err = ENOTSUP;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail break;
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail }
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail return (err);
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail}
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek/* ARGSUSED */
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekstatic int
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinekvnic_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek uint_t pr_valsize, void *pr_val)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek{
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek vnic_t *vn = arg;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek int ret = 0;
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi boolean_t out;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek switch (pr_num) {
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi case MAC_PROP_VN_PROMISC_FILTERED:
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi out = mac_get_promisc_filtered(vn->vn_mch);
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi ASSERT(pr_valsize >= sizeof (boolean_t));
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi bcopy(&out, pr_val, sizeof (boolean_t));
10a404923096d60a26c785c3cee15a5c364d51c0Robert Mustacchi break;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek case MAC_PROP_SECONDARY_ADDRS:
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek ret = vnic_get_secondary_macs(vn, pr_valsize, pr_val);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek break;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek default:
238d8f47d92b5b99a374f9639e0704420d3aef77Dale Ghent ret = ENOTSUP;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek break;
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek }
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek return (ret);
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek}
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer/* ARGSUSED */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic void vnic_m_propinfo(void *m_driver, const char *pr_name,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_id_t pr_num, mac_prop_info_handle_t prh)
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail{
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer vnic_t *vn = m_driver;
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail switch (pr_num) {
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail case MAC_PROP_MTU:
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (vn->vn_link_id == DATALINK_INVALID_LINKID) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_prop_info_set_range_uint32(prh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi ANCHOR_VNIC_MIN_MTU, ANCHOR_VNIC_MAX_MTU);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi } else {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi uint32_t max;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_perim_handle_t mph;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_propval_range_t range;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi /*
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * The valid range for a VNIC's MTU is the minimum that
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * the device supports and the current value of the
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * device. A VNIC cannot increase the current MTU of the
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * device. Therefore we need to get the range from the
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * propinfo endpoint and current mtu from the
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi * traditional property endpoint.
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi */
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_perim_enter_by_mh(vn->vn_lower_mh, &mph);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (mac_get_prop(vn->vn_lower_mh, MAC_PROP_MTU, "mtu",
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi &max, sizeof (uint32_t)) != 0) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_perim_exit(mph);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi return;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi range.mpr_count = 1;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi if (mac_prop_info(vn->vn_lower_mh, MAC_PROP_MTU, "mtu",
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi NULL, 0, &range, NULL) != 0) {
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_perim_exit(mph);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi return;
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_prop_info_set_default_uint32(prh, max);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_prop_info_set_range_uint32(prh,
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi range.mpr_range_uint32[0].mpur_min, max);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi mac_perim_exit(mph);
a776d98e5f349dbb7f5a47eca48f50e6117adcb7Robert Mustacchi }
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail break;
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail }
f0f2c3a5cf65a61de34af42edac38b2a7bda3416Girish Moodalbail}
ab6f61efc4ce594c2a9d4396ce159129fad91192Girish Moodalbail
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Royvnic_info(vnic_info_t *info, cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_t *vnic;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int err;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* Make sure that the VNIC link is visible from the caller's zone. */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!dls_devnet_islinkvisible(info->vn_vnic_id, crgetzoneid(credp)))
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (ENOENT);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rw_enter(&vnic_lock, RW_WRITER);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = mod_hash_find(vnic_hash, VNIC_HASH_KEY(info->vn_vnic_id),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (mod_hash_val_t *)&vnic);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (err != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rw_exit(&vnic_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (ENOENT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_link_id = vnic->vn_link_id;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_mac_addr_type = vnic->vn_addr_type;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_mac_len = vnic->vn_addr_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bcopy(vnic->vn_addr, info->vn_mac_addr, MAXMACADDRLEN);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_mac_slot = vnic->vn_slot_id;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_mac_prefix_len = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_vid = vnic->vn_vid;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng info->vn_force = vnic->vn_force;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou info->vn_vrid = vnic->vn_vrid;
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou info->vn_af = vnic->vn_af;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bzero(&info->vn_resource_props, sizeof (mac_resource_props_t));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vnic->vn_mch != NULL)
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek mac_client_get_resources(vnic->vn_mch,
1a41ca239310955ae95b2569b707432432a58580Jerry Jelinek &info->vn_resource_props);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev rw_exit(&vnic_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvnic_notify_cb(void *arg, mac_notify_type_t type)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vnic_t *vnic = arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng * Do not deliver notifications if the vnic is not fully initialized
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng * or is in process of being torn down.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng if (!vnic->vn_enabled)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng switch (type) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case MAC_NOTE_UNICST:
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng /*
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng * Only the VLAN VNIC needs to be notified with primary MAC
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng * address change.
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng */
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng if (vnic->vn_addr_type != VNIC_MAC_ADDR_TYPE_PRIMARY)
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng return;
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* the unicast MAC address value */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicast_primary_get(vnic->vn_lower_mh, vnic->vn_addr);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* notify its upper layer MAC about MAC address change */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicst_update(vnic->vn_mh, (const uint8_t *)vnic->vn_addr);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng case MAC_NOTE_LINK:
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng mac_link_update(vnic->vn_mh,
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng mac_client_stat_get(vnic->vn_mch, MAC_STAT_LINK_STATE));
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng break;
2c4ec68272805fba7d569318536bd680e9c52e03Eric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng default:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}