[libvirt] [PATCH v4 13/15] Add IPv6 support for the ebtables layer

Daniel Veillard veillard at redhat.com
Fri Mar 26 17:10:14 UTC 2010


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




More information about the libvir-list mailing list