Change in vdsm[master]: configNetwork: provide IPv6 configuration editing API

mhuntxu at gmail.com mhuntxu at gmail.com
Tue Feb 5 12:07:44 UTC 2013


Hunt Xu has uploaded a new change for review.

Change subject: configNetwork: provide IPv6 configuration editing API
......................................................................

configNetwork: provide IPv6 configuration editing API

Change-Id: Ibf39d8cba75e8879a84e83e22a46a4a00eab1384
Signed-off-by: huntxu <mhuntxu at gmail.com>
---
M vdsm/configNetwork.py
M vdsm_api/vdsmapi-schema.json
2 files changed, 157 insertions(+), 19 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/41/11741/1

diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py
index 963528c..4f1be10 100755
--- a/vdsm/configNetwork.py
+++ b/vdsm/configNetwork.py
@@ -415,7 +415,8 @@
 
     def _createConfFile(self, conf, name, ipaddr=None, netmask=None,
                         gateway=None, bootproto=None, mtu=None, onboot='yes',
-                        **kwargs):
+                        ipv6=False, ipv6addrs=None, ipv6gateway=None,
+                        dhcpv6=False, **kwargs):
         """ Create ifcfg-* file with proper fields per device """
 
         cfg = """DEVICE=%s\nONBOOT=%s\n""" % (pipes.quote(name),
@@ -435,6 +436,25 @@
         if mtu:
             cfg = cfg + 'MTU=%d\n' % mtu
         cfg += 'NM_CONTROLLED=no\n'
+
+        if ipv6:
+            cfg += 'IPV6INIT=yes\n'
+            ipv6autoconf = 'no'
+            if ipv6addrs is not None:
+                ipv6addrs = ipv6addrs.split(',')
+                primary = ipv6addrs[0]
+                secs = ' '.join(ipv6addrs[1:]).strip()
+                cfg += 'IPV6ADDR=%s\n' % pipes.quote(primary)
+                if secs:
+                    cfg += 'IPV6ADDR_SECONDARIES=%s\n' % pipes.quote(secs)
+                if ipv6gateway is not None:
+                    cfg += 'IPV6_DEFAULTGW=%s\n' % pipes.quote(ipv6gateway)
+            elif dhcpv6:
+                cfg += 'DHCPV6C=yes\n'
+            else:
+                ipv6autoconf = 'yes'
+            cfg += 'IPV6_AUTOCONF=%s\n' % pipes.quote(ipv6autoconf)
+
         BLACKLIST = ['TYPE', 'NAME', 'DEVICE', 'bondingOptions',
                      'force', 'blockingdhcp',
                      'connectivityCheck', 'connectivityTimeout',
@@ -489,6 +509,22 @@
                 if mtu:
                     mtu = int(mtu)
 
+            if not utils.tobool(kwargs.get('ipv6', False)):
+                if confParams.get('IPV6INIT', 'no') == 'yes':
+                    kwargs['ipv6'] = True
+                    kwargs['ipv6gateway'] = confParams.get('IPV6_DEFAULTGW',
+                                                           None)
+                    kwargs['dhcpv6'] = (confParams.get('DHCPV6C', 'no')
+                                        == 'yes')
+
+                    primary = confParams.get('IPV6ADDR', '')
+                    secs = confParams.get('IPV6ADDR_SECONDARIES', '')
+                    ipv6addrs = (primary + ' ' + secs).strip()
+                    if len(ipv6addrs) > 0:
+                        kwargs['ipv6addrs'] = ','.join(ipv6addrs.split(' '))
+                    else:
+                        kwargs['ipv6addrs'] = None
+
         self._createConfFile(conf, bonding, ipaddr, netmask, gateway,
                              bootproto, mtu, onboot, **kwargs)
 
@@ -521,6 +557,22 @@
                 mtu = confParams.get('MTU', None)
                 if mtu:
                     mtu = int(mtu)
+
+            if not utils.tobool(kwargs.get('ipv6', False)):
+                if confParams.get('IPV6INIT', 'no') == 'yes':
+                    kwargs['ipv6'] = True
+                    kwargs['ipv6gateway'] = confParams.get('IPV6_DEFAULTGW',
+                                                           None)
+                    kwargs['dhcpv6'] = (confParams.get('DHCPV6C', 'no')
+                                        == 'yes')
+
+                    primary = confParams.get('IPV6ADDR', '')
+                    secs = confParams.get('IPV6ADDR_SECONDARIES', '')
+                    ipv6addrs = (primary + ' ' + secs).strip()
+                    if len(ipv6addrs) > 0:
+                        kwargs['ipv6addrs'] = ','.join(ipv6addrs.split(' '))
+                    else:
+                        kwargs['ipv6addrs'] = None
 
         self._createConfFile(conf, nic, ipaddr, netmask, gateway,
                              bootproto, mtu, onboot, **kwargs)
@@ -718,6 +770,37 @@
                                  "Bad gateway: %r" % gateway)
 
 
+def _validateIPv6Address(address):
+    try:
+        socket.inet_pton(socket.AF_INET6, address)
+    except socket.error:
+        return False
+    return True
+
+
+def validateIPv6Address(addr):
+    if not _validateIPv6Address(addr):
+        raise ConfigNetworkError(ne.ERR_BAD_ADDR,
+                                 "Bad IPv6 address: %r" % addr)
+
+
+def validateIPv6Prefixlen(prefixlen):
+    try:
+        prefixlen = int(prefixlen)
+        if prefixlen < 0 or prefixlen > 127:
+            raise ConfigNetworkError(ne.ERR_BAD_ADDR,
+                                     "Bad IPv6 prefixlen: %r" % prefixlen)
+    except ValueError:
+        raise ConfigNetworkError(ne.ERR_BAD_ADDR,
+                                 "Bad IPv6 prefixlen: %r" % prefixlen)
+
+
+def validateIPv6Gateway(gateway):
+    if not _validateIPv6Address(gateway):
+        raise ConfigNetworkError(ne.ERR_BAD_ADDR,
+                                 "Bad IPv6 gateway: %r" % gateway)
+
+
 def validateBondingName(bonding):
     if not re.match('^bond[0-9]+$', bonding):
         raise ConfigNetworkError(ne.ERR_BAD_BONDING,
@@ -790,8 +873,9 @@
 
 
 def _addNetworkValidation(_netinfo, network, vlan, bonding, nics, ipaddr,
-                          netmask, gateway, bondingOptions, bridged=True,
-                          implicitBonding=False, **options):
+                          netmask, gateway, bondingOptions, ipv6=False,
+                          ipv6addrs=None, ipv6gateway=None, dhcpv6=False,
+                          bridged=True, implicitBonding=False, **options):
     # The (relatively) new setupNetwork verb allows to specify a network on
     # top of an existing bonding device. The nics of this bonds are taken
     # implictly from current host configuration
@@ -825,6 +909,24 @@
         if netmask or gateway:
             raise ConfigNetworkError(ne.ERR_BAD_ADDR,
                                      'Specified netmask or gateway but not ip')
+
+    # Check IPv6
+    if ipv6:
+        if ipv6addrs:
+            if dhcpv6:
+                raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Specified both'
+                                         'IPv6 addresses and DHCPv6')
+            for addr in ipv6addrs.split(','):
+                if '/' in addr:  # prefixlen is optional
+                    addr, prefixlen = addr.split('/')
+                    validateIPv6Prefixlen(prefixlen)
+                validateIPv6Address(addr)
+        if ipv6gateway:
+            validateIPv6Gateway(ipv6gateway)
+    else:
+        if ipv6addrs or ipv6gateway or dhcpv6:
+            raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'Specified IPv6-'
+                                     'related params with IPv6 disabled')
 
     # Check bonding
     if bonding:
@@ -876,6 +978,11 @@
     nics = nics or ()
     _netinfo = netinfo.NetInfo()
     bridged = utils.tobool(bridged)
+
+    if 'ipv6' in options:
+        options['ipv6'] = utils.tobool(options['ipv6'])
+    if 'dhcpv6' in options:
+        options['dhcpv6'] = utils.tobool(options['dhcpv6'])
 
     if mtu:
         mtu = int(mtu)
@@ -932,6 +1039,8 @@
         # reset ip, netmask, gateway and bootproto for lower level devices
         bridgeBootproto = options.get('bootproto')
         ipaddr = netmask = gateway = options['bootproto'] = None
+        options['ipv6'] = options['dhcpv6'] = False
+        options['ipv6addrs'] = options['ipv6gateway'] = None
 
     # For VLAN we should attach bridge only to the VLAN device
     # rather than to underlying NICs or bond
@@ -952,6 +1061,8 @@
         vlanBootproto = options.get('bootproto')
         # reset ip, netmask, gateway and bootproto for lower level devices
         ipaddr = netmask = gateway = options['bootproto'] = None
+        options['ipv6'] = options['dhcpv6'] = False
+        options['ipv6addrs'] = options['ipv6gateway'] = None
 
     # First we need to prepare all conf files
     if bonding:
@@ -963,6 +1074,8 @@
         bondBootproto = options.get('bootproto')
         # reset ip, netmask, gateway and bootproto for lower level devices
         ipaddr = netmask = gateway = options['bootproto'] = None
+        options['ipv6'] = options['dhcpv6'] = False
+        options['ipv6addrs'] = options['ipv6gateway'] = None
 
     for nic in nics:
         configWriter.addNic(nic, bonding=bonding,
@@ -1302,6 +1415,10 @@
                         ipaddr="<ip>"
                         netmask="<ip>"
                         gateway="<ip>"
+                        ipv6=True|False
+                        ipv6addrs="<ip>[/<prefixlen>], ..." | dhcpv6=True|False
+                        (ipv6addrs and dhcpv6 are mutually exclusive)
+                        ipv6gateway="<ip>"
                         bootproto="..."
                         delay="..."
                         onboot="yes"|"no"
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index e2512ea..6d9c64e 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -54,6 +54,15 @@
 #
 # @gateway:         #optional IP address of the network gateway
 #
+# @ipv6:            #optional Whether to use IPv6 on the interface
+#
+# @ipv6addrs:       #optional A list of IPv6 addresses to be assigned to the
+#                   interface (in the format of '<ip>[/<prefixlen>], ...')
+#
+# @ipv6gateway:     #optional IPv6 address of the gateway of the network
+#
+# @dhcpv6:          #optional Whether to use DHCPv6 on the interface
+#
 # @bootproto:       #optional Interface autoconfiguration protocol (typically
 #                   'dhcp' or 'static')
 #
@@ -67,8 +76,9 @@
 ##
 {'type': 'NetworkOptions',
  'data': {'*ipaddr': 'str', '*netmask': 'str', '*gateway': 'str',
-          '*bootproto': 'str', '*delay': 'uint', '*onboot': 'str',
-          '*bondingOptions', 'str'}}
+          '*ipv6': 'bool', '*ipv6addrs': 'str', '*ipv6gateway': 'str',
+          '*dhcpv6': 'bool', '*bootproto': 'str', '*delay': 'uint',
+          '*onboot': 'str', '*bondingOptions', 'str'}}
 
 ##
 # @Host.addNetwork:
@@ -141,34 +151,45 @@
 #
 # Configuration attributes for a single host network.
 #
-# @vlan:       #optional The name of an associated vlan
+# @vlan:        #optional The name of an associated vlan
 #
-# @bonding:    #optional If the network is bonded, the name of the bond device
+# @bonding:     #optional If the network is bonded, the name of the bond device
 #
-# @nic:        #optional If the network is not bonded, an array containing a
-#              single network device name
+# @nic:         #optional If the network is not bonded, an array containing a
+#               single network device name
 #
-# @ipaddr:     #optional Assign this static IP address to the network
+# @ipaddr:      #optional Assign this static IP address to the network
 #
-# @netmask:    #optional Assign this netmask to the network
+# @netmask:     #optional Assign this netmask to the network
 #
-# @gateway:    #optional Assign this gateway to the network
+# @gateway:     #optional Assign this gateway to the network
 #
-# @bootproto:  #optional Interface autoconfiguration protocol (typically 'dhcp'
-#              or 'static')
+# @ipv6:        #optional Whether to use IPv6 on the interface
 #
-# @delay:      #optional The time to wait before starting the network device
+# @ipv6addrs:   #optional A list of IPv6 addresses to be assigned to the
+#                   interface (in the format of '<ip>[/<prefixlen>], ...')
 #
-# @onboot:     #optional Start the network device automatically during boot
+# @ipv6gateway: #optional IPv6 address of the gateway of the network
 #
-# @remove:     #optional If True, remove existing network only
+# @dhcpv6:      #optional Whether to use DHCPv6 on the interface
+#
+# @bootproto:   #optional Interface autoconfiguration protocol (typically
+#               'dhcp' or 'static')
+#
+# @delay:       #optional The time to wait before starting the network device
+#
+# @onboot:      #optional Start the network device automatically during boot
+#
+# @remove:      #optional If True, remove existing network only
 #
 # Since: 4.10.0
 ##
 {'type': 'SetupNetworkNetAttributes',
  'data': {'*vlan': 'str', '*bonding': 'str', '*nic': ['str'], '*ipaddr': 'str',
-          '*netmask': 'str', '*gateway': 'str', '*bootproto': 'str',
-          '*delay': 'uint', '*onboot': 'bool', '*remove': 'bool'}}
+          '*netmask': 'str', '*gateway': 'str', '*ipv6': 'bool',
+          '*ipv6addrs': 'str', '*ipv6gateway': 'str', '*dhcpv6': 'bool',
+          '*bootproto': 'str', '*delay': 'uint', '*onboot': 'bool',
+          '*remove': 'bool'}}
 
 ##
 # @SetupNetworkBondAttributes:


--
To view, visit http://gerrit.ovirt.org/11741
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibf39d8cba75e8879a84e83e22a46a4a00eab1384
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Hunt Xu <mhuntxu at gmail.com>


More information about the vdsm-patches mailing list