mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Add support for STP filtering
This patch adds support for filtering of STP (spanning tree protocol) traffic to the parser and makes us of the ebtables support for STP filtering. This code now enables the filtering of traffic in chains with prefix 'stp'. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
af37ce3dc7
commit
ba3bf00acf
@ -38,6 +38,16 @@
|
|||||||
</element>
|
</element>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name="stp">
|
||||||
|
<ref name="match-attribute"/>
|
||||||
|
<ref name="srcmacandmask-attributes"/>
|
||||||
|
<ref name="stp-attributes"/>
|
||||||
|
<ref name="comment-attribute"/>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<element name="arp">
|
<element name="arp">
|
||||||
@ -299,6 +309,9 @@
|
|||||||
<data type="string">
|
<data type="string">
|
||||||
<param name="pattern">mac[a-zA-Z0-9_\.:-]{0,9}</param>
|
<param name="pattern">mac[a-zA-Z0-9_\.:-]{0,9}</param>
|
||||||
</data>
|
</data>
|
||||||
|
<data type="string">
|
||||||
|
<param name="pattern">stp[a-zA-Z0-9_\.:-]{0,9}</param>
|
||||||
|
</data>
|
||||||
<data type="string">
|
<data type="string">
|
||||||
<param name="pattern">vlan[a-zA-Z0-9_\.:-]{0,8}</param>
|
<param name="pattern">vlan[a-zA-Z0-9_\.:-]{0,8}</param>
|
||||||
</data>
|
</data>
|
||||||
@ -382,7 +395,7 @@
|
|||||||
</interleave>
|
</interleave>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
<define name="common-l2-attributes">
|
<define name="srcmacandmask-attributes">
|
||||||
<interleave>
|
<interleave>
|
||||||
<ref name="srcmac-attribute"/>
|
<ref name="srcmac-attribute"/>
|
||||||
<optional>
|
<optional>
|
||||||
@ -390,6 +403,12 @@
|
|||||||
<ref name="addrMAC"/>
|
<ref name="addrMAC"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
|
</interleave>
|
||||||
|
</define>
|
||||||
|
|
||||||
|
<define name="common-l2-attributes">
|
||||||
|
<interleave>
|
||||||
|
<ref name="srcmacandmask-attributes"/>
|
||||||
<optional>
|
<optional>
|
||||||
<attribute name="dstmacaddr">
|
<attribute name="dstmacaddr">
|
||||||
<ref name="addrMAC"/>
|
<ref name="addrMAC"/>
|
||||||
@ -588,6 +607,119 @@
|
|||||||
</interleave>
|
</interleave>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="stp-attributes">
|
||||||
|
<optional>
|
||||||
|
<attribute name="type">
|
||||||
|
<ref name="uint8range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="flags">
|
||||||
|
<ref name="uint8range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-priority">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-priority-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-address">
|
||||||
|
<ref name="addrMAC"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-address-mask">
|
||||||
|
<ref name="addrMAC"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-cost">
|
||||||
|
<ref name="uint32range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="root-cost-hi">
|
||||||
|
<ref name="uint32range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="sender-priority">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="sender-priority-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="sender-address">
|
||||||
|
<ref name="addrMAC"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="sender-address-mask">
|
||||||
|
<ref name="addrMAC"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="port">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="port-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="age">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="age-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="max-age">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="max-age-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="hello-time">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="hello-time-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="forward-delay">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="forward-delay-hi">
|
||||||
|
<ref name="uint16range"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="arp-attributes">
|
<define name="arp-attributes">
|
||||||
<interleave>
|
<interleave>
|
||||||
<optional>
|
<optional>
|
||||||
@ -852,6 +984,24 @@
|
|||||||
</choice>
|
</choice>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="uint32range">
|
||||||
|
<choice>
|
||||||
|
<!-- variable -->
|
||||||
|
<data type="string">
|
||||||
|
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data type="string">
|
||||||
|
<param name="pattern">0x[0-9a-fA-F]{1,8}</param>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data type="int">
|
||||||
|
<param name="minInclusive">0</param>
|
||||||
|
<param name="maxInclusive">4294967295</param>
|
||||||
|
</data>
|
||||||
|
</choice>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="boolean">
|
<define name="boolean">
|
||||||
<choice>
|
<choice>
|
||||||
<value>yes</value>
|
<value>yes</value>
|
||||||
|
@ -84,6 +84,7 @@ VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST,
|
|||||||
"root",
|
"root",
|
||||||
"mac",
|
"mac",
|
||||||
"vlan",
|
"vlan",
|
||||||
|
"stp",
|
||||||
"arp",
|
"arp",
|
||||||
"rarp",
|
"rarp",
|
||||||
"ipv4",
|
"ipv4",
|
||||||
@ -93,6 +94,7 @@ VIR_ENUM_IMPL(virNWFilterRuleProtocol, VIR_NWFILTER_RULE_PROTOCOL_LAST,
|
|||||||
"none",
|
"none",
|
||||||
"mac",
|
"mac",
|
||||||
"vlan",
|
"vlan",
|
||||||
|
"stp",
|
||||||
"arp",
|
"arp",
|
||||||
"rarp",
|
"rarp",
|
||||||
"ip",
|
"ip",
|
||||||
@ -1047,6 +1049,138 @@ static const virXMLAttr2Struct vlanAttributes[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* STP is documented by IEEE 802.1D; for a synopsis,
|
||||||
|
* see http://www.javvin.com/protocolSTP.html */
|
||||||
|
static const virXMLAttr2Struct stpAttributes[] = {
|
||||||
|
/* spanning tree uses a special destination MAC address */
|
||||||
|
{
|
||||||
|
.name = SRCMACADDR,
|
||||||
|
.datatype = DATATYPE_MACADDR,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef,
|
||||||
|
p.stpHdrFilter.ethHdr.dataSrcMACAddr),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = SRCMACMASK,
|
||||||
|
.datatype = DATATYPE_MACMASK,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef,
|
||||||
|
p.stpHdrFilter.ethHdr.dataSrcMACMask),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "type",
|
||||||
|
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "flags",
|
||||||
|
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataFlags),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-priority",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootPri),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-priority-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootPriHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-address",
|
||||||
|
.datatype = DATATYPE_MACADDR,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootAddr),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-address-mask",
|
||||||
|
.datatype = DATATYPE_MACMASK,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootAddrMask),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-cost",
|
||||||
|
.datatype = DATATYPE_UINT32 | DATATYPE_UINT32_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootCost),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "root-cost-hi",
|
||||||
|
.datatype = DATATYPE_UINT32 | DATATYPE_UINT32_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataRootCostHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "sender-priority",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataSndrPrio),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "sender-priority-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataSndrPrioHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "sender-address",
|
||||||
|
.datatype = DATATYPE_MACADDR,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataSndrAddr),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "sender-address-mask",
|
||||||
|
.datatype = DATATYPE_MACMASK,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataSndrAddrMask),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "port",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataPort),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "port-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataPortHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "age",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataAge),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "age-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataAgeHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "max-age",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataMaxAge),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "max-age-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataMaxAgeHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "hello-time",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataHelloTime),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "hello-time-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataHelloTimeHi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "forward-delay",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataFwdDelay),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "forward-delay-hi",
|
||||||
|
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
|
||||||
|
.dataIdx = offsetof(virNWFilterRuleDef, p.stpHdrFilter.dataFwdDelayHi),
|
||||||
|
},
|
||||||
|
COMMENT_PROP(stpHdrFilter),
|
||||||
|
{
|
||||||
|
.name = NULL,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static const virXMLAttr2Struct arpAttributes[] = {
|
static const virXMLAttr2Struct arpAttributes[] = {
|
||||||
COMMON_MAC_PROPS(arpHdrFilter),
|
COMMON_MAC_PROPS(arpHdrFilter),
|
||||||
{
|
{
|
||||||
@ -1505,6 +1639,7 @@ static const virAttributes virAttr[] = {
|
|||||||
PROTOCOL_ENTRY("rarp" , arpAttributes , VIR_NWFILTER_RULE_PROTOCOL_RARP),
|
PROTOCOL_ENTRY("rarp" , arpAttributes , VIR_NWFILTER_RULE_PROTOCOL_RARP),
|
||||||
PROTOCOL_ENTRY("mac" , macAttributes , VIR_NWFILTER_RULE_PROTOCOL_MAC),
|
PROTOCOL_ENTRY("mac" , macAttributes , VIR_NWFILTER_RULE_PROTOCOL_MAC),
|
||||||
PROTOCOL_ENTRY("vlan" , vlanAttributes , VIR_NWFILTER_RULE_PROTOCOL_VLAN),
|
PROTOCOL_ENTRY("vlan" , vlanAttributes , VIR_NWFILTER_RULE_PROTOCOL_VLAN),
|
||||||
|
PROTOCOL_ENTRY("stp" , stpAttributes , VIR_NWFILTER_RULE_PROTOCOL_STP),
|
||||||
PROTOCOL_ENTRY("ip" , ipAttributes , VIR_NWFILTER_RULE_PROTOCOL_IP),
|
PROTOCOL_ENTRY("ip" , ipAttributes , VIR_NWFILTER_RULE_PROTOCOL_IP),
|
||||||
PROTOCOL_ENTRY("ipv6" , ipv6Attributes , VIR_NWFILTER_RULE_PROTOCOL_IPV6),
|
PROTOCOL_ENTRY("ipv6" , ipv6Attributes , VIR_NWFILTER_RULE_PROTOCOL_IPV6),
|
||||||
PROTOCOL_ENTRY("tcp" , tcpAttributes , VIR_NWFILTER_RULE_PROTOCOL_TCP),
|
PROTOCOL_ENTRY("tcp" , tcpAttributes , VIR_NWFILTER_RULE_PROTOCOL_TCP),
|
||||||
@ -1628,6 +1763,18 @@ virNWFilterRuleDetailsParse(xmlNodePtr node,
|
|||||||
rc = -1;
|
rc = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_UINT32_HEX:
|
||||||
|
base = 16;
|
||||||
|
/* fallthrough */
|
||||||
|
case DATATYPE_UINT32:
|
||||||
|
if (virStrToLong_ui(prop, NULL, base, &uint_val) >= 0) {
|
||||||
|
item->u.u32 = uint_val;
|
||||||
|
found = 1;
|
||||||
|
data.ui = uint_val;
|
||||||
|
} else
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case DATATYPE_IPADDR:
|
case DATATYPE_IPADDR:
|
||||||
if (virSocketAddrParseIPv4(&item->u.ipaddr, prop) < 0)
|
if (virSocketAddrParseIPv4(&item->u.ipaddr, prop) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
@ -1839,6 +1986,31 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
|
|||||||
rule->p.vlanHdrFilter.ethHdr.dataDstMACAddr);
|
rule->p.vlanHdrFilter.ethHdr.dataDstMACAddr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_NWFILTER_RULE_PROTOCOL_STP:
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.ethHdr.dataSrcMACMask,
|
||||||
|
rule->p.stpHdrFilter.ethHdr.dataSrcMACAddr);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataRootPriHi,
|
||||||
|
rule->p.stpHdrFilter.dataRootPri);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataRootAddrMask,
|
||||||
|
rule->p.stpHdrFilter.dataRootAddr);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataRootCostHi,
|
||||||
|
rule->p.stpHdrFilter.dataRootCost);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataSndrPrioHi,
|
||||||
|
rule->p.stpHdrFilter.dataSndrPrio);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataSndrAddrMask,
|
||||||
|
rule->p.stpHdrFilter.dataSndrAddr);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataPortHi,
|
||||||
|
rule->p.stpHdrFilter.dataPort);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataAgeHi,
|
||||||
|
rule->p.stpHdrFilter.dataAge);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataMaxAgeHi,
|
||||||
|
rule->p.stpHdrFilter.dataMaxAge);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataHelloTimeHi,
|
||||||
|
rule->p.stpHdrFilter.dataHelloTime);
|
||||||
|
COPY_NEG_SIGN(rule->p.stpHdrFilter.dataFwdDelayHi,
|
||||||
|
rule->p.stpHdrFilter.dataFwdDelay);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_IP:
|
case VIR_NWFILTER_RULE_PROTOCOL_IP:
|
||||||
COPY_NEG_SIGN(rule->p.ipHdrFilter.ipHdr.dataSrcIPMask,
|
COPY_NEG_SIGN(rule->p.ipHdrFilter.ipHdr.dataSrcIPMask,
|
||||||
rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr);
|
rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr);
|
||||||
@ -2921,6 +3093,14 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf,
|
|||||||
item->u.u16);
|
item->u.u16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_UINT32_HEX:
|
||||||
|
asHex = true;
|
||||||
|
/* fallthrough */
|
||||||
|
case DATATYPE_UINT32:
|
||||||
|
virBufferAsprintf(buf, asHex ? "0x%x" : "%u",
|
||||||
|
item->u.u32);
|
||||||
|
break;
|
||||||
|
|
||||||
case DATATYPE_IPADDR:
|
case DATATYPE_IPADDR:
|
||||||
case DATATYPE_IPV6ADDR:
|
case DATATYPE_IPV6ADDR:
|
||||||
virNWIPAddressFormat(buf,
|
virNWIPAddressFormat(buf,
|
||||||
|
@ -101,10 +101,14 @@ enum attrDatatype {
|
|||||||
DATATYPE_IPV6MASK = (1 << 10),
|
DATATYPE_IPV6MASK = (1 << 10),
|
||||||
DATATYPE_STRINGCOPY = (1 << 11),
|
DATATYPE_STRINGCOPY = (1 << 11),
|
||||||
DATATYPE_BOOLEAN = (1 << 12),
|
DATATYPE_BOOLEAN = (1 << 12),
|
||||||
|
DATATYPE_UINT32 = (1 << 13),
|
||||||
|
DATATYPE_UINT32_HEX = (1 << 14),
|
||||||
|
|
||||||
DATATYPE_LAST = (1 << 13),
|
DATATYPE_LAST = (1 << 15),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# define NWFILTER_MAC_BGA "01:80:c2:00:00:00"
|
||||||
|
|
||||||
|
|
||||||
typedef struct _nwMACAddress nwMACAddress;
|
typedef struct _nwMACAddress nwMACAddress;
|
||||||
typedef nwMACAddress *nwMACAddressPtr;
|
typedef nwMACAddress *nwMACAddressPtr;
|
||||||
@ -125,6 +129,7 @@ struct _nwItemDesc {
|
|||||||
bool boolean;
|
bool boolean;
|
||||||
uint8_t u8;
|
uint8_t u8;
|
||||||
uint16_t u16;
|
uint16_t u16;
|
||||||
|
uint32_t u32;
|
||||||
char protocolID[10];
|
char protocolID[10];
|
||||||
char *string;
|
char *string;
|
||||||
struct {
|
struct {
|
||||||
@ -164,6 +169,36 @@ struct _vlanHdrFilterDef {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _stpHdrFilterDef stpHdrFilterDef;
|
||||||
|
typedef stpHdrFilterDef *stpHdrFilterDefPtr;
|
||||||
|
struct _stpHdrFilterDef {
|
||||||
|
ethHdrDataDef ethHdr;
|
||||||
|
nwItemDesc dataType;
|
||||||
|
nwItemDesc dataFlags;
|
||||||
|
nwItemDesc dataRootPri;
|
||||||
|
nwItemDesc dataRootPriHi;
|
||||||
|
nwItemDesc dataRootAddr;
|
||||||
|
nwItemDesc dataRootAddrMask;
|
||||||
|
nwItemDesc dataRootCost;
|
||||||
|
nwItemDesc dataRootCostHi;
|
||||||
|
nwItemDesc dataSndrPrio;
|
||||||
|
nwItemDesc dataSndrPrioHi;
|
||||||
|
nwItemDesc dataSndrAddr;
|
||||||
|
nwItemDesc dataSndrAddrMask;
|
||||||
|
nwItemDesc dataPort;
|
||||||
|
nwItemDesc dataPortHi;
|
||||||
|
nwItemDesc dataAge;
|
||||||
|
nwItemDesc dataAgeHi;
|
||||||
|
nwItemDesc dataMaxAge;
|
||||||
|
nwItemDesc dataMaxAgeHi;
|
||||||
|
nwItemDesc dataHelloTime;
|
||||||
|
nwItemDesc dataHelloTimeHi;
|
||||||
|
nwItemDesc dataFwdDelay;
|
||||||
|
nwItemDesc dataFwdDelayHi;
|
||||||
|
nwItemDesc dataComment;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct _arpHdrFilterDef arpHdrFilterDef;
|
typedef struct _arpHdrFilterDef arpHdrFilterDef;
|
||||||
typedef arpHdrFilterDef *arpHdrFilterDefPtr;
|
typedef arpHdrFilterDef *arpHdrFilterDefPtr;
|
||||||
struct _arpHdrFilterDef {
|
struct _arpHdrFilterDef {
|
||||||
@ -337,6 +372,7 @@ enum virNWFilterRuleProtocolType {
|
|||||||
VIR_NWFILTER_RULE_PROTOCOL_NONE = 0,
|
VIR_NWFILTER_RULE_PROTOCOL_NONE = 0,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_MAC,
|
VIR_NWFILTER_RULE_PROTOCOL_MAC,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_VLAN,
|
VIR_NWFILTER_RULE_PROTOCOL_VLAN,
|
||||||
|
VIR_NWFILTER_RULE_PROTOCOL_STP,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_ARP,
|
VIR_NWFILTER_RULE_PROTOCOL_ARP,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_RARP,
|
VIR_NWFILTER_RULE_PROTOCOL_RARP,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_IP,
|
VIR_NWFILTER_RULE_PROTOCOL_IP,
|
||||||
@ -378,6 +414,7 @@ enum virNWFilterEbtablesTableType {
|
|||||||
# define NWFILTER_MAX_FILTER_PRIORITY MAX_RULE_PRIORITY
|
# define NWFILTER_MAX_FILTER_PRIORITY MAX_RULE_PRIORITY
|
||||||
|
|
||||||
# define NWFILTER_ROOT_FILTER_PRI 0
|
# define NWFILTER_ROOT_FILTER_PRI 0
|
||||||
|
# define NWFILTER_STP_FILTER_PRI -810
|
||||||
# define NWFILTER_MAC_FILTER_PRI -800
|
# define NWFILTER_MAC_FILTER_PRI -800
|
||||||
# define NWFILTER_VLAN_FILTER_PRI -750
|
# define NWFILTER_VLAN_FILTER_PRI -750
|
||||||
# define NWFILTER_IPV4_FILTER_PRI -700
|
# define NWFILTER_IPV4_FILTER_PRI -700
|
||||||
@ -418,6 +455,7 @@ struct _virNWFilterRuleDef {
|
|||||||
union {
|
union {
|
||||||
ethHdrFilterDef ethHdrFilter;
|
ethHdrFilterDef ethHdrFilter;
|
||||||
vlanHdrFilterDef vlanHdrFilter;
|
vlanHdrFilterDef vlanHdrFilter;
|
||||||
|
stpHdrFilterDef stpHdrFilter;
|
||||||
arpHdrFilterDef arpHdrFilter; /* also used for rarp */
|
arpHdrFilterDef arpHdrFilter; /* also used for rarp */
|
||||||
ipHdrFilterDef ipHdrFilter;
|
ipHdrFilterDef ipHdrFilter;
|
||||||
ipv6HdrFilterDef ipv6HdrFilter;
|
ipv6HdrFilterDef ipv6HdrFilter;
|
||||||
@ -459,6 +497,7 @@ enum virNWFilterChainSuffixType {
|
|||||||
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
|
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_MAC,
|
VIR_NWFILTER_CHAINSUFFIX_MAC,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_VLAN,
|
VIR_NWFILTER_CHAINSUFFIX_VLAN,
|
||||||
|
VIR_NWFILTER_CHAINSUFFIX_STP,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_ARP,
|
VIR_NWFILTER_CHAINSUFFIX_ARP,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_RARP,
|
VIR_NWFILTER_CHAINSUFFIX_RARP,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_IPv4,
|
VIR_NWFILTER_CHAINSUFFIX_IPv4,
|
||||||
|
@ -830,6 +830,7 @@ virNWFilterPrintStateMatchFlags;
|
|||||||
virNWFilterPrintTCPFlags;
|
virNWFilterPrintTCPFlags;
|
||||||
virNWFilterRegisterCallbackDriver;
|
virNWFilterRegisterCallbackDriver;
|
||||||
virNWFilterRuleActionTypeToString;
|
virNWFilterRuleActionTypeToString;
|
||||||
|
virNWFilterRuleDirectionTypeToString;
|
||||||
virNWFilterRuleProtocolTypeToString;
|
virNWFilterRuleProtocolTypeToString;
|
||||||
virNWFilterTestUnassignDef;
|
virNWFilterTestUnassignDef;
|
||||||
virNWFilterUnlockFilterUpdates;
|
virNWFilterUnlockFilterUpdates;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "configmake.h"
|
#include "configmake.h"
|
||||||
|
#include "intprops.h"
|
||||||
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
||||||
@ -190,6 +191,7 @@ enum l3_proto_idx {
|
|||||||
L3_PROTO_RARP_IDX,
|
L3_PROTO_RARP_IDX,
|
||||||
L2_PROTO_MAC_IDX,
|
L2_PROTO_MAC_IDX,
|
||||||
L2_PROTO_VLAN_IDX,
|
L2_PROTO_VLAN_IDX,
|
||||||
|
L2_PROTO_STP_IDX,
|
||||||
L3_PROTO_LAST_IDX
|
L3_PROTO_LAST_IDX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -206,6 +208,7 @@ static const struct ushort_map l3_protocols[] = {
|
|||||||
USHORTMAP_ENTRY_IDX(L3_PROTO_ARP_IDX , ETHERTYPE_ARP , "arp"),
|
USHORTMAP_ENTRY_IDX(L3_PROTO_ARP_IDX , ETHERTYPE_ARP , "arp"),
|
||||||
USHORTMAP_ENTRY_IDX(L3_PROTO_RARP_IDX, ETHERTYPE_REVARP, "rarp"),
|
USHORTMAP_ENTRY_IDX(L3_PROTO_RARP_IDX, ETHERTYPE_REVARP, "rarp"),
|
||||||
USHORTMAP_ENTRY_IDX(L2_PROTO_VLAN_IDX, ETHERTYPE_VLAN , "vlan"),
|
USHORTMAP_ENTRY_IDX(L2_PROTO_VLAN_IDX, ETHERTYPE_VLAN , "vlan"),
|
||||||
|
USHORTMAP_ENTRY_IDX(L2_PROTO_STP_IDX, 0 , "stp"),
|
||||||
USHORTMAP_ENTRY_IDX(L2_PROTO_MAC_IDX, 0 , "mac"),
|
USHORTMAP_ENTRY_IDX(L2_PROTO_MAC_IDX, 0 , "mac"),
|
||||||
USHORTMAP_ENTRY_IDX(L3_PROTO_LAST_IDX, 0 , NULL),
|
USHORTMAP_ENTRY_IDX(L3_PROTO_LAST_IDX, 0 , NULL),
|
||||||
};
|
};
|
||||||
@ -306,6 +309,16 @@ _printDataType(virNWFilterVarCombIterPtr vars,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_UINT32:
|
||||||
|
case DATATYPE_UINT32_HEX:
|
||||||
|
if (snprintf(buf, bufsize, asHex ? "0x%x" : "%u",
|
||||||
|
item->u.u32) >= bufsize) {
|
||||||
|
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Buffer too small for uint32 type"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DATATYPE_UINT16:
|
case DATATYPE_UINT16:
|
||||||
case DATATYPE_UINT16_HEX:
|
case DATATYPE_UINT16_HEX:
|
||||||
if (snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
|
if (snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
|
||||||
@ -937,7 +950,8 @@ iptablesHandleIpHdr(virBufferPtr buf,
|
|||||||
virBufferPtr prefix)
|
virBufferPtr prefix)
|
||||||
{
|
{
|
||||||
char ipaddr[INET6_ADDRSTRLEN],
|
char ipaddr[INET6_ADDRSTRLEN],
|
||||||
number[20];
|
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
|
||||||
|
INT_BUFSIZE_BOUND(int))];
|
||||||
const char *src = "--source";
|
const char *src = "--source";
|
||||||
const char *dst = "--destination";
|
const char *dst = "--destination";
|
||||||
const char *srcrange = "--src-range";
|
const char *srcrange = "--src-range";
|
||||||
@ -1218,7 +1232,8 @@ _iptablesCreateRuleInstance(int directionIn,
|
|||||||
bool maySkipICMP)
|
bool maySkipICMP)
|
||||||
{
|
{
|
||||||
char chain[MAX_CHAINNAME_LENGTH];
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
char number[20];
|
char number[MAX(INT_BUFSIZE_BOUND(uint32_t),
|
||||||
|
INT_BUFSIZE_BOUND(int))];
|
||||||
virBuffer prefix = VIR_BUFFER_INITIALIZER;
|
virBuffer prefix = VIR_BUFFER_INITIALIZER;
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
virBuffer afterStateMatch = VIR_BUFFER_INITIALIZER;
|
virBuffer afterStateMatch = VIR_BUFFER_INITIALIZER;
|
||||||
@ -1953,7 +1968,9 @@ ebtablesCreateRuleInstance(char chainPrefix,
|
|||||||
char macaddr[VIR_MAC_STRING_BUFLEN],
|
char macaddr[VIR_MAC_STRING_BUFLEN],
|
||||||
ipaddr[INET_ADDRSTRLEN],
|
ipaddr[INET_ADDRSTRLEN],
|
||||||
ipv6addr[INET6_ADDRSTRLEN],
|
ipv6addr[INET6_ADDRSTRLEN],
|
||||||
number[20];
|
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
|
||||||
|
INT_BUFSIZE_BOUND(int))],
|
||||||
|
field[MAX(VIR_MAC_STRING_BUFLEN, INET6_ADDRSTRLEN)];
|
||||||
char chain[MAX_CHAINNAME_LENGTH];
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
const char *target;
|
const char *target;
|
||||||
@ -2019,19 +2036,91 @@ ebtablesCreateRuleInstance(char chainPrefix,
|
|||||||
#define INST_ITEM(STRUCT, ITEM, CLI) \
|
#define INST_ITEM(STRUCT, ITEM, CLI) \
|
||||||
if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
|
if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
|
||||||
if (printDataType(vars, \
|
if (printDataType(vars, \
|
||||||
number, sizeof(number), \
|
field, sizeof(field), \
|
||||||
&rule->p.STRUCT.ITEM)) \
|
&rule->p.STRUCT.ITEM)) \
|
||||||
goto err_exit; \
|
goto err_exit; \
|
||||||
virBufferAsprintf(&buf, \
|
virBufferAsprintf(&buf, \
|
||||||
" " CLI " %s %s", \
|
" " CLI " %s %s", \
|
||||||
ENTRY_GET_NEG_SIGN(&rule->p.STRUCT.ITEM), \
|
ENTRY_GET_NEG_SIGN(&rule->p.STRUCT.ITEM), \
|
||||||
number); \
|
field); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INST_ITEM_2PARMS(STRUCT, ITEM, ITEM_HI, CLI, SEP) \
|
||||||
|
if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
|
||||||
|
if (printDataType(vars, \
|
||||||
|
field, sizeof(field), \
|
||||||
|
&rule->p.STRUCT.ITEM)) \
|
||||||
|
goto err_exit; \
|
||||||
|
virBufferAsprintf(&buf, \
|
||||||
|
" " CLI " %s %s", \
|
||||||
|
ENTRY_GET_NEG_SIGN(&rule->p.STRUCT.ITEM), \
|
||||||
|
field); \
|
||||||
|
if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM_HI)) { \
|
||||||
|
if (printDataType(vars, \
|
||||||
|
field, sizeof(field), \
|
||||||
|
&rule->p.STRUCT.ITEM_HI)) \
|
||||||
|
goto err_exit; \
|
||||||
|
virBufferAsprintf(&buf, SEP "%s", field); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define INST_ITEM_RANGE(S, I, I_HI, C) \
|
||||||
|
INST_ITEM_2PARMS(S, I, I_HI, C, ":")
|
||||||
|
#define INST_ITEM_MASK(S, I, MASK, C) \
|
||||||
|
INST_ITEM_2PARMS(S, I, MASK, C, "/")
|
||||||
|
|
||||||
INST_ITEM(vlanHdrFilter, dataVlanID, "--vlan-id")
|
INST_ITEM(vlanHdrFilter, dataVlanID, "--vlan-id")
|
||||||
INST_ITEM(vlanHdrFilter, dataVlanEncap, "--vlan-encap")
|
INST_ITEM(vlanHdrFilter, dataVlanEncap, "--vlan-encap")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_NWFILTER_RULE_PROTOCOL_STP:
|
||||||
|
|
||||||
|
/* cannot handle inout direction with srcmask set in reverse dir.
|
||||||
|
since this clashes with -d below... */
|
||||||
|
if (reverse &&
|
||||||
|
HAS_ENTRY_ITEM(&rule->p.stpHdrFilter.ethHdr.dataSrcMACAddr)) {
|
||||||
|
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("STP filtering in %s direction with "
|
||||||
|
"source MAC address set is not supported"),
|
||||||
|
virNWFilterRuleDirectionTypeToString(
|
||||||
|
VIR_NWFILTER_RULE_DIRECTION_INOUT));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAsprintf(&buf,
|
||||||
|
CMD_DEF_PRE "%s -t %s -%%c %s %%s",
|
||||||
|
ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
|
||||||
|
|
||||||
|
|
||||||
|
if (ebtablesHandleEthHdr(&buf,
|
||||||
|
vars,
|
||||||
|
&rule->p.stpHdrFilter.ethHdr,
|
||||||
|
reverse))
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
virBufferAddLit(&buf, " -d " NWFILTER_MAC_BGA);
|
||||||
|
|
||||||
|
INST_ITEM(stpHdrFilter, dataType, "--stp-type")
|
||||||
|
INST_ITEM(stpHdrFilter, dataFlags, "--stp-flags")
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataRootPri, dataRootPriHi,
|
||||||
|
"--stp-root-pri");
|
||||||
|
INST_ITEM_MASK( stpHdrFilter, dataRootAddr, dataRootAddrMask,
|
||||||
|
"--stp-root-addr");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataRootCost, dataRootCostHi,
|
||||||
|
"--stp-root-cost");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataSndrPrio, dataSndrPrioHi,
|
||||||
|
"--stp-sender-prio");
|
||||||
|
INST_ITEM_MASK( stpHdrFilter, dataSndrAddr, dataSndrAddrMask,
|
||||||
|
"--stp-sender-addr");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataPort, dataPortHi, "--stp-port");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataAge, dataAgeHi, "--stp-msg-age");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataMaxAge, dataMaxAgeHi,
|
||||||
|
"--stp-max-age");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataHelloTime, dataHelloTimeHi,
|
||||||
|
"--stp-hello-time");
|
||||||
|
INST_ITEM_RANGE(stpHdrFilter, dataFwdDelay, dataFwdDelayHi,
|
||||||
|
"--stp-forward-delay");
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
|
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
|
||||||
|
|
||||||
@ -2480,6 +2569,7 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
case VIR_NWFILTER_RULE_PROTOCOL_IP:
|
case VIR_NWFILTER_RULE_PROTOCOL_IP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
|
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_VLAN:
|
case VIR_NWFILTER_RULE_PROTOCOL_VLAN:
|
||||||
|
case VIR_NWFILTER_RULE_PROTOCOL_STP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
|
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||||
@ -2818,6 +2908,9 @@ ebtablesCreateTmpSubChain(ebiptablesRuleInstPtr *inst,
|
|||||||
case L2_PROTO_MAC_IDX:
|
case L2_PROTO_MAC_IDX:
|
||||||
protostr = strdup("");
|
protostr = strdup("");
|
||||||
break;
|
break;
|
||||||
|
case L2_PROTO_STP_IDX:
|
||||||
|
virAsprintf(&protostr, "-d " NWFILTER_MAC_BGA " ");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
virAsprintf(&protostr, "-p 0x%04x ", l3_protocols[protoidx].attr);
|
virAsprintf(&protostr, "-p 0x%04x ", l3_protocols[protoidx].attr);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user