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(a)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(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/