VBoxNetFltBow-solaris.c revision 0499c1d2ec22c24d76b805994b08378f8e3465c2
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/* $Id$ */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** @file
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*
0499c1d2ec22c24d76b805994b08378f8e3465c2vboxsync * Copyright (C) 2008-2012 Oracle Corporation
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * available from http://www.virtualbox.org. This file is free software;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * General Public License (GPL) as published by the Free Software
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync *
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * The contents of this file may alternatively be used under the terms
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * of the Common Development and Distribution License Version 1.0
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * CDDL are applicable instead of those of the GPL.
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync *
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * You may elect to license modified versions of this file under the
d1d578bcfa0fcb019ef9cde17b7e493625143ab9vboxsync * terms and conditions of either the GPL or the CDDL or both.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync* Header Files *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync#ifdef DEBUG_ramshankar
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync# define LOG_ENABLED
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync# define LOG_INSTANCE RTLogRelDefaultInstance()
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync#endif
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <VBox/log.h>
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync#include <VBox/err.h>
6dd8f5023a9ba7588212331db90059553136fe33vboxsync#include <VBox/intnetinline.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <VBox/version.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/initterm.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/alloca.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/assert.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/err.h>
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync#include <iprt/string.h>
e7b615a442051960547fd3835527b975ab7da970vboxsync#include <iprt/rand.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/net.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <iprt/spinlock.h>
e7b615a442051960547fd3835527b975ab7da970vboxsync#include <iprt/mem.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync#include <sys/types.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/modctl.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/conf.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/stat.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/ddi.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/gld.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/sunddi.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/strsubr.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/dlpi.h>
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync#include <sys/dls_mgmt.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/mac.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include <sys/strsun.h>
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#include <sys/vnic_mgmt.h>
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#include <sys/mac_client.h>
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#include <sys/mac_provider.h>
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#include <sys/dls.h>
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#include <sys/dld.h>
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#include <sys/cred.h>
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#define VBOXNETFLT_OS_SPECFIC 1
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#include "../VBoxNetFltInternal.h"
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync* Defined Constants And Macros *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** The module name. */
2eef97414c483090011bf681518f2ee1894664e7vboxsync#define DEVICE_NAME "vboxbow"
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** The module descriptions as seen in 'modinfo'. */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#define DEVICE_DESC_DRV "VirtualBox NetBow"
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/** The dynamically created VNIC name (hardcoded in NetIf-solaris.cpp).
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @todo move this define into a common header. */
2eef97414c483090011bf681518f2ee1894664e7vboxsync#define VBOXBOW_VNIC_NAME "vboxvnic"
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/** The VirtualBox VNIC template name (hardcoded in NetIf-solaris.cpp).
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * * @todo move this define into a common header. */
2eef97414c483090011bf681518f2ee1894664e7vboxsync#define VBOXBOW_VNIC_TEMPLATE_NAME "vboxvnic_template"
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** Debugging switch for using symbols in kmdb */
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync# define LOCAL static
e7b615a442051960547fd3835527b975ab7da970vboxsync/** VBOXNETFLTVNIC::u32Magic */
e7b615a442051960547fd3835527b975ab7da970vboxsync# define VBOXNETFLTVNIC_MAGIC 0x0ddfaced
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync/** VLAN tag masking, should probably be in IPRT? */
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#define VLAN_ID(vlan) (((vlan) >> 0) & 0x0fffu)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#define VLAN_CFI(vlan) (((vlan) >> 12) & 0x0001u)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#define VLAN_PRI(vlan) (((vlan) >> 13) & 0x0007u)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync#define VLAN_TAG(pri,cfi,vid) (((pri) << 13) | ((cfi) << 12) | ((vid) << 0))
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsynctypedef struct VLANHEADER
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync{
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync uint16_t Type;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync uint16_t Data;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync} VLANHEADER;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsynctypedef struct VLANHEADER *PVLANHEADER;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/* Private: from sys/vlan.h */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#ifndef VLAN_ID_NONE
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync# define VLAN_ID_NONE 0
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#endif
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/* Private: from sys/param.h */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#ifndef MAXLINKNAMESPECIFIER
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync# define MAXLINKNAMESPECIFIER 96 /* MAXLINKNAMELEN + ZONENAME_MAX */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#endif
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/* Private: from sys/mac_client_priv.h, mac client function prototypes. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncextern uint16_t mac_client_vid(mac_client_handle_t hClient);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncextern void mac_client_get_resources(mac_client_handle_t hClient, mac_resource_props_t *pResources);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncextern int mac_client_set_resources(mac_client_handle_t hClient, mac_resource_props_t *pResources);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync* Kernel Entry Hooks *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync* Structures and Typedefs *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * cb_ops: for drivers that support char/block entry points
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic struct cb_ops g_VBoxNetFltSolarisCbOps =
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nulldev, /* c open */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nulldev, /* c close */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* b strategy */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* b dump */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* b print */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c read */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c write*/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c ioctl*/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c devmap */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c mmap */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c segmap */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nochpoll, /* c poll */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync ddi_prop_op, /* property ops */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync NULL, /* streamtab */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync D_NEW | D_MP, /* compat. flag */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync CB_REV, /* revision */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* c aread */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev /* c awrite */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync};
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * dev_ops: for driver device operations
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic struct dev_ops g_VBoxNetFltSolarisDevOps =
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync DEVO_REV, /* driver build revision */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync 0, /* ref count */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync VBoxNetFltSolarisGetInfo,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nulldev, /* identify */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nulldev, /* probe */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync VBoxNetFltSolarisAttach,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync VBoxNetFltSolarisDetach,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* reset */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync &g_VBoxNetFltSolarisCbOps,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync NULL, /* bus ops */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync nodev, /* power */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync ddi_quiesce_not_needed
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync};
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * modldrv: export driver specifics to the kernel
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic struct modldrv g_VBoxNetFltSolarisModule =
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync &mod_driverops, /* extern from kernel */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync &g_VBoxNetFltSolarisDevOps
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync};
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * modlinkage: export install/remove/info to the kernel
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic struct modlinkage g_VBoxNetFltSolarisModLinkage =
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync MODREV_1,
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync {
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync &g_VBoxNetFltSolarisModule,
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync NULL,
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync};
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * VBOXNETFLTVNICTEMPLATE: VNIC template information.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsynctypedef struct VBOXNETFLTVNICTEMPLATE
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync{
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** The name of link on which the VNIC template is created on. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync char szLinkName[MAXNAMELEN];
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** The VLAN Id (can be VLAN_ID_NONE). */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync uint16_t uVLANId;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Resources (bandwidth, CPU bindings, flow priority etc.) */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_resource_props_t Resources;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync} VBOXNETFLTVNICTEMPLATE;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsynctypedef struct VBOXNETFLTVNICTEMPLATE *PVBOXNETFLTVNICTEMPLATE;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync/**
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync * VBOXNETFLTVNIC: Per-VNIC instance data.
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync */
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsynctypedef struct VBOXNETFLTVNIC
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync{
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Magic number (VBOXNETFLTVNIC_MAGIC). */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync uint32_t u32Magic;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Whether we created the VNIC or not. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync bool fCreated;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Pointer to the VNIC template if any. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync PVBOXNETFLTVNICTEMPLATE pVNICTemplate;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Pointer to the VirtualBox interface instance. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync void *pvIf;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync /** The MAC handle. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_handle_t hInterface;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** The VNIC link ID. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync datalink_id_t hLinkId;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** The MAC client handle */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_client_handle_t hClient;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync /** The unicast address handle. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_unicast_handle_t hUnicast;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync /** The promiscuous handle. */
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_promisc_handle_t hPromisc;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /* The VNIC name. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync char szName[MAXLINKNAMESPECIFIER];
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /** Handle to the next VNIC in the list. */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync list_node_t hNode;
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync} VBOXNETFLTVNIC;
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsynctypedef struct VBOXNETFLTVNIC *PVBOXNETFLTVNIC;
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync* Global Variables *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** Global Device handle we only support one instance. */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic dev_info_t *g_pVBoxNetFltSolarisDip = NULL;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** Global Mutex (actually an rw lock). */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic RTSEMFASTMUTEX g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/** The (common) global data. */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncstatic VBOXNETFLTGLOBALS g_VBoxNetFltSolarisGlobals;
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync/** Global next-free VNIC Id (never decrements). */
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsyncstatic volatile uint64_t g_VBoxNetFltSolarisVNICId = 0;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/*******************************************************************************
e7b615a442051960547fd3835527b975ab7da970vboxsync* Internal Functions *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync*******************************************************************************/
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncLOCAL int vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis, mac_handle_t hInterface, bool fIsVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC);
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsyncLOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNICTEMPLATE pVNICTemplate);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncLOCAL inline int vboxNetFltSolarisGetLinkId(const char *pszMacName, datalink_id_t *pLinkId);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Kernel entry points
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint _init(void)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":_init\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Prevent module autounloading.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync modctl_t *pModCtl = mod_getctl(&g_VBoxNetFltSolarisModLinkage);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (pModCtl)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Initialize IPRT.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync int rc = RTR0Init(0);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (RT_SUCCESS(rc))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Initialize Solaris specific globals here.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (RT_SUCCESS(rc))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Initialize the globals and connect to the support driver.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * for establishing the connect to the support driver.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (RT_SUCCESS(rc))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (!rc)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync RTR0Term();
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":failed to initialize IPRT (rc=%d)\n", rc));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return RTErrConvertToErrno(rc);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint _fini(void)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync int rc;
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":_fini\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Undo the work done during start (in reverse order).
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync rc = vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (RT_FAILURE(rc))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":_fini - busy!\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return EBUSY;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync rc = mod_remove(&g_VBoxNetFltSolarisModLinkage);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (!rc)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (g_VBoxNetFltSolarisMtx != NIL_RTSEMFASTMUTEX)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync RTR0Term();
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint _info(struct modinfo *pModInfo)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":_info\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync int rc = mod_info(&g_VBoxNetFltSolarisModLinkage, pModInfo);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":_info returns %d\n", rc));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Attach entry point, to attach a device to the system or resume it.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pDip The module structure instance.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param enmCmd Operation type (attach/resume).
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns corresponding solaris error code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":VBoxNetFltSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync switch (enmCmd)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_ATTACH:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
2eef97414c483090011bf681518f2ee1894664e7vboxsync g_pVBoxNetFltSolarisDip = pDip;
2eef97414c483090011bf681518f2ee1894664e7vboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_RESUME:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /* Nothing to do here... */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /* case DDI_PM_RESUME: */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync default:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_FAILURE;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Detach entry point, to detach a device to the system or suspend it.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pDip The module structure instance.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param enmCmd Operation type (detach/suspend).
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns corresponding solaris error code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":VBoxNetFltSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync switch (enmCmd)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_DETACH:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_RESUME:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /* Nothing to do here... */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /* case DDI_PM_SUSPEND: */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /* case DDI_HOT_PLUG_DETACH: */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync default:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_FAILURE;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Info entry point, called by solaris kernel for obtaining driver info.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pDip The module structure instance (do not use).
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param enmCmd Information request type.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pvArg Type specific argument.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param ppvResult Where to store the requested info.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns corresponding solaris error code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int VBoxNetFltSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppResult)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":VBoxNetFltSolarisGetInfo pDip=%p enmCmd=%d pArg=%p instance=%d\n", pDip, enmCmd, getminor((dev_t)pvArg)));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync switch (enmCmd)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_INFO_DEVT2DEVINFO:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *ppResult = g_pVBoxNetFltSolarisDip;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync case DDI_INFO_DEVT2INSTANCE:
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync int instance = getminor((dev_t)pvArg);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *ppResult = (void *)(uintptr_t)instance;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return DDI_FAILURE;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Create a solaris message block from the SG list.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pThis The instance.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pSG Pointer to the scatter-gather list.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns Solaris message block.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsyncLOCAL inline mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG pThis=%p pSG=%p\n", pThis, pSG));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync mblk_t *pMsg = allocb(pSG->cbTotal, BPRI_HI);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (RT_UNLIKELY(!pMsg))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG failed to alloc %d bytes for mblk_t.\n", pSG->cbTotal));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return NULL;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Single buffer copy. Maybe later explore the
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * need/possibility for using a mblk_t chain rather.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync for (unsigned i = 0; i < pSG->cSegsUsed; i++)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (pSG->aSegs[i].pv)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync bcopy(pSG->aSegs[i].pv, pMsg->b_wptr, pSG->aSegs[i].cb);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pMsg->b_wptr += pSG->aSegs[i].cb;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return pMsg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Calculate the number of segments required for this message block.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pThis The instance
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pMsg Pointer to the data message.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns Number of segments.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync unsigned cSegs = 0;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync for (mblk_t *pCur = pMsg; pCur; pCur = pCur->b_cont)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (MBLKL(pCur))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync cSegs++;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#ifdef PADD_RUNT_FRAMES_FROM_HOST
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (msgdsize(pMsg) < 60)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync cSegs++;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#endif
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync NOREF(pThis);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return RT_MAX(cSegs, 1);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Initializes an SG list from the given message block.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pThis The instance.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pMsg Pointer to the data message.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync The caller must ensure it's not a control message block.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pSG Pointer to the SG.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param cSegs Number of segments in the SG.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * This should match the number in the message block exactly!
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param fSrc The source of the message.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @returns VBox status code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pThis=%p pMsg=%p pSG=%p cSegs=%d\n", pThis, pMsg, pSG, cSegs));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
6dd8f5023a9ba7588212331db90059553136fe33vboxsync * Convert the message block to segments. Works cbTotal and sets cSegsUsed.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
9127c416edfd6f9266e387f7abd7aa9904eecbc9vboxsync IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync mblk_t *pCur = pMsg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync unsigned iSeg = 0;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync while (pCur)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync size_t cbSeg = MBLKL(pCur);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (cbSeg)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync void *pvSeg = pCur->b_rptr;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].pv = pvSeg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].cb = cbSeg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->cbTotal += cbSeg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync iSeg++;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pCur = pCur->b_cont;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->cSegsUsed = iSeg;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#ifdef PADD_RUNT_FRAMES_FROM_HOST
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (pSG->cbTotal < 60 && (fSrc & INTNETTRUNKDIR_HOST))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pulling up to length.\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync static uint8_t const s_abZero[128] = {0};
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].pv = (void *)&s_abZero[0];
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->cbTotal = 60;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync pSG->cSegsUsed++;
6dd8f5023a9ba7588212331db90059553136fe33vboxsync Assert(iSeg + 1 < cSegs);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync#endif
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG iSeg=%d pSG->cbTotal=%d msgdsize=%d\n", iSeg, pSG->cbTotal, msgdsize(pMsg)));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return VINF_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Simple packet dump, used for internal debugging.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pMsg Pointer to the message to analyze and dump.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsyncLOCAL void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync LogFunc((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n", pMsg));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pMsg->b_rptr;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync uint8_t *pb = pMsg->b_rptr;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV4))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (!pMsg->b_cont)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if (pIpHdr->ip_p == RTNETIPV4_PROT_ICMP)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":ICMP D=%.6Rhxs S=%.6Rhxs T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":TCP D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync if ( RT_BE2H_U16(pUdpHdr->uh_sport) == 67
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync && RT_BE2H_U16(pUdpHdr->uh_dport) == 68)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync LogRel((DEVICE_NAME ":UDP bootp ack D=%.6Rhxs S=%.6Rhxs UDP_CheckSum=%04x Computex=%04x\n", pb, pb + 6,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync RT_BE2H_U16(pUdpHdr->uh_sum), RT_BE2H_U16(RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1))));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":Chained IP packet. Skipping validity check.\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_VLAN))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync PVLANHEADER pVlanHdr = (PVLANHEADER)(pMsg->b_rptr + sizeof(RTNETETHERHDR) - sizeof(pEthHdr->EtherType));
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":VLAN Pcp=%u Cfi=%u Id=%u\n", VLAN_PRI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_CFI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_ID(RT_BE2H_U16(pVlanHdr->Data))));
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME "%.*Rhxd\n", sizeof(VLANHEADER), pVlanHdr));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PRTNETARPHDR pArpHdr = (PRTNETARPHDR)(pEthHdr + 1);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_1)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync || pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_2)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync || pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_3))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":IPX packet.\n"));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync &pEthHdr->SrcMac));
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync /* Log((DEVICE_NAME ":%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr)); */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e9de8285074ab7533c564399c671bfa415f24a67vboxsync
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync/**
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync * Helper.
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync */
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsyncDECLINLINE(bool) vboxNetFltPortSolarisIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync{
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync return pThis->u.s.MacAddr.au16[0] == pMac->au16[0]
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync && pThis->u.s.MacAddr.au16[1] == pMac->au16[1]
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync && pThis->u.s.MacAddr.au16[2] == pMac->au16[2];
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync}
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Receive (rx) entry point.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pvData Private data.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param hResource The resource handle.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pMsg The packet.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param fLoopback Whether this is a loopback packet or not.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncLOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisRecv pvData=%p pMsg=%p fLoopback=%d cbData=%d\n", pvData, pMsg, fLoopback, pMsg ? MBLKL(pMsg) : 0));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvData;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync AssertPtrReturnVoid(pThis);
aae1f903b51565bdbc8bebd1fb7f8c7a7a761470vboxsync AssertPtrReturnVoid(pMsg);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Active? Retain the instance and increment the busy counter.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
d61e6f5b11d9031623420bd7ed3013477d8f402dvboxsync if (!vboxNetFltTryRetainBusyActive(pThis))
ebcf8692873035c08df84f4dfb9395e2810b7adfvboxsync {
ebcf8692873035c08df84f4dfb9395e2810b7adfvboxsync freemsgchain(pMsg);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return;
ebcf8692873035c08df84f4dfb9395e2810b7adfvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync uint32_t fSrc = INTNETTRUNKDIR_WIRE;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr;
e9de8285074ab7533c564399c671bfa415f24a67vboxsync if ( MBLKL(pMsg) >= sizeof(RTNETETHERHDR)
5f809eed9fe4d8f7f317e8102657eb877fd5fbdavboxsync && vboxNetFltPortSolarisIsHostMac(pThis, &pEthHdr->SrcMac))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync fSrc = INTNETTRUNKDIR_HOST;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Route all received packets into the internal network.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync uint16_t cFailed = 0;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync for (mblk_t *pCurMsg = pMsg; pCurMsg != NULL; pCurMsg = pCurMsg->b_next)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync unsigned cSegs = vboxNetFltSolarisMBlkCalcSGSegs(pThis, pCurMsg);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync int rc = vboxNetFltSolarisMBlkToSG(pThis, pMsg, pSG, cSegs, fSrc);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync if (RT_SUCCESS(rc))
586cf6585d0e6aa3bef888eeff116bf82d18cd83vboxsync pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL, pSG, fSrc);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync else
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync cFailed++;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync }
aae1f903b51565bdbc8bebd1fb7f8c7a7a761470vboxsync vboxNetFltRelease(pThis, true /* fBusy */);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync if (RT_UNLIKELY(cFailed))
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed for %u packets.\n", cFailed));
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync freemsgchain(pMsg);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync NOREF(hResource);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync#if 0
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync/**
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * MAC layer link notification hook.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync *
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * @param pvArg Opaque pointer to the instance.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * @param Type Notification Type.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync *
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * @remarks This hook will be invoked for various changes to the underlying
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * interface even when VMs aren't running so don't do any funky stuff
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * here.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsyncLOCAL void vboxNetFltSolarisLinkNotify(void *pvArg, mac_notify_type_t Type)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync{
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisLinkNotify pvArg=%p Type=%d\n", pvArg, Type));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync PVBOXNETFLTINS pThis = pvArg;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync AssertReturnVoid(VALID_PTR(pThis));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync AssertReturnVoid(pThis->u.s.hInterface);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync switch (Type)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync case MAC_NOTE_LINK:
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisLinkNotify link state change\n"));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync link_state_t hLinkState = mac_stat_get(pThis->u.s.hInterface, MAC_STAT_LINK_STATE);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync bool fDisconnectedFromHost = hLinkState == LINK_STATE_UP ? false : true;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (fDisconnectedFromHost != ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost))
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, fDisconnectedFromHost);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisLinkNotify link state change: new state=%s\n", fDisconnectedFromHost ? "DOWN" : "UP"));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync break;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync default:
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync}
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync#endif
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync/**
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Report capabilities and MAC address to IntNet after obtaining the MAC address
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * of the underlying interface for a VNIC or the current interface if it's a
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * physical/ether-stub interface.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @param pThis The instance.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param hInterface The Interface handle.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param fIsVNIC Whether this interface handle corresponds to a VNIC
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * or not.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @remarks Retains the instance while doing it's job.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @returns VBox status code.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncLOCAL int vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis, mac_handle_t hInterface, bool fIsVNIC)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync{
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync mac_handle_t hLowerMac = NULL;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (!fIsVNIC)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync hLowerMac = hInterface;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync hLowerMac = mac_get_lower_mac_handle(hInterface);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (RT_UNLIKELY(!hLowerMac))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisReportInfo failed to get lower MAC handle for '%s'\n", pThis->szName));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return VERR_INVALID_HANDLE;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->u.s.hInterface = hLowerMac;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync#if 0
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync /*
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * Try setup link notification hooks, this might fail if mac_no_notification()
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * doesn't support it. We won't bother using the private function since link notification
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * isn't critical for us and ignore failures.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->u.s.hNotify = mac_notify_add(hLowerMac, vboxNetFltSolarisLinkNotify, pThis);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (!pThis->u.s.hNotify)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisReportInfo Warning! Failed to setup link notification hook.\n"));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync#endif
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync mac_unicast_primary_get(hLowerMac, (uint8_t *)pThis->u.s.MacAddr.au8);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync Assert(pThis->pSwitchPort);
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisReportInfo phys mac %.6Rhxs\n", &pThis->u.s.MacAddr));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync vboxNetFltRelease(pThis, true /*fBusy*/);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return VINF_SUCCESS;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisReportInfo failed to retain interface. pThis=%p\n", pThis));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return VERR_INTNET_FLT_IF_BUSY;
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync}
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync/**
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Initialize a VNIC, optionally from a template.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @param pThis The instance.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @param pVNIC Pointer to the VNIC.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param pVNICTemplate Pointer to the VNIC template initialize from, can be
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * NULL.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @returns VBox status code.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC)
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync{
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Some paranoia.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertReturn(pThis, VERR_INVALID_PARAMETER);
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertReturn(pVNIC, VERR_INVALID_PARAMETER);
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertReturn(pVNIC->hInterface, VERR_INVALID_POINTER);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync AssertReturn(pVNIC->hLinkId != DATALINK_INVALID_LINKID, VERR_INVALID_HANDLE);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync AssertReturn(!pVNIC->hClient, VERR_INVALID_POINTER);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync int rc = mac_client_open(pVNIC->hInterface, &pVNIC->hClient,
e7b615a442051960547fd3835527b975ab7da970vboxsync NULL, /* name of this client */
e7b615a442051960547fd3835527b975ab7da970vboxsync MAC_OPEN_FLAGS_USE_DATALINK_NAME | /* client name same as underlying NIC */
e7b615a442051960547fd3835527b975ab7da970vboxsync MAC_OPEN_FLAGS_MULTI_PRIMARY /* allow multiple primary unicasts */
e7b615a442051960547fd3835527b975ab7da970vboxsync );
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (pVNIC->pVNICTemplate)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = mac_client_set_resources(pVNIC->hClient, &pVNIC->pVNICTemplate->Resources);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisInitVNIC succesfully initialized VNIC.\n"));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return VINF_SUCCESS;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC mac_client_set_resources failed. rc=%d\n", rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_client_close(pVNIC->hClient, 0 /* flags */);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hClient = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return rc;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync}
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/**
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Initializes the VNIC template. This involves opening the template VNIC to
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * retreive info. like the VLAN Id, underlying MAC address etc.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param pThis The VM connection instance.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param pVNICTemplate Pointer to a VNIC template to initialize.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @returns VBox status code.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsyncLOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNICTEMPLATE pVNICTemplate)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate pThis=%p pVNICTemplate=%p\n", pThis, pVNICTemplate));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync AssertReturn(pVNICTemplate, VERR_INVALID_PARAMETER);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync AssertReturn(pThis->u.s.fIsVNICTemplate == true, VERR_INVALID_STATE);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Get the VNIC template's datalink ID.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync datalink_id_t VNICLinkId;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync int rc = vboxNetFltSolarisGetLinkId(pThis->szName, &VNICLinkId);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_SUCCESS(rc))
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync {
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Open the VNIC to obtain a MAC handle so as to retreive the VLAN ID.
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_handle_t hInterface;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = mac_open_by_linkid(VNICLinkId, &hInterface);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (!rc)
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Get the underlying linkname.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_handle_t hPhysLinkHandle = mac_get_lower_mac_handle(hInterface);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(hPhysLinkHandle))
e7b615a442051960547fd3835527b975ab7da970vboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync const char *pszLinkName = mac_name(hPhysLinkHandle);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = RTStrCopy(pVNICTemplate->szLinkName, sizeof(pVNICTemplate->szLinkName), pszLinkName);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_SUCCESS(rc))
e7b615a442051960547fd3835527b975ab7da970vboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Now open the VNIC template to retrieve the VLAN Id & resources.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_client_handle_t hClient;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = mac_client_open(hInterface, &hClient,
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync NULL, /* name of this client */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync MAC_OPEN_FLAGS_USE_DATALINK_NAME | /* client name same as underlying NIC */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync MAC_OPEN_FLAGS_MULTI_PRIMARY /* allow multiple primary unicasts */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync );
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNICTemplate->uVLANId = mac_client_vid(hClient);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_client_get_resources(hClient, &pVNICTemplate->Resources);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_client_close(hClient, 0 /* fFlags */);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_close(hInterface);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate successfully init. VNIC template. szLinkName=%s\n",
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNICTemplate->szLinkName));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return VINF_SUCCESS;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open VNIC template. rc=%d\n", rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = VERR_INTNET_FLT_IF_FAILED;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to copy link name of underlying interface. rc=%d\n", rc));
e7b615a442051960547fd3835527b975ab7da970vboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get lower handle for VNIC template '%s'.\n", pThis->szName));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = VERR_INTNET_FLT_IF_FAILED;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_close(hInterface);
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync }
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open by link ID. rc=%d\n", rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = VERR_INTNET_FLT_IF_FAILED;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync }
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get VNIC template link Id. rc=%d\n", rc));
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return rc;
e7b615a442051960547fd3835527b975ab7da970vboxsync}
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync/**
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * Allocate a VNIC structure.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @returns An allocated VNIC structure or NULL in case of errors.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void)
e7b615a442051960547fd3835527b975ab7da970vboxsync{
ab2e57121ad311a565b1737da0d1640b6ec532a7vboxsync PVBOXNETFLTVNIC pVNIC = RTMemAllocZ(sizeof(VBOXNETFLTVNIC));
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_UNLIKELY(!pVNIC))
e7b615a442051960547fd3835527b975ab7da970vboxsync return NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->u32Magic = VBOXNETFLTVNIC_MAGIC;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->fCreated = false;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->pVNICTemplate = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->pvIf = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hInterface = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hLinkId = DATALINK_INVALID_LINKID;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hClient = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hUnicast = NULL;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync pVNIC->hPromisc = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync RT_ZERO(pVNIC->szName);
e7b615a442051960547fd3835527b975ab7da970vboxsync list_link_init(&pVNIC->hNode);
e7b615a442051960547fd3835527b975ab7da970vboxsync return pVNIC;
e7b615a442051960547fd3835527b975ab7da970vboxsync}
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync/**
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * Frees an allocated VNIC.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @param pVNIC Pointer to the VNIC.
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync */
0b1dcacc4b338fc752fffa2bd92a84897b9d97efvboxsyncLOCAL inline void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC)
e7b615a442051960547fd3835527b975ab7da970vboxsync{
ab2e57121ad311a565b1737da0d1640b6ec532a7vboxsync RTMemFree(pVNIC);
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync}
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * Destroy a created VNIC if it was created by us, or just
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * de-initializes the VNIC freeing up resources handles.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync * @param pVNIC Pointer to the VNIC.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
ab2e57121ad311a565b1737da0d1640b6ec532a7vboxsync AssertPtrReturnVoid(pVNIC);
ab2e57121ad311a565b1737da0d1640b6ec532a7vboxsync AssertMsgReturnVoid(pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC, ("pVNIC=%p u32Magic=%#x\n", pVNIC, pVNIC->u32Magic));
e7b615a442051960547fd3835527b975ab7da970vboxsync if (pVNIC)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync if (pVNIC->hClient)
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync {
cd8f4e64786c9ee82734c2ced86f21b8e60d4415vboxsync#if 0
e7b615a442051960547fd3835527b975ab7da970vboxsync if (pVNIC->hUnicast)
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->hUnicast = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
cd8f4e64786c9ee82734c2ced86f21b8e60d4415vboxsync#endif
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (pVNIC->hPromisc)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_promisc_remove(pVNIC->hPromisc);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync pVNIC->hPromisc = NULL;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_rx_clear(pVNIC->hClient);
de1338ccd96eef7da920a0db96699ab9bb6829efvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_client_close(pVNIC->hClient, 0 /* fFlags */);
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->hClient = NULL;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync if (pVNIC->hInterface)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_close(pVNIC->hInterface);
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->hInterface = NULL;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync if (pVNIC->fCreated)
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync vnic_delete(pVNIC->hLinkId, 0 /* Flags */);
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->hLinkId = DATALINK_INVALID_LINKID;
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->fCreated = false;
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (pVNIC->pVNICTemplate)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync RTMemFree(pVNIC->pVNICTemplate);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->pVNICTemplate = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/**
e7b615a442051960547fd3835527b975ab7da970vboxsync * Create a non-persistent VNIC over the given interface.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync *
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @param pThis The VM connection instance.
e7b615a442051960547fd3835527b975ab7da970vboxsync * @param ppVNIC Where to store the created VNIC.
e7b615a442051960547fd3835527b975ab7da970vboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @returns VBox status code.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsyncLOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC pThis=%p\n", pThis));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertReturn(pThis, VERR_INVALID_POINTER);
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertReturn(ppVNIC, VERR_INVALID_POINTER);
e7b615a442051960547fd3835527b975ab7da970vboxsync
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync int rc = VERR_INVALID_STATE;
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = vboxNetFltSolarisAllocVNIC();
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_UNLIKELY(!pVNIC))
e7b615a442051960547fd3835527b975ab7da970vboxsync return VERR_NO_MEMORY;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
76a6b12b9722672f423c9c5026c4b1df6c9ef762vboxsync * Set a random MAC address for now. It will be changed to the VM interface's
76a6b12b9722672f423c9c5026c4b1df6c9ef762vboxsync * MAC address later, see vboxNetFltPortOsNotifyMacAddress().
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync RTMAC GuestMac;
e7b615a442051960547fd3835527b975ab7da970vboxsync GuestMac.au8[0] = 0x08;
e7b615a442051960547fd3835527b975ab7da970vboxsync GuestMac.au8[1] = 0x00;
e7b615a442051960547fd3835527b975ab7da970vboxsync GuestMac.au8[2] = 0x27;
e7b615a442051960547fd3835527b975ab7da970vboxsync RTRandBytes(&GuestMac.au8[3], 3);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertCompile(sizeof(RTMAC) <= MAXMACADDRLEN);
e7b615a442051960547fd3835527b975ab7da970vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync const char *pszLinkName = pThis->szName;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync uint16_t uVLANId = VLAN_ID_NONE;
e7b615a442051960547fd3835527b975ab7da970vboxsync vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
e7b615a442051960547fd3835527b975ab7da970vboxsync vnic_ioc_diag_t Diag = VNIC_IOC_DIAG_NONE;
e7b615a442051960547fd3835527b975ab7da970vboxsync int MacSlot = 0;
e7b615a442051960547fd3835527b975ab7da970vboxsync int MacLen = sizeof(GuestMac);
76a6b12b9722672f423c9c5026c4b1df6c9ef762vboxsync uint32_t fFlags = 0;
e7b615a442051960547fd3835527b975ab7da970vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (pThis->u.s.fIsVNICTemplate)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->pVNICTemplate = RTMemAllocZ(sizeof(VBOXNETFLTVNICTEMPLATE));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_UNLIKELY(!pVNIC->pVNICTemplate))
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return VERR_NO_MEMORY;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Initialize the VNIC template.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync rc = vboxNetFltSolarisInitVNICTemplate(pThis, pVNIC->pVNICTemplate);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_FAILURE(rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to initialize VNIC from VNIC template. rc=%Rrc\n", rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return rc;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pszLinkName = pVNIC->pVNICTemplate->szLinkName;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync uVLANId = pVNIC->pVNICTemplate->uVLANId;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#if 0
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Required only if we're creating a VLAN interface & not a VNIC with a VLAN Id.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (uVLANId != VLAN_ID_NONE)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync fFlags |= MAC_VLAN;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync#endif
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC pThis=%p VLAN Id=%u\n", pThis, uVLANId));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Create the VNIC under 'pszLinkName', which can be the one from the VNIC template or can
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * be a physical interface.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync rc = RTSemFastMutexRequest(g_VBoxNetFltSolarisMtx); AssertRC(rc);
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXBOW_VNIC_NAME, g_VBoxNetFltSolarisVNICId);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = vnic_create(pVNIC->szName, pszLinkName, &AddrType, &MacLen, GuestMac.au8, &MacSlot, 0 /* Mac-Prefix Length */, uVLANId,
e7b615a442051960547fd3835527b975ab7da970vboxsync fFlags, &pVNIC->hLinkId, &Diag, NULL /* Reserved */);
e7b615a442051960547fd3835527b975ab7da970vboxsync if (!rc)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->fCreated = true;
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync ASMAtomicIncU64(&g_VBoxNetFltSolarisVNICId);
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Now try opening the created VNIC.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = mac_open_by_linkid(pVNIC->hLinkId, &pVNIC->hInterface);
e7b615a442051960547fd3835527b975ab7da970vboxsync if (!rc)
aae1f903b51565bdbc8bebd1fb7f8c7a7a761470vboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Initialize the VNIC from the physical interface or the VNIC template.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = vboxNetFltSolarisInitVNIC(pThis, pVNIC);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_SUCCESS(rc))
e7b615a442051960547fd3835527b975ab7da970vboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s' with random mac %.6Rhxs\n",
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->szName, pszLinkName, &GuestMac));
e7b615a442051960547fd3835527b975ab7da970vboxsync *ppVNIC = pVNIC;
e7b615a442051960547fd3835527b975ab7da970vboxsync return VINF_SUCCESS;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC vboxNetFltSolarisInitVNIC failed. rc=%d\n", rc));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_close(pVNIC->hInterface);
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->hInterface = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to open VNIC '%s' over '%s'. rc=%d\n", pVNIC->szName,
e7b615a442051960547fd3835527b975ab7da970vboxsync pThis->szName, rc));
e7b615a442051960547fd3835527b975ab7da970vboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisDestroyVNIC(pVNIC);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
95e57e4ba9f359a891dd411729781d791e0eccb8vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create VNIC '%s' over '%s' rc=%d Diag=%d\n", pVNIC->szName,
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pszLinkName, rc, Diag));
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
02b513fa9b51a6c37baf6eaef0a9d0b2064fdcccvboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync/**
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Wrapper for getting the datalink ID given the MAC name.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param pszMacName The MAC name.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @param pLinkId Where to store the datalink ID.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync *
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * @returns VBox status code.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsyncLOCAL inline int vboxNetFltSolarisGetLinkId(const char *pszMacName, datalink_id_t *pLinkId)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync{
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * dls_mgmt_get_linkid() requires to be in a state to answer upcalls. We should always use this
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * first before resorting to other means to retrieve the MAC name.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync int rc = dls_mgmt_get_linkid(pszMacName, pLinkId);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (rc)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = dls_devnet_macname2linkid(pszMacName, pLinkId);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return VINF_SUCCESS;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisGetLinkId failed for '%s'. rc=%d\n", pszMacName, rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return RTErrConvertFromErrno(rc);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync}
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync/**
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * Set the promiscuous mode RX hook.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync *
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * @param pThis The VM connection instance.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * @param pVNIC Pointer to the VNIC.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync *
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * @returns VBox status code.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync */
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsyncLOCAL inline int vboxNetFltSolarisSetPromisc(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync{
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync int rc = VINF_SUCCESS;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (!pVNIC->hPromisc)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync rc = mac_promisc_add(pVNIC->hClient, MAC_CLIENT_PROMISC_FILTERED, vboxNetFltSolarisRecv, pThis, &pVNIC->hPromisc,
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync MAC_PROMISC_FLAGS_NO_TX_LOOP | MAC_PROMISC_FLAGS_VLAN_TAG_STRIP | MAC_PROMISC_FLAGS_NO_PHYS);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (RT_UNLIKELY(rc))
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync LogRel((DEVICE_NAME ":vboxNetFltSolarisSetPromisc failed. rc=%d\n", rc));
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync rc = RTErrConvertFromErrno(rc);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync return rc;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync}
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync/**
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * Clear the promiscuous mode RX hook.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync *
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * @param pThis The VM connection instance.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * @param pVNIC Pointer to the VNIC.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync */
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsyncLOCAL inline void vboxNetFltSolarisRemovePromisc(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync{
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (pVNIC->hPromisc)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_promisc_remove(pVNIC->hPromisc);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync pVNIC->hPromisc = NULL;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync}
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync/* -=-=-=-=-=- Common Hooks -=-=-=-=-=- */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncvoid vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsSetActive pThis=%p fActive=%d\n", pThis, fActive));
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync /*
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync * Reactivate/quiesce the interface.
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync */
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync PVBOXNETFLTVNIC pVNIC = list_head(&pThis->u.s.hVNICs);
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync if (fActive)
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync {
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync for (; pVNIC != NULL; pVNIC = list_next(&pThis->u.s.hVNICs, pVNIC))
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync if (pVNIC->hClient)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#if 0
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync mac_rx_set(pVNIC->hClient, vboxNetFltSolarisRecv, pThis);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#endif
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync vboxNetFltSolarisSetPromisc(pThis, pVNIC);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync }
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync else
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync {
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync for (; pVNIC != NULL; pVNIC = list_next(&pThis->u.s.hVNICs, pVNIC))
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync if (pVNIC->hClient)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#if 0
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync mac_rx_clear(pVNIC->hClient);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#endif
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync vboxNetFltSolarisRemovePromisc(pThis, pVNIC);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
4d83ca06f7e361adaa2d2c1e97b33cd0321b4d32vboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsDisconnectIt pThis=%p\n", pThis));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync return VINF_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsConnectIt pThis=%p\n", pThis));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync return VINF_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncvoid vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsDeleteInstance pThis=%p\n", pThis));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (pThis->u.s.hNotify)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync mac_notify_remove(pThis->u.s.hNotify, B_TRUE /* Wait */);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Destroy all managed VNICs. If a VNIC was passed to us, there
e7b615a442051960547fd3835527b975ab7da970vboxsync * will be only 1 item in the list, otherwise as many interfaces
e7b615a442051960547fd3835527b975ab7da970vboxsync * that were somehow not destroyed using DisconnectInterface() will be
e7b615a442051960547fd3835527b975ab7da970vboxsync * present.
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync while ((pVNIC = list_remove_head(&pThis->u.s.hVNICs)) != NULL)
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisDestroyVNIC(pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync list_destroy(&pThis->u.s.hVNICs);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p pvContext=%p\n", pThis, pvContext));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync /*
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * Figure out if the interface is a VNIC or a physical/etherstub/whatever NIC, then
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * do the actual VNIC creation if necessary in vboxNetFltPortOsConnectInterface().
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_handle_t hInterface;
e7b615a442051960547fd3835527b975ab7da970vboxsync int rc = mac_open_by_linkname(pThis->szName, &hInterface);
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync if (RT_LIKELY(!rc))
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = mac_is_vnic(hInterface);
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync if (!rc)
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p physical interface '%s' detected.\n", pThis, pThis->szName));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync pThis->u.s.fIsVNIC = false;
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->u.s.fIsVNIC = true;
2eef97414c483090011bf681518f2ee1894664e7vboxsync if (RTStrNCmp(pThis->szName, VBOXBOW_VNIC_TEMPLATE_NAME, sizeof(VBOXBOW_VNIC_TEMPLATE_NAME) - 1) == 0)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p VNIC template '%s' detected.\n", pThis, pThis->szName));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->u.s.fIsVNICTemplate = true;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if ( pThis->u.s.fIsVNIC
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync && !pThis->u.s.fIsVNICTemplate)
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p VNIC '%s' detected.\n", pThis, pThis->szName));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * Report info. (host MAC address, promiscuous, GSO capabilities etc.) to IntNet.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = vboxNetFltSolarisReportInfo(pThis, hInterface, pThis->u.s.fIsVNIC);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (RT_FAILURE(rc))
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to report info. rc=%d\n", rc));
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_close(hInterface);
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
bfde57a3a4d74895d4c5434f9bdfb2be700f9e57vboxsync LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to open link '%s'! rc=%d\n", pThis->szName, rc));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = VERR_INTNET_FLT_IF_FAILED;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncint vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * Init. the solaris specific data.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pThis->u.s.fIsVNIC = false;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pThis->u.s.fIsVNICTemplate = false;
e7b615a442051960547fd3835527b975ab7da970vboxsync list_create(&pThis->u.s.hVNICs, sizeof(VBOXNETFLTVNIC), offsetof(VBOXNETFLTVNIC, hNode));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pThis->u.s.hNotify = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync RT_ZERO(pThis->u.s.MacAddr);
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return VINF_SUCCESS;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsyncbool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync * @todo Think about this.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return false;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
586cf6585d0e6aa3bef888eeff116bf82d18cd83vboxsyncint vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst)
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync{
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Validate parameters.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = pvIfData;
be15f1c841ea1638851876dd83b165caa174892dvboxsync AssertReturn(VALID_PTR(pVNIC), VERR_INVALID_POINTER);
be15f1c841ea1638851876dd83b165caa174892dvboxsync AssertMsgReturn(pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
be15f1c841ea1638851876dd83b165caa174892dvboxsync ("Invalid magic=%#x (expected %#x)\n", pVNIC->u32Magic, VBOXNETFLTVNIC_MAGIC),
be15f1c841ea1638851876dd83b165caa174892dvboxsync VERR_INVALID_MAGIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Xmit the packet down the appropriate VNIC interface.
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync int rc = VINF_SUCCESS;
e7b615a442051960547fd3835527b975ab7da970vboxsync mblk_t *pMsg = vboxNetFltSolarisMBlkFromSG(pThis, pSG, fDst);
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_LIKELY(pMsg))
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync {
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p cbData=%d\n", pThis, MBLKL(pMsg)));
aae1f903b51565bdbc8bebd1fb7f8c7a7a761470vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync mac_tx_cookie_t pXmitCookie = mac_tx(pVNIC->hClient, pMsg, 0 /* Hint */, MAC_DROP_ON_NO_DESC, NULL /* return message */);
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_LIKELY(!pXmitCookie))
e7b615a442051960547fd3835527b975ab7da970vboxsync return VINF_SUCCESS;
e9de8285074ab7533c564399c671bfa415f24a67vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync pMsg = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = VERR_NET_IO_ERROR;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsXmit Xmit failed pVNIC=%p.\n", pVNIC));
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsXmit no memory for allocating Xmit packet.\n"));
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = VERR_NO_MEMORY;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync return rc;
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync}
becf3c759c574f9450ebc8b558c1cca8dc8b944bvboxsync
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync
586cf6585d0e6aa3bef888eeff116bf82d18cd83vboxsyncvoid vboxNetFltPortOsNotifyMacAddress(PVBOXNETFLTINS pThis, void *pvIfData, PCRTMAC pMac)
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOSNotifyMacAddress pszIf=%s pszVNIC=%s MAC=%.6Rhxs\n", pThis->szName,
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync ((PVBOXNETFLTVNIC)pvIfData)->szName, pMac));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Validate parameters.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = pvIfData;
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertMsgReturnVoid(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync ("Invalid pVNIC=%p magic=%#x (expected %#x)\n", pvIfData, VALID_PTR(pVNIC) ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC));
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertMsgReturnVoid(pVNIC->hLinkId != DATALINK_INVALID_LINKID,
e7b615a442051960547fd3835527b975ab7da970vboxsync ("Invalid hLinkId pVNIC=%p magic=%#x\n", pVNIC, pVNIC->u32Magic));
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Set the MAC address of the VNIC to the one used by the VM interface.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync uchar_t au8GuestMac[MAXMACADDRLEN];
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync bcopy(pMac->au8, au8GuestMac, sizeof(RTMAC));
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
e7b615a442051960547fd3835527b975ab7da970vboxsync vnic_ioc_diag_t Diag = VNIC_IOC_DIAG_NONE;
e7b615a442051960547fd3835527b975ab7da970vboxsync int MacSlot = 0;
e7b615a442051960547fd3835527b975ab7da970vboxsync int MacLen = sizeof(RTMAC);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync int rc = vnic_modify_addr(pVNIC->hLinkId, &AddrType, &MacLen, au8GuestMac, &MacSlot, 0 /* Mac-Prefix Length */, &Diag);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * Remove existing unicast address, promisc. and the RX hook.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
cd8f4e64786c9ee82734c2ced86f21b8e60d4415vboxsync#if 0
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (pVNIC->hUnicast)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_rx_clear(pVNIC->hClient);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pVNIC->hUnicast = NULL;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
cd8f4e64786c9ee82734c2ced86f21b8e60d4415vboxsync#endif
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (pVNIC->hPromisc)
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_promisc_remove(pVNIC->hPromisc);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync pVNIC->hPromisc = NULL;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync mac_diag_t MacDiag = MAC_DIAG_NONE;
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /* uint16_t uVLANId = pVNIC->pVNICTemplate ? pVNIC->pVNICTemplate->uVLANId : 0; */
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#if 0
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync rc = mac_unicast_add(pVNIC->hClient, NULL, MAC_UNICAST_PRIMARY, &pVNIC->hUnicast, 0 /* VLAN Id */, &MacDiag);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#endif
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (RT_LIKELY(!rc))
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync rc = vboxNetFltSolarisSetPromisc(pThis, pVNIC);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#if 0
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync if (RT_SUCCESS(rc))
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync {
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync /*
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * Set the RX receive function.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * This shouldn't be necessary as vboxNetFltPortOsSetActive() will be invoked after this, but in the future,
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync * if the guest NIC changes MAC address this may not be followed by a vboxNetFltPortOsSetActive() call, so set it here anyway.
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync */
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_rx_set(pVNIC->hClient, vboxNetFltSolarisRecv, pThis);
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress successfully added unicast address %.6Rhxs\n", pMac));
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync }
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync else
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed to set promiscuous mode. rc=%d\n", rc));
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync pVNIC->hUnicast = NULL;
ee2e20fb5dfc6c88f57585245849e57d16ded841vboxsync#endif
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed to add primary unicast address. rc=%d Diag=%d\n", rc, MacDiag));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * They really ought to use EEXIST, but I'm afraid this error comes from the VNIC device driver directly.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * Sequence: vnic_modify_addr()->mac_unicast_primary_set()->mac_update_macaddr() which uses a function pointer
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * to the MAC driver (calls mac_vnic_unicast_set() in our case). Documented here if the error code should change we know
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * where to look.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync if (rc == ENOTSUP)
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress: failed! a VNIC with mac %.6Rhxs probably already exists.",
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pMac, rc));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress: This NIC cannot establish connection. szName=%s szVNIC=%s\n",
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync pThis->szName, pVNIC->szName));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync else
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed! mac %.6Rhxs rc=%d Diag=%d\n", pMac, rc, Diag));
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync}
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsyncint vboxNetFltPortOsConnectInterface(PVBOXNETFLTINS pThis, void *pvIf, void **ppvIfData)
e7b615a442051960547fd3835527b975ab7da970vboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsConnectInterface pThis=%p pvIf=%p\n", pThis, pvIf));
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync int rc = VINF_SUCCESS;
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * If the underlying interface is a physical interface or a VNIC template, we need to create
e7b615a442051960547fd3835527b975ab7da970vboxsync * a VNIC per guest NIC.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if ( !pThis->u.s.fIsVNIC
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync || pThis->u.s.fIsVNICTemplate)
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = NULL;
e7b615a442051960547fd3835527b975ab7da970vboxsync rc = vboxNetFltSolarisCreateVNIC(pThis, &pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_SUCCESS(rc))
e7b615a442051960547fd3835527b975ab7da970vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * VM Interface<->VNIC association so that we can Xmit/Recv on the right ones.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync pVNIC->pvIf = pvIf;
e7b615a442051960547fd3835527b975ab7da970vboxsync *ppvIfData = pVNIC;
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Add the created VNIC to the list of VNICs we manage.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync list_insert_tail(&pThis->u.s.hVNICs, pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync return VINF_SUCCESS;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
f6443fc96d014da2dcc4b03894fd1cd3ed841843vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface failed to create VNIC rc=%d\n", rc));
e7b615a442051960547fd3835527b975ab7da970vboxsync }
e7b615a442051960547fd3835527b975ab7da970vboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync {
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync /*
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync * This is a VNIC passed to us, use it directly.
a1fb412664878af4f651bc29cb8e324fe09be33fvboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync PVBOXNETFLTVNIC pVNIC = vboxNetFltSolarisAllocVNIC();
e7b615a442051960547fd3835527b975ab7da970vboxsync if (RT_LIKELY(pVNIC))
e7b615a442051960547fd3835527b975ab7da970vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pVNIC->fCreated = false;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = mac_open_by_linkname(pThis->szName, &pVNIC->hInterface);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (!rc)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync /*
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * Obtain the data link ID for this VNIC, it's needed for modifying the MAC address among other things.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = vboxNetFltSolarisGetLinkId(pThis->szName, &pVNIC->hLinkId);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (RT_SUCCESS(rc))
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync /*
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync * Initialize the VNIC and add it to the list of managed VNICs.
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync */
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s", pThis->szName);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = vboxNetFltSolarisInitVNIC(pThis, pVNIC);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync if (!rc)
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync pVNIC->pvIf = pvIf;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync *ppvIfData = pVNIC;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync list_insert_head(&pThis->u.s.hVNICs, pVNIC);
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync return VINF_SUCCESS;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface failed to initialize VNIC. rc=%d\n", rc));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface failed to get link id for '%s'. rc=%d\n", pThis->szName, rc));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync else
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface failed to open VNIC '%s'. rc=%d\n", pThis->szName, rc));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = VERR_OPEN_FAILED;
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync }
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync else
e7b615a442051960547fd3835527b975ab7da970vboxsync {
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to allocate VNIC private data.\n"));
c81875f70da5889b3d503129c57e02d0a2c2dfa1vboxsync rc = VERR_NO_MEMORY;
e7b615a442051960547fd3835527b975ab7da970vboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync }
2135a0a48189b91cd746a83b2758bc4cfe257b94vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync return rc;
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync}
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsyncint vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync{
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface pThis=%p\n", pThis));
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync PVBOXNETFLTVNIC pVNIC = pvIfData;
e7b615a442051960547fd3835527b975ab7da970vboxsync AssertMsgReturn(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
e7b615a442051960547fd3835527b975ab7da970vboxsync ("Invalid pvIfData=%p magic=%#x (expected %#x)\n", pvIfData, pVNIC ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC),
e7b615a442051960547fd3835527b975ab7da970vboxsync VERR_INVALID_POINTER);
e7b615a442051960547fd3835527b975ab7da970vboxsync
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * If the underlying interface is not a VNIC, we need to delete the created VNIC.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync if (!pThis->u.s.fIsVNIC)
e7b615a442051960547fd3835527b975ab7da970vboxsync {
e7b615a442051960547fd3835527b975ab7da970vboxsync /*
e7b615a442051960547fd3835527b975ab7da970vboxsync * Remove the VNIC from the list, destroy and free it.
e7b615a442051960547fd3835527b975ab7da970vboxsync */
e7b615a442051960547fd3835527b975ab7da970vboxsync list_remove(&pThis->u.s.hVNICs, pVNIC);
1e564d9937b98dc6016ebcb9d83cb3635819baebvboxsync Log((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisDestroyVNIC(pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync vboxNetFltSolarisFreeVNIC(pVNIC);
e7b615a442051960547fd3835527b975ab7da970vboxsync }
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync return VINF_SUCCESS;
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync}
69c51855f3b700d7b26a81f1d7dfed523097b7e2vboxsync