Beispiel #1
0
/*
 * --------------------------------------------------------------------------
 *  This function activates the switch by initializing it with all the runtime
 *  state. First it queries all of the MAC addresses set as custom switch policy
 *  to allow sends from, and adds tme to the property list. Then it queries the
 *  NIC list and verifies it can support all of the NICs currently connected to
 *  the switch, and adds the NICs to the NIC list.
 * --------------------------------------------------------------------------
 */
static NDIS_STATUS
OvsActivateSwitch(POVS_SWITCH_CONTEXT switchContext)
{
    NDIS_STATUS status;

    ASSERT(!switchContext->isActivated);

    OVS_LOG_TRACE("Enter: activate switch %p, dpNo: %ld",
                  switchContext, switchContext->dpNo);

    status = OvsAddConfiguredSwitchPorts(switchContext);

    if (status != NDIS_STATUS_SUCCESS) {
        OVS_LOG_WARN("Failed to add configured switch ports");
        goto cleanup;

    }
    status = OvsInitConfiguredSwitchNics(switchContext);

    if (status != NDIS_STATUS_SUCCESS) {
        OVS_LOG_WARN("Failed to add configured vports");
        OvsClearAllSwitchVports(switchContext);
        goto cleanup;
    }
    switchContext->isActivated = TRUE;
    OvsPostEvent(OVS_DEFAULT_PORT_NO, OVS_DEFAULT_EVENT_STATUS);

cleanup:
    OVS_LOG_TRACE("Exit: activate switch:%p, isActivated: %s, status = %lx",
                  switchContext,
                  (switchContext->isActivated ? "TRUE" : "FALSE"), status);
    return status;
}
Beispiel #2
0
/*
 * ---------------------------------------------------------------------------
 * Validate the netlink attribute against the policy
 * ---------------------------------------------------------------------------
 */
BOOLEAN
NlAttrValidate(const PNL_ATTR nla, const PNL_POLICY policy)
{
    UINT32 minLen;
    UINT32 maxLen;
    UINT32 len;
    BOOLEAN ret = FALSE;

    if ((policy->type == NL_A_NO_ATTR) ||
        (policy->type == NL_A_VAR_LEN) ||
        (policy->type == NL_A_NESTED)) {
        /* Do not validate anything for attributes of type var length */
        ret = TRUE;
        goto done;
    }

    /* Figure out min and max length. */
    minLen = policy->minLen;
    if (!minLen) {
        minLen = NlAttrMinLen(policy->type);
    }
    maxLen = policy->maxLen;
    if (!maxLen) {
        maxLen = NlAttrMaxLen(policy->type);
    }

    /* Verify length. */
    len = NlAttrGetSize(nla);
    if (len < minLen || len > maxLen) {
        OVS_LOG_WARN("Attribute: %p, len: %d, not in valid range, "
                     "min: %d, max: %d", nla, len, minLen, maxLen);
        goto done;
    }

    /* Strings must be null terminated and must not have embedded nulls. */
    if (policy->type == NL_A_STRING) {
        if (((PCHAR) nla)[nla->nlaLen - 1]) {
            OVS_LOG_WARN("Attributes %p lacks null at the end", nla);
            goto done;
        }

        if (memchr(nla + 1, '\0', len - 1) != NULL) {
            OVS_LOG_WARN("Attributes %p has bad length", nla);
            goto done;
        }
    }

    ret = TRUE;

done:
    return ret;
}
Beispiel #3
0
/*
 *----------------------------------------------------------------------------
 * Parses the netlink message at a given offset (attrOffset)
 * as a series of attributes. A pointer to the attribute with type
 * 'type' is stored in attrs at index 'type'. policy is used to define the
 * attribute type validation parameters.
 * 'nla_offset' should be NLMSG_HDRLEN + GENL_HDRLEN + OVS_HEADER
 *
 * Returns BOOLEAN to indicate success/failure.
 *----------------------------------------------------------------------------
 */
BOOLEAN
NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
            UINT32 totalAttrLen,
            const NL_POLICY policy[],
            PNL_ATTR attrs[], UINT32 n_attrs)
{
    PNL_ATTR nla;
    UINT32 left;
    UINT32 iter;
    BOOLEAN ret = FALSE;

    RtlZeroMemory(attrs, n_attrs * sizeof *attrs);


    /* There is nothing to parse */
    if (!(NlMsgAttrsLen(nlMsg))) {
        ret = TRUE;
        goto done;
    }

    if ((NlMsgSize(nlMsg) < attrOffset)) {
        OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d",
                     nlMsg, attrOffset);
        goto done;
    }

    NL_ATTR_FOR_EACH (nla, left, NlMsgAt(nlMsg, attrOffset),
                      totalAttrLen)
    {
        UINT16 type = NlAttrType(nla);
        if (type < n_attrs && policy[type].type != NL_A_NO_ATTR) {
            /* Typecasting to keep the compiler happy */
            const PNL_POLICY e = (const PNL_POLICY)(&policy[type]);
            if (!NlAttrValidate(nla, e)) {
                goto done;
            }

            if (attrs[type]) {
                OVS_LOG_WARN("Duplicate attribute in nlMsg: %p, "
                             "type: %u", nlMsg, type);
            }

            attrs[type] = nla;
        }
    }
Beispiel #4
0
/*
 * --------------------------------------------------------------------------
 *  Implements filter driver's FilterRestart function.
 * --------------------------------------------------------------------------
 */
_Use_decl_annotations_
NDIS_STATUS
OvsExtRestart(NDIS_HANDLE filterModuleContext,
              PNDIS_FILTER_RESTART_PARAMETERS filterRestartParameters)
{
    POVS_SWITCH_CONTEXT switchContext = (POVS_SWITCH_CONTEXT)filterModuleContext;
    NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    BOOLEAN switchActive;

    UNREFERENCED_PARAMETER(filterRestartParameters);

    OVS_LOG_TRACE("Enter: filterModuleContext %p",
                  filterModuleContext);

    /* Activate the switch if this is the first restart. */
    if (!switchContext->isActivated && !switchContext->isActivateFailed) {
        status = OvsQuerySwitchActivationComplete(switchContext,
                                                  &switchActive);
        if (status != NDIS_STATUS_SUCCESS) {
            switchContext->isActivateFailed = TRUE;
            status = NDIS_STATUS_RESOURCES;
            goto cleanup;
        }

        if (switchActive) {
            status = OvsActivateSwitch(switchContext);

            if (status != NDIS_STATUS_SUCCESS) {
                OVS_LOG_WARN("Failed to activate switch, dpNo:%d",
                             switchContext->dpNo);
                status = NDIS_STATUS_RESOURCES;
                goto cleanup;
            }
        }
    }

    ASSERT(switchContext->dataFlowState == OvsSwitchPaused);
    switchContext->dataFlowState = OvsSwitchRunning;

cleanup:
    OVS_LOG_TRACE("Exit: Restart switch:%p, dpNo: %d, status: %#x",
                  switchContext, switchContext->dpNo, status);
    return status;
}
Beispiel #5
0
/*
 * ---------------------------------------------------------------------------
 * Default maximum payload size for each type of attribute.
 * ---------------------------------------------------------------------------
 */
UINT32
NlAttrMaxLen(NL_ATTR_TYPE type)
{
    switch (type) {
    case NL_A_NO_ATTR: return SIZE_MAX;
    case NL_A_UNSPEC: return SIZE_MAX;
    case NL_A_U8: return 1;
    case NL_A_U16: return 2;
    case NL_A_U32: return 4;
    case NL_A_U64: return 8;
    case NL_A_STRING: return MAXUINT16;
    case NL_A_FLAG: return SIZE_MAX;
    case NL_A_NESTED: return SIZE_MAX;
    case N_NL_ATTR_TYPES:
    default:
    OVS_LOG_WARN("Unsupprted attribute type: %d", type);
    ASSERT(0);
    }

    /* To keep compiler happy */
    return 0;
}
Beispiel #6
0
/*
 *----------------------------------------------------------------------------
 * Traverses all attributes in received buffer in order to insure all are valid
 *----------------------------------------------------------------------------
 */
BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
                           UINT32 totalAttrLen,
                           const NL_POLICY policy[], const UINT32 numPolicy)
{
    PNL_ATTR nla;
    INT left;
    BOOLEAN ret = TRUE;

    if ((NlMsgSize(nlMsg) < attrOffset)) {
        OVS_LOG_WARN("No attributes in nlMsg: %p at offset: %d",
            nlMsg, attrOffset);
        ret = FALSE;
        goto done;
    }

    NL_ATTR_FOR_EACH_UNSAFE(nla, left, NlMsgAt(nlMsg, attrOffset),
                            totalAttrLen)
    {
        if (!NlAttrIsValid(nla, left)) {
            ret = FALSE;
            goto done;
        }

        UINT16 type = NlAttrType(nla);
        if (type < numPolicy && policy[type].type != NL_A_NO_ATTR) {
            /* Typecasting to keep the compiler happy */
            const PNL_POLICY e = (const PNL_POLICY)(&policy[type]);
            if (!NlAttrValidate(nla, e)) {
                ret = FALSE;
                goto done;
            }
        }
    }

done:
    return ret;
}