提交 3a3b3691 编写于 作者: S Stefan Berger

nwfilter: Add support for icmpv6 filtering

Make use of the ebtables functionality to be able to filter certain
parameters of icmpv6 packets. Extend the XML parser for icmpv6 types,
type ranges, codes, and code ranges. Extend the nwfilter documentation,
schema, and test cases.

Being able to filter icmpv6 types and codes helps extending the DHCP
snooper for IPv6 and filtering at least some parameters of IPv6's NDP
(Neighbor Discovery Protocol) packets. However, the filtering will not
be as good as the filtering of ARP packets since we cannot
check on IP addresses in the payload of the NDP packets.
Signed-off-by: NStefan Berger <stefanb@linux.vnet.ibm.com>
上级 b0731790
......@@ -1196,6 +1196,26 @@
<td>UINT16</td>
<td>End of range of valid destination ports; requires <code>protocol</code></td>
</tr>
<tr>
<td>type<span class="since">(Since 1.2.12)</span></td>
<td>UINT8</td>
<td>ICMPv6 type; requires <code>protocol</code> to be set to <code>icmpv6</code></td>
</tr>
<tr>
<td>typeend<span class="since">(Since 1.2.12)</span></td>
<td>UINT8</td>
<td>ICMPv6 type end of range; requires <code>protocol</code> to be set to <code>icmpv6</code></td>
</tr>
<tr>
<td>code<span class="since">(Since 1.2.12)</span></td>
<td>UINT8</td>
<td>ICMPv6 code; requires <code>protocol</code> to be set to <code>icmpv6</code></td>
</tr>
<tr>
<td>code<span class="since">(Since 1.2.12)</span></td>
<td>UINT8</td>
<td>ICMPv6 code end of range; requires <code>protocol</code> to be set to <code>icmpv6</code></td>
</tr>
<tr>
<td>comment <span class="since">(Since 0.8.5)</span></td>
<td>STRING</td>
......
......@@ -90,6 +90,7 @@
<ref name="common-ipv6-attributes-p1"/>
<ref name="common-port-attributes"/>
<ref name="ip-attributes"/>
<ref name="icmp-attribute-ranges"/>
<ref name="comment-attribute"/>
</element>
</zeroOrMore>
......@@ -588,6 +589,31 @@
</interleave>
</define>
<define name="icmp-attribute-ranges">
<interleave>
<optional>
<attribute name="type">
<ref name="uint8range"/>
</attribute>
</optional>
<optional>
<attribute name="typeend">
<ref name="uint8range"/>
</attribute>
</optional>
<optional>
<attribute name="code">
<ref name="uint8range"/>
</attribute>
</optional>
<optional>
<attribute name="codeend">
<ref name="uint8range"/>
</attribute>
</optional>
</interleave>
</define>
<define name="mac-attributes">
<interleave>
<optional>
......
......@@ -1445,6 +1445,26 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
.datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataDstPortEnd),
},
{
.name = "type",
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.dataICMPTypeStart),
},
{
.name = "typeend",
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.dataICMPTypeEnd),
},
{
.name = "code",
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.dataICMPCodeStart),
},
{
.name = "codeend",
.datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.dataICMPCodeEnd),
},
COMMENT_PROP_IPHDR(ipv6HdrFilter),
{
.name = NULL,
......@@ -2219,6 +2239,12 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask,
rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.dataICMPTypeEnd,
rule->p.ipv6HdrFilter.dataICMPTypeStart);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.dataICMPCodeStart,
rule->p.ipv6HdrFilter.dataICMPTypeStart);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.dataICMPCodeEnd,
rule->p.ipv6HdrFilter.dataICMPTypeStart);
virNWFilterRuleDefFixupIPSet(&rule->p.ipv6HdrFilter.ipHdr);
break;
......
......@@ -265,6 +265,10 @@ struct _ipv6HdrFilterDef {
ethHdrDataDef ethHdr;
ipHdrDataDef ipHdr;
portDataDef portData;
nwItemDesc dataICMPTypeStart;
nwItemDesc dataICMPTypeEnd;
nwItemDesc dataICMPCodeStart;
nwItemDesc dataICMPCodeEnd;
};
......
......@@ -1826,6 +1826,7 @@ ebtablesCreateRuleInstance(virFirewallPtr fw,
bool hasMask = false;
virFirewallRulePtr fwrule;
int ret = -1;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (STREQ(chainSuffix,
virNWFilterChainSuffixTypeToString(
......@@ -2342,6 +2343,83 @@ ebtablesCreateRuleInstance(virFirewallPtr fw,
virFirewallRuleAddArg(fw, fwrule, number);
}
}
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPTypeStart) ||
HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPTypeEnd) ||
HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPCodeStart) ||
HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPCodeEnd)) {
bool lo = false;
char *r;
virFirewallRuleAddArg(fw, fwrule,
"--ip6-icmp-type");
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPTypeStart)) {
if (printDataType(vars,
number, sizeof(number),
&rule->p.ipv6HdrFilter.dataICMPTypeStart) < 0)
goto cleanup;
lo = true;
} else {
ignore_value(virStrcpyStatic(number, "0"));
}
virBufferStrcat(&buf, number, ":", NULL);
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPTypeEnd)) {
if (printDataType(vars,
numberalt, sizeof(numberalt),
&rule->p.ipv6HdrFilter.dataICMPTypeEnd) < 0)
goto cleanup;
} else {
if (lo)
ignore_value(virStrcpyStatic(numberalt, number));
else
ignore_value(virStrcpyStatic(numberalt, "255"));
}
virBufferStrcat(&buf, numberalt, "/", NULL);
lo = false;
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPCodeStart)) {
if (printDataType(vars,
number, sizeof(number),
&rule->p.ipv6HdrFilter.dataICMPCodeStart) < 0)
goto cleanup;
lo = true;
} else {
ignore_value(virStrcpyStatic(number, "0"));
}
virBufferStrcat(&buf, number, ":", NULL);
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPCodeEnd)) {
if (printDataType(vars,
numberalt, sizeof(numberalt),
&rule->p.ipv6HdrFilter.dataICMPCodeEnd) < 0)
goto cleanup;
} else {
if (lo)
ignore_value(virStrcpyStatic(numberalt, number));
else
ignore_value(virStrcpyStatic(numberalt, "255"));
}
virBufferStrcat(&buf, numberalt, NULL);
if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.dataICMPTypeStart))
virFirewallRuleAddArg(fw, fwrule, "!");
if (virBufferCheckError(&buf) < 0)
goto cleanup;
r = virBufferContentAndReset(&buf);
virFirewallRuleAddArg(fw, fwrule, r);
VIR_FREE(r);
}
break;
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
......@@ -2376,6 +2454,8 @@ ebtablesCreateRuleInstance(virFirewallPtr fw,
ret = 0;
cleanup:
virBufferFreeAndReset(&buf);
return ret;
}
......
......@@ -18,3 +18,19 @@ ebtables -t nat -A libvirt-J-vnet0 -p ipv6 --ip6-destination 1::2/128 \
--ip6-source a:b:c::/65 --ip6-protocol 18 -j ACCEPT
ebtables -t nat -A libvirt-P-vnet0 -p ipv6 --ip6-source 1::2/128 \
--ip6-destination a:b:c::/65 --ip6-protocol 18 -j ACCEPT
ebtables -t nat -A libvirt-J-vnet0 -p ipv6 --ip6-destination 1::2/128 \
--ip6-source a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:11/10:11 -j ACCEPT
ebtables -t nat -A libvirt-P-vnet0 -p ipv6 --ip6-source 1::2/128 \
--ip6-destination a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:11/10:11 -j ACCEPT
ebtables -t nat -A libvirt-J-vnet0 -p ipv6 --ip6-destination 1::2/128 \
--ip6-source a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:1/10:10 -j ACCEPT
ebtables -t nat -A libvirt-P-vnet0 -p ipv6 --ip6-source 1::2/128 \
--ip6-destination a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:1/10:10 -j ACCEPT
ebtables -t nat -A libvirt-J-vnet0 -p ipv6 --ip6-destination 1::2/128 \
--ip6-source a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 0:255/10:10 -j ACCEPT
ebtables -t nat -A libvirt-P-vnet0 -p ipv6 --ip6-source 1::2/128 \
--ip6-destination a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 0:255/10:10 -j ACCEPT
ebtables -t nat -A libvirt-J-vnet0 -p ipv6 --ip6-destination 1::2/128 \
--ip6-source a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:1/0:255 -j ACCEPT
ebtables -t nat -A libvirt-P-vnet0 -p ipv6 --ip6-source 1::2/128 \
--ip6-destination a:b:c::/65 --ip6-protocol 58 --ip6-icmp-type 1:1/0:255 -j ACCEPT
......@@ -40,4 +40,42 @@
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1' typeend='11'
code='10' codeend='11'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1'
code='10'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
code='10'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1'
/>
</rule>
</filter>
......@@ -40,4 +40,42 @@
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1' typeend='11'
code='10' codeend='11'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1'
code='10'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
code='10'
/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128'
dstipaddr='a:b:c::'
dstipmask='ffff:ffff:ffff:ffff:8000::'
protocol='icmpv6'
type='1'
/>
</rule>
</filter>
......@@ -12,4 +12,16 @@
<rule action='accept' direction='inout' priority='500'>
<ipv6 srcipaddr='1::2' srcipmask='128' dstipaddr='a:b:c::' dstipmask='65' protocol='18'/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128' dstipaddr='a:b:c::' dstipmask='65' protocol='icmpv6' type='1' typeend='11' code='10' codeend='11'/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128' dstipaddr='a:b:c::' dstipmask='65' protocol='icmpv6' type='1' code='10'/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128' dstipaddr='a:b:c::' dstipmask='65' protocol='icmpv6' code='10'/>
</rule>
<rule action='accept' direction='inout'>
<ipv6 srcipaddr='1::2' srcipmask='128' dstipaddr='a:b:c::' dstipmask='65' protocol='icmpv6' type='1'/>
</rule>
</filter>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册