diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index 073b852abc..4a60e2ea9a 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -1196,6 +1196,26 @@ UINT16 End of range of valid destination ports; requires protocol + + type(Since 1.2.12) + UINT8 + ICMPv6 type; requires protocol to be set to icmpv6 + + + typeend(Since 1.2.12) + UINT8 + ICMPv6 type end of range; requires protocol to be set to icmpv6 + + + code(Since 1.2.12) + UINT8 + ICMPv6 code; requires protocol to be set to icmpv6 + + + code(Since 1.2.12) + UINT8 + ICMPv6 code end of range; requires protocol to be set to icmpv6 + comment (Since 0.8.5) STRING diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng index 2b54fd54a0..9df39c0a64 100644 --- a/docs/schemas/nwfilter.rng +++ b/docs/schemas/nwfilter.rng @@ -90,6 +90,7 @@ + @@ -588,6 +589,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 317792eb50..aed82ad288 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -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; diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index f81df60dc3..6e68ecc857 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -265,6 +265,10 @@ struct _ipv6HdrFilterDef { ethHdrDataDef ethHdr; ipHdrDataDef ipHdr; portDataDef portData; + nwItemDesc dataICMPTypeStart; + nwItemDesc dataICMPTypeEnd; + nwItemDesc dataICMPCodeStart; + nwItemDesc dataICMPCodeEnd; }; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 377b59bcaa..423d069e1b 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -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; } diff --git a/tests/nwfilterxml2firewalldata/ipv6-linux.args b/tests/nwfilterxml2firewalldata/ipv6-linux.args index a42566ca70..735f663716 100644 --- a/tests/nwfilterxml2firewalldata/ipv6-linux.args +++ b/tests/nwfilterxml2firewalldata/ipv6-linux.args @@ -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 diff --git a/tests/nwfilterxml2firewalldata/ipv6.xml b/tests/nwfilterxml2firewalldata/ipv6.xml index 9f67bea737..2400958030 100644 --- a/tests/nwfilterxml2firewalldata/ipv6.xml +++ b/tests/nwfilterxml2firewalldata/ipv6.xml @@ -40,4 +40,42 @@ /> + + + + + + + + + + + + + + + + diff --git a/tests/nwfilterxml2xmlin/ipv6-test.xml b/tests/nwfilterxml2xmlin/ipv6-test.xml index 556796fa01..2daa3b96dd 100644 --- a/tests/nwfilterxml2xmlin/ipv6-test.xml +++ b/tests/nwfilterxml2xmlin/ipv6-test.xml @@ -40,4 +40,42 @@ /> + + + + + + + + + + + + + + + + diff --git a/tests/nwfilterxml2xmlout/ipv6-test.xml b/tests/nwfilterxml2xmlout/ipv6-test.xml index fcc5c0da26..ce9dd06233 100644 --- a/tests/nwfilterxml2xmlout/ipv6-test.xml +++ b/tests/nwfilterxml2xmlout/ipv6-test.xml @@ -12,4 +12,16 @@ + + + + + + + + + + + +