18698425 DHCP and L3 agent are unable to plumb VNICs with IPv6 address s11-update
authorGirish Moodalbail <Girish.Moodalbail@oracle.COM>
Tue, 06 May 2014 10:16:09 -0700
branchs11-update
changeset 3121 462024268450
parent 3120 ad554abcb0c5
child 3123 561512d0b61d
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	Mon May 05 23:01:08 2014 -0700
+++ b/components/openstack/neutron/files/agent/solaris/dhcp.py	Tue May 06 10:16:09 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	Mon May 05 23:01:08 2014 -0700
+++ b/components/openstack/neutron/files/agent/solaris/net_lib.py	Tue May 06 10:16:09 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)