
On Thu, Mar 25, 2010 at 01:46:11PM -0400, Stefan Berger wrote:
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>
[...]
+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; +} +
hum, we already have an IPv6 parser, virSocketParseIpv6Addr() can we reuse that instead of an hand made parser ?
+ if (checkIPv6Mask(datatype, + ipaddr.addr.ipv6Addr, nwf)) + *(uint8_t *)storage_ptr = + getMaskNumBits(ipaddr.addr.ipv6Addr, + sizeof(ipaddr.addr.ipv6Addr));
there are also already netmask checkers for IPv4 and IPv6, let's reuse them
@@ -1076,6 +1264,13 @@ virNWFilterRuleDefFixup(virNWFilterRuleD 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, n 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, ":"); }
and virSocketFormatAddr()
@@ -304,6 +323,7 @@ ebtablesCreateRuleInstance(virConnectPtr { char macaddr[VIR_MAC_STRING_BUFLEN], ipaddr[INET_ADDRSTRLEN], + ipv6addr[INET6_ADDRSTRLEN], number[20]; char chain[MAX_CHAINNAME_LENGTH]; virBuffer buf = VIR_BUFFER_INITIALIZER;
it seems that code was really coded without looking at util/network.h first. I don't think it's a blocker but I would like to see this reunified, unless network.h routines really prove unusable (but maybe we should fix them instead then). 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/