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,
|
VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST,
|
||||||
"root",
|
"root",
|
||||||
"arp",
|
"arp",
|
||||||
"ipv4");
|
"ipv4",
|
||||||
|
"ipv6");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -365,6 +366,9 @@ static const struct int_map macProtoMap[] = {
|
|||||||
}, {
|
}, {
|
||||||
.attr = ETHERTYPE_IP,
|
.attr = ETHERTYPE_IP,
|
||||||
.val = "ipv4",
|
.val = "ipv4",
|
||||||
|
}, {
|
||||||
|
.attr = ETHERTYPE_IPV6,
|
||||||
|
.val = "ipv6",
|
||||||
}, {
|
}, {
|
||||||
.val = NULL,
|
.val = NULL,
|
||||||
}
|
}
|
||||||
@ -449,6 +453,13 @@ checkIPv4Mask(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *maskptr,
|
|||||||
return checkValidMask(maskptr, 4);
|
return checkValidMask(maskptr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
checkIPv6Mask(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *maskptr,
|
||||||
|
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return checkValidMask(maskptr, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
checkMACMask(enum attrDatatype datatype ATTRIBUTE_UNUSED,
|
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;
|
typedef struct _virAttributes virAttributes;
|
||||||
struct _virAttributes {
|
struct _virAttributes {
|
||||||
const char *id;
|
const char *id;
|
||||||
@ -786,6 +852,10 @@ static const virAttributes virAttr[] = {
|
|||||||
.id = "ip",
|
.id = "ip",
|
||||||
.att = ipAttributes,
|
.att = ipAttributes,
|
||||||
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IP,
|
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IP,
|
||||||
|
}, {
|
||||||
|
.id = "ipv6",
|
||||||
|
.att = ipv6Attributes,
|
||||||
|
.prtclType = VIR_NWFILTER_RULE_PROTOCOL_IPV6,
|
||||||
}, {
|
}, {
|
||||||
.id = NULL,
|
.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
|
static int
|
||||||
virNWFilterRuleDetailsParse(virConnectPtr conn ATTRIBUTE_UNUSED,
|
virNWFilterRuleDetailsParse(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
@ -969,6 +1122,41 @@ virNWFilterRuleDetailsParse(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
found = 1;
|
found = 1;
|
||||||
break;
|
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:
|
case DATATYPE_STRING:
|
||||||
if (!validator) {
|
if (!validator) {
|
||||||
// not supported
|
// not supported
|
||||||
@ -1076,6 +1264,13 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
|
|||||||
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
|
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
|
||||||
break;
|
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_ARP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||||
break;
|
break;
|
||||||
@ -1952,7 +2147,36 @@ virNWIPAddressFormat(virBufferPtr buf, nwIPAddressPtr ipaddr)
|
|||||||
ipaddr->addr.ipv4Addr[2],
|
ipaddr->addr.ipv4Addr[2],
|
||||||
ipaddr->addr.ipv4Addr[3]);
|
ipaddr->addr.ipv4Addr[3]);
|
||||||
} else {
|
} 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) {
|
switch (att[i].datatype) {
|
||||||
|
|
||||||
case DATATYPE_IPMASK:
|
case DATATYPE_IPMASK:
|
||||||
|
case DATATYPE_IPV6MASK:
|
||||||
// display all masks in CIDR format
|
// display all masks in CIDR format
|
||||||
case DATATYPE_UINT8:
|
case DATATYPE_UINT8:
|
||||||
storage_ptr = &item->u.u8;
|
storage_ptr = &item->u.u8;
|
||||||
@ -2033,6 +2258,7 @@ virNWFilterRuleDefDetailsFormat(virConnectPtr conn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DATATYPE_IPADDR:
|
case DATATYPE_IPADDR:
|
||||||
|
case DATATYPE_IPV6ADDR:
|
||||||
storage_ptr = &item->u.ipaddr;
|
storage_ptr = &item->u.ipaddr;
|
||||||
virNWIPAddressFormat(buf,
|
virNWIPAddressFormat(buf,
|
||||||
(nwIPAddressPtr)storage_ptr);
|
(nwIPAddressPtr)storage_ptr);
|
||||||
|
@ -68,8 +68,10 @@ enum attrDatatype {
|
|||||||
DATATYPE_IPADDR = (1 << 4),
|
DATATYPE_IPADDR = (1 << 4),
|
||||||
DATATYPE_IPMASK = (1 << 5),
|
DATATYPE_IPMASK = (1 << 5),
|
||||||
DATATYPE_STRING = (1 << 6),
|
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;
|
int isIPv6;
|
||||||
union {
|
union {
|
||||||
unsigned char ipv4Addr[4];
|
unsigned char ipv4Addr[4];
|
||||||
/* unsigned char ipv6Addr[16]; future :-) */
|
unsigned char ipv6Addr[16];
|
||||||
} addr;
|
} addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,6 +173,15 @@ struct _ipHdrFilterDef {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _ipv6HdrFilterDef ipv6HdrFilterDef;
|
||||||
|
typedef ipv6HdrFilterDef *ipv6HdrFilterDefPtr;
|
||||||
|
struct _ipv6HdrFilterDef {
|
||||||
|
ethHdrDataDef ethHdr;
|
||||||
|
ipHdrDataDef ipHdr;
|
||||||
|
portDataDef portData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum virNWFilterRuleActionType {
|
enum virNWFilterRuleActionType {
|
||||||
VIR_NWFILTER_RULE_ACTION_DROP = 0,
|
VIR_NWFILTER_RULE_ACTION_DROP = 0,
|
||||||
VIR_NWFILTER_RULE_ACTION_ACCEPT,
|
VIR_NWFILTER_RULE_ACTION_ACCEPT,
|
||||||
@ -198,6 +209,7 @@ enum virNWFilterRuleProtocolType {
|
|||||||
VIR_NWFILTER_RULE_PROTOCOL_MAC,
|
VIR_NWFILTER_RULE_PROTOCOL_MAC,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_ARP,
|
VIR_NWFILTER_RULE_PROTOCOL_ARP,
|
||||||
VIR_NWFILTER_RULE_PROTOCOL_IP,
|
VIR_NWFILTER_RULE_PROTOCOL_IP,
|
||||||
|
VIR_NWFILTER_RULE_PROTOCOL_IPV6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum virNWFilterEbtablesTableType {
|
enum virNWFilterEbtablesTableType {
|
||||||
@ -223,6 +235,7 @@ struct _virNWFilterRuleDef {
|
|||||||
ethHdrFilterDef ethHdrFilter;
|
ethHdrFilterDef ethHdrFilter;
|
||||||
arpHdrFilterDef arpHdrFilter;
|
arpHdrFilterDef arpHdrFilter;
|
||||||
ipHdrFilterDef ipHdrFilter;
|
ipHdrFilterDef ipHdrFilter;
|
||||||
|
ipv6HdrFilterDef ipv6HdrFilter;
|
||||||
} p;
|
} p;
|
||||||
|
|
||||||
int nvars;
|
int nvars;
|
||||||
@ -249,6 +262,7 @@ enum virNWFilterChainSuffixType {
|
|||||||
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
|
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_ARP,
|
VIR_NWFILTER_CHAINSUFFIX_ARP,
|
||||||
VIR_NWFILTER_CHAINSUFFIX_IPv4,
|
VIR_NWFILTER_CHAINSUFFIX_IPv4,
|
||||||
|
VIR_NWFILTER_CHAINSUFFIX_IPv6,
|
||||||
|
|
||||||
VIR_NWFILTER_CHAINSUFFIX_LAST,
|
VIR_NWFILTER_CHAINSUFFIX_LAST,
|
||||||
};
|
};
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
static const char *supported_protocols[] = {
|
static const char *supported_protocols[] = {
|
||||||
"ipv4",
|
"ipv4",
|
||||||
|
"ipv6",
|
||||||
"arp",
|
"arp",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
@ -117,6 +118,8 @@ printDataType(virConnectPtr conn,
|
|||||||
nwItemDescPtr item)
|
nwItemDescPtr item)
|
||||||
{
|
{
|
||||||
int done;
|
int done;
|
||||||
|
int i, pos, s;
|
||||||
|
|
||||||
if (printVar(conn, vars, buf, bufsize, item, &done))
|
if (printVar(conn, vars, buf, bufsize, item, &done))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -136,6 +139,21 @@ printDataType(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case DATATYPE_MACADDR:
|
||||||
if (bufsize < VIR_MAC_STRING_BUFLEN) {
|
if (bufsize < VIR_MAC_STRING_BUFLEN) {
|
||||||
virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER,
|
virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER,
|
||||||
@ -155,6 +173,7 @@ printDataType(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_IPV6MASK:
|
||||||
case DATATYPE_IPMASK:
|
case DATATYPE_IPMASK:
|
||||||
case DATATYPE_UINT8:
|
case DATATYPE_UINT8:
|
||||||
if (snprintf(buf, bufsize, "%d",
|
if (snprintf(buf, bufsize, "%d",
|
||||||
@ -304,6 +323,7 @@ ebtablesCreateRuleInstance(virConnectPtr conn,
|
|||||||
{
|
{
|
||||||
char macaddr[VIR_MAC_STRING_BUFLEN],
|
char macaddr[VIR_MAC_STRING_BUFLEN],
|
||||||
ipaddr[INET_ADDRSTRLEN],
|
ipaddr[INET_ADDRSTRLEN],
|
||||||
|
ipv6addr[INET6_ADDRSTRLEN],
|
||||||
number[20];
|
number[20];
|
||||||
char chain[MAX_CHAINNAME_LENGTH];
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
@ -587,6 +607,135 @@ ebtablesCreateRuleInstance(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||||
virBufferVSprintf(&buf,
|
virBufferVSprintf(&buf,
|
||||||
CMD_DEF_PRE EBTABLES_CMD " -t %s -%%c %s %%s",
|
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_MAC:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
|
||||||
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
|
||||||
|
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
|
||||||
|
|
||||||
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
|
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
|
||||||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
|
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
|
||||||
@ -1230,6 +1380,11 @@ ebiptablesApplyNewRules(virConnectPtr conn,
|
|||||||
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv4))
|
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv4))
|
||||||
ebtablesCreateTmpSubChain(conn, &buf, 0, ifname, "ipv4", 1);
|
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
|
// keep arp as last
|
||||||
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_ARP))
|
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_ARP))
|
||||||
ebtablesCreateTmpSubChain(conn, &buf, 1, ifname, "arp", 1);
|
ebtablesCreateTmpSubChain(conn, &buf, 1, ifname, "arp", 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user