Add ip6tables support for IPv6 filtering

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.
This commit is contained in:
Stefan Berger 2010-03-30 10:36:35 -04:00
parent 0af0ded038
commit bc2102104f
5 changed files with 390 additions and 111 deletions

View File

@ -300,6 +300,9 @@ AC_DEFINE_UNQUOTED([BASH_PATH], "$BASH_PATH", [path to bash binary])
AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH]) AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH])
AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary]) 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_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/sbin:$PATH])
AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary])

View File

@ -86,7 +86,15 @@ VIR_ENUM_IMPL(virNWFilterRuleProtocol, VIR_NWFILTER_RULE_PROTOCOL_LAST,
"esp", "esp",
"ah", "ah",
"sctp", "sctp",
"all"); "all",
"tcp-ipv6",
"icmpv6",
"udp-ipv6",
"udplite-ipv6",
"esp-ipv6",
"ah-ipv6",
"sctp-ipv6",
"all-ipv6");
/* /*
@ -869,41 +877,41 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.dataSrcMACAddr),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.dataSrcMACAddr),\
} }
#define COMMON_IP_PROPS(STRUCT) \ #define COMMON_IP_PROPS(STRUCT, ADDRTYPE, MASKTYPE) \
COMMON_L3_MAC_PROPS(STRUCT),\ COMMON_L3_MAC_PROPS(STRUCT),\
{\ {\
.name = SRCIPADDR,\ .name = SRCIPADDR,\
.datatype = DATATYPE_IPADDR,\ .datatype = ADDRTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPAddr),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPAddr),\
},\ },\
{\ {\
.name = DSTIPADDR,\ .name = DSTIPADDR,\
.datatype = DATATYPE_IPADDR,\ .datatype = ADDRTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPAddr),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPAddr),\
},\ },\
{\ {\
.name = SRCIPMASK,\ .name = SRCIPMASK,\
.datatype = DATATYPE_IPMASK,\ .datatype = MASKTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPMask),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPMask),\
},\ },\
{\ {\
.name = DSTIPMASK,\ .name = DSTIPMASK,\
.datatype = DATATYPE_IPMASK,\ .datatype = MASKTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPMask),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPMask),\
},\ },\
{\ {\
.name = SRCIPFROM,\ .name = SRCIPFROM,\
.datatype = DATATYPE_IPADDR,\ .datatype = ADDRTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPFrom),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPFrom),\
},\ },\
{\ {\
.name = SRCIPTO,\ .name = SRCIPTO,\
.datatype = DATATYPE_IPADDR,\ .datatype = ADDRTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPTo),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPTo),\
},\ },\
{\ {\
.name = DSTIPFROM,\ .name = DSTIPFROM,\
.datatype = DATATYPE_IPADDR,\ .datatype = ADDRTYPE,\
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPFrom),\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPFrom),\
},\ },\
{\ {\
@ -941,7 +949,7 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
} }
static const virXMLAttr2Struct tcpAttributes[] = { static const virXMLAttr2Struct tcpAttributes[] = {
COMMON_IP_PROPS(tcpHdrFilter), COMMON_IP_PROPS(tcpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
COMMON_PORT_PROPS(tcpHdrFilter), COMMON_PORT_PROPS(tcpHdrFilter),
{ {
.name = "option", .name = "option",
@ -954,7 +962,7 @@ static const virXMLAttr2Struct tcpAttributes[] = {
}; };
static const virXMLAttr2Struct udpAttributes[] = { static const virXMLAttr2Struct udpAttributes[] = {
COMMON_IP_PROPS(udpHdrFilter), COMMON_IP_PROPS(udpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
COMMON_PORT_PROPS(udpHdrFilter), COMMON_PORT_PROPS(udpHdrFilter),
{ {
.name = NULL, .name = NULL,
@ -962,28 +970,28 @@ static const virXMLAttr2Struct udpAttributes[] = {
}; };
static const virXMLAttr2Struct udpliteAttributes[] = { static const virXMLAttr2Struct udpliteAttributes[] = {
COMMON_IP_PROPS(udpliteHdrFilter), COMMON_IP_PROPS(udpliteHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
{ {
.name = NULL, .name = NULL,
} }
}; };
static const virXMLAttr2Struct espAttributes[] = { static const virXMLAttr2Struct espAttributes[] = {
COMMON_IP_PROPS(espHdrFilter), COMMON_IP_PROPS(espHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
{ {
.name = NULL, .name = NULL,
} }
}; };
static const virXMLAttr2Struct ahAttributes[] = { static const virXMLAttr2Struct ahAttributes[] = {
COMMON_IP_PROPS(ahHdrFilter), COMMON_IP_PROPS(ahHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
{ {
.name = NULL, .name = NULL,
} }
}; };
static const virXMLAttr2Struct sctpAttributes[] = { static const virXMLAttr2Struct sctpAttributes[] = {
COMMON_IP_PROPS(sctpHdrFilter), COMMON_IP_PROPS(sctpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
COMMON_PORT_PROPS(sctpHdrFilter), COMMON_PORT_PROPS(sctpHdrFilter),
{ {
.name = NULL, .name = NULL,
@ -992,7 +1000,7 @@ static const virXMLAttr2Struct sctpAttributes[] = {
static const virXMLAttr2Struct icmpAttributes[] = { static const virXMLAttr2Struct icmpAttributes[] = {
COMMON_IP_PROPS(icmpHdrFilter), COMMON_IP_PROPS(icmpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
{ {
.name = "type", .name = "type",
.datatype = DATATYPE_UINT8, .datatype = DATATYPE_UINT8,
@ -1010,7 +1018,7 @@ static const virXMLAttr2Struct icmpAttributes[] = {
static const virXMLAttr2Struct allAttributes[] = { static const virXMLAttr2Struct allAttributes[] = {
COMMON_IP_PROPS(allHdrFilter), COMMON_IP_PROPS(allHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
{ {
.name = NULL, .name = NULL,
} }
@ -1018,7 +1026,88 @@ static const virXMLAttr2Struct allAttributes[] = {
static const virXMLAttr2Struct igmpAttributes[] = { 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, .name = NULL,
} }
@ -1086,6 +1175,38 @@ static const virAttributes virAttr[] = {
.id = "igmp", .id = "igmp",
.att = igmpAttributes, .att = igmpAttributes,
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IGMP, .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, .id = NULL,
} }
@ -1506,6 +1627,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCP:
case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataSrcIPMask,
rule->p.tcpHdrFilter.ipHdr.dataSrcIPAddr); rule->p.tcpHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.tcpHdrFilter.ipHdr.dataDstIPMask,
@ -1523,6 +1645,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP: case VIR_NWFILTER_RULE_PROTOCOL_UDP:
case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6:
COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataSrcIPMask,
rule->p.udpHdrFilter.ipHdr.dataSrcIPAddr); rule->p.udpHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.udpHdrFilter.ipHdr.dataDstIPMask,
@ -1540,6 +1663,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6:
COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataSrcIPMask,
rule->p.udpliteHdrFilter.ipHdr.dataSrcIPAddr); rule->p.udpliteHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPMask,
@ -1551,6 +1675,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP: case VIR_NWFILTER_RULE_PROTOCOL_ESP:
case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6:
COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataSrcIPMask,
rule->p.espHdrFilter.ipHdr.dataSrcIPAddr); rule->p.espHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPMask,
@ -1562,6 +1687,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_AH: case VIR_NWFILTER_RULE_PROTOCOL_AH:
case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6:
COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataSrcIPMask,
rule->p.ahHdrFilter.ipHdr.dataSrcIPAddr); rule->p.ahHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPMask,
@ -1573,6 +1699,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP: case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6:
COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataSrcIPMask,
rule->p.sctpHdrFilter.ipHdr.dataSrcIPAddr); rule->p.sctpHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.sctpHdrFilter.ipHdr.dataDstIPMask,
@ -1590,6 +1717,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP: case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6:
COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataSrcIPMask,
rule->p.icmpHdrFilter.ipHdr.dataSrcIPAddr); rule->p.icmpHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.icmpHdrFilter.ipHdr.dataDstIPMask,
@ -1603,6 +1731,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL: case VIR_NWFILTER_RULE_PROTOCOL_ALL:
case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6:
COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataSrcIPMask, COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataSrcIPMask,
rule->p.allHdrFilter.ipHdr.dataSrcIPAddr); rule->p.allHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataDstIPMask, COPY_NEG_SIGN(rule->p.allHdrFilter.ipHdr.dataDstIPMask,

View File

@ -302,6 +302,14 @@ enum virNWFilterRuleProtocolType {
VIR_NWFILTER_RULE_PROTOCOL_AH, VIR_NWFILTER_RULE_PROTOCOL_AH,
VIR_NWFILTER_RULE_PROTOCOL_SCTP, VIR_NWFILTER_RULE_PROTOCOL_SCTP,
VIR_NWFILTER_RULE_PROTOCOL_ALL, 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 VIR_NWFILTER_RULE_PROTOCOL_LAST
}; };

View File

@ -64,6 +64,7 @@
#define EBTABLES_CMD EBTABLES_PATH #define EBTABLES_CMD EBTABLES_PATH
#define IPTABLES_CMD IPTABLES_PATH #define IPTABLES_CMD IPTABLES_PATH
#define IP6TABLES_CMD IP6TABLES_PATH
#define BASH_CMD BASH_PATH #define BASH_CMD BASH_PATH
#define GREP_CMD GREP_PATH #define GREP_CMD GREP_PATH
#define GAWK_CMD GAWK_PATH #define GAWK_CMD GAWK_PATH
@ -327,6 +328,7 @@ ebtablesHandleEthHdr(virConnectPtr conn,
/************************ iptables support ************************/ /************************ iptables support ************************/
static int iptablesLinkIPTablesBaseChain(virConnectPtr conn ATTRIBUTE_UNUSED, static int iptablesLinkIPTablesBaseChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *udchain, const char *udchain,
const char *syschain, const char *syschain,
@ -334,53 +336,58 @@ static int iptablesLinkIPTablesBaseChain(virConnectPtr conn ATTRIBUTE_UNUSED,
int stopOnError) int stopOnError)
{ {
virBufferVSprintf(buf, virBufferVSprintf(buf,
"res=$(" "res=$(%s -L %s -n --line-number | "
IPTABLES_CMD " -L %s -n --line-number | "
GREP_CMD " \" %s \")\n" GREP_CMD " \" %s \")\n"
"if [ $? -ne 0 ]; then\n" "if [ $? -ne 0 ]; then\n"
" " IPTABLES_CMD " -I %s %d -j %s\n" " %s -I %s %d -j %s\n"
"else\n" "else\n"
" r=$(echo $res | " GAWK_CMD " '{print $1}')\n" " r=$(echo $res | " GAWK_CMD " '{print $1}')\n"
" if [ \"${r}\" != \"%d\" ]; then\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 " " CMD_EXEC
" %s" " %s"
" let r=r+1\n" " let r=r+1\n"
" " CMD_DEF(IPTABLES_CMD " -D %s ${r}") CMD_SEPARATOR " " CMD_DEF("%s -D %s ${r}") CMD_SEPARATOR
" " CMD_EXEC " " CMD_EXEC
" %s" " %s"
" fi\n" " fi\n"
"fi\n", "fi\n",
syschain, udchain, iptables_cmd, syschain,
udchain,
syschain, pos, udchain, iptables_cmd, syschain, pos, udchain,
pos, pos,
syschain, pos, udchain, iptables_cmd, syschain, pos, udchain,
CMD_STOPONERR(stopOnError), CMD_STOPONERR(stopOnError),
syschain, iptables_cmd, syschain,
CMD_STOPONERR(stopOnError)); CMD_STOPONERR(stopOnError));
return 0; return 0;
} }
static int iptablesCreateBaseChains(virConnectPtr conn, static int iptablesCreateBaseChains(virConnectPtr conn,
const char *iptables_cmd,
virBufferPtr buf) virBufferPtr buf)
{ {
virBufferAddLit(buf, IPTABLES_CMD " -N " VIRT_IN_CHAIN CMD_SEPARATOR virBufferVSprintf(buf,"%s -N " VIRT_IN_CHAIN CMD_SEPARATOR
IPTABLES_CMD " -N " VIRT_OUT_CHAIN CMD_SEPARATOR "%s -N " VIRT_OUT_CHAIN CMD_SEPARATOR
IPTABLES_CMD " -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR "%s -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR
IPTABLES_CMD " -N " HOST_IN_CHAIN CMD_SEPARATOR); "%s -N " HOST_IN_CHAIN CMD_SEPARATOR,
iptablesLinkIPTablesBaseChain(conn, buf, iptables_cmd,
iptables_cmd,
iptables_cmd,
iptables_cmd);
iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf,
VIRT_IN_CHAIN , "FORWARD", 1, 1); VIRT_IN_CHAIN , "FORWARD", 1, 1);
iptablesLinkIPTablesBaseChain(conn, buf, iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf,
VIRT_OUT_CHAIN , "FORWARD", 2, 1); VIRT_OUT_CHAIN , "FORWARD", 2, 1);
iptablesLinkIPTablesBaseChain(conn, buf, iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf,
VIRT_IN_POST_CHAIN, "FORWARD", 3, 1); VIRT_IN_POST_CHAIN, "FORWARD", 3, 1);
iptablesLinkIPTablesBaseChain(conn, buf, iptablesLinkIPTablesBaseChain(conn, iptables_cmd, buf,
HOST_IN_CHAIN , "INPUT" , 1, 1); HOST_IN_CHAIN , "INPUT" , 1, 1);
return 0; return 0;
@ -389,6 +396,7 @@ static int iptablesCreateBaseChains(virConnectPtr conn,
static int static int
iptablesCreateTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesCreateTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
char prefix, char prefix,
int incoming, const char *ifname, int incoming, const char *ifname,
@ -404,9 +412,10 @@ iptablesCreateTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferVSprintf(buf, virBufferVSprintf(buf,
CMD_DEF(IPTABLES_CMD " -N %s") CMD_SEPARATOR CMD_DEF("%s -N %s") CMD_SEPARATOR
CMD_EXEC CMD_EXEC
"%s", "%s",
iptables_cmd,
chain, chain,
CMD_STOPONERR(stopOnError)); CMD_STOPONERR(stopOnError));
@ -416,18 +425,20 @@ iptablesCreateTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesCreateTmpRootChains(virConnectPtr conn, iptablesCreateTmpRootChains(virConnectPtr conn,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesCreateTmpRootChain(conn, buf, 'F', 0, ifname, 1); iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname, 1);
iptablesCreateTmpRootChain(conn, buf, 'F', 1, ifname, 1); iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname, 1);
iptablesCreateTmpRootChain(conn, buf, 'H', 1, ifname, 1); iptablesCreateTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname, 1);
return 0; return 0;
} }
static int static int
_iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, _iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
char prefix, char prefix,
int incoming, const char *ifname, int incoming, const char *ifname,
@ -448,10 +459,10 @@ _iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferVSprintf(buf, virBufferVSprintf(buf,
IPTABLES_CMD " -F %s" CMD_SEPARATOR "%s -F %s" CMD_SEPARATOR
IPTABLES_CMD " -X %s" CMD_SEPARATOR, "%s -X %s" CMD_SEPARATOR,
chain, iptables_cmd, chain,
chain); iptables_cmd, chain);
return 0; return 0;
} }
@ -459,52 +470,59 @@ _iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesRemoveRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
char prefix, char prefix,
int incoming, int incoming,
const char *ifname) const char *ifname)
{ {
return _iptablesRemoveRootChain(conn, buf, prefix, incoming, ifname, 0); return _iptablesRemoveRootChain(conn, iptables_cmd,
buf, prefix, incoming, ifname, 0);
} }
static int static int
iptablesRemoveTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesRemoveTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
char prefix, char prefix,
int incoming, int incoming,
const char *ifname) const char *ifname)
{ {
return _iptablesRemoveRootChain(conn, buf, prefix, incoming, ifname, 1); return _iptablesRemoveRootChain(conn, iptables_cmd, buf, prefix,
incoming, ifname, 1);
} }
static int static int
iptablesRemoveTmpRootChains(virConnectPtr conn, iptablesRemoveTmpRootChains(virConnectPtr conn,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesRemoveTmpRootChain(conn, buf, 'F', 0, ifname); iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname);
iptablesRemoveTmpRootChain(conn, buf, 'F', 1, ifname); iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname);
iptablesRemoveTmpRootChain(conn, buf, 'H', 1, ifname); iptablesRemoveTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname);
return 0; return 0;
} }
static int static int
iptablesRemoveRootChains(virConnectPtr conn, iptablesRemoveRootChains(virConnectPtr conn,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesRemoveRootChain(conn, buf, 'F', 0, ifname); iptablesRemoveRootChain(conn, iptables_cmd, buf, 'F', 0, ifname);
iptablesRemoveRootChain(conn, buf, 'F', 1, ifname); iptablesRemoveRootChain(conn, iptables_cmd, buf, 'F', 1, ifname);
iptablesRemoveRootChain(conn, buf, 'H', 1, ifname); iptablesRemoveRootChain(conn, iptables_cmd, buf, 'H', 1, ifname);
return 0; return 0;
} }
static int static int
iptablesLinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesLinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *basechain, const char *basechain,
char prefix, char prefix,
@ -523,10 +541,11 @@ iptablesLinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferVSprintf(buf, virBufferVSprintf(buf,
CMD_DEF(IPTABLES_CMD " -A %s " CMD_DEF("%s -A %s "
"%s %s -g %s") CMD_SEPARATOR "%s %s -g %s") CMD_SEPARATOR
CMD_EXEC CMD_EXEC
"%s", "%s",
iptables_cmd,
basechain, basechain,
match, ifname, chain, match, ifname, chain,
@ -538,12 +557,13 @@ iptablesLinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesLinkTmpRootChains(virConnectPtr conn, iptablesLinkTmpRootChains(virConnectPtr conn,
const char *cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesLinkTmpRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1); iptablesLinkTmpRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1);
iptablesLinkTmpRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1); iptablesLinkTmpRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1);
iptablesLinkTmpRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname, 1); iptablesLinkTmpRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname, 1);
return 0; return 0;
} }
@ -551,21 +571,24 @@ iptablesLinkTmpRootChains(virConnectPtr conn,
static int static int
iptablesSetupVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesSetupVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
const char *match = MATCH_PHYSDEV_IN; const char *match = MATCH_PHYSDEV_IN;
virBufferVSprintf(buf, virBufferVSprintf(buf,
"res=$(" IPTABLES_CMD " -L " VIRT_IN_POST_CHAIN "res=$(%s -L " VIRT_IN_POST_CHAIN
" | grep \"\\%s %s\")\n" " | grep \"\\%s %s\")\n"
"if [ \"${res}\" == \"\" ]; then " "if [ \"${res}\" == \"\" ]; then "
CMD_DEF(IPTABLES_CMD CMD_DEF("%s"
" -A " VIRT_IN_POST_CHAIN " -A " VIRT_IN_POST_CHAIN
" %s %s -j ACCEPT") CMD_SEPARATOR " %s %s -j ACCEPT") CMD_SEPARATOR
CMD_EXEC CMD_EXEC
"%s" "%s"
"fi\n", "fi\n",
iptables_cmd,
PHYSDEV_IN, ifname, PHYSDEV_IN, ifname,
iptables_cmd,
match, ifname, match, ifname,
CMD_STOPONERR(1)); CMD_STOPONERR(1));
return 0; return 0;
@ -574,20 +597,22 @@ iptablesSetupVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesClearVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesClearVirtInPost(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
const char *match = MATCH_PHYSDEV_IN; const char *match = MATCH_PHYSDEV_IN;
virBufferVSprintf(buf, virBufferVSprintf(buf,
IPTABLES_CMD "%s -D " VIRT_IN_POST_CHAIN
" -D " VIRT_IN_POST_CHAIN
" %s %s -j ACCEPT" CMD_SEPARATOR, " %s %s -j ACCEPT" CMD_SEPARATOR,
iptables_cmd,
match, ifname); match, ifname);
return 0; return 0;
} }
static int static int
_iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, _iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *basechain, const char *basechain,
char prefix, char prefix,
@ -610,8 +635,9 @@ _iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferVSprintf(buf, virBufferVSprintf(buf,
IPTABLES_CMD " -D %s " "%s -D %s "
"%s %s -g %s" CMD_SEPARATOR, "%s %s -g %s" CMD_SEPARATOR,
iptables_cmd,
basechain, basechain,
match, ifname, chain); match, ifname, chain);
@ -621,36 +647,39 @@ _iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesUnlinkRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *basechain, const char *basechain,
char prefix, char prefix,
int incoming, const char *ifname) int incoming, const char *ifname)
{ {
return _iptablesUnlinkRootChain(conn, buf, return _iptablesUnlinkRootChain(conn, iptables_cmd, buf,
basechain, prefix, incoming, ifname, 0); basechain, prefix, incoming, ifname, 0);
} }
static int static int
iptablesUnlinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesUnlinkTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *basechain, const char *basechain,
char prefix, char prefix,
int incoming, const char *ifname) int incoming, const char *ifname)
{ {
return _iptablesUnlinkRootChain(conn, buf, return _iptablesUnlinkRootChain(conn, iptables_cmd, buf,
basechain, prefix, incoming, ifname, 1); basechain, prefix, incoming, ifname, 1);
} }
static int static int
iptablesUnlinkRootChains(virConnectPtr conn, iptablesUnlinkRootChains(virConnectPtr conn,
const char *cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesUnlinkRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); iptablesUnlinkRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
iptablesUnlinkRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname); iptablesUnlinkRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname);
iptablesUnlinkRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname); iptablesUnlinkRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname);
return 0; return 0;
} }
@ -658,18 +687,20 @@ iptablesUnlinkRootChains(virConnectPtr conn,
static int static int
iptablesUnlinkTmpRootChains(virConnectPtr conn, iptablesUnlinkTmpRootChains(virConnectPtr conn,
const char *cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesUnlinkTmpRootChain(conn, buf, VIRT_OUT_CHAIN, 'F', 0, ifname); iptablesUnlinkTmpRootChain(conn, cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
iptablesUnlinkTmpRootChain(conn, buf, VIRT_IN_CHAIN , 'F', 1, ifname); iptablesUnlinkTmpRootChain(conn, cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname);
iptablesUnlinkTmpRootChain(conn, buf, HOST_IN_CHAIN , 'H', 1, ifname); iptablesUnlinkTmpRootChain(conn, cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname);
return 0; return 0;
} }
static int static int
iptablesRenameTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED, iptablesRenameTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
char prefix, char prefix,
int incoming, int incoming,
@ -691,7 +722,8 @@ iptablesRenameTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
PRINT_IPT_ROOT_CHAIN( chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN( chain, chainPrefix, ifname);
virBufferVSprintf(buf, virBufferVSprintf(buf,
IPTABLES_CMD " -E %s %s" CMD_SEPARATOR, "%s -E %s %s" CMD_SEPARATOR,
iptables_cmd,
tmpchain, tmpchain,
chain); chain);
return 0; return 0;
@ -700,12 +732,13 @@ iptablesRenameTmpRootChain(virConnectPtr conn ATTRIBUTE_UNUSED,
static int static int
iptablesRenameTmpRootChains(virConnectPtr conn, iptablesRenameTmpRootChains(virConnectPtr conn,
const char *iptables_cmd,
virBufferPtr buf, virBufferPtr buf,
const char *ifname) const char *ifname)
{ {
iptablesRenameTmpRootChain(conn, buf, 'F', 0, ifname); iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'F', 0, ifname);
iptablesRenameTmpRootChain(conn, buf, 'F', 1, ifname); iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'F', 1, ifname);
iptablesRenameTmpRootChain(conn, buf, 'H', 1, ifname); iptablesRenameTmpRootChain(conn, iptables_cmd, buf, 'H', 1, ifname);
return 0; return 0;
} }
@ -763,7 +796,7 @@ iptablesHandleIpHdr(virConnectPtr conn ATTRIBUTE_UNUSED,
ipHdrDataDefPtr ipHdr, ipHdrDataDefPtr ipHdr,
int directionIn) int directionIn)
{ {
char ipaddr[INET_ADDRSTRLEN], char ipaddr[INET6_ADDRSTRLEN],
number[20]; number[20];
const char *src = "--source"; const char *src = "--source";
const char *dst = "--destination"; const char *dst = "--destination";
@ -1007,19 +1040,23 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
virNWFilterHashTablePtr vars, virNWFilterHashTablePtr vars,
virNWFilterRuleInstPtr res, virNWFilterRuleInstPtr res,
const char *match, const char *match,
const char *accept_target) const char *accept_target,
bool isIPv6)
{ {
char chain[MAX_CHAINNAME_LENGTH]; char chain[MAX_CHAINNAME_LENGTH];
char number[20]; char number[20];
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *target; const char *target;
const char *iptables_cmd = (isIPv6) ? IP6TABLES_CMD : IPTABLES_CMD;
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
switch (rule->prtclType) { switch (rule->prtclType) {
case VIR_NWFILTER_RULE_PROTOCOL_TCP: case VIR_NWFILTER_RULE_PROTOCOL_TCP:
case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p tcp"); virBufferAddLit(&buf, " -p tcp");
@ -1061,8 +1098,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP: case VIR_NWFILTER_RULE_PROTOCOL_UDP:
case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p udp"); virBufferAddLit(&buf, " -p udp");
@ -1090,8 +1129,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p udplite"); virBufferAddLit(&buf, " -p udplite");
@ -1113,8 +1154,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP: case VIR_NWFILTER_RULE_PROTOCOL_ESP:
case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p esp"); virBufferAddLit(&buf, " -p esp");
@ -1136,8 +1179,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_AH: case VIR_NWFILTER_RULE_PROTOCOL_AH:
case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p ah"); virBufferAddLit(&buf, " -p ah");
@ -1159,8 +1204,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP: case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p sctp"); virBufferAddLit(&buf, " -p sctp");
@ -1188,11 +1235,16 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP: case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
if (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ICMP)
virBufferAddLit(&buf, " -p icmp"); virBufferAddLit(&buf, " -p icmp");
else
virBufferAddLit(&buf, " -p icmpv6");
if (iptablesHandleSrcMacAddr(conn, if (iptablesHandleSrcMacAddr(conn,
&buf, &buf,
@ -1235,8 +1287,10 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
break; break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL: case VIR_NWFILTER_RULE_PROTOCOL_ALL:
case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6:
virBufferVSprintf(&buf, virBufferVSprintf(&buf,
CMD_DEF_PRE IPTABLES_CMD " -%%c %s %%s", CMD_DEF_PRE "%s -%%c %s %%s",
iptables_cmd,
chain); chain);
virBufferAddLit(&buf, " -p all"); virBufferAddLit(&buf, " -p all");
@ -1286,7 +1340,7 @@ _iptablesCreateRuleInstance(virConnectPtr conn,
nwfilter->chainsuffix, nwfilter->chainsuffix,
'\0', '\0',
rule->priority, rule->priority,
1); (isIPv6) ? RT_IP6TABLES : RT_IPTABLES);
err_exit: err_exit:
@ -1303,7 +1357,8 @@ iptablesCreateRuleInstance(virConnectPtr conn,
virNWFilterRuleDefPtr rule, virNWFilterRuleDefPtr rule,
const char *ifname, const char *ifname,
virNWFilterHashTablePtr vars, virNWFilterHashTablePtr vars,
virNWFilterRuleInstPtr res) virNWFilterRuleInstPtr res,
bool isIPv6)
{ {
int rc; int rc;
int directionIn = 0; int directionIn = 0;
@ -1329,7 +1384,8 @@ iptablesCreateRuleInstance(virConnectPtr conn,
res, res,
needState ? MATCH_STATE_OUT needState ? MATCH_STATE_OUT
: NULL, : NULL,
"RETURN"); "RETURN",
isIPv6);
if (rc) if (rc)
return rc; return rc;
@ -1344,7 +1400,8 @@ iptablesCreateRuleInstance(virConnectPtr conn,
res, res,
needState ? MATCH_STATE_IN needState ? MATCH_STATE_IN
: NULL, : NULL,
"ACCEPT"); "ACCEPT",
isIPv6);
if (rc) if (rc)
return rc; return rc;
@ -1359,7 +1416,8 @@ iptablesCreateRuleInstance(virConnectPtr conn,
vars, vars,
res, res,
NULL, NULL,
"ACCEPT"); "ACCEPT",
isIPv6);
if (rc) if (rc)
return rc; return rc;
@ -1870,6 +1928,7 @@ ebiptablesCreateRuleInstance(virConnectPtr conn,
virNWFilterRuleInstPtr res) virNWFilterRuleInstPtr res)
{ {
int rc = 0; int rc = 0;
bool isIPv6;
switch (rule->prtclType) { switch (rule->prtclType) {
case VIR_NWFILTER_RULE_PROTOCOL_IP: case VIR_NWFILTER_RULE_PROTOCOL_IP:
@ -1919,12 +1978,39 @@ ebiptablesCreateRuleInstance(virConnectPtr conn,
virDomainNetTypeToString(nettype)); virDomainNetTypeToString(nettype));
return 1; return 1;
} }
isIPv6 = 0;
rc = iptablesCreateRuleInstance(conn, rc = iptablesCreateRuleInstance(conn,
nwfilter, nwfilter,
rule, rule,
ifname, ifname,
vars, 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; break;
case VIR_NWFILTER_RULE_PROTOCOL_LAST: case VIR_NWFILTER_RULE_PROTOCOL_LAST:
@ -2460,6 +2546,7 @@ ebiptablesApplyNewRules(virConnectPtr conn,
int chains_in = 0, chains_out = 0; int chains_in = 0, chains_out = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
int haveIptables = 0; int haveIptables = 0;
int haveIp6tables = 0;
if (inst) if (inst)
qsort(inst, nruleInstances, sizeof(inst[0]), qsort(inst, nruleInstances, sizeof(inst[0]),
@ -2515,6 +2602,9 @@ ebiptablesApplyNewRules(virConnectPtr conn,
case RT_IPTABLES: case RT_IPTABLES:
haveIptables = 1; haveIptables = 1;
break; break;
case RT_IP6TABLES:
haveIp6tables = 1;
break;
} }
if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0)
@ -2523,21 +2613,21 @@ ebiptablesApplyNewRules(virConnectPtr conn,
// FIXME: establishment of iptables user define table tree goes here // FIXME: establishment of iptables user define table tree goes here
if (haveIptables) { if (haveIptables) {
iptablesUnlinkTmpRootChains(conn, &buf, ifname); iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesRemoveTmpRootChains(conn, &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) if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0)
goto tear_down_tmpebchains; goto tear_down_tmpebchains;
iptablesCreateTmpRootChains(conn, &buf, ifname); iptablesCreateTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0)
goto tear_down_tmpiptchains; goto tear_down_tmpiptchains;
iptablesLinkTmpRootChains(conn, &buf, ifname); iptablesLinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesSetupVirtInPost(conn, &buf, ifname); iptablesSetupVirtInPost(conn, IPTABLES_CMD, &buf, ifname);
if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0) if (ebiptablesExecCLI(conn, &buf, &cli_status) || cli_status != 0)
goto tear_down_tmpiptchains; goto tear_down_tmpiptchains;
@ -2552,6 +2642,36 @@ ebiptablesApplyNewRules(virConnectPtr conn,
goto tear_down_tmpiptchains; 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 // END IPTABLES stuff
@ -2569,10 +2689,16 @@ tear_down_ebsubchains_and_unlink:
ebtablesUnlinkTmpRootChain(conn, &buf, 1, ifname); ebtablesUnlinkTmpRootChain(conn, &buf, 1, ifname);
ebtablesUnlinkTmpRootChain(conn, &buf, 0, 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: tear_down_tmpiptchains:
if (haveIptables) { if (haveIptables) {
iptablesUnlinkTmpRootChains(conn, &buf, ifname); iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesRemoveTmpRootChains(conn, &buf, ifname); iptablesRemoveTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
} }
tear_down_tmpebchains: tear_down_tmpebchains:
@ -2597,8 +2723,11 @@ ebiptablesTearNewRules(virConnectPtr conn,
int cli_status; int cli_status;
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
iptablesUnlinkTmpRootChains(conn, &buf, ifname); iptablesUnlinkTmpRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesRemoveTmpRootChains(conn, &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, 1, ifname);
ebtablesUnlinkTmpRootChain(conn, &buf, 0, ifname); ebtablesUnlinkTmpRootChain(conn, &buf, 0, ifname);
@ -2621,10 +2750,16 @@ ebiptablesTearOldRules(virConnectPtr conn,
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
// switch to new iptables user defined chains // switch to new iptables user defined chains
iptablesUnlinkRootChains(conn, &buf, ifname); iptablesUnlinkRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesRemoveRootChains(conn, &buf, ifname); iptablesRemoveRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesRenameTmpRootChains(conn, &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, IP6TABLES_CMD, &buf, ifname);
ebiptablesExecCLI(conn, &buf, &cli_status); ebiptablesExecCLI(conn, &buf, &cli_status);
ebtablesUnlinkRootChain(conn, &buf, 1, ifname); ebtablesUnlinkRootChain(conn, &buf, 1, ifname);
@ -2706,9 +2841,13 @@ ebiptablesAllTeardown(const char *ifname)
int cli_status; int cli_status;
virConnectPtr conn = NULL; virConnectPtr conn = NULL;
iptablesUnlinkRootChains(conn, &buf, ifname); iptablesUnlinkRootChains(conn, IPTABLES_CMD, &buf, ifname);
iptablesClearVirtInPost(conn, &buf, ifname); iptablesClearVirtInPost (conn, IPTABLES_CMD, &buf, ifname);
iptablesRemoveRootChains(conn, &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, 1, ifname);
ebtablesUnlinkRootChain(conn, &buf, 0, ifname); ebtablesUnlinkRootChain(conn, &buf, 0, ifname);

View File

@ -28,7 +28,7 @@
enum RuleType { enum RuleType {
RT_EBTABLES, RT_EBTABLES,
RT_IPTABLES, RT_IPTABLES,
/* RT_IP6TABLES, for future use */ RT_IP6TABLES,
}; };
typedef struct _ebiptablesRuleInst ebiptablesRuleInst; typedef struct _ebiptablesRuleInst ebiptablesRuleInst;