[libvirt] [PATCH v1 0/2] Add missing protocol filters for IPv4 and add IPv6 support

The first one of the following two patches adds support for filtering of ah, esp and udplite protocols. The 2nd one adds support for filtering of IPv6 traffic. With this now nearly all protocols of IPv4 and IPv6 (except mh) as supported by iptables/ip6tables are reachable via the filtering XML. Some features of those protocols still need support in data structures and XML attributes, though. Another thing that's missing is support for filtering of IPv6's NDP traffic (IPv6 equivalent of ARP) but there's no support for this in ebtables. Regards, Stefan

This patch adds filtering support for the so-far missing protocols 'ah', 'esp' and 'udplite'. Signed-off-by: Stefan Berger <stefanb@us.ibm.com> Index: libvirt-acl/src/conf/nwfilter_conf.c =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.c +++ libvirt-acl/src/conf/nwfilter_conf.c @@ -85,6 +85,9 @@ VIR_ENUM_IMPL(virNWFilterRuleProtocol, V "icmp", "igmp", "udp", + "udplite", + "esp", + "ah", "sctp", "all"); @@ -586,6 +589,17 @@ static const struct int_map ipProtoMap[] } , { .attr = IPPROTO_UDP, .val = "udp", +#ifdef IPPROTO_UDPLITE + } , { + .attr = IPPROTO_UDPLITE, + .val = "udplite", +#endif + } , { + .attr = IPPROTO_ESP, + .val = "esp", + } , { + .attr = IPPROTO_AH, + .val = "ah", } , { .attr = IPPROTO_ICMP, .val = "icmp", @@ -950,6 +964,26 @@ static const virXMLAttr2Struct udpAttrib } }; +static const virXMLAttr2Struct udpliteAttributes[] = { + COMMON_IP_PROPS(udpliteHdrFilter), + { + .name = NULL, + } +}; + +static const virXMLAttr2Struct espAttributes[] = { + COMMON_IP_PROPS(espHdrFilter), + { + .name = NULL, + } +}; + +static const virXMLAttr2Struct ahAttributes[] = { + COMMON_IP_PROPS(ahHdrFilter), + { + .name = NULL, + } +}; static const virXMLAttr2Struct sctpAttributes[] = { COMMON_IP_PROPS(sctpHdrFilter), @@ -1028,6 +1062,18 @@ static const virAttributes virAttr[] = { .att = udpAttributes, .prtclType = VIR_NWFILTER_RULE_PROTOCOL_UDP, }, { + .id = "udplite", + .att = udpliteAttributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_UDPLITE, + }, { + .id = "esp", + .att = espAttributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_ESP, + }, { + .id = "ah", + .att = ahAttributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_AH, + }, { .id = "sctp", .att = sctpAttributes, .prtclType = VIR_NWFILTER_RULE_PROTOCOL_SCTP, @@ -1496,6 +1542,39 @@ virNWFilterRuleDefFixup(virNWFilterRuleD rule->p.udpHdrFilter.portData.dataSrcPortStart); break; + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataSrcIPMask, + rule->p.udpliteHdrFilter.ipHdr.dataSrcIPAddr); + COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPMask, + rule->p.udpliteHdrFilter.ipHdr.dataDstIPAddr); + COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataSrcIPTo, + rule->p.udpliteHdrFilter.ipHdr.dataSrcIPFrom); + COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPTo, + rule->p.udpliteHdrFilter.ipHdr.dataDstIPFrom); + break; + + case VIR_NWFILTER_RULE_PROTOCOL_ESP: + COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataSrcIPMask, + rule->p.espHdrFilter.ipHdr.dataSrcIPAddr); + COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPMask, + rule->p.espHdrFilter.ipHdr.dataDstIPAddr); + COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataSrcIPTo, + rule->p.espHdrFilter.ipHdr.dataSrcIPFrom); + COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPTo, + rule->p.espHdrFilter.ipHdr.dataDstIPFrom); + break; + + case VIR_NWFILTER_RULE_PROTOCOL_AH: + COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataSrcIPMask, + rule->p.ahHdrFilter.ipHdr.dataSrcIPAddr); + COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPMask, + rule->p.ahHdrFilter.ipHdr.dataDstIPAddr); + COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataSrcIPTo, + rule->p.ahHdrFilter.ipHdr.dataSrcIPFrom); + COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPTo, + rule->p.ahHdrFilter.ipHdr.dataDstIPFrom); + break; + case VIR_NWFILTER_RULE_PROTOCOL_SCTP: COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataSrcIPMask, rule->p.sctpHdrFilter.ipHdr.dataSrcIPAddr); Index: libvirt-acl/src/conf/nwfilter_conf.h =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.h +++ libvirt-acl/src/conf/nwfilter_conf.h @@ -241,6 +241,30 @@ struct _sctpHdrFilterDef { }; +typedef struct _espHdrFilterDef espHdrFilterDef; +typedef espHdrFilterDef *espHdrFilterDefPtr; +struct _espHdrFilterDef { + nwItemDesc dataSrcMACAddr; + ipHdrDataDef ipHdr; +}; + + +typedef struct _ahHdrFilterDef ahHdrFilterDef; +typedef ahHdrFilterDef *ahHdrFilterDefPtr; +struct _ahHdrFilterDef { + nwItemDesc dataSrcMACAddr; + ipHdrDataDef ipHdr; +}; + + +typedef struct _udpliteHdrFilterDef udpliteHdrFilterDef; +typedef udpliteHdrFilterDef *udpliteHdrFilterDefPtr; +struct _udpliteHdrFilterDef { + nwItemDesc dataSrcMACAddr; + ipHdrDataDef ipHdr; +}; + + enum virNWFilterRuleActionType { VIR_NWFILTER_RULE_ACTION_DROP = 0, VIR_NWFILTER_RULE_ACTION_ACCEPT, @@ -273,6 +297,9 @@ enum virNWFilterRuleProtocolType { VIR_NWFILTER_RULE_PROTOCOL_ICMP, VIR_NWFILTER_RULE_PROTOCOL_IGMP, VIR_NWFILTER_RULE_PROTOCOL_UDP, + VIR_NWFILTER_RULE_PROTOCOL_UDPLITE, + VIR_NWFILTER_RULE_PROTOCOL_ESP, + VIR_NWFILTER_RULE_PROTOCOL_AH, VIR_NWFILTER_RULE_PROTOCOL_SCTP, VIR_NWFILTER_RULE_PROTOCOL_ALL, @@ -306,6 +333,9 @@ struct _virNWFilterRuleDef { tcpHdrFilterDef tcpHdrFilter; icmpHdrFilterDef icmpHdrFilter; udpHdrFilterDef udpHdrFilter; + udpliteHdrFilterDef udpliteHdrFilter; + espHdrFilterDef espHdrFilter; + ahHdrFilterDef ahHdrFilter; allHdrFilterDef allHdrFilter; igmpHdrFilterDef igmpHdrFilter; sctpHdrFilterDef sctpHdrFilter; Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c +++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c @@ -1089,6 +1089,75 @@ _iptablesCreateRuleInstance(virConnectPt goto err_exit; break; + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + virBufferVSprintf(&buf, + CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + chain); + + virBufferAddLit(&buf, " -p udplite"); + + if (iptablesHandleSrcMacAddr(conn, + &buf, + vars, + &rule->p.udpliteHdrFilter.dataSrcMACAddr, + directionIn)) + goto err_exit; + + if (iptablesHandleIpHdr(conn, + &buf, + vars, + &rule->p.udpliteHdrFilter.ipHdr, + directionIn)) + goto err_exit; + + break; + + case VIR_NWFILTER_RULE_PROTOCOL_ESP: + virBufferVSprintf(&buf, + CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + chain); + + virBufferAddLit(&buf, " -p esp"); + + if (iptablesHandleSrcMacAddr(conn, + &buf, + vars, + &rule->p.espHdrFilter.dataSrcMACAddr, + directionIn)) + goto err_exit; + + if (iptablesHandleIpHdr(conn, + &buf, + vars, + &rule->p.espHdrFilter.ipHdr, + directionIn)) + goto err_exit; + + break; + + case VIR_NWFILTER_RULE_PROTOCOL_AH: + virBufferVSprintf(&buf, + CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + chain); + + virBufferAddLit(&buf, " -p ah"); + + if (iptablesHandleSrcMacAddr(conn, + &buf, + vars, + &rule->p.ahHdrFilter.dataSrcMACAddr, + directionIn)) + goto err_exit; + + if (iptablesHandleIpHdr(conn, + &buf, + vars, + &rule->p.ahHdrFilter.ipHdr, + directionIn)) + goto err_exit; + + break; + case VIR_NWFILTER_RULE_PROTOCOL_SCTP: virBufferVSprintf(&buf, CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", @@ -1836,6 +1905,9 @@ ebiptablesCreateRuleInstance(virConnectP case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_UDP: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + case VIR_NWFILTER_RULE_PROTOCOL_ESP: + case VIR_NWFILTER_RULE_PROTOCOL_AH: case VIR_NWFILTER_RULE_PROTOCOL_SCTP: case VIR_NWFILTER_RULE_PROTOCOL_ICMP: case VIR_NWFILTER_RULE_PROTOCOL_IGMP:

On Fri, Mar 26, 2010 at 04:41:18PM -0400, Stefan Berger wrote:
This patch adds filtering support for the so-far missing protocols 'ah', 'esp' and 'udplite'.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
ACK, looks fine to me, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This patch adds IPv6 filtering support for the following protocols: - tcp-ipv6 - udp-ipv6 - udplite-ipv6 - esp-ipv6 - ah-ipv6 - sctp-ipv6 - all-ipv6 - icmpv6 Many of the IPv4 data structure could be re-used for IPv6 support. Since ip6tables also supports pretty much the same command line parameters as iptables does, also much of the code could be re-used and now command lines are invoked with the ip(6)tables tool parameter passed through the functions as a parameter. Signed-off-by: Stefan Berger <stefanb@us.ibm.com> --- configure.ac | 3 src/conf/nwfilter_conf.c | 165 +++++++++++++++-- src/conf/nwfilter_conf.h | 8 src/nwfilter/nwfilter_ebiptables_driver.c | 287 ++++++++++++++++++++++-------- src/nwfilter/nwfilter_ebiptables_driver.h | 2 5 files changed, 370 insertions(+), 95 deletions(-) Index: libvirt-acl/configure.ac =================================================================== --- libvirt-acl.orig/configure.ac +++ libvirt-acl/configure.ac @@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_P AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary]) +AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary]) Index: libvirt-acl/src/conf/nwfilter_conf.h =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.h +++ libvirt-acl/src/conf/nwfilter_conf.h @@ -302,6 +302,14 @@ enum virNWFilterRuleProtocolType { VIR_NWFILTER_RULE_PROTOCOL_AH, VIR_NWFILTER_RULE_PROTOCOL_SCTP, VIR_NWFILTER_RULE_PROTOCOL_ALL, + VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_ICMPV6, + VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6, + VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6, VIR_NWFILTER_RULE_PROTOCOL_LAST }; Index: libvirt-acl/src/conf/nwfilter_conf.c =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.c +++ libvirt-acl/src/conf/nwfilter_conf.c @@ -89,7 +89,15 @@ VIR_ENUM_IMPL(virNWFilterRuleProtocol, V "esp", "ah", "sctp", - "all"); + "all", + "tcp-ipv6", + "icmpv6", + "udp-ipv6", + "udplite-ipv6", + "esp-ipv6", + "ah-ipv6", + "sctp-ipv6", + "all-ipv6"); /* @@ -872,41 +880,41 @@ static const virXMLAttr2Struct ipv6Attri .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.dataSrcMACAddr),\ } -#define COMMON_IP_PROPS(STRUCT) \ +#define COMMON_IP_PROPS(STRUCT, ADDRTYPE, MASKTYPE) \ COMMON_L3_MAC_PROPS(STRUCT),\ {\ .name = SRCIPADDR,\ - .datatype = DATATYPE_IPADDR,\ + .datatype = ADDRTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPAddr),\ },\ {\ .name = DSTIPADDR,\ - .datatype = DATATYPE_IPADDR,\ + .datatype = ADDRTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPAddr),\ },\ {\ .name = SRCIPMASK,\ - .datatype = DATATYPE_IPMASK,\ + .datatype = MASKTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPMask),\ },\ {\ .name = DSTIPMASK,\ - .datatype = DATATYPE_IPMASK,\ + .datatype = MASKTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPMask),\ },\ {\ .name = SRCIPFROM,\ - .datatype = DATATYPE_IPADDR,\ + .datatype = ADDRTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPFrom),\ },\ {\ .name = SRCIPTO,\ - .datatype = DATATYPE_IPADDR,\ + .datatype = ADDRTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPTo),\ },\ {\ .name = DSTIPFROM,\ - .datatype = DATATYPE_IPADDR,\ + .datatype = ADDRTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPFrom),\ },\ {\ @@ -944,7 +952,7 @@ static const virXMLAttr2Struct ipv6Attri } static const virXMLAttr2Struct tcpAttributes[] = { - COMMON_IP_PROPS(tcpHdrFilter), + COMMON_IP_PROPS(tcpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), COMMON_PORT_PROPS(tcpHdrFilter), { .name = "option", @@ -957,7 +965,7 @@ static const virXMLAttr2Struct tcpAttrib }; static const virXMLAttr2Struct udpAttributes[] = { - COMMON_IP_PROPS(udpHdrFilter), + COMMON_IP_PROPS(udpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), COMMON_PORT_PROPS(udpHdrFilter), { .name = NULL, @@ -965,28 +973,28 @@ static const virXMLAttr2Struct udpAttrib }; static const virXMLAttr2Struct udpliteAttributes[] = { - COMMON_IP_PROPS(udpliteHdrFilter), + COMMON_IP_PROPS(udpliteHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), { .name = NULL, } }; static const virXMLAttr2Struct espAttributes[] = { - COMMON_IP_PROPS(espHdrFilter), + COMMON_IP_PROPS(espHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), { .name = NULL, } }; static const virXMLAttr2Struct ahAttributes[] = { - COMMON_IP_PROPS(ahHdrFilter), + COMMON_IP_PROPS(ahHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), { .name = NULL, } }; static const virXMLAttr2Struct sctpAttributes[] = { - COMMON_IP_PROPS(sctpHdrFilter), + COMMON_IP_PROPS(sctpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), COMMON_PORT_PROPS(sctpHdrFilter), { .name = NULL, @@ -995,7 +1003,7 @@ static const virXMLAttr2Struct sctpAttri static const virXMLAttr2Struct icmpAttributes[] = { - COMMON_IP_PROPS(icmpHdrFilter), + COMMON_IP_PROPS(icmpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), { .name = "type", .datatype = DATATYPE_UINT8, @@ -1013,7 +1021,7 @@ static const virXMLAttr2Struct icmpAttri static const virXMLAttr2Struct allAttributes[] = { - COMMON_IP_PROPS(allHdrFilter), + COMMON_IP_PROPS(allHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), { .name = NULL, } @@ -1021,7 +1029,88 @@ static const virXMLAttr2Struct allAttrib static const virXMLAttr2Struct igmpAttributes[] = { - COMMON_IP_PROPS(igmpHdrFilter), + COMMON_IP_PROPS(igmpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct tcpipv6Attributes[] = { + COMMON_IP_PROPS(tcpHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + COMMON_PORT_PROPS(tcpHdrFilter), + { + .name = "option", + .datatype = DATATYPE_UINT8, + .dataIdx = offsetof(virNWFilterRuleDef, p.tcpHdrFilter.dataTCPOption), + }, + { + .name = NULL, + } +}; + +static const virXMLAttr2Struct udpipv6Attributes[] = { + COMMON_IP_PROPS(udpHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + COMMON_PORT_PROPS(udpHdrFilter), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct udpliteipv6Attributes[] = { + COMMON_IP_PROPS(udpliteHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct espipv6Attributes[] = { + COMMON_IP_PROPS(espHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct ahipv6Attributes[] = { + COMMON_IP_PROPS(ahHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct sctpipv6Attributes[] = { + COMMON_IP_PROPS(sctpHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + COMMON_PORT_PROPS(sctpHdrFilter), + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct icmpv6Attributes[] = { + COMMON_IP_PROPS(icmpHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), + { + .name = "type", + .datatype = DATATYPE_UINT8, + .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPType), + }, + { + .name = "code", + .datatype = DATATYPE_UINT8, + .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPCode), + }, + { + .name = NULL, + } +}; + + +static const virXMLAttr2Struct allipv6Attributes[] = { + COMMON_IP_PROPS(allHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK), { .name = NULL, } @@ -1090,6 +1179,38 @@ static const virAttributes virAttr[] = { .att = igmpAttributes, .prtclType = VIR_NWFILTER_RULE_PROTOCOL_IGMP, }, { + .id = "tcp-ipv6", + .att = tcpipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6, + }, { + .id = "udp-ipv6", + .att = udpipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6, + }, { + .id = "udplite-ipv6", + .att = udpliteipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6, + }, { + .id = "esp-ipv6", + .att = espipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6, + }, { + .id = "ah-ipv6", + .att = ahipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6, + }, { + .id = "sctp-ipv6", + .att = sctpipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6, + }, { + .id = "icmpv6", + .att = icmpv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_ICMPV6, + }, { + .id = "all-ipv6", // = 'any' + .att = allipv6Attributes, + .prtclType = VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6, + }, { .id = NULL, } }; @@ -1509,6 +1630,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_TCP: + case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataSrcIPMask, rule->p.tcpHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataDstIPMask, @@ -1526,6 +1648,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_UDP: + case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6: COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataSrcIPMask, rule->p.udpHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataDstIPMask, @@ -1543,6 +1666,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6: COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataSrcIPMask, rule->p.udpliteHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPMask, @@ -1554,6 +1678,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_ESP: + case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6: COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataSrcIPMask, rule->p.espHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPMask, @@ -1565,6 +1690,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_AH: + case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6: COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataSrcIPMask, rule->p.ahHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPMask, @@ -1576,6 +1702,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_SCTP: + case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6: COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataSrcIPMask, rule->p.sctpHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataDstIPMask, @@ -1593,6 +1720,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_ICMP: + case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6: COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataSrcIPMask, rule->p.icmpHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataDstIPMask, @@ -1606,6 +1734,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD break; case VIR_NWFILTER_RULE_PROTOCOL_ALL: + case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6: COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataSrcIPMask, rule->p.allHdrFilter.ipHdr.dataSrcIPAddr); COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataDstIPMask, Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c +++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c @@ -62,11 +62,12 @@ : "" -#define EBTABLES_CMD EBTABLES_PATH -#define IPTABLES_CMD IPTABLES_PATH -#define BASH_CMD BASH_PATH -#define GREP_CMD GREP_PATH -#define GAWK_CMD GAWK_PATH +#define EBTABLES_CMD EBTABLES_PATH +#define IPTABLES_CMD IPTABLES_PATH +#define IP6TABLES_CMD IP6TABLES_PATH +#define BASH_CMD BASH_PATH +#define GREP_CMD GREP_PATH +#define GAWK_CMD GAWK_PATH #define PRINT_ROOT_CHAIN(buf, prefix, ifname) \ snprintf(buf, sizeof(buf), "libvirt-%c-%s", prefix, ifname) @@ -327,6 +328,7 @@ ebtablesHandleEthHdr(virConnectPtr conn, /************************ iptables support ************************/ static int iptablesLinkIPTablesBaseChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *udchain, const char *syschain, @@ -334,53 +336,58 @@ static int iptablesLinkIPTablesBaseChain int stopOnError) { virBufferVSprintf(buf, - "res=$(" - IPTABLES_CMD " -L %s -n --line-number | " + "res=$(%s -L %s -n --line-number | " GREP_CMD " \" %s \")\n" "if [ $? -ne 0 ]; then\n" - " " IPTABLES_CMD " -I %s %d -j %s\n" + " %s -I %s %d -j %s\n" "else\n" " r=$(echo $res | " GAWK_CMD " '{print $1}')\n" " if [ \"${r}\" != \"%d\" ]; then\n" - " " CMD_DEF(IPTABLES_CMD " -I %s %d -j %s") CMD_SEPARATOR + " " CMD_DEF("%s -I %s %d -j %s") CMD_SEPARATOR " " CMD_EXEC " %s" " let r=r+1\n" - " " CMD_DEF(IPTABLES_CMD " -D %s ${r}") CMD_SEPARATOR + " " CMD_DEF("%s -D %s ${r}") CMD_SEPARATOR " " CMD_EXEC " %s" " fi\n" "fi\n", - syschain, udchain, + iptables_cmd, syschain, + udchain, - syschain, pos, udchain, + iptables_cmd, syschain, pos, udchain, pos, - syschain, pos, udchain, + iptables_cmd, syschain, pos, udchain, CMD_STOPONERR(stopOnError), - syschain, + iptables_cmd, syschain, CMD_STOPONERR(stopOnError)); return 0; } static int iptablesCreateBaseChains(virConnectPtr conn, + const char *iptables_cmd, virBufferPtr buf) { - virBufferAddLit(buf, IPTABLES_CMD " -N " VIRT_IN_CHAIN CMD_SEPARATOR - IPTABLES_CMD " -N " VIRT_OUT_CHAIN CMD_SEPARATOR - IPTABLES_CMD " -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR - IPTABLES_CMD " -N " HOST_IN_CHAIN CMD_SEPARATOR); - iptablesLinkIPTablesBaseChain(conn, buf, + virBufferVSprintf(buf,"%s -N " VIRT_IN_CHAIN CMD_SEPARATOR + "%s -N " VIRT_OUT_CHAIN CMD_SEPARATOR + "%s -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR + "%s -N " HOST_IN_CHAIN CMD_SEPARATOR, + iptables_cmd, + iptables_cmd, + iptables_cmd, + iptables_cmd); + iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf, VIRT_IN_CHAIN , "FORWARD", 1, 1); - iptablesLinkIPTablesBaseChain(conn, buf, + iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf, VIRT_OUT_CHAIN , "FORWARD", 2, 1); - iptablesLinkIPTablesBaseChain(conn, buf, + iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf, VIRT_IN_POST_CHAIN, "FORWARD", 3, 1); - iptablesLinkIPTablesBaseChain(conn, buf, + iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf, HOST_IN_CHAIN , "INPUT" , 1, 1); return 0; @@ -389,6 +396,7 @@ static int iptablesCreateBaseChains(virC static int iptablesCreateTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, char prefix, int incoming, const char *ifname, @@ -404,9 +412,10 @@ iptablesCreateTmpRootChain(virConnectPtr PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferVSprintf(buf, - CMD_DEF(IPTABLES_CMD " -N %s") CMD_SEPARATOR + CMD_DEF("%s -N %s") CMD_SEPARATOR CMD_EXEC "%s", + iptables_cmd, chain, CMD_STOPONERR(stopOnError)); @@ -416,18 +425,20 @@ iptablesCreateTmpRootChain(virConnectPtr static int iptablesCreateTmpRootChains(virConnectPtr conn, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { - iptablesCreateTmpRootChain(conn, buf, 'F', 0, ifname, 1); - iptablesCreateTmpRootChain(conn, buf, 'F', 1, ifname, 1); - iptablesCreateTmpRootChain(conn, buf, 'H', 1, ifname, 1); + iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname, 1); + iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname, 1); + iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname, 1); return 0; } static int _iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, char prefix, int incoming, const char *ifname, @@ -448,10 +459,10 @@ _iptablesRemoveRootChain(virConnectPtr c PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferVSprintf(buf, - IPTABLES_CMD " -F %s" CMD_SEPARATOR - IPTABLES_CMD " -X %s" CMD_SEPARATOR, - chain, - chain); + "%s -F %s" CMD_SEPARATOR + "%s -X %s" CMD_SEPARATOR, + iptables_cmd, chain, + iptables_cmd, chain); return 0; } @@ -459,52 +470,59 @@ _iptablesRemoveRootChain(virConnectPtr c static int iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, char prefix, int incoming, const char *ifname) { - return _iptablesRemoveRootChain(conn, buf, prefix, incoming, ifname, 0); + return _iptablesRemoveRootChain(conn, iptables_cmd, + buf, prefix, incoming, ifname, 0); } static int iptablesRemoveTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, char prefix, int incoming, const char *ifname) { - return _iptablesRemoveRootChain(conn, buf, prefix, incoming, ifname, 1); + return _iptablesRemoveRootChain(conn, iptables_cmd, buf, prefix, + incoming, ifname, 1); } static int iptablesRemoveTmpRootChains(virConnectPtr conn, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { - iptablesRemoveTmpRootChain(conn, buf, 'F', 0, ifname); - iptablesRemoveTmpRootChain(conn, buf, 'F', 1, ifname); - iptablesRemoveTmpRootChain(conn, buf, 'H', 1, ifname); + iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname); + iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname); + iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname); return 0; } static int iptablesRemoveRootChains(virConnectPtr conn, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { - iptablesRemoveRootChain(conn, buf, 'F', 0, ifname); - iptablesRemoveRootChain(conn, buf, 'F', 1, ifname); - iptablesRemoveRootChain(conn, buf, 'H', 1, ifname); + iptablesRemoveRootChain(conn, iptables_cmd, buf, 'F', 0, ifname); + iptablesRemoveRootChain(conn, iptables_cmd, buf, 'F', 1, ifname); + iptablesRemoveRootChain(conn, iptables_cmd, buf, 'H', 1, ifname); return 0; } static int iptablesLinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *basechain, char prefix, @@ -523,10 +541,11 @@ iptablesLinkTmpRootChain(virConnectPtr c PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferVSprintf(buf, - CMD_DEF(IPTABLES_CMD " -A %s " + CMD_DEF("%s -A %s " "%s %s -g %s") CMD_SEPARATOR CMD_EXEC "%s", + iptables_cmd, basechain, match, ifname, chain, @@ -538,12 +557,13 @@ iptablesLinkTmpRootChain(virConnectPtr c static int iptablesLinkTmpRootChains(virConnectPtr conn, + const char *cmd, virBufferPtr buf, const char *ifname) { - iptablesLinkTmpRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1); - iptablesLinkTmpRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1); - iptablesLinkTmpRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname, 1); + iptablesLinkTmpRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1); + iptablesLinkTmpRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1); + iptablesLinkTmpRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname, 1); return 0; } @@ -551,21 +571,24 @@ iptablesLinkTmpRootChains(virConnectPtr static int iptablesSetupVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { const char *match = MATCH_PHYSDEV_IN; virBufferVSprintf(buf, - "res=$(" IPTABLES_CMD " -L " VIRT_IN_POST_CHAIN + "res=$(%s -L " VIRT_IN_POST_CHAIN " | grep \"\\%s %s\")\n" "if [ \"${res}\" == \"\" ]; then " - CMD_DEF(IPTABLES_CMD + CMD_DEF("%s" " -A " VIRT_IN_POST_CHAIN " %s %s -j ACCEPT") CMD_SEPARATOR CMD_EXEC "%s" "fi\n", + iptables_cmd, PHYSDEV_IN, ifname, + iptables_cmd, match, ifname, CMD_STOPONERR(1)); return 0; @@ -574,20 +597,22 @@ iptablesSetupVirtInPost(virConnectPtr co static int iptablesClearVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { const char *match = MATCH_PHYSDEV_IN; virBufferVSprintf(buf, - IPTABLES_CMD - " -D " VIRT_IN_POST_CHAIN + "%s -D " VIRT_IN_POST_CHAIN " %s %s -j ACCEPT" CMD_SEPARATOR, + iptables_cmd, match, ifname); return 0; } static int _iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *basechain, char prefix, @@ -610,8 +635,9 @@ _iptablesUnlinkRootChain(virConnectPtr c PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); virBufferVSprintf(buf, - IPTABLES_CMD " -D %s " + "%s -D %s " "%s %s -g %s" CMD_SEPARATOR, + iptables_cmd, basechain, match, ifname, chain); @@ -621,36 +647,39 @@ _iptablesUnlinkRootChain(virConnectPtr c static int iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *basechain, char prefix, int incoming, const char *ifname) { - return _iptablesUnlinkRootChain(conn, buf, + return _iptablesUnlinkRootChain(conn, iptables_cmd, buf, basechain, prefix, incoming, ifname, 0); } static int iptablesUnlinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, const char *basechain, char prefix, int incoming, const char *ifname) { - return _iptablesUnlinkRootChain(conn, buf, + return _iptablesUnlinkRootChain(conn, iptables_cmd, buf, basechain, prefix, incoming, ifname, 1); } static int iptablesUnlinkRootChains(virConnectPtr conn, + const char *cmd, virBufferPtr buf, const char *ifname) { - iptablesUnlinkRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); - iptablesUnlinkRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname); - iptablesUnlinkRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname); + iptablesUnlinkRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); + iptablesUnlinkRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname); + iptablesUnlinkRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname); return 0; } @@ -658,18 +687,20 @@ iptablesUnlinkRootChains(virConnectPtr c static int iptablesUnlinkTmpRootChains(virConnectPtr conn, + const char *cmd, virBufferPtr buf, const char *ifname) { - iptablesUnlinkTmpRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); - iptablesUnlinkTmpRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname); - iptablesUnlinkTmpRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname); + iptablesUnlinkTmpRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); + iptablesUnlinkTmpRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname); + iptablesUnlinkTmpRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname); return 0; } static int iptablesRenameTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *iptables_cmd, virBufferPtr buf, char prefix, int incoming, @@ -691,7 +722,8 @@ iptablesRenameTmpRootChain(virConnectPtr PRINT_IPT_ROOT_CHAIN( chain, chainPrefix, ifname); virBufferVSprintf(buf, - IPTABLES_CMD " -E %s %s" CMD_SEPARATOR, + "%s -E %s %s" CMD_SEPARATOR, + iptables_cmd, tmpchain, chain); return 0; @@ -700,12 +732,13 @@ iptablesRenameTmpRootChain(virConnectPtr static int iptablesRenameTmpRootChains(virConnectPtr conn, + const char *iptables_cmd, virBufferPtr buf, const char *ifname) { - iptablesRenameTmpRootChain(conn, buf, 'F', 0, ifname); - iptablesRenameTmpRootChain(conn, buf, 'F', 1, ifname); - iptablesRenameTmpRootChain(conn, buf, 'H', 1, ifname); + iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname); + iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname); + iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname); return 0; } @@ -763,7 +796,7 @@ iptablesHandleIpHdr(virConnectPtr conn A ipHdrDataDefPtr ipHdr, int directionIn) { - char ipaddr[INET_ADDRSTRLEN], + char ipaddr[INET6_ADDRSTRLEN], number[20]; const char *src = "--source"; const char *dst = "--destination"; @@ -1007,19 +1040,23 @@ _iptablesCreateRuleInstance(virConnectPt virNWFilterHashTablePtr vars, virNWFilterRuleInstPtr res, const char *match, - const char *accept_target) + const char *accept_target, + bool isIPv6) { char chain[MAX_CHAINNAME_LENGTH]; char number[20]; virBuffer buf = VIR_BUFFER_INITIALIZER; const char *target; + const char *iptables_cmd = (isIPv6) ? IP6TABLES_CMD : IPTABLES_CMD; PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_TCP: + case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p tcp"); @@ -1061,8 +1098,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_UDP: + case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p udp"); @@ -1090,8 +1129,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p udplite"); @@ -1113,8 +1154,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_ESP: + case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p esp"); @@ -1136,8 +1179,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_AH: + case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p ah"); @@ -1159,8 +1204,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_SCTP: + case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p sctp"); @@ -1188,11 +1235,16 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_ICMP: + case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); - virBufferAddLit(&buf, " -p icmp"); + if (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ICMP) + virBufferAddLit(&buf, " -p icmp"); + else + virBufferAddLit(&buf, " -p icmpv6"); if (iptablesHandleSrcMacAddr(conn, &buf, @@ -1235,8 +1287,10 @@ _iptablesCreateRuleInstance(virConnectPt break; case VIR_NWFILTER_RULE_PROTOCOL_ALL: + case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6: virBufferVSprintf(&buf, - CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", + CMD_DEF_PRE "%s -%%c %s %%s", + iptables_cmd, chain); virBufferAddLit(&buf, " -p all"); @@ -1286,7 +1340,7 @@ _iptablesCreateRuleInstance(virConnectPt nwfilter->chainsuffix, '\0', rule->priority, - 1); + (isIPv6) ? RT_IP6TABLES : RT_IPTABLES); err_exit: @@ -1303,7 +1357,8 @@ iptablesCreateRuleInstance(virConnectPtr virNWFilterRuleDefPtr rule, const char *ifname, virNWFilterHashTablePtr vars, - virNWFilterRuleInstPtr res) + virNWFilterRuleInstPtr res, + bool isIPv6) { int rc; int directionIn = 0; @@ -1329,7 +1384,8 @@ iptablesCreateRuleInstance(virConnectPtr res, needState ? MATCH_STATE_OUT : NULL, - "RETURN"); + "RETURN", + isIPv6); if (rc) return rc; @@ -1344,7 +1400,8 @@ iptablesCreateRuleInstance(virConnectPtr res, needState ? MATCH_STATE_IN : NULL, - "ACCEPT"); + "ACCEPT", + isIPv6); if (rc) return rc; @@ -1359,7 +1416,8 @@ iptablesCreateRuleInstance(virConnectPtr vars, res, NULL, - "ACCEPT"); + "ACCEPT", + isIPv6); if (rc) return rc; @@ -1870,6 +1928,7 @@ ebiptablesCreateRuleInstance(virConnectP virNWFilterRuleInstPtr res) { int rc = 0; + bool isIPv6; switch (rule->prtclType) { case VIR_NWFILTER_RULE_PROTOCOL_IP: @@ -1919,12 +1978,39 @@ ebiptablesCreateRuleInstance(virConnectP virDomainNetTypeToString(nettype)); return 1; } + isIPv6 = 0; rc = iptablesCreateRuleInstance(conn, nwfilter, rule, ifname, vars, - res); + res, + isIPv6); + break; + + case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6: + case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6: + case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6: + if (nettype == VIR_DOMAIN_NET_TYPE_DIRECT) { + virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER, + _("'%s' protocol not support for net type '%s'"), + virNWFilterRuleProtocolTypeToString(rule->prtclType), + virDomainNetTypeToString(nettype)); + return 1; + } + isIPv6 = 1; + rc = iptablesCreateRuleInstance(conn, + nwfilter, + rule, + ifname, + vars, + res, + isIPv6); break; case VIR_NWFILTER_RULE_PROTOCOL_LAST: @@ -2460,6 +2546,7 @@ ebiptablesApplyNewRules(virConnectPtr co int chains_in = 0, chains_out = 0; virBuffer buf = VIR_BUFFER_INITIALIZER; int haveIptables = 0; + int haveIp6tables = 0; if (inst) qsort(inst, nruleInstances, sizeof(inst[0]), @@ -2515,6 +2602,9 @@ ebiptablesApplyNewRules(virConnectPtr co case RT_IPTABLES: haveIptables = 1; break; + case RT_IP6TABLES: + haveIp6tables = 1; + break; } if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) @@ -2523,21 +2613,21 @@ ebiptablesApplyNewRules(virConnectPtr co // FIXME: establishment of iptables user define table tree goes here if (haveIptables) { - iptablesUnlinkTmpRootChains(conn, &buf, ifname); - iptablesRemoveTmpRootChains(conn, &buf, ifname); + iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); - iptablesCreateBaseChains(conn, &buf); + iptablesCreateBaseChains(conn, IPTABLES_CMD, &buf); if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) goto tear_down_tmpebchains; - iptablesCreateTmpRootChains(conn, &buf, ifname); + iptablesCreateTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) goto tear_down_tmpiptchains; - iptablesLinkTmpRootChains(conn, &buf, ifname); - iptablesSetupVirtInPost(conn, &buf, ifname); + iptablesLinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesSetupVirtInPost(conn, IPTABLES_CMD, &buf, ifname); if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) goto tear_down_tmpiptchains; @@ -2552,6 +2642,36 @@ ebiptablesApplyNewRules(virConnectPtr co goto tear_down_tmpiptchains; } + if (haveIp6tables) { + iptablesUnlinkTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + + iptablesCreateBaseChains(conn, IP6TABLES_CMD, &buf); + + if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) + goto tear_down_tmpiptchains; + + iptablesCreateTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + + if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) + goto tear_down_tmpip6tchains; + + iptablesLinkTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesSetupVirtInPost(conn, IP6TABLES_CMD, &buf, ifname); + if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) + goto tear_down_tmpip6tchains; + + for (i = 0; i < nruleInstances; i++) { + if (inst[i]->ruleType == RT_IP6TABLES) + iptablesInstCommand(conn, &buf, + inst[i]->commandTemplate, + 'A', -1, 1); + } + + if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) + goto tear_down_tmpip6tchains; + } + // END IPTABLES stuff @@ -2569,10 +2689,16 @@ tear_down_ebsubchains_and_unlink: ebtablesUnlinkTmpRootChain(conn, &buf, 1, ifname); ebtablesUnlinkTmpRootChain(conn, &buf, 0, ifname); +tear_down_tmpip6tchains: + if (haveIp6tables) { + iptablesUnlinkTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + } + tear_down_tmpiptchains: if (haveIptables) { - iptablesUnlinkTmpRootChains(conn, &buf, ifname); - iptablesRemoveTmpRootChains(conn, &buf, ifname); + iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); } tear_down_tmpebchains: @@ -2597,8 +2723,11 @@ ebiptablesTearNewRules(virConnectPtr con int cli_status; virBuffer buf = VIR_BUFFER_INITIALIZER; - iptablesUnlinkTmpRootChains(conn, &buf, ifname); - iptablesRemoveTmpRootChains(conn, &buf, ifname); + iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + + iptablesUnlinkTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesRemoveTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); ebtablesUnlinkTmpRootChain(conn, &buf, 1, ifname); ebtablesUnlinkTmpRootChain(conn, &buf, 0, ifname); @@ -2621,10 +2750,16 @@ ebiptablesTearOldRules(virConnectPtr con virBuffer buf = VIR_BUFFER_INITIALIZER; // switch to new iptables user defined chains - iptablesUnlinkRootChains(conn, &buf, ifname); - iptablesRemoveRootChains(conn, &buf, ifname); + iptablesUnlinkRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesRemoveRootChains(conn, IPTABLES_CMD, &buf, ifname); + + iptablesRenameTmpRootChains(conn, IPTABLES_CMD, &buf, ifname); + ebiptablesExecCLI(conn, &buf, &cli_status); + + iptablesUnlinkRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesRemoveRootChains(conn, IP6TABLES_CMD, &buf, ifname); - iptablesRenameTmpRootChains(conn, &buf, ifname); + iptablesRenameTmpRootChains(conn, IP6TABLES_CMD, &buf, ifname); ebiptablesExecCLI(conn, &buf, &cli_status); ebtablesUnlinkRootChain(conn, &buf, 1, ifname); @@ -2706,9 +2841,13 @@ ebiptablesAllTeardown(const char *ifname int cli_status; virConnectPtr conn = NULL; - iptablesUnlinkRootChains(conn, &buf, ifname); - iptablesClearVirtInPost(conn, &buf, ifname); - iptablesRemoveRootChains(conn, &buf, ifname); + iptablesUnlinkRootChains(conn, IPTABLES_CMD, &buf, ifname); + iptablesClearVirtInPost (conn, IPTABLES_CMD, &buf, ifname); + iptablesRemoveRootChains(conn, IPTABLES_CMD, &buf, ifname); + + iptablesUnlinkRootChains(conn, IP6TABLES_CMD, &buf, ifname); + iptablesClearVirtInPost (conn, IP6TABLES_CMD, &buf, ifname); + iptablesRemoveRootChains(conn, IP6TABLES_CMD, &buf, ifname); ebtablesUnlinkRootChain(conn, &buf, 1, ifname); ebtablesUnlinkRootChain(conn, &buf, 0, ifname); Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.h =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.h +++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.h @@ -28,7 +28,7 @@ enum RuleType { RT_EBTABLES, RT_IPTABLES, -/* RT_IP6TABLES, for future use */ + RT_IP6TABLES, }; typedef struct _ebiptablesRuleInst ebiptablesRuleInst;

On Fri, Mar 26, 2010 at 04:41:19PM -0400, Stefan Berger wrote:
This patch adds IPv6 filtering support for the following protocols: - tcp-ipv6 - udp-ipv6 - udplite-ipv6 - esp-ipv6 - ah-ipv6 - sctp-ipv6 - all-ipv6 - icmpv6
Many of the IPv4 data structure could be re-used for IPv6 support. Since ip6tables also supports pretty much the same command line parameters as iptables does, also much of the code could be re-used and now command lines are invoked with the ip(6)tables tool parameter passed through the functions as a parameter.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
--- configure.ac | 3 src/conf/nwfilter_conf.c | 165 +++++++++++++++-- src/conf/nwfilter_conf.h | 8 src/nwfilter/nwfilter_ebiptables_driver.c | 287 ++++++++++++++++++++++-------- src/nwfilter/nwfilter_ebiptables_driver.h | 2 5 files changed, 370 insertions(+), 95 deletions(-)
Index: libvirt-acl/configure.ac =================================================================== --- libvirt-acl.orig/configure.ac +++ libvirt-acl/configure.ac @@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_P AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary])
+AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary])
The patch looks fine, based on the existing code, but I'm a bit surprized by the fact that while there is a lookup for ip6tables/iptables at configure time, i.e. when it's compiled, there is no check at runtime to verify that the binaries which were detected then are actually available on the target. I think some of this should be relaxed like we do for other commands launched at runtime and somehow we should instead use virFindFileInPath() from util.h to find the location of the preferred ip[6]tables. ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard <veillard@redhat.com> wrote on 03/30/2010 10:02:09 AM:
Please respond to veillard
On Fri, Mar 26, 2010 at 04:41:19PM -0400, Stefan Berger wrote:
This patch adds IPv6 filtering support for the following protocols: - tcp-ipv6 - udp-ipv6 - udplite-ipv6 - esp-ipv6 - ah-ipv6 - sctp-ipv6 - all-ipv6 - icmpv6
Many of the IPv4 data structure could be re-used for IPv6 support. Since ip6tables also supports pretty much the same command line
parameters
as iptables does, also much of the code could be re-used and now command lines are invoked with the ip(6)tables tool parameter passed through the functions as a parameter.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
--- configure.ac | 3 src/conf/nwfilter_conf.c | 165 +++++++++++++++-- src/conf/nwfilter_conf.h | 8 src/nwfilter/nwfilter_ebiptables_driver.c | 287 ++++++++++++++++ ++++++-------- src/nwfilter/nwfilter_ebiptables_driver.h | 2 5 files changed, 370 insertions(+), 95 deletions(-)
Index: libvirt-acl/configure.ac =================================================================== --- libvirt-acl.orig/configure.ac +++ libvirt-acl/configure.ac @@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_P AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary])
+AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/ usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary])
The patch looks fine, based on the existing code, but I'm a bit surprized by the fact that while there is a lookup for ip6tables/iptables at configure time, i.e. when it's compiled, there is no check at runtime to verify that the binaries which were detected then are actually available on the target. I think some of this should be relaxed like we do for other commands launched at runtime and somehow we should instead use virFindFileInPath() from util.h to find the location of the preferred ip[6]tables.
I followed a previous example of what was originally ebtables that's detected like this as well. Sure, this can be changed to rely on the function you are mentioning. Pushed. Regards, Stefan
ACK,
Daniel
-- Daniel Veillard | libxml Gnome XML XSLT toolkit
daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard <veillard@redhat.com> wrote on 03/30/2010 10:02:09 AM:
Index: libvirt-acl/configure.ac =================================================================== --- libvirt-acl.orig/configure.ac +++ libvirt-acl/configure.ac @@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_P AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary])
+AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/ usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary])
The patch looks fine, based on the existing code, but I'm a bit surprized by the fact that while there is a lookup for ip6tables/iptables at configure time, i.e. when it's compiled, there is no check at runtime to verify that the binaries which were detected then are actually available on the target. I think some of this should be relaxed like we do for other commands launched at runtime and somehow we should instead use virFindFileInPath() from util.h to find the location of the preferred ip[6]tables.
I created a patch using this function call now. It's a bit bigger than expected. Should I wait for after the next release? Stefan
ACK,
Daniel
-- Daniel Veillard | libxml Gnome XML XSLT toolkit
daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Mon, Apr 12, 2010 at 11:41:31AM -0400, Stefan Berger wrote:
Daniel Veillard <veillard@redhat.com> wrote on 03/30/2010 10:02:09 AM:
Index: libvirt-acl/configure.ac =================================================================== --- libvirt-acl.orig/configure.ac +++ libvirt-acl/configure.ac @@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_P AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary])
+AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/ usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/ sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary])
The patch looks fine, based on the existing code, but I'm a bit surprized by the fact that while there is a lookup for ip6tables/iptables at configure time, i.e. when it's compiled, there is no check at runtime to verify that the binaries which were detected then are actually available on the target. I think some of this should be relaxed like we do for other commands launched at runtime and somehow we should instead use virFindFileInPath() from util.h to find the location of the preferred ip[6]tables.
I created a patch using this function call now. It's a bit bigger than expected. Should I wait for after the next release?
Yeah, it's a bit late in the process, doesn't affect APIs so no urgency, so let's do that after 0.8.0, that doesn't change the core concepts. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (2)
-
Daniel Veillard
-
Stefan Berger