18698425 DHCP and L3 agent are unable to plumb VNICs with IPv6 address
authorGirish Moodalbail <Girish.Moodalbail@oracle.COM>
Sun, 04 May 2014 18:23:14 -0700
changeset 1872 0b81e3d9f3ae
parent 1871 0a2201439908
child 1873 7aace11840a0
18698425 DHCP and L3 agent are unable to plumb VNICs with IPv6 address 18700171 Neutron DHCP agent fails to run dnsmasq(8) for IPv6 subnets
components/openstack/neutron/files/agent/solaris/dhcp.py
components/openstack/neutron/files/agent/solaris/net_lib.py
--- a/components/openstack/neutron/files/agent/solaris/dhcp.py	Fri May 02 19:59:18 2014 -0700
+++ b/components/openstack/neutron/files/agent/solaris/dhcp.py	Sun May 04 18:23:14 2014 -0700
@@ -252,11 +252,11 @@
             '--except-interface=lo0',
             '--pid-file=%s' % self.get_conf_file_name(
                 'pid', ensure_conf_dir=True),
-            #TODO(gmoodalb): calculate value from cidr (defaults to 150)
-            #'--dhcp-lease-max=%s' % ?,
+            # TODO(gmoodalb): calculate value from cidr (defaults to 150)
+            # '--dhcp-lease-max=%s' % ?,
             '--dhcp-hostsfile=%s' % self._output_hosts_file(),
             '--dhcp-optsfile=%s' % self._output_opts_file(),
-            #'--dhcp-script=%s' % self._lease_relay_script_path(),
+            # '--dhcp-script=%s' % self._lease_relay_script_path(),
             '--leasefile-ro',
         ]
 
@@ -267,8 +267,17 @@
             if subnet.ip_version == 4:
                 mode = 'static'
             else:
-                #TODO(gmoodalb): how do we indicate other options
-                #ra-only, slaac, ra-nameservers, and ra-stateless.
+                # TODO(gmoodalb): how do we indicate other options
+                # ra-only, slaac, ra-nameservers, and ra-stateless.
+                # We need to also set the DUID for DHCPv6 server to use
+                macaddr_cmd = ['/usr/sbin/dladm', 'show-linkprop',
+                               '-co', 'value', '-p', 'mac-address',
+                               self.interface_name]
+                stdout = utils.execute(macaddr_cmd)
+                uid = stdout.splitlines()[0].strip()
+                # IANA assigned ID for Oracle
+                enterprise_id = '111'
+                cmd.append('--dhcp-duid=%s,%s' % (enterprise_id, uid))
                 mode = 'static'
             cmd.append('--dhcp-range=set:%s,%s,%s,%ss' %
                        (self._TAG_PREFIX % i,
--- a/components/openstack/neutron/files/agent/solaris/net_lib.py	Fri May 02 19:59:18 2014 -0700
+++ b/components/openstack/neutron/files/agent/solaris/net_lib.py	Sun May 04 18:23:14 2014 -0700
@@ -17,6 +17,8 @@
 # @author: Girish Moodalbail, Oracle, Inc.
 #
 
+import netaddr
+
 from quantum.agent.linux import utils
 
 
@@ -72,10 +74,7 @@
             val.append(addr)
         return result
 
-    #TODO(gmoodalb): - might not work for IPv6
-    def create_address(self, ipaddr, addrobjname=None,
-                       addrtype='static', temp=True):
-
+    def create_address(self, ipaddr, addrobjname=None, temp=True):
         if not self.ifname_exists(self._ifname):
             # create ip interface
             cmd = ['/usr/sbin/ipadm', 'create-ip', self._ifname]
@@ -86,7 +85,25 @@
         if self.ipaddr_exists(self._ifname, ipaddr):
             return
 
-        cmd = ['/usr/sbin/ipadm', 'create-addr', '-T', addrtype, '-a',
+        # If an address is IPv6, then to create a static IPv6 address
+        # we need to create link-local address first
+        if netaddr.IPNetwork(ipaddr).version == 6:
+            # check if link-local address already exists
+            cmd = ['/usr/sbin/dladm', 'show-linkprop', '-co', 'value',
+                   '-p', 'mac-address', self._ifname]
+            stdout = self.execute(cmd)
+            mac_addr = stdout.splitlines()[0].strip()
+            ll_addr = netaddr.EUI(mac_addr).ipv6_link_local()
+
+            if not self.ipaddr_exists(self._ifname, str(ll_addr)):
+                # create a link-local address
+                cmd = ['/usr/sbin/ipadm', 'create-addr', '-T', 'static', '-a',
+                       str(ll_addr), self._ifname]
+                if temp:
+                    cmd.append('-t')
+                self.execute_with_pfexec(cmd)
+
+        cmd = ['/usr/sbin/ipadm', 'create-addr', '-T', 'static', '-a',
                ipaddr, self._ifname]
         if temp:
             cmd.append('-t')
@@ -109,9 +126,9 @@
             self.execute_with_pfexec(cmd)
             break
 
-        if len(aobj_addrs) == 1:
+        isV6 = netaddr.IPNetwork(ipaddr).version == 6
+        if len(aobj_addrs) == 1 or (isV6 and len(aobj_addrs) == 2):
             # delete the interface as well
-            # TODO(gmoodalb): might not work for ipv6
             cmd = ['/usr/sbin/ipadm', 'delete-ip', self._ifname]
             self.execute_with_pfexec(cmd)