static BOOLEAN _PIFromArgs_HandleEncap(_In_ const OVS_ARGUMENT_GROUP* pPIGroup, _Inout_ OVS_ARGUMENT* pEthTypeArg, _Out_ BOOLEAN* pEncapValid)
{
    BE16 vlanTci = 0;

    OVS_ARGUMENT* pVlanTciArg = NULL, *pEncapArg = NULL;

    OVS_CHECK(pEncapValid);
    OVS_CHECK(pEthTypeArg);

    *pEncapValid = FALSE;

    pVlanTciArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_VLAN_TCI);

    pEncapArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ENCAP_GROUP);

    if (!pVlanTciArg || !pEncapArg)
    {
        DEBUGP(LOG_ERROR, "the vlan frame is invalid!\n");
        return FALSE;
    }

    pEthTypeArg->isDisabled = TRUE;

    vlanTci = GET_ARG_DATA(pVlanTciArg, BE16);
    pEncapArg->isDisabled = TRUE;

    *pEncapValid = TRUE;

    if (!vlanTci)
    {
        if (pEncapArg->length > 0)
        {
            DEBUGP(LOG_ERROR, "The truncated vlan header has vlan tci != 0!\n");
            return FALSE;
        }
    }
    else
    {
        DEBUGP(LOG_ERROR, "Tried to set encapsulation data to a non-vlan frame!\n");
        return FALSE;
    }

    return TRUE;
}
示例#2
0
void CCommandLineParser::ProcessCommand(const char* command_str)
{
	const s_arg_entry* command;
	if (!FindArgument(command_str, false, &command))
		RaiseError("unknown command");

	if (this->command.id != kNone)
		RaiseError("unexpected command.. already got one.");
	this->command.SetID(command->id);
	ReadParams(command, this->command);		
}
static BOOLEAN _MasksFromArgs_HandleEncap(_In_ const OVS_ARGUMENT_GROUP* pMaskGroup, _Inout_ OVS_ARGUMENT* pEncapArg, _Inout_ OVS_ARGUMENT* pEtherTypeArg)
{
    BE16 ethType = 0;
    BE16 vlanTci = 0;
    BOOLEAN ok = TRUE;
    OVS_ARGUMENT* pVlanTciArg = NULL;

    OVS_CHECK(pEncapArg);

    pEncapArg->isDisabled = TRUE;

    if (pEtherTypeArg)
    {
        ethType = GET_ARG_DATA(pEtherTypeArg, BE16);
    }
    else
    {
        DEBUGP(LOG_ERROR, "The eth type argument was not found\n");
        return FALSE;
    }

    if (ethType == OVS_PI_MASK_MATCH_EXACT(UINT16))
    {
        pEtherTypeArg->isDisabled = TRUE;
    }
    else
    {
        DEBUGP(LOG_ERROR, "The vlan frame must have an exact match for ethType. Mask value: %x.\n", RtlUshortByteSwap(ethType));
        return FALSE;
    }

    pVlanTciArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_VLAN_TCI);

    if (pVlanTciArg)
    {
        vlanTci = GET_ARG_DATA(pVlanTciArg, BE16);
    }
    else
    {
        DEBUGP(LOG_ERROR, "vlan tci arg not given");
        return FALSE;
    }

    if (!(vlanTci & RtlUshortByteSwap(OVS_VLAN_TAG_PRESENT)))
    {
        DEBUGP(LOG_ERROR, "The vlan field 'tag present' bit must be exact match! Mask value: %x.\n", RtlUshortByteSwap(vlanTci));
        return FALSE;
    }

    return ok;
}
示例#4
0
void CCommandLineParser::ProcessSwitch(const char* switch_str)
{
	const s_arg_entry* s;
	if (!FindArgument(switch_str, true, &s))
		RaiseError("unknown switch");
	CArgEntity entity(s->id);
#ifdef CP_IGNORE_REST
	// special case: if we get the forward switch stop processing
	// everything and treat it as a single command.
	if (s->id == kIgnoreRest) {
		char* arg_str;
		while (ReadString(&arg_str)) entity.Add(arg_str);
	} else 	ReadParams(s, entity);
#else
	ReadParams(s, entity);
#endif
	switches.insert(std::pair<e_arg_ids, CArgEntity>(entity.id, entity));
}
示例#5
0
void CPathFinder::AddSetArgument(LPCTSTR szFlag, LPCTSTR szArgument)
{
	int	nIndex;

	nIndex = FindArgument(szFlag);

	if (nIndex != -1)
	{
		// An argument with the same flag already exists. Update it!
		_aArgs[nIndex].sValue = szArgument;
	}
	else
	{
		CArgument arg;

		arg.sValue = szArgument;
		arg.SetFlag(szFlag);

		_aArgs.Add(arg);
		_sArgs.Empty();
	}
}
BOOLEAN GetFlowMatchFromArguments(_Inout_ OVS_FLOW_MATCH* pFlowMatch, _In_ const OVS_ARGUMENT_GROUP* pPIGroup, const OVS_ARGUMENT_GROUP* pPIMaskGroup)
{
    BOOLEAN encapIsValid = FALSE;
    BOOLEAN ok = TRUE;
    OVS_ARGUMENT* pEthTypeArg = NULL, *pEthAddrArg = NULL;
    OVS_PI_RANGE* pPiRange = NULL;
    OVS_OFPACKET_INFO* pPacketInfo = NULL;

    OVS_CHECK(pFlowMatch);

    if (!pFlowMatch)
    {
        return FALSE;
    }

    pEthTypeArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ETH_TYPE);
#if OVS_VERSION == OVS_VERSION_1_11
    EXPECT(pEthAddrArg);
#endif

    pEthAddrArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ETH_ADDRESS);
    EXPECT(pEthAddrArg);

    if (pEthTypeArg && RtlUshortByteSwap(OVS_ETHERTYPE_QTAG) == GET_ARG_DATA(pEthTypeArg, BE16))
    {
        if (!_PIFromArgs_HandleEncap(pPIGroup, pEthAddrArg, &encapIsValid))
        {
            return FALSE;
        }
    }

    pPiRange = &pFlowMatch->piRange;
    pPacketInfo = pFlowMatch->pPacketInfo;

    ok = GetPacketInfoFromArguments(pPacketInfo, pPiRange, pPIGroup, /*isMask*/ FALSE);
    if (!ok)
    {
        return FALSE;
    }

    if (!pPIMaskGroup)
    {
        if (pFlowMatch->pFlowMask)
        {
            UINT8* pStart = (UINT8*)&pFlowMatch->pFlowMask->packetInfo + pPiRange->startRange;
            UINT16 range = (UINT16)(pPiRange->endRange - pPiRange->startRange);

            pFlowMatch->pFlowMask->piRange = *pPiRange;
            memset(pStart, OVS_PI_MASK_MATCH_EXACT(UINT8), range);
        }
    }
    else
    {
        OVS_ARGUMENT* pEncapArg = NULL;

        pEncapArg = FindArgument(pPIMaskGroup, OVS_ARGTYPE_PI_ENCAP_GROUP);

        if (pEncapArg)
        {
            if (!encapIsValid)
            {
                DEBUGP(LOG_ERROR, "Tryed to set encapsulation to non-vlan frame!\n");
                return FALSE;
            }

            if (!pEthTypeArg || !_MasksFromArgs_HandleEncap(pPIMaskGroup, pEncapArg, pEthTypeArg))
            {
                return FALSE;
            }
        }

        OVS_CHECK(pFlowMatch->pFlowMask);
        pPiRange = &pFlowMatch->pFlowMask->piRange;
        pPacketInfo = &pFlowMatch->pFlowMask->packetInfo;

        ok = GetPacketInfoFromArguments(pPacketInfo, pPiRange, pPIMaskGroup, /*is mask*/TRUE);
        if (!ok)
        {
            return FALSE;
        }
    }

    //if the userspace gives us bad / unexpected args, we cannot simply deny the flow:
    //a) this might not be a bug (i.e. the userspace intends to set flows like this)
    //b) if it is a bug, we can do little in the kernel to help it.
#if __VERIFY_MASKS
    if (!_VerifyMasks(pFlowMatch, pPIGroup, pPIMaskGroup))
    {
        return FALSE;
    }
#endif

    return TRUE;
}
static BOOLEAN _VerifyMasks(_In_ const OVS_FLOW_MATCH* pFlowMatch, _In_ const OVS_ARGUMENT_GROUP* pPIGroup, _In_ const OVS_ARGUMENT_GROUP* pMaskGroup)
{
    OVS_ARGUMENT* pMaskArg = NULL, *pPacketInfoArg = NULL;
    BOOLEAN isIpv4 = FALSE;
    BOOLEAN isIpv6 = FALSE;
    BOOLEAN isWildcard = FALSE;
    BOOLEAN isIcmp6 = FALSE;

    OVS_OFPACKET_INFO* pPacketInfo = NULL, *pMask = NULL;

    OVS_CHECK(pFlowMatch);

    if (!pMaskGroup)
    {
        return TRUE;
    }

    pPacketInfo = pFlowMatch->pPacketInfo;
    pMask = (pFlowMatch->pFlowMask ? &pFlowMatch->pFlowMask->packetInfo : NULL);

    //NOTE: we must have key, but we need not have mask!
    OVS_CHECK(pPacketInfo);

    //ETHERNET TYPE
    isWildcard = (pMask ? (pMask->ethInfo.type == OVS_PI_MASK_MATCH_WILDCARD(UINT16)) : FALSE);

    switch (RtlUshortByteSwap(pPacketInfo->ethInfo.type))
    {
    case OVS_ETHERTYPE_ARP:
        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ARP);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_ARP);

        if (isWildcard && pMaskArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " cannot have mask arg type %u: eth type is wildcard!\n", OVS_ARGTYPE_PI_ARP);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for eth type is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_ARP);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }

        break;

    case OVS_ETHERTYPE_IPV4:
        isIpv4 = TRUE;

        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_IPV4);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_IPV4);

        if (isWildcard && pMaskArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " cannot have mask arg type %u: eth type is wildcard!\n", OVS_ARGTYPE_PI_IPV4);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for eth type is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_IPV4);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }

        break;

    case OVS_ETHERTYPE_IPV6:
        isIpv6 = TRUE;

        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_IPV6);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_IPV6);

        if (isWildcard && pMaskArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " cannot have mask arg type %u: eth type is wildcard!\n", OVS_ARGTYPE_PI_IPV6);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for eth type is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_IPV6);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        break;

    default:
        if (!isWildcard)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " invalid eth type, when eth type mask = exact!\n");
            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        //ignore: we have eth type wildcarded
    }

    if (pMask)
    {
        isWildcard = (pMask->ipInfo.protocol == OVS_PI_MASK_MATCH_WILDCARD(UINT8) ? TRUE : FALSE);
    }
    else
    {
        isWildcard = FALSE;
    }

    isWildcard = (pMask ? (pMask->ipInfo.protocol == OVS_PI_MASK_MATCH_WILDCARD(UINT8)) : FALSE);

    switch (pPacketInfo->ipInfo.protocol)
    {
    case OVS_IPPROTO_TCP:
        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_TCP);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_TCP);

        if (pMaskArg && !isIpv4 && !isIpv6)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we have neither ipv4, nor ipv6, but have mask for tcp? (bad)\n", OVS_ARGTYPE_PI_TCP);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }
        else if (isWildcard && pMaskArg)
        {
            //the userspace actually sets mask this way
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for proto is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_TCP);

            //remove the assert and the 'return FALSE' if it fails, and it also looks to be a valid scenario
            OVS_CHECK(__UNEXPECTED__);
            return FALSE;
        }

        break;

    case OVS_IPPROTO_UDP:
        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_UDP);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_UDP);

        if (pMaskArg && !isIpv4 && !isIpv6)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we have neither ipv4, nor ipv6, but have mask for udp? (bad)\n", OVS_ARGTYPE_PI_UDP);

            return FALSE;
        }
        else if (isWildcard && pMaskArg)
        {
            //the userspace actually sets mask this way
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for proto is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_UDP);

            return FALSE;
        }
        break;

    case OVS_IPPROTO_SCTP:
        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_SCTP);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_SCTP);

        if (pMaskArg && !isIpv4 && !isIpv6)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we have neither ipv4, nor ipv6, but have mask for sctp? (bad)\n", OVS_ARGTYPE_PI_SCTP);

            return FALSE;
        }
        else if (isWildcard && pMaskArg)
        {
            //the userspace actually sets mask this way
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for proto is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_SCTP);

            return FALSE;
        }

        break;

    case OVS_IPPROTO_ICMP:
        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ICMP);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_ICMP);

        if (pMaskArg && !isIpv4)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we don't have ipv4, but have mask for icmp4? (bad)\n", OVS_ARGTYPE_PI_ICMP);

            return FALSE;
        }
        else if (isWildcard && pMaskArg)
        {
            //the userspace actually sets mask this way
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for proto is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_ICMP);

            return FALSE;
        }

        break;

    case OVS_IPV6_EXTH_ICMP6:
        isIcmp6 = TRUE;

        pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_ICMP6);

        pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_ICMP6);

        if (pMaskArg && !isIpv6)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we don't have ipv6, but have mask for icmp6? (bad)\n", OVS_ARGTYPE_PI_ICMP6);

            return FALSE;
        }
        else if (isWildcard && pMaskArg)
        {
            //the userspace actually sets mask this way
        }
        else if (!isWildcard && !pPacketInfoArg)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for proto is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_ICMP6);

            return FALSE;
        }

        break;

    default:
        //ignore: we have ipv4 proto wildcarded
        if (!isWildcard)
        {
            DEBUGP(LOG_ERROR, __FUNCTION__ " invalid ipv4/ipv6 proto, when proto mask = exact!\n");
            return FALSE;
        }
        //ignore: we have eth type wildcarded
    }

    //IPV6 / ICMP6 / ND
    isWildcard = (pMask ? (pMask->tpInfo.sourcePort == OVS_PI_MASK_MATCH_WILDCARD(UINT8)) : FALSE);

    pPacketInfoArg = FindArgument(pPIGroup, OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

    pMaskArg = FindArgument(pMaskGroup, OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

    if (pMaskArg && !isIcmp6)
    {
        DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we don't have icmp6, but have mask for icmp6/nd? (bad)\n", OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

        return FALSE;
    }

    if (pMaskArg && !isIpv6)
    {
        DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u: we don't have ipv6, but have mask for icmp6/nd? (bad)\n", OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

        return FALSE;
    }

    if (isWildcard && pMaskArg)
    {
        DEBUGP(LOG_ERROR, __FUNCTION__ " cannot have mask arg type %u: ipv6 src port is wildcard!\n", OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

        return FALSE;
    }
    else if (!isWildcard && !pPacketInfoArg)
    {
        DEBUGP(LOG_ERROR, __FUNCTION__ " arg type %u -- mask for ipv6 src port is 'exact', but we don't have the key!\n", OVS_ARGTYPE_PI_NEIGHBOR_DISCOVERY);

        return FALSE;
    }

    return TRUE;
}