mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Add IPv6 support for the ebtables layer
This patch adds IPv6 support for the ebtables layer. Since the parser etc. are all parameterized, it was fairly easy to add this... Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
parent
d498175aad
commit
f85208eec6
@ -73,7 +73,8 @@ VIR_ENUM_IMPL(virNWFilterEbtablesTable, VIR_NWFILTER_EBTABLES_TABLE_LAST,
|
||||
VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST,
|
||||
"root",
|
||||
"arp",
|
||||
"ipv4");
|
||||
"ipv4",
|
||||
"ipv6");
|
||||
|
||||
|
||||
/*
|
||||
@ -365,6 +366,9 @@ static const struct int_map macProtoMap[] = {
|
||||
}, {
|
||||
.attr = ETHERTYPE_IP,
|
||||
.val = "ipv4",
|
||||
}, {
|
||||
.attr = ETHERTYPE_IPV6,
|
||||
.val = "ipv6",
|
||||
}, {
|
||||
.val = NULL,
|
||||
}
|
||||
@ -449,6 +453,13 @@ checkIPv4Mask(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *maskptr,
|
||||
return checkValidMask(maskptr, 4);
|
||||
}
|
||||
|
||||
static bool
|
||||
checkIPv6Mask(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *maskptr,
|
||||
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return checkValidMask(maskptr, 16);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
checkMACMask(enum attrDatatype datatype ATTRIBUTE_UNUSED,
|
||||
@ -765,6 +776,61 @@ static const virXMLAttr2Struct ipAttributes[] = {
|
||||
};
|
||||
|
||||
|
||||
static const virXMLAttr2Struct ipv6Attributes[] = {
|
||||
COMMON_MAC_PROPS(ipv6HdrFilter),
|
||||
{
|
||||
.name = SRCIPADDR,
|
||||
.datatype = DATATYPE_IPV6ADDR,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataSrcIPAddr),
|
||||
},
|
||||
{
|
||||
.name = DSTIPADDR,
|
||||
.datatype = DATATYPE_IPV6ADDR,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataDstIPAddr),
|
||||
},
|
||||
{
|
||||
.name = SRCIPMASK,
|
||||
.datatype = DATATYPE_IPV6MASK,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataSrcIPMask),
|
||||
},
|
||||
{
|
||||
.name = DSTIPMASK,
|
||||
.datatype = DATATYPE_IPV6MASK,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataDstIPMask),
|
||||
},
|
||||
{
|
||||
.name = "protocol",
|
||||
.datatype = DATATYPE_STRING,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataProtocolID),
|
||||
.validator= checkIPProtocolID,
|
||||
.formatter= formatIPProtocolID,
|
||||
},
|
||||
{
|
||||
.name = SRCPORTSTART,
|
||||
.datatype = DATATYPE_UINT16,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataSrcPortStart),
|
||||
},
|
||||
{
|
||||
.name = SRCPORTEND,
|
||||
.datatype = DATATYPE_UINT16,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataSrcPortEnd),
|
||||
},
|
||||
{
|
||||
.name = DSTPORTSTART,
|
||||
.datatype = DATATYPE_UINT16,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataDstPortStart),
|
||||
},
|
||||
{
|
||||
.name = DSTPORTEND,
|
||||
.datatype = DATATYPE_UINT16,
|
||||
.dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataDstPortEnd),
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virAttributes virAttributes;
|
||||
struct _virAttributes {
|
||||
const char *id;
|
||||
@ -786,6 +852,10 @@ static const virAttributes virAttr[] = {
|
||||
.id = "ip",
|
||||
.att = ipAttributes,
|
||||
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IP,
|
||||
}, {
|
||||
.id = "ipv6",
|
||||
.att = ipv6Attributes,
|
||||
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IPV6,
|
||||
}, {
|
||||
.id = NULL,
|
||||
}
|
||||
@ -825,6 +895,89 @@ virNWIPv4AddressParser(const char *input,
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
virNWIPv6AddressParser(const char *input,
|
||||
nwIPAddressPtr output)
|
||||
{
|
||||
int i, j, pos;
|
||||
uint16_t n;
|
||||
int shiftpos = -1;
|
||||
char prevchar;
|
||||
char base;
|
||||
|
||||
memset(output, 0x0, sizeof(*output));
|
||||
|
||||
output->isIPv6 = 1;
|
||||
|
||||
pos = 0;
|
||||
i = 0;
|
||||
|
||||
while (i < 8) {
|
||||
j = 0;
|
||||
n = 0;
|
||||
while (1) {
|
||||
prevchar = input[pos++];
|
||||
if (prevchar == ':' || prevchar == 0) {
|
||||
if (j > 0) {
|
||||
output->addr.ipv6Addr[i * 2 + 0] = n >> 8;
|
||||
output->addr.ipv6Addr[i * 2 + 1] = n;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (j >= 4)
|
||||
return 0;
|
||||
|
||||
if (prevchar >= '0' && prevchar <= '9')
|
||||
base = '0';
|
||||
else if (prevchar >= 'a' && prevchar <= 'f')
|
||||
base = 'a' - 10;
|
||||
else if (prevchar >= 'A' && prevchar <= 'F')
|
||||
base = 'A' - 10;
|
||||
else
|
||||
return 0;
|
||||
n <<= 4;
|
||||
n |= (prevchar - base);
|
||||
j++;
|
||||
}
|
||||
|
||||
if (prevchar == 0)
|
||||
break;
|
||||
|
||||
if (input[pos] == ':') {
|
||||
pos ++;
|
||||
// sequence of zeros
|
||||
if (prevchar != ':')
|
||||
return 0;
|
||||
|
||||
if (shiftpos != -1)
|
||||
return 0;
|
||||
|
||||
shiftpos = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (shiftpos != -1) {
|
||||
if (i >= 7)
|
||||
return 0;
|
||||
i--;
|
||||
j = 0;
|
||||
while (i >= shiftpos) {
|
||||
output->addr.ipv6Addr[15 - (j*2) - 1] =
|
||||
output->addr.ipv6Addr[i * 2 + 0];
|
||||
output->addr.ipv6Addr[15 - (j*2) - 0] =
|
||||
output->addr.ipv6Addr[i * 2 + 1];
|
||||
output->addr.ipv6Addr[i * 2 + 0] = 0;
|
||||
output->addr.ipv6Addr[i * 2 + 1] = 0;
|
||||
i--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virNWFilterRuleDetailsParse(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
xmlNodePtr node,
|
||||
@ -969,6 +1122,41 @@ virNWFilterRuleDetailsParse(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
found = 1;
|
||||
break;
|
||||
|
||||
case DATATYPE_IPV6ADDR:
|
||||
storage_ptr = &item->u.ipaddr;
|
||||
if (!virNWIPv6AddressParser(prop,
|
||||
(nwIPAddressPtr)storage_ptr)) {
|
||||
rc = -1;
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
|
||||
case DATATYPE_IPV6MASK:
|
||||
storage_ptr = &item->u.u8;
|
||||
if (!virNWIPv6AddressParser(prop, &ipaddr)) {
|
||||
if (sscanf(prop, "%d", &int_val) == 1) {
|
||||
if (int_val >= 0 && int_val <= 128) {
|
||||
if (!validator)
|
||||
*(uint8_t *)storage_ptr =
|
||||
(uint8_t)int_val;
|
||||
found = 1;
|
||||
data_ptr = &int_val;
|
||||
} else
|
||||
rc = -1;
|
||||
} else
|
||||
rc = -1;
|
||||
} else {
|
||||
if (checkIPv6Mask(datatype,
|
||||
ipaddr.addr.ipv6Addr, nwf))
|
||||
*(uint8_t *)storage_ptr =
|
||||
getMaskNumBits(ipaddr.addr.ipv6Addr,
|
||||
sizeof(ipaddr.addr.ipv6Addr));
|
||||
else
|
||||
rc = -1;
|
||||
found = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case DATATYPE_STRING:
|
||||
if (!validator) {
|
||||
// not supported
|
||||
@ -1076,6 +1264,13 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
|
||||
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
|
||||
break;
|
||||
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
|
||||
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask,
|
||||
rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr);
|
||||
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask,
|
||||
rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr);
|
||||
break;
|
||||
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||
break;
|
||||
@ -1952,7 +2147,36 @@ virNWIPAddressFormat(virBufferPtr buf, nwIPAddressPtr ipaddr)
|
||||
ipaddr->addr.ipv4Addr[2],
|
||||
ipaddr->addr.ipv4Addr[3]);
|
||||
} else {
|
||||
virBufferAddLit(buf, "MISSING IPv6 ADDRESS FORMATTER");
|
||||
int i;
|
||||
int dcshown = 0, in_dc = 0;
|
||||
unsigned short n;
|
||||
while (i < 8) {
|
||||
n = (ipaddr->addr.ipv6Addr[i * 2 + 0] << 8) |
|
||||
ipaddr->addr.ipv6Addr[i * 2 + 1];
|
||||
if (n == 0) {
|
||||
if (!dcshown) {
|
||||
in_dc = 1;
|
||||
if (i == 0)
|
||||
virBufferAddLit(buf, ":");
|
||||
dcshown = 1;
|
||||
}
|
||||
if (in_dc) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (in_dc) {
|
||||
dcshown = 1;
|
||||
virBufferAddLit(buf, ":");
|
||||
in_dc = 0;
|
||||
}
|
||||
i++;
|
||||
virBufferVSprintf(buf, "%x", n);
|
||||
if (i < 8)
|
||||
virBufferAddLit(buf, ":");
|
||||
}
|
||||
if (in_dc)
|
||||
virBufferAddLit(buf, ":");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2021,6 +2245,7 @@ virNWFilterRuleDefDetailsFormat(virConnectPtr conn,
|
||||
switch (att[i].datatype) {
|
||||
|
||||
case DATATYPE_IPMASK:
|
||||
case DATATYPE_IPV6MASK:
|
||||
// display all masks in CIDR format
|
||||
case DATATYPE_UINT8:
|
||||
storage_ptr = &item->u.u8;
|
||||
@ -2033,6 +2258,7 @@ virNWFilterRuleDefDetailsFormat(virConnectPtr conn,
|
||||
break;
|
||||
|
||||
case DATATYPE_IPADDR:
|
||||
case DATATYPE_IPV6ADDR:
|
||||
storage_ptr = &item->u.ipaddr;
|
||||
virNWIPAddressFormat(buf,
|
||||
(nwIPAddressPtr)storage_ptr);
|
||||
|
@ -68,8 +68,10 @@ enum attrDatatype {
|
||||
DATATYPE_IPADDR = (1 << 4),
|
||||
DATATYPE_IPMASK = (1 << 5),
|
||||
DATATYPE_STRING = (1 << 6),
|
||||
DATATYPE_IPV6ADDR = (1 << 7),
|
||||
DATATYPE_IPV6MASK = (1 << 8),
|
||||
|
||||
DATATYPE_LAST = (1 << 7),
|
||||
DATATYPE_LAST = (1 << 9),
|
||||
};
|
||||
|
||||
|
||||
@ -86,7 +88,7 @@ struct _nwIPAddress {
|
||||
int isIPv6;
|
||||
union {
|
||||
unsigned char ipv4Addr[4];
|
||||
/* unsigned char ipv6Addr[16]; future :-) */
|
||||
unsigned char ipv6Addr[16];
|
||||
} addr;
|
||||
};
|
||||
|
||||
@ -171,6 +173,15 @@ struct _ipHdrFilterDef {
|
||||
};
|
||||
|
||||
|
||||
typedef struct _ipv6HdrFilterDef ipv6HdrFilterDef;
|
||||
typedef ipv6HdrFilterDef *ipv6HdrFilterDefPtr;
|
||||
struct _ipv6HdrFilterDef {
|
||||
ethHdrDataDef ethHdr;
|
||||
ipHdrDataDef ipHdr;
|
||||
portDataDef portData;
|
||||
};
|
||||
|
||||
|
||||
enum virNWFilterRuleActionType {
|
||||
VIR_NWFILTER_RULE_ACTION_DROP = 0,
|
||||
VIR_NWFILTER_RULE_ACTION_ACCEPT,
|
||||
@ -198,6 +209,7 @@ enum virNWFilterRuleProtocolType {
|
||||
VIR_NWFILTER_RULE_PROTOCOL_MAC,
|
||||
VIR_NWFILTER_RULE_PROTOCOL_ARP,
|
||||
VIR_NWFILTER_RULE_PROTOCOL_IP,
|
||||
VIR_NWFILTER_RULE_PROTOCOL_IPV6,
|
||||
};
|
||||
|
||||
enum virNWFilterEbtablesTableType {
|
||||
@ -223,6 +235,7 @@ struct _virNWFilterRuleDef {
|
||||
ethHdrFilterDef ethHdrFilter;
|
||||
arpHdrFilterDef arpHdrFilter;
|
||||
ipHdrFilterDef ipHdrFilter;
|
||||
ipv6HdrFilterDef ipv6HdrFilter;
|
||||
} p;
|
||||
|
||||
int nvars;
|
||||
@ -249,6 +262,7 @@ enum virNWFilterChainSuffixType {
|
||||
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
|
||||
VIR_NWFILTER_CHAINSUFFIX_ARP,
|
||||
VIR_NWFILTER_CHAINSUFFIX_IPv4,
|
||||
VIR_NWFILTER_CHAINSUFFIX_IPv6,
|
||||
|
||||
VIR_NWFILTER_CHAINSUFFIX_LAST,
|
||||
};
|
||||
|
@ -73,6 +73,7 @@
|
||||
|
||||
static const char *supported_protocols[] = {
|
||||
"ipv4",
|
||||
"ipv6",
|
||||
"arp",
|
||||
NULL,
|
||||
};
|
||||
@ -117,6 +118,8 @@ printDataType(virConnectPtr conn,
|
||||
nwItemDescPtr item)
|
||||
{
|
||||
int done;
|
||||
int i, pos, s;
|
||||
|
||||
if (printVar(conn, vars, buf, bufsize, item, &done))
|
||||
return 1;
|
||||
|
||||
@ -136,6 +139,21 @@ printDataType(virConnectPtr conn,
|
||||
}
|
||||
break;
|
||||
|
||||
case DATATYPE_IPV6ADDR:
|
||||
pos = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
s = snprintf(&buf[pos], bufsize - pos, "%x%s",
|
||||
(unsigned int)item->u.ipaddr.addr.ipv6Addr[i],
|
||||
((i & 1) && (i < 15)) ? ":" : "" );
|
||||
if (s >= bufsize - pos) {
|
||||
virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER,
|
||||
_("Buffer too small for IPv6 address"));
|
||||
return 1;
|
||||
}
|
||||
pos += s;
|
||||
}
|
||||
break;
|
||||
|
||||
case DATATYPE_MACADDR:
|
||||
if (bufsize < VIR_MAC_STRING_BUFLEN) {
|
||||
virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER,
|
||||
@ -155,6 +173,7 @@ printDataType(virConnectPtr conn,
|
||||
}
|
||||
break;
|
||||
|
||||
case DATATYPE_IPV6MASK:
|
||||
case DATATYPE_IPMASK:
|
||||
case DATATYPE_UINT8:
|
||||
if (snprintf(buf, bufsize, "%d",
|
||||
@ -304,6 +323,7 @@ ebtablesCreateRuleInstance(virConnectPtr conn,
|
||||
{
|
||||
char macaddr[VIR_MAC_STRING_BUFLEN],
|
||||
ipaddr[INET_ADDRSTRLEN],
|
||||
ipv6addr[INET6_ADDRSTRLEN],
|
||||
number[20];
|
||||
char chain[MAX_CHAINNAME_LENGTH];
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
@ -587,6 +607,135 @@ ebtablesCreateRuleInstance(virConnectPtr conn,
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
|
||||
virBufferVSprintf(&buf,
|
||||
CMD_DEF_PRE EBTABLES_CMD " -t %s -%%c %s %%s",
|
||||
EBTABLES_DEFAULT_TABLE, chain);
|
||||
|
||||
if (ebtablesHandleEthHdr(conn,
|
||||
&buf,
|
||||
vars,
|
||||
&rule->p.ipv6HdrFilter.ethHdr))
|
||||
goto err_exit;
|
||||
|
||||
virBufferAddLit(&buf,
|
||||
" -p ipv6");
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
ipv6addr, sizeof(ipv6addr),
|
||||
&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
" --ip6-source %s %s",
|
||||
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr),
|
||||
ipv6addr);
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask))
|
||||
goto err_exit;
|
||||
virBufferVSprintf(&buf,
|
||||
"/%s",
|
||||
number);
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr)) {
|
||||
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
ipv6addr, sizeof(ipv6addr),
|
||||
&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
" --ip6-destination %s %s",
|
||||
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr),
|
||||
ipv6addr);
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask))
|
||||
goto err_exit;
|
||||
virBufferVSprintf(&buf,
|
||||
"/%s",
|
||||
number);
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
" --ip6-protocol %s %s",
|
||||
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID),
|
||||
number);
|
||||
}
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataSrcPortStart)) {
|
||||
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.portData.dataSrcPortStart))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
" --ip6-source-port %s %s",
|
||||
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataSrcPortStart),
|
||||
number);
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataSrcPortEnd)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.portData.dataSrcPortEnd))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
":%s",
|
||||
number);
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataDstPortStart)) {
|
||||
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.portData.dataDstPortStart))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
" --ip6-destination-port %s %s",
|
||||
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataDstPortStart),
|
||||
number);
|
||||
|
||||
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataDstPortEnd)) {
|
||||
if (printDataType(conn,
|
||||
vars,
|
||||
number, sizeof(number),
|
||||
&rule->p.ipv6HdrFilter.portData.dataDstPortEnd))
|
||||
goto err_exit;
|
||||
|
||||
virBufferVSprintf(&buf,
|
||||
":%s",
|
||||
number);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||
virBufferVSprintf(&buf,
|
||||
CMD_DEF_PRE EBTABLES_CMD " -t %s -%%c %s %%s",
|
||||
@ -650,6 +799,7 @@ ebiptablesCreateRuleInstance(virConnectPtr conn,
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
|
||||
|
||||
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
|
||||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
|
||||
@ -1230,6 +1380,11 @@ ebiptablesApplyNewRules(virConnectPtr conn,
|
||||
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv4))
|
||||
ebtablesCreateTmpSubChain(conn, &buf, 0, ifname, "ipv4", 1);
|
||||
|
||||
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv6))
|
||||
ebtablesCreateTmpSubChain(conn, &buf, 1, ifname, "ipv6", 1);
|
||||
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv6))
|
||||
ebtablesCreateTmpSubChain(conn, &buf, 0, ifname, "ipv6", 1);
|
||||
|
||||
// keep arp as last
|
||||
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_ARP))
|
||||
ebtablesCreateTmpSubChain(conn, &buf, 1, ifname, "arp", 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user