VirtualBox

Changeset 36075 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 24, 2011 4:36:48 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70197
Message:

More flexible internal network promisc mode (++) policy management.

Location:
trunk/src/VBox/Devices/Network
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r35353 r36075  
    182182/** Pointer to instance data of the internal networking driver. */
    183183typedef DRVINTNET *PDRVINTNET;
     184
     185/**
     186 * Config value to flag translation structure.
     187 */
     188typedef struct DRVINTNETFLAG
     189{
     190    /** The value. */
     191    const char *pszChoice;
     192    /** The corresponding flag. */
     193    uint32_t    fFlag;
     194} DRVINTNETFLAG;
     195/** Pointer to a const flag value translation. */
     196typedef DRVINTNETFLAG const *PCDRVINTNETFLAG;
    184197
    185198
     
    11341147        AbortWaitReq.fNoMoreWaits = true;
    11351148        int rc = PDMDrvHlpSUPCallVMMR0Ex(pDrvIns, VMMR0_DO_INTNET_IF_ABORT_WAIT, &AbortWaitReq, sizeof(AbortWaitReq));
    1136         AssertRC(rc);
     1149        AssertMsg(RT_SUCCESS(rc) || rc == VERR_SEM_DESTROYED, ("%Rrc\n", rc));
    11371150    }
    11381151
     
    12181231
    12191232/**
     1233 * Queries the 'fixed' policy config value and sets the corresponding flag.
     1234 *
     1235 * @returns VBox status code (error set on failure).
     1236 * @param   pDrvIns             The driver instance.
     1237 * @param   pszName             The value name.
     1238 * @param   fFixedFlag          The open network flag.
     1239 * @param   pfFlags             The flags variable to update.
     1240 */
     1241static int drvIntNetR3CfgFixedPolicy(PPDMDRVINS pDrvIns, const char *pszName, uint32_t fFixedFlag, uint32_t *pfFlags)
     1242{
     1243    bool fFixed;
     1244    int rc = CFGMR3QueryBoolDef(pDrvIns->pCfg, pszName, &fFixed, false /*fDef*/);
     1245    if (RT_SUCCESS(rc))
     1246    {
     1247        if (fFixed)
     1248            *pfFlags |= fFixedFlag;
     1249    }
     1250    else
     1251        rc = PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     1252                                 N_("Configuration error: Failed to query the value of \"%s\""), pszName);
     1253    return rc;
     1254}
     1255
     1256
     1257/**
     1258 * Queries a policy config value and translates it into open network flag.
     1259 *
     1260 * @returns VBox status code (error set on failure).
     1261 * @param   pDrvIns             The driver instance.
     1262 * @param   pszName             The value name.
     1263 * @param   paFlags             The open network flag descriptors.
     1264 * @param   cFlags              The number of descriptors.
     1265 * @param   pfFlags             The flags variable to update.
     1266 */
     1267static int drvIntNetR3CfgGetPolicy(PPDMDRVINS pDrvIns, const char *pszName, PCDRVINTNETFLAG paFlags, size_t cFlags, uint32_t *pfFlags)
     1268{
     1269    char szValue[64];
     1270    int rc = CFGMR3QueryString(pDrvIns->pCfg, pszName, szValue, sizeof(szValue));
     1271    if (RT_SUCCESS(rc))
     1272    {
     1273        size_t i = cFlags;
     1274        while (i-- > 0)
     1275            if (!strcmp(paFlags[i].pszChoice, szValue))
     1276            {
     1277                *pfFlags |= paFlags[i].fFlag;
     1278                return VINF_SUCCESS;
     1279            }
     1280        if (!strcmp(szValue, "none"))
     1281            return VINF_SUCCESS;
     1282
     1283        rc = PDMDrvHlpVMSetError(pDrvIns, VERR_INVALID_PARAMETER, RT_SRC_POS,
     1284                                 N_("Configuration error: The value of \"%s\" is unknown: \"%s\""), pszName, szValue);
     1285    }
     1286    else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1287        return VINF_SUCCESS;
     1288    else
     1289        rc = PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     1290                                 N_("Configuration error: Failed to query value of \"%s\""), pszName);
     1291    return rc;
     1292}
     1293
     1294
     1295/**
    12201296 * Construct a TAP network transport driver instance.
    12211297 *
     
    12261302    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
    12271303    bool f;
    1228     bool fIgnoreConnectFailure;
    12291304    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    12301305
     
    12611336     * Validate the config.
    12621337     */
    1263     if (!CFGMR3AreValuesValid(pCfg,
    1264                               "Network\0"
    1265                               "Trunk\0"
    1266                               "TrunkType\0"
    1267                               "ReceiveBufferSize\0"
    1268                               "SendBufferSize\0"
    1269                               "RestrictAccess\0"
    1270                               "SharedMacOnWire\0"
    1271                               "IgnoreAllPromisc\0"
    1272                               "QuietlyIgnoreAllPromisc\0"
    1273                               "IgnoreClientPromisc\0"
    1274                               "QuietlyIgnoreClientPromisc\0"
    1275                               "IgnoreTrunkWirePromisc\0"
    1276                               "QuietlyIgnoreTrunkWirePromisc\0"
    1277                               "IgnoreTrunkHostPromisc\0"
    1278                               "IgnoreConnectFailure\0"
    1279                               "QuietlyIgnoreTrunkHostPromisc\0"
    1280                               "IsService\0"))
    1281         return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
     1338    PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns,
     1339                                  "Network"
     1340                                  "|Trunk"
     1341                                  "|TrunkType"
     1342                                  "|ReceiveBufferSize"
     1343                                  "|SendBufferSize"
     1344                                  "|SharedMacOnWire"
     1345                                  "|RestrictAccess"
     1346                                  "|RequireExactPolicyMatch"
     1347                                  "|RequireAsRestrictivePolicy"
     1348                                  "|AccessPolicy"
     1349                                  "|AccessPolicyFixed"
     1350                                  "|PromiscPolicyClients"
     1351                                  "|PromiscPolicyHost"
     1352                                  "|PromiscPolicyWire"
     1353                                  "|PromiscPolicyFixed"
     1354                                  "|IfPolicyPromisc"
     1355                                  "|IfPolicyFixed"
     1356                                  "|TrunkPolicyHost"
     1357                                  "|TrunkPolicyWire"
     1358                                  "|TrunkPolicyFixed"
     1359                                  "|IsService"
     1360                                  "|IgnoreConnectFailure",
     1361                                  "");
    12821362
    12831363    /*
     
    13031383     */
    13041384    INTNETOPENREQ OpenReq;
    1305     memset(&OpenReq, 0, sizeof(OpenReq));
     1385    RT_ZERO(OpenReq);
    13061386    OpenReq.Hdr.cbReq = sizeof(OpenReq);
    13071387    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     
    13391419                                N_("Configuration error: Failed to get the \"Trunk\" value"));
    13401420
    1341     /** @cfgm{RestrictAccess, boolean, true}
    1342      * Whether to restrict the access to the network or if it should be public. Everyone on
    1343      * the computer can connect to a public network. Don't change this.
    1344      */
    1345     bool fRestrictAccess;
    1346     rc = CFGMR3QueryBool(pCfg, "RestrictAccess", &fRestrictAccess);
    1347     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    1348         fRestrictAccess = true;
    1349     else if (RT_FAILURE(rc))
    1350         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1351                                 N_("Configuration error: Failed to get the \"RestrictAccess\" value"));
    1352     OpenReq.fFlags = fRestrictAccess ? 0 : INTNET_OPEN_FLAGS_PUBLIC;
    1353 
    1354     /** @cfgm{IgnoreAllPromisc, boolean, false}
    1355      * When set all request for operating any interface or trunk in promiscuous
    1356      * mode will be ignored. */
    1357     rc = CFGMR3QueryBoolDef(pCfg, "IgnoreAllPromisc", &f, false);
    1358     if (RT_FAILURE(rc))
    1359         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1360                                 N_("Configuration error: Failed to get the \"IgnoreAllPromisc\" value"));
    1361     if (f)
    1362         OpenReq.fFlags |= INTNET_OPEN_FLAGS_IGNORE_PROMISC;
    1363 
    1364     /** @cfgm{QuietlyIgnoreAllPromisc, boolean, false}
    1365      * When set all request for operating any interface or trunk in promiscuous
    1366      * mode will be ignored.  This differs from IgnoreAllPromisc in that clients
    1367      * won't get VERR_INTNET_INCOMPATIBLE_FLAGS. */
    1368     rc = CFGMR3QueryBoolDef(pCfg, "QuietlyIgnoreAllPromisc", &f, false);
    1369     if (RT_FAILURE(rc))
    1370         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1371                                 N_("Configuration error: Failed to get the \"QuietlyIgnoreAllPromisc\" value"));
    1372     if (f)
    1373         OpenReq.fFlags |= INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC;
    1374 
    1375     /** @cfgm{IgnoreClientPromisc, boolean, false}
    1376      * When set all request for operating any non-trunk interface in promiscuous
    1377      * mode will be ignored. */
    1378     rc = CFGMR3QueryBoolDef(pCfg, "IgnoreClientPromisc", &f, false);
    1379     if (RT_FAILURE(rc))
    1380         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1381                                 N_("Configuration error: Failed to get the \"IgnoreClientPromisc\" value"));
    1382     if (f)
    1383         OpenReq.fFlags |= INTNET_OPEN_FLAGS_IGNORE_PROMISC; /** @todo add special flag for this. */
    1384 
    1385     /** @cfgm{QuietlyIgnoreClientPromisc, boolean, false}
    1386      * When set all request for operating any non-trunk interface promiscuous mode
    1387      * will be ignored.  This differs from IgnoreClientPromisc in that clients won't
    1388      * get VERR_INTNET_INCOMPATIBLE_FLAGS. */
    1389     rc = CFGMR3QueryBoolDef(pCfg, "QuietlyIgnoreClientPromisc", &f, false);
    1390     if (RT_FAILURE(rc))
    1391         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1392                                 N_("Configuration error: Failed to get the \"QuietlyIgnoreClientPromisc\" value"));
    1393     if (f)
    1394         OpenReq.fFlags |= INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC;  /** @todo add special flag for this. */
    1395 
    1396     /** @cfgm{IgnoreTrunkWirePromisc, boolean, false}
    1397      * When set all request for operating the trunk-wire connection in promiscuous
    1398      * mode will be ignored. */
    1399     rc = CFGMR3QueryBoolDef(pCfg, "IgnoreTrunkWirePromisc", &f, false);
    1400     if (RT_FAILURE(rc))
    1401         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1402                                 N_("Configuration error: Failed to get the \"IgnoreTrunkWirePromisc\" value"));
    1403     if (f)
    1404         OpenReq.fFlags |= INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE;
    1405 
    1406     /** @cfgm{QuietlyIgnoreTrunkWirePromisc, boolean, false}
    1407      * When set all request for operating any trunk-wire connection promiscuous mode
    1408      * will be ignored.  This differs from IgnoreTrunkWirePromisc in that clients
    1409      * won't get VERR_INTNET_INCOMPATIBLE_FLAGS. */
    1410     rc = CFGMR3QueryBoolDef(pCfg, "QuietlyIgnoreTrunkWirePromisc", &f, false);
    1411     if (RT_FAILURE(rc))
    1412         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1413                                 N_("Configuration error: Failed to get the \"QuietlyIgnoreTrunkWirePromisc\" value"));
    1414     if (f)
    1415         OpenReq.fFlags |= INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE;
    1416 
    1417     /** @cfgm{IgnoreTrunkHostPromisc, boolean, false}
    1418      * When set all request for operating the trunk-host connection in promiscuous
    1419      * mode will be ignored. */
    1420     rc = CFGMR3QueryBoolDef(pCfg, "IgnoreTrunkHostPromisc", &f, false);
    1421     if (RT_FAILURE(rc))
    1422         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1423                                 N_("Configuration error: Failed to get the \"IgnoreTrunkHostPromisc\" value"));
    1424     if (f)
    1425         OpenReq.fFlags |= INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_HOST;
    1426 
    1427     /** @cfgm{QuietlyIgnoreTrunkHostPromisc, boolean, false}
    1428      * When set all request for operating any trunk-host connection promiscuous mode
    1429      * will be ignored.  This differs from IgnoreTrunkHostPromisc in that clients
    1430      * won't get VERR_INTNET_INCOMPATIBLE_FLAGS. */
    1431     rc = CFGMR3QueryBoolDef(pCfg, "QuietlyIgnoreTrunkHostPromisc", &f, false);
    1432     if (RT_FAILURE(rc))
    1433         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1434                                 N_("Configuration error: Failed to get the \"QuietlyIgnoreTrunkHostPromisc\" value"));
    1435     if (f)
    1436         OpenReq.fFlags |= INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_HOST;
    1437 
    1438     /** @todo flags for not sending to the host and for setting the trunk-wire
    1439      *        connection in promiscuous mode. */
    1440 
    1441 
    1442     /** @cfgm{IgnoreConnectFailure, boolean, false}
    1443      * When set only raise a runtime error if we cannot connect to the internal
    1444      * network. */
    1445     rc = CFGMR3QueryBoolDef(pCfg, "IgnoreConnectFailure", &fIgnoreConnectFailure, false);
    1446     if (RT_FAILURE(rc))
    1447         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1448                                 N_("Configuration error: Failed to get the \"IgnoreConnectFailure\" value"));
    1449     if (f)
    1450         OpenReq.fFlags |= INTNET_OPEN_FLAGS_IGNORE_PROMISC;
    1451 
     1421    OpenReq.fFlags = 0;
    14521422
    14531423    /** @cfgm{SharedMacOnWire, boolean, false}
     
    14621432    if (fSharedMacOnWire)
    14631433        OpenReq.fFlags |= INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE;
     1434
     1435    /** @cfgm{RestrictAccess, boolean, true}
     1436     * Whether to restrict the access to the network or if it should be public.
     1437     * Everyone on the computer can connect to a public network.
     1438     * @deprecated Use AccessPolicy instead.
     1439     */
     1440    rc = CFGMR3QueryBool(pCfg, "RestrictAccess", &f);
     1441    if (RT_SUCCESS(rc))
     1442    {
     1443        if (f)
     1444            OpenReq.fFlags |= INTNET_OPEN_FLAGS_ACCESS_RESTRICTED;
     1445        else
     1446            OpenReq.fFlags |= INTNET_OPEN_FLAGS_ACCESS_PUBLIC;
     1447    }
     1448    else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
     1449        return PDMDRV_SET_ERROR(pDrvIns, rc,
     1450                                N_("Configuration error: Failed to get the \"RestrictAccess\" value"));
     1451
     1452
     1453    /** @cfgm{AccessPolicy, string, "none"}
     1454     * The access policy of the network: public, restricted or none.  A
     1455     * "public" network is accessible to everyone on the same host, while a
     1456     * "restricted" one is only accessible to VMs & services started by the
     1457     * same user.  The "none" policy, which is the default, means no policy
     1458     * change or choice is made and that the current (existing network) or
     1459     * default (new) policy should be used. */
     1460    static const DRVINTNETFLAG s_aAccessPolicyFlags[] =
     1461    {
     1462        { "public",         INTNET_OPEN_FLAGS_ACCESS_PUBLIC             },
     1463        { "restricted",     INTNET_OPEN_FLAGS_ACCESS_RESTRICTED         }
     1464    };
     1465    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "AccessPolicy", &s_aAccessPolicyFlags[0], RT_ELEMENTS(s_aAccessPolicyFlags),
     1466                                 &OpenReq.fFlags);
     1467    AssertRCReturn(rc, rc);
     1468    /** @cfgm{AccessPolicyFixed, boolean, false}
     1469     * Whether the access policy is to be locked against further changes. */
     1470    rc = drvIntNetR3CfgFixedPolicy(pDrvIns, "AccessPolicyFixed", INTNET_OPEN_FLAGS_ACCESS_FIXED, &OpenReq.fFlags);
     1471    AssertRCReturn(rc, rc);
     1472
     1473    /** @cfgm{PromiscPolicyClients, string, "none"}
     1474     * The network wide promiscuous mode policy for client (non-trunk)
     1475     * interfaces: allow, deny, none. */
     1476    static const DRVINTNETFLAG s_aPromiscPolicyClient[] =
     1477    {
     1478        { "allow",         INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS      },
     1479        { "deny",          INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS       }
     1480    };
     1481    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "PromiscPolicyClients", &s_aPromiscPolicyClient[0], RT_ELEMENTS(s_aPromiscPolicyClient),
     1482                                 &OpenReq.fFlags);
     1483    AssertRCReturn(rc, rc);
     1484    /** @cfgm{PromiscPolicyHost, string, "none"}
     1485     * The promiscuous mode policy for the trunk-host
     1486     * connection: allow, deny, none. */
     1487    static const DRVINTNETFLAG s_aPromiscPolicyHost[] =
     1488    {
     1489        { "allow",         INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST   },
     1490        { "deny",          INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST    }
     1491    };
     1492    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "PromiscPolicyHost", &s_aPromiscPolicyHost[0], RT_ELEMENTS(s_aPromiscPolicyHost),
     1493                                 &OpenReq.fFlags);
     1494    AssertRCReturn(rc, rc);
     1495    /** @cfgm{PromiscPolicyWire, string, "none"}
     1496     * The promiscuous mode policy for the trunk-host
     1497     * connection: allow, deny, none. */
     1498    static const DRVINTNETFLAG s_aPromiscPolicyWire[] =
     1499    {
     1500        { "allow",         INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE   },
     1501        { "deny",          INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE    }
     1502    };
     1503    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "PromiscPolicyWire", &s_aPromiscPolicyWire[0], RT_ELEMENTS(s_aPromiscPolicyWire),
     1504                                 &OpenReq.fFlags);
     1505    AssertRCReturn(rc, rc);
     1506    /** @cfgm{PromiscPolicyFixed, boolean, false}
     1507     * Whether the promiscuous mode policies are to be locked against further
     1508     * changes. */
     1509    rc = drvIntNetR3CfgFixedPolicy(pDrvIns, "PromiscPolicyFixed", INTNET_OPEN_FLAGS_PROMISC_FIXED, &OpenReq.fFlags);
     1510    AssertRCReturn(rc, rc);
     1511
     1512
     1513    /** @cfgm{IfPolicyPromisc, string, "none"}
     1514     * The promiscuous mode policy for this
     1515     * interface: allow, deny, none. */
     1516    static const DRVINTNETFLAG s_aIfPolicyPromisc[] =
     1517    {
     1518        { "allow",         INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW           },
     1519        { "deny",          INTNET_OPEN_FLAGS_IF_PROMISC_DENY            }
     1520    };
     1521    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "IfPolicyPromisc", &s_aIfPolicyPromisc[0], RT_ELEMENTS(s_aIfPolicyPromisc),
     1522                                 &OpenReq.fFlags);
     1523    AssertRCReturn(rc, rc);
     1524
     1525    /** @cfgm{IfPolicyPromiscTrunk, string, "none"}
     1526     * The promiscuous mode policy for this interface with regard to unrelated
     1527     * trunk traffic: see-trunk, no-trunk, none. */
     1528    static const DRVINTNETFLAG s_aIfPolicyPromiscTrunk[] =
     1529    {
     1530        { "see-trunk",      INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK      },
     1531        { "no-trunk",       INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK       }
     1532    };
     1533    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "IfPolicyPromiscTrunk", &s_aIfPolicyPromiscTrunk[0], RT_ELEMENTS(s_aIfPolicyPromiscTrunk),
     1534                                 &OpenReq.fFlags);
     1535    AssertRCReturn(rc, rc);
     1536
     1537    /** @cfgm{IfPolicyFixed, boolean, false}
     1538     * Whether the interface policies are to be locked against further
     1539     * changes. */
     1540    rc = drvIntNetR3CfgFixedPolicy(pDrvIns, "IfPolicyFixed", INTNET_OPEN_FLAGS_IF_FIXED, &OpenReq.fFlags);
     1541    AssertRCReturn(rc, rc);
     1542
     1543
     1544    /** @cfgm{TrunkPolicyHost, string, "none"}
     1545     * The trunk-host policy: enabled, disabled, non
     1546     * This can be used to prevent packages to be routed to the host. */
     1547    static const DRVINTNETFLAG s_aTrunkPolicyHost[] =
     1548    {
     1549        { "enabled",        INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED        },
     1550        { "disabled",       INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED       }
     1551    };
     1552    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "TrunkPolicyHost", &s_aTrunkPolicyHost[0], RT_ELEMENTS(s_aTrunkPolicyHost),
     1553                                 &OpenReq.fFlags);
     1554    AssertRCReturn(rc, rc);
     1555    /** @cfgm{TrunkPolicyWire, string, "none"}
     1556     * The trunk-host policy: enabled, disabled, non
     1557     * This can be used to prevent packages to be routed to the host. */
     1558    static const DRVINTNETFLAG s_aTrunkPolicyWire[] =
     1559    {
     1560        { "enabled",        INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED        },
     1561        { "disabled",       INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED       }
     1562    };
     1563    rc = drvIntNetR3CfgGetPolicy(pDrvIns, "TrunkPolicyWire", &s_aTrunkPolicyWire[0], RT_ELEMENTS(s_aTrunkPolicyWire),
     1564                                 &OpenReq.fFlags);
     1565    AssertRCReturn(rc, rc);
     1566    /** @cfgm{TrunkPolicyFixed, boolean, false}
     1567     * Whether the trunk policies are to be locked against further changes. */
     1568    rc = drvIntNetR3CfgFixedPolicy(pDrvIns, "TrunkPolicyFixed", INTNET_OPEN_FLAGS_TRUNK_FIXED, &OpenReq.fFlags);
     1569    AssertRCReturn(rc, rc);
     1570
    14641571
    14651572    /** @cfgm{ReceiveBufferSize, uint32_t, 318 KB}
     
    15041611                                N_("Configuration error: Failed to get the \"IsService\" value"));
    15051612
    1506     LogRel(("IntNet#%u: szNetwork={%s} enmTrunkType=%d szTrunk={%s} fFlags=%#x cbRecv=%u cbSend=%u\n",
     1613
     1614    /** @cfgm{IgnoreConnectFailure, boolean, false}
     1615     * When set only raise a runtime error if we cannot connect to the internal
     1616     * network. */
     1617    bool fIgnoreConnectFailure;
     1618    rc = CFGMR3QueryBoolDef(pCfg, "IgnoreConnectFailure", &fIgnoreConnectFailure, false);
     1619    if (RT_FAILURE(rc))
     1620        return PDMDRV_SET_ERROR(pDrvIns, rc,
     1621                                N_("Configuration error: Failed to get the \"IgnoreConnectFailure\" value"));
     1622
     1623    LogRel(("IntNet#%u: szNetwork={%s} enmTrunkType=%d szTrunk={%s} fFlags=%#x cbRecv=%u cbSend=%u fIgnoreConnectFailure=%RTbool\n",
    15071624            pDrvIns->iInstance, OpenReq.szNetwork, OpenReq.enmTrunkType, OpenReq.szTrunk, OpenReq.fFlags,
    1508             OpenReq.cbRecv, OpenReq.cbSend));
     1625            OpenReq.cbRecv, OpenReq.cbSend, fIgnoreConnectFailure));
    15091626
    15101627#ifdef RT_OS_DARWIN
     
    15591676             * Therefore don't abort but just raise a runtime warning.
    15601677             */
    1561             PDMDrvHlpVMSetRuntimeError (pDrvIns, 0 /*fFlags*/, "HostIfNotConnecting",
    1562                                         N_ ("Cannot connect to the network interface '%s'. The virtual "
    1563                                             "network card will appear to work but the guest will not "
    1564                                             "be able to connect. Please choose a different network in the "
    1565                                             "network settings"), OpenReq.szTrunk);
     1678            PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "HostIfNotConnecting",
     1679                                       N_ ("Cannot connect to the network interface '%s'. The virtual "
     1680                                           "network card will appear to work but the guest will not "
     1681                                           "be able to connect. Please choose a different network in the "
     1682                                           "network settings"), OpenReq.szTrunk);
    15661683
    15671684            return VERR_PDM_NO_ATTACHED_DRIVER;
    15681685        }
    1569         else
    1570         {
    1571             return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
    1572                                        N_("Failed to open/create the internal network '%s'"), pThis->szNetwork);
    1573         }
     1686        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
     1687                                   N_("Failed to open/create the internal network '%s'"), pThis->szNetwork);
    15741688    }
    15751689
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r35346 r36075  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7272    /** The MAC address of this entry. */
    7373    RTMAC                   MacAddr;
    74     /** Is it promiscuous.  */
    75     bool                    fPromiscuous;
     74    /** Is it promiscuous.
     75     * Shadows INTNETIF::fPromiscuousEff.  */
     76    bool                    fPromiscuousEff;
     77    /** Is it promiscuous and should it see unrelated trunk traffic. */
     78    bool                    fPromiscuousSeeTrunk;
    7679    /** Is it active.
    7780     * We ignore the entry if this is clear and may end up sending packets addressed
     
    102105    /** The host MAC address (reported). */
    103106    RTMAC                   HostMac;
    104     /** The host promiscuous setting (reported). */
    105     bool                    fHostPromiscuous;
     107    /** The effective host promiscuous setting (reported). */
     108    bool                    fHostPromiscuousEff;
     109    /** The real host promiscuous setting (reported). */
     110    bool                    fHostPromiscuousReal;
    106111    /** Whether the host is active. */
    107112    bool                    fHostActive;
    108113
    109114    /** Whether the wire is promiscuous (config). */
    110     bool                    fWirePromiscuous;
     115    bool                    fWirePromiscuousEff;
     116    /** Whether the wire is promiscuous (config).
     117     * (Shadows INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE in
     118     * INTNETNETWORK::fFlags.) */
     119    bool                    fWirePromiscuousReal;
    111120    /** Whether the wire is active. */
    112121    bool                    fWireActive;
     
    217226    /** Set if the interface is in promiscuous mode.
    218227     * This is shadowed by INTNETMACTABENTRY::fPromiscuous. */
    219     bool                    fPromiscuous;
     228    bool                    fPromiscuousEff;
     229    /** Tracks the desired promiscuous setting of the interface. */
     230    bool                    fPromiscuousReal;
    220231    /** Whether the interface is active or not.
    221232     * This is shadowed by INTNETMACTABENTRY::fActive. */
     
    224235     *  the end is nigh by means of IntNetR0IfAbortWait. */
    225236    bool volatile           fDestroying;
     237    /** The flags specified when opening this interface. */
     238    uint32_t                fOpenFlags;
    226239    /** Number of yields done to try make the interface read pending data.
    227240     * We will stop yielding when this reaches a threshold assuming that the VM is
     
    357370    /** Network creation flags (INTNET_OPEN_FLAGS_*). */
    358371    uint32_t                fFlags;
     372    /** Any restrictive policies required as a minimum by some interface.
     373     * (INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES) */
     374    uint32_t                fMinFlags;
    359375    /** The number of active interfaces (excluding the trunk). */
    360376    uint32_t                cActiveIFs;
     
    370386/** Pointer to an internal network. */
    371387typedef INTNETNETWORK *PINTNETNETWORK;
     388/** Pointer to a const internal network. */
     389typedef const INTNETNETWORK *PCINTNETNETWORK;
    372390
    373391/** The size of the buffer INTNETNETWORK::pbTmp points at. */
     
    403421static PINTNET volatile g_pIntNet = NULL;
    404422
     423static const struct INTNETOPENNETWORKFLAGS
     424{
     425    uint32_t fRestrictive;  /**< The restrictive flag (deny/disabled). */
     426    uint32_t fRelaxed;      /**< The relaxed flag (allow/enabled). */
     427    uint32_t fFixed;        /**< The config-fixed flag. */
     428    uint32_t fPair;         /**< The pair of restrictive and relaxed flags. */
     429}
     430/** Open network policy flags relating to the network. */
     431g_afIntNetOpenNetworkNetFlags[] =
     432{
     433    { INTNET_OPEN_FLAGS_ACCESS_RESTRICTED,       INTNET_OPEN_FLAGS_ACCESS_PUBLIC,            INTNET_OPEN_FLAGS_ACCESS_FIXED,  INTNET_OPEN_FLAGS_ACCESS_RESTRICTED       | INTNET_OPEN_FLAGS_ACCESS_PUBLIC            },
     434    { INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS,    INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS,    INTNET_OPEN_FLAGS_PROMISC_FIXED, INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS    | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS    },
     435    { INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST, INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST, INTNET_OPEN_FLAGS_PROMISC_FIXED, INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST },
     436    { INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE, INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE, INTNET_OPEN_FLAGS_PROMISC_FIXED, INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE },
     437    { INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED,     INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED,       INTNET_OPEN_FLAGS_TRUNK_FIXED,   INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED     | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED       },
     438    { INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE,  INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE,  INTNET_OPEN_FLAGS_TRUNK_FIXED,   INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE  | INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE  },
     439    { INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED,     INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED,       INTNET_OPEN_FLAGS_TRUNK_FIXED,   INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED     | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED       },
     440    { INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE,  INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE,  INTNET_OPEN_FLAGS_TRUNK_FIXED,   INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE  | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE  },
     441},
     442/** Open network policy flags relating to the new interface. */
     443g_afIntNetOpenNetworkIfFlags[] =
     444{
     445    { INTNET_OPEN_FLAGS_IF_PROMISC_DENY,        INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW,          INTNET_OPEN_FLAGS_IF_FIXED,      INTNET_OPEN_FLAGS_IF_PROMISC_DENY         | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW         },
     446    { INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK,    INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK,      INTNET_OPEN_FLAGS_IF_FIXED,      INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK     | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK     },
     447};
     448
    405449
    406450/*******************************************************************************
     
    14191463            PINTNETIF pIf    = pTab->paEntries[iIfMac].pIf;         AssertPtr(pIf); Assert(pIf->pNetwork == pNetwork);
    14201464            bool      fExact = intnetR0IfAddrCacheLookup(&pIf->aAddrCache[enmL3AddrType], pL3Addr, cbL3Addr) >= 0;
    1421             if (fExact || pTab->paEntries[iIfMac].fPromiscuous)
     1465            if (fExact || pTab->paEntries[iIfMac].fPromiscuousSeeTrunk)
    14221466            {
    14231467                cExactHits += fExact;
     
    14371481        if (   fExact
    14381482            || intnetR0IsMacAddrDummy(&pTab->HostMac)
    1439             || pTab->fHostPromiscuous)
     1483            || pTab->fHostPromiscuousEff)
    14401484        {
    14411485            cExactHits += fExact;
     
    14451489
    14461490    /* Hit the wire if there are no exact matches or if it's in promiscuous mode. */
    1447     if (pTab->fWireActive && (!cExactHits || pTab->fWirePromiscuous))
     1491    if (pTab->fWireActive && (!cExactHits || pTab->fWirePromiscuousEff))
    14481492        pDstTab->fTrunkDst |= INTNETTRUNKDIR_WIRE;
    14491493    pDstTab->fTrunkDst &= ~fSrc;
     
    14761520{
    14771521    Assert(!intnetR0IsMacAddrMulticast(pDstAddr));
     1522    Assert(fSrc);
    14781523
    14791524    /*
     
    14971542                break;
    14981543
     1544            /* Promiscuous mode? */
     1545            if (pTab->paEntries[iIfMac].fPromiscuousSeeTrunk)
     1546                break;
     1547
    14991548            /* Paranoia - this shouldn't happen, right? */
    15001549            if (    pSrcAddr
     
    15051554            if (intnetR0AreMacAddrsEqual(&pTab->paEntries[iIfMac].MacAddr, pDstAddr))
    15061555            {
    1507                 enmSwDecision = pTab->fHostPromiscuous && fSrc == INTNETTRUNKDIR_WIRE
     1556                enmSwDecision = pTab->fHostPromiscuousEff && fSrc == INTNETTRUNKDIR_WIRE
    15081557                              ? INTNETSWDECISION_BROADCAST
    15091558                              : INTNETSWDECISION_INTNET;
     
    15571606            if (   fExact
    15581607                || intnetR0IsMacAddrDummy(&pTab->paEntries[iIfMac].MacAddr)
    1559                 || pTab->paEntries[iIfMac].fPromiscuous)
     1608                || (   pTab->paEntries[iIfMac].fPromiscuousSeeTrunk
     1609                    || (!fSrc && pTab->paEntries[iIfMac].fPromiscuousEff) )
     1610               )
    15601611            {
    15611612                cExactHits += fExact;
     
    15801631        if (   fExact
    15811632            || intnetR0IsMacAddrDummy(&pTab->HostMac)
    1582             || pTab->fHostPromiscuous)
     1633            || pTab->fHostPromiscuousEff)
    15831634        {
    15841635            cExactHits += fExact;
     
    15901641    if (   fSrc != INTNETTRUNKDIR_WIRE
    15911642        && pTab->fWireActive
    1592         && (!cExactHits || pTab->fWirePromiscuous)
     1643        && (!cExactHits || pTab->fWirePromiscuousEff)
    15931644       )
    15941645        pDstTab->fTrunkDst |= INTNETTRUNKDIR_WIRE;
     
    17021753    {
    17031754        if (   pTab->paEntries[iIfMac].fActive
    1704             && pTab->paEntries[iIfMac].fPromiscuous)
     1755            && (   pTab->paEntries[iIfMac].fPromiscuousSeeTrunk
     1756                || (!fSrc && pTab->paEntries[iIfMac].fPromiscuousEff) )
     1757           )
    17051758        {
    17061759            PINTNETIF pIf    = pTab->paEntries[iIfMac].pIf;         AssertPtr(pIf); Assert(pIf->pNetwork == pNetwork);
     
    36023655        RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
    36033656
    3604         if (pIf->fPromiscuous != fPromiscuous)
     3657        if (pIf->fPromiscuousReal != fPromiscuous)
    36053658        {
    3606             Log(("IntNetR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n",
    3607                  hIf, !fPromiscuous, !!fPromiscuous));
    3608             ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous);
     3659            const bool fPromiscuousEff = fPromiscuous
     3660                                      && (pIf->fOpenFlags  & INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW)
     3661                                      && (pNetwork->fFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS);
     3662            Log(("IntNetR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d (%d) -> %d (%d)\n",
     3663                 hIf, !fPromiscuous, pIf->fPromiscuousEff, !!fPromiscuous, fPromiscuousEff));
     3664
     3665            pIf->fPromiscuousReal = fPromiscuous;
     3666            pIf->fPromiscuousEff  = fPromiscuousEff;
    36093667
    36103668            PINTNETMACTABENTRY pEntry = intnetR0NetworkFindMacAddrEntry(pNetwork, pIf); Assert(pEntry);
    36113669            if (RT_LIKELY(pEntry))
    3612                 pEntry->fPromiscuous = fPromiscuous;
    3613             pIf->fPromiscuous        = fPromiscuous;
     3670            {
     3671                pEntry->fPromiscuousEff      = fPromiscuousEff;
     3672                pEntry->fPromiscuousSeeTrunk = fPromiscuousEff
     3673                                            && (pIf->fOpenFlags & INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK);
     3674            }
    36143675        }
    36153676
     
    37813842                    if (pTrunk)
    37823843                    {
    3783                         pNetwork->MacTab.fHostActive = true;
    3784                         pNetwork->MacTab.fWireActive = true;
     3844                        pNetwork->MacTab.fHostActive = RT_BOOL(pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED);
     3845                        pNetwork->MacTab.fWireActive = RT_BOOL(pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED);
    37853846                    }
    37863847                }
     
    41794240            }
    41804241
     4242        /* recalc the min flags. */
     4243        if (pIf->fOpenFlags & INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES)
     4244        {
     4245            uint32_t fMinFlags = 0;
     4246            iIf = pNetwork->MacTab.cEntries;
     4247            while (iIf-- > 0)
     4248            {
     4249                PINTNETIF pIf2 = pNetwork->MacTab.paEntries[iIf].pIf;
     4250                if (   pIf2 /* paranoia */
     4251                    && (pIf2->fOpenFlags & INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES))
     4252                    fMinFlags |= pIf2->fOpenFlags & INTNET_OPEN_FLAGS_STRICT_MASK;
     4253            }
     4254            pNetwork->fMinFlags = fMinFlags;
     4255        }
    41814256        PINTNETTRUNKIF pTrunk = pNetwork->MacTab.pTrunk;
    41824257
     
    42814356 * @param   cbSend      The size of the send buffer.
    42824357 * @param   cbRecv      The size of the receive buffer.
     4358 * @param   fFlags      The open network flags.
    42834359 * @param   phIf        Where to store the interface handle.
    42844360 */
    4285 static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv,
     4361static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession,
     4362                                   unsigned cbSend, unsigned cbRecv, uint32_t fFlags,
    42864363                                   PINTNETIFHANDLE phIf)
    42874364{
    4288     LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u phIf=%p\n",
    4289              pNetwork, pSession, cbSend, cbRecv, phIf));
     4365    LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u fFlags=%#x phIf=%p\n",
     4366             pNetwork, pSession, cbSend, cbRecv, fFlags, phIf));
    42904367
    42914368    /*
     
    42944371    AssertPtr(pNetwork);
    42954372    AssertPtr(phIf);
     4373
     4374    /*
     4375     * Adjust the flags with defaults for the interface policies.
     4376     * Note: Main restricts promiscuous mode per interface.
     4377     */
     4378    uint32_t const  fDefFlags = INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW
     4379                              | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK;
     4380    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkIfFlags); i++)
     4381        if (!(fFlags & g_afIntNetOpenNetworkIfFlags[i].fPair))
     4382            fFlags |= g_afIntNetOpenNetworkIfFlags[i].fPair & fDefFlags;
    42964383
    42974384    /*
     
    43114398    memset(&pIf->MacAddr, 0xff, sizeof(pIf->MacAddr)); /* broadcast */
    43124399    //pIf->fMacSet          = false;
    4313     //pIf->fPromiscuous     = false;
     4400    //pIf->fPromiscuousEff  = false;
     4401    //pIf->fPromiscuousReal = false;
    43144402    //pIf->fActive          = false;
    43154403    //pIf->fDestroying      = false;
     4404    pIf->fOpenFlags         = fFlags;
    43164405    //pIf->cYields          = 0;
    43174406    //pIf->pIntBuf          = 0;
     
    43784467                    Assert(iIf + 1 <= pNetwork->MacTab.cEntriesAllocated);
    43794468
    4380                     pNetwork->MacTab.paEntries[iIf].MacAddr         = pIf->MacAddr;
    4381                     pNetwork->MacTab.paEntries[iIf].fActive         = false;
    4382                     pNetwork->MacTab.paEntries[iIf].fPromiscuous    = false;
    4383                     pNetwork->MacTab.paEntries[iIf].pIf             = pIf;
     4469                    pNetwork->MacTab.paEntries[iIf].MacAddr              = pIf->MacAddr;
     4470                    pNetwork->MacTab.paEntries[iIf].fActive              = false;
     4471                    pNetwork->MacTab.paEntries[iIf].fPromiscuousEff      = false;
     4472                    pNetwork->MacTab.paEntries[iIf].fPromiscuousSeeTrunk = false;
     4473                    pNetwork->MacTab.paEntries[iIf].pIf                  = pIf;
    43844474
    43854475                    pNetwork->MacTab.cEntries = iIf + 1;
     
    44924582        RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
    44934583
    4494         pNetwork->MacTab.fHostPromiscuous = fPromiscuous;
     4584        pNetwork->MacTab.fHostPromiscuousReal = fPromiscuous
     4585                                             || (pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE);
     4586        pNetwork->MacTab.fHostPromiscuousEff  = pNetwork->MacTab.fHostPromiscuousReal
     4587                                             && (pNetwork->fFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST);
    44954588
    44964589        RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock, &Tmp);
     
    49455038             * Note! We don't need to lock the MacTab here - creation time.
    49465039             */
    4947             pNetwork->MacTab.pTrunk           = pTrunk;
    4948             pNetwork->MacTab.HostMac          = pTrunk->MacAddr;
    4949             pNetwork->MacTab.fHostPromiscuous = false;
    4950             pNetwork->MacTab.fHostActive      = false;
    4951             pNetwork->MacTab.fWirePromiscuous = false; /** @todo !!(fFlags & INTNET_OPEN_FLAGS_PROMISC_TRUNK_WIRE); */
    4952             pNetwork->MacTab.fWireActive      = false;
     5040            pNetwork->MacTab.pTrunk               = pTrunk;
     5041            pNetwork->MacTab.HostMac              = pTrunk->MacAddr;
     5042            pNetwork->MacTab.fHostPromiscuousReal = false;
     5043            pNetwork->MacTab.fHostPromiscuousEff  = (pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE)
     5044                                                 && (pNetwork->fFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST);
     5045            pNetwork->MacTab.fHostActive          = false;
     5046            pNetwork->MacTab.fWirePromiscuousReal = pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE;
     5047            pNetwork->MacTab.fWirePromiscuousEff  = pNetwork->MacTab.fWirePromiscuousReal
     5048                                                 && (pNetwork->fFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE);
     5049            pNetwork->MacTab.fWireActive          = false;
    49535050
    49545051#ifdef IN_RING0 /* (testcase is ring-3) */
     
    51255222
    51265223/**
     5224 * Checks if the open network flags are compatible.
     5225 *
     5226 * @returns VBox status code.
     5227 * @param   pNetwork            The network.
     5228 * @param   fFlags              The open network flags.
     5229 */
     5230static int intnetR0CheckOpenNetworkFlags(PINTNETNETWORK pNetwork, uint32_t fFlags)
     5231{
     5232    uint32_t const fNetFlags = pNetwork->fFlags;
     5233
     5234    if (  (fFlags    & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
     5235        ^ (fNetFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE))
     5236        return VERR_INTNET_INCOMPATIBLE_FLAGS;
     5237
     5238    if (fFlags & INTNET_OPEN_FLAGS_REQUIRE_EXACT)
     5239    {
     5240        for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5241            if (   (fFlags & g_afIntNetOpenNetworkNetFlags[i].fPair)
     5242                &&     (fFlags    & g_afIntNetOpenNetworkNetFlags[i].fPair)
     5243                   !=  (fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fPair) )
     5244            return VERR_INTNET_INCOMPATIBLE_FLAGS;
     5245    }
     5246
     5247    if (fFlags & INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES)
     5248    {
     5249        for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5250            if (    (fFlags    & g_afIntNetOpenNetworkNetFlags[i].fRestrictive)
     5251                && !(fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fRestrictive)
     5252                &&  (fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fFixed) )
     5253                 return VERR_INTNET_INCOMPATIBLE_FLAGS;
     5254    }
     5255
     5256    return VINF_SUCCESS;
     5257}
     5258
     5259
     5260/**
     5261 * Adapts flag changes on network opening.
     5262 *
     5263 * @returns VBox status code.
     5264 * @param   pNetwork            The network.
     5265 * @param   fFlags              The open network flags.
     5266 */
     5267static int intnetR0AdaptOpenNetworkFlags(PINTNETNETWORK pNetwork, uint32_t fFlags)
     5268{
     5269    /*
     5270     * Upgrade the minimum policy flags.
     5271     */
     5272    uint32_t fNetMinFlags = pNetwork->fMinFlags;
     5273    Assert(!(fNetMinFlags & INTNET_OPEN_FLAGS_RELAXED_MASK));
     5274    if (fFlags & INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES)
     5275    {
     5276        fNetMinFlags |= fFlags & INTNET_OPEN_FLAGS_STRICT_MASK;
     5277        if (fNetMinFlags != pNetwork->fMinFlags)
     5278        {
     5279            LogRel(("INTNET: %s - min flags changed %#x -> %#x\n", pNetwork->szName, pNetwork->fMinFlags, fNetMinFlags));
     5280            pNetwork->fMinFlags = fNetMinFlags;
     5281        }
     5282    }
     5283
     5284    /*
     5285     * Calculate the new network flags.
     5286     * (Depends on fNetMinFlags being recalculated first.)
     5287     */
     5288    uint32_t fNetFlags = pNetwork->fFlags;
     5289
     5290    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5291    {
     5292        Assert(fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fPair);
     5293        Assert(!(fNetMinFlags & g_afIntNetOpenNetworkNetFlags[i].fRelaxed));
     5294
     5295        if (!(fFlags & g_afIntNetOpenNetworkNetFlags[i].fPair))
     5296            continue;
     5297        if (fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fFixed)
     5298            continue;
     5299
     5300        if (   (fNetMinFlags & g_afIntNetOpenNetworkNetFlags[i].fRestrictive)
     5301            || (fFlags       & g_afIntNetOpenNetworkNetFlags[i].fRestrictive) )
     5302        {
     5303            fNetFlags &= ~g_afIntNetOpenNetworkNetFlags[i].fPair;
     5304            fNetFlags |= g_afIntNetOpenNetworkNetFlags[i].fRestrictive;
     5305        }
     5306        else if (!(fFlags & INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES))
     5307        {
     5308            fNetFlags &= ~g_afIntNetOpenNetworkNetFlags[i].fPair;
     5309            fNetFlags |= g_afIntNetOpenNetworkNetFlags[i].fRelaxed;
     5310        }
     5311    }
     5312
     5313    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5314    {
     5315        Assert(fNetFlags & g_afIntNetOpenNetworkNetFlags[i].fPair);
     5316        fNetFlags |= fFlags & g_afIntNetOpenNetworkNetFlags[i].fFixed;
     5317    }
     5318
     5319    /*
     5320     * Apply the flags if they changed.
     5321     */
     5322    uint32_t const fOldNetFlags = pNetwork->fFlags;
     5323    if (fOldNetFlags != fNetFlags)
     5324    {
     5325        LogRel(("INTNET: %s - flags changed %#x -> %#x\n", pNetwork->szName, fOldNetFlags, fNetFlags));
     5326
     5327        RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
     5328        RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
     5329
     5330        pNetwork->fFlags = fNetFlags;
     5331
     5332        /* Recalculate some derived switcher variables. */
     5333        bool fActiveTrunk = pNetwork->MacTab.pTrunk
     5334                         && pNetwork->cActiveIFs > 0;
     5335        pNetwork->MacTab.fHostActive         = fActiveTrunk
     5336                                            && (fNetFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED);
     5337        pNetwork->MacTab.fHostPromiscuousEff = (   pNetwork->MacTab.fHostPromiscuousReal
     5338                                                || (fNetFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE))
     5339                                            && (fNetFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST);
     5340
     5341        pNetwork->MacTab.fWireActive         = fActiveTrunk
     5342                                            && (fNetFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED);
     5343        pNetwork->MacTab.fWirePromiscuousReal= (fNetFlags & INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE);
     5344        pNetwork->MacTab.fWirePromiscuousEff = pNetwork->MacTab.fWirePromiscuousReal
     5345                                            && (fNetFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE);
     5346
     5347        if ((fOldNetFlags ^ fNetFlags) & INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS)
     5348        {
     5349            uint32_t iIf = pNetwork->MacTab.cEntries;
     5350            while (iIf-- > 0)
     5351            {
     5352                PINTNETMACTABENTRY  pEntry = &pNetwork->MacTab.paEntries[iIf];
     5353                PINTNETIF           pIf2   = pEntry->pIf;
     5354                if (   pIf2 /* paranoia */
     5355                    && pIf2->fPromiscuousReal)
     5356                {
     5357                    bool fPromiscuousEff = (fNetFlags & INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS)
     5358                                        && (pIf2->fOpenFlags & INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW);
     5359                    pIf2->fPromiscuousEff        = fPromiscuousEff;
     5360                    pEntry->fPromiscuousEff      = fPromiscuousEff;
     5361                    pEntry->fPromiscuousSeeTrunk = fPromiscuousEff
     5362                                                && (pIf2->fOpenFlags & INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK);
     5363                }
     5364            }
     5365        }
     5366
     5367        RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock, &Tmp);
     5368    }
     5369
     5370    return VINF_SUCCESS;
     5371}
     5372
     5373
     5374/**
    51275375 * Opens an existing network.
    51285376 *
     
    51505398    Assert(enmTrunkType > kIntNetTrunkType_Invalid && enmTrunkType < kIntNetTrunkType_End);
    51515399    AssertPtr(pszTrunk);
    5152     Assert(!(fFlags & ~(INTNET_OPEN_FLAGS_MASK)));
     5400    Assert(!(fFlags & ~INTNET_OPEN_FLAGS_MASK));
    51535401    AssertPtr(ppNetwork);
    51545402    *ppNetwork = NULL;
     
    51765424                     && !strcmp(pCur->szTrunk, pszTrunk)))
    51775425            {
    5178                 if (!((pCur->fFlags ^ fFlags) & INTNET_OPEN_FLAGS_COMPATIBILITY_XOR_MASK))
     5426                rc = intnetR0CheckOpenNetworkFlags(pCur, fFlags);
     5427                if (RT_SUCCESS(rc))
    51795428                {
    51805429                    /*
     
    51855434                    if (RT_SUCCESS(rc))
    51865435                    {
    5187                         if (!(pCur->fFlags & INTNET_OPEN_FLAGS_PUBLIC))
     5436                        if (pCur->fFlags & INTNET_OPEN_FLAGS_ACCESS_RESTRICTED)
    51885437                            rc = SUPR0ObjVerifyAccess(pCur->pvObj, pSession, pCur->szName);
    51895438                        if (RT_SUCCESS(rc))
    5190                         {
    5191                             pCur->fFlags |= fFlags & INTNET_OPEN_FLAGS_SECURITY_OR_MASK;
    5192 
    51935439                            *ppNetwork = pCur;
    5194                         }
    51955440                        else
    51965441                            SUPR0ObjRelease(pCur->pvObj, pSession);
     
    51995444                        rc = VERR_NOT_FOUND; /* destruction race, pretend the other isn't there. */
    52005445                }
    5201                 else
    5202                     rc = VERR_INTNET_INCOMPATIBLE_FLAGS;
    52035446            }
    52045447            else
     
    52535496    Assert(!(fFlags & ~INTNET_OPEN_FLAGS_MASK));
    52545497    AssertPtr(ppNetwork);
     5498
    52555499    *ppNetwork = NULL;
     5500
     5501    /*
     5502     * Adjust the flags with defaults for the network policies.
     5503     * Note: Main restricts promiscuous mode on the per interface level.
     5504     */
     5505    fFlags &= ~(  INTNET_OPEN_FLAGS_IF_FIXED
     5506                | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW
     5507                | INTNET_OPEN_FLAGS_IF_PROMISC_DENY
     5508                | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK
     5509                | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK
     5510                | INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES
     5511                | INTNET_OPEN_FLAGS_REQUIRE_EXACT);
     5512    uint32_t const  fDefFlags = INTNET_OPEN_FLAGS_ACCESS_RESTRICTED
     5513                              | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS
     5514                              | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST
     5515                              | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE
     5516                              | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED
     5517                              | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE
     5518                              | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED
     5519                              | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE
     5520                              ;
     5521    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5522        if (!(fFlags & g_afIntNetOpenNetworkNetFlags[i].fPair))
     5523            fFlags |= g_afIntNetOpenNetworkNetFlags[i].fPair & fDefFlags;
    52565524
    52575525    /*
     
    52645532    if (!pNetwork)
    52655533        return VERR_NO_MEMORY;
    5266     //pNetwork->pNext                   = NULL;
    5267     //pNetwork->pIfs                    = NULL;
    5268     pNetwork->hAddrSpinlock             = NIL_RTSPINLOCK;
    5269     pNetwork->MacTab.cEntries           = 0;
    5270     pNetwork->MacTab.cEntriesAllocated  = INTNET_GROW_DSTTAB_SIZE;
    5271     pNetwork->MacTab.paEntries          = NULL;
    5272     pNetwork->MacTab.fHostPromiscuous   = false;
    5273     pNetwork->MacTab.fHostActive        = false;
    5274     pNetwork->MacTab.fWirePromiscuous   = false;
    5275     pNetwork->MacTab.fWireActive        = false;
    5276     pNetwork->MacTab.pTrunk             = NULL;
    5277     pNetwork->hEvtBusyIf                = NIL_RTSEMEVENT;
    5278     pNetwork->pIntNet                   = pIntNet;
    5279     //pNetwork->pvObj                   = NULL;
     5534    //pNetwork->pNext                       = NULL;
     5535    //pNetwork->pIfs                        = NULL;
     5536    pNetwork->hAddrSpinlock                 = NIL_RTSPINLOCK;
     5537    pNetwork->MacTab.cEntries               = 0;
     5538    pNetwork->MacTab.cEntriesAllocated      = INTNET_GROW_DSTTAB_SIZE;
     5539    pNetwork->MacTab.paEntries              = NULL;
     5540    pNetwork->MacTab.fHostPromiscuousReal   = false;
     5541    pNetwork->MacTab.fHostPromiscuousEff    = false;
     5542    pNetwork->MacTab.fHostActive            = false;
     5543    pNetwork->MacTab.fWirePromiscuousReal   = false;
     5544    pNetwork->MacTab.fWirePromiscuousEff    = false;
     5545    pNetwork->MacTab.fWireActive            = false;
     5546    pNetwork->MacTab.pTrunk                 = NULL;
     5547    pNetwork->hEvtBusyIf                    = NIL_RTSEMEVENT;
     5548    pNetwork->pIntNet                       = pIntNet;
     5549    //pNetwork->pvObj                       = NULL;
    52805550    if (fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
    5281         pNetwork->pbTmp                 = RT_ALIGN_PT(pNetwork + 1, 64, uint8_t *);
     5551        pNetwork->pbTmp                     = RT_ALIGN_PT(pNetwork + 1, 64, uint8_t *);
    52825552    //else
    5283     //    pNetwork->pbTmp               = NULL;
    5284     pNetwork->fFlags                    = fFlags;
    5285     //pNetwork->cActiveIFs              = 0;
    5286     size_t cchName                      = strlen(pszNetwork);
    5287     pNetwork->cchName                   = (uint8_t)cchName;
     5553    //    pNetwork->pbTmp                   = NULL;
     5554    pNetwork->fFlags                        = fFlags;
     5555    //pNetwork->fMinFlags                   = 0;
     5556    //pNetwork->cActiveIFs                  = 0;
     5557    size_t cchName                          = strlen(pszNetwork);
     5558    pNetwork->cchName                       = (uint8_t)cchName;
    52885559    Assert(cchName && cchName < sizeof(pNetwork->szName));  /* caller's responsibility. */
    52895560    memcpy(pNetwork->szName, pszNetwork, cchName);          /* '\0' at courtesy of alloc. */
    5290     pNetwork->enmTrunkType              = enmTrunkType;
     5561    pNetwork->enmTrunkType                  = enmTrunkType;
    52915562    Assert(strlen(pszTrunk) < sizeof(pNetwork->szTrunk));   /* caller's responsibility. */
    52925563    strcpy(pNetwork->szTrunk, pszTrunk);
     
    54225693
    54235694    AssertMsgReturn(!(fFlags & ~INTNET_OPEN_FLAGS_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
     5695    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkNetFlags); i++)
     5696        AssertMsgReturn((fFlags & g_afIntNetOpenNetworkNetFlags[i].fPair) != g_afIntNetOpenNetworkNetFlags[i].fPair,
     5697                        ("%#x (%#x)\n", fFlags, g_afIntNetOpenNetworkNetFlags[i].fPair), VERR_INVALID_PARAMETER);
     5698    for (uint32_t i = 0; i < RT_ELEMENTS(g_afIntNetOpenNetworkIfFlags); i++)
     5699        AssertMsgReturn((fFlags & g_afIntNetOpenNetworkIfFlags[i].fPair) != g_afIntNetOpenNetworkIfFlags[i].fPair,
     5700                        ("%#x (%#x)\n", fFlags, g_afIntNetOpenNetworkIfFlags[i].fPair), VERR_INVALID_PARAMETER);
    54245701    AssertPtrReturn(phIf, VERR_INVALID_PARAMETER);
    54255702
     
    54395716    if (RT_SUCCESS(rc))
    54405717    {
    5441         rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, phIf);
     5718        rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
    54425719        if (RT_SUCCESS(rc))
     5720        {
     5721            intnetR0AdaptOpenNetworkFlags(pNetwork, fFlags);
    54435722            rc = VINF_ALREADY_INITIALIZED;
     5723        }
    54445724        else
    54455725            SUPR0ObjRelease(pNetwork->pvObj, pSession);
     
    54505730        if (RT_SUCCESS(rc))
    54515731        {
    5452             rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, phIf);
     5732            rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
    54535733            if (RT_FAILURE(rc))
    54545734                SUPR0ObjRelease(pNetwork->pvObj, pSession);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette