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