]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Allow DHCPv6 reply from server to client
authorXu Han Peng <xuhanp@cn.ibm.com>
Tue, 1 Jul 2014 08:57:51 +0000 (16:57 +0800)
committerXu Han Peng <xuhanp@cn.ibm.com>
Wed, 10 Sep 2014 10:58:08 +0000 (18:58 +0800)
Add security group rule to allow DHCPv6 reply from dhcp server
link local addres port 547 to client port 546.

Change-Id: I5fd9561e855b1d3999649934977af659d5ca221f
Closes-Bug: 1335984

neutron/db/securitygroups_rpc_base.py
neutron/tests/unit/bigswitch/test_base.py
neutron/tests/unit/test_security_groups_rpc.py

index 6555850dde312389bd65d8f93e0352e8c14bfab2..8f87a8c804f78619f0c954fbfe1a68ce35399117 100644 (file)
@@ -27,13 +27,11 @@ from neutron.openstack.common import log as logging
 LOG = logging.getLogger(__name__)
 
 
-IP_MASK = {q_const.IPv4: 32,
-           q_const.IPv6: 128}
-
-
 DIRECTION_IP_PREFIX = {'ingress': 'source_ip_prefix',
                        'egress': 'dest_ip_prefix'}
 
+DHCP_RULE_PORT = {4: (67, 68, q_const.IPv4), 6: (547, 546, q_const.IPv6)}
+
 
 class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
     """Mixin class to add agent-based security group implementation."""
@@ -282,7 +280,14 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
             ips[network_id] = []
 
         for port, ip in query:
-            ips[port['network_id']].append(ip)
+            if (netaddr.IPAddress(ip).version == 6
+                and not netaddr.IPAddress(ip).is_link_local()):
+                mac_address = port['mac_address']
+                ip = str(ipv6.get_ipv6_addr_by_EUI64(q_const.IPV6_LLA_PREFIX,
+                    mac_address))
+            if ip not in ips[port['network_id']]:
+                ips[port['network_id']].append(ip)
+
         return ips
 
     def _select_ra_ips_for_network_ids(self, context, network_ids):
@@ -376,18 +381,16 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
     def _add_ingress_dhcp_rule(self, port, ips):
         dhcp_ips = ips.get(port['network_id'])
         for dhcp_ip in dhcp_ips:
-            if not netaddr.IPAddress(dhcp_ip).version == 4:
-                return
-
+            source_port, dest_port, ethertype = DHCP_RULE_PORT[
+                netaddr.IPAddress(dhcp_ip).version]
             dhcp_rule = {'direction': 'ingress',
-                         'ethertype': q_const.IPv4,
+                         'ethertype': ethertype,
                          'protocol': 'udp',
-                         'port_range_min': 68,
-                         'port_range_max': 68,
-                         'source_port_range_min': 67,
-                         'source_port_range_max': 67}
-            dhcp_rule['source_ip_prefix'] = "%s/%s" % (dhcp_ip,
-                                                       IP_MASK[q_const.IPv4])
+                         'port_range_min': dest_port,
+                         'port_range_max': dest_port,
+                         'source_port_range_min': source_port,
+                         'source_port_range_max': source_port,
+                         'source_ip_prefix': dhcp_ip}
             port['security_group_rules'].append(dhcp_rule)
 
     def _add_ingress_ra_rule(self, port, ips):
index e31760e4ff6a028c640b666264fb5e512757a684..422c5b95d46432e5642865cad12c4c8ff11f0bf4 100644 (file)
@@ -52,6 +52,7 @@ class BigSwitchTestBase(object):
         # The mock interferes with HTTP(S) connection caching
         cfg.CONF.set_override('cache_connections', False, 'RESTPROXY')
         cfg.CONF.set_override('service_plugins', ['bigswitch_l3'])
+        cfg.CONF.set_override('add_meta_server_route', False, 'RESTPROXY')
 
     def setup_patches(self):
         self.plugin_notifier_p = mock.patch(NOTIFIER)
index c841bf322e828ff174c9d725d3d4fa740153904c..ee6e2f72be85a74a61854325a3d909f8dba28f68 100644 (file)
@@ -44,7 +44,8 @@ FAKE_PREFIX = {const.IPv4: '10.0.0.0/24',
 FAKE_IP = {const.IPv4: '10.0.0.1',
            const.IPv6: 'fe80::1',
            'IPv6_GLOBAL': '2001:0db8::1',
-           'IPv6_LLA': 'fe80::123'}
+           'IPv6_LLA': 'fe80::123',
+           'IPv6_DHCP': '2001:db8::3'}
 
 
 TEST_PLUGIN_CLASS = ('neutron.tests.unit.test_security_groups_rpc.'
@@ -483,6 +484,18 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
                 self.deserialize(self.fmt, res)
                 self.assertEqual(res.status_int, webob.exc.HTTPCreated.code)
 
+                dhcp_port = self._create_port(
+                    self.fmt, n['network']['id'],
+                    fixed_ips=[{'subnet_id': subnet_v6['subnet']['id'],
+                                'ip_address': FAKE_IP['IPv6_DHCP']}],
+                    device_owner=const.DEVICE_OWNER_DHCP,
+                    security_groups=[sg1_id])
+                dhcp_rest = self.deserialize(self.fmt, dhcp_port)
+                dhcp_mac = dhcp_rest['port']['mac_address']
+                dhcp_lla_ip = str(ipv6.get_ipv6_addr_by_EUI64(
+                    const.IPV6_LLA_PREFIX,
+                    dhcp_mac))
+
                 res1 = self._create_port(
                     self.fmt, n['network']['id'],
                     fixed_ips=[{'subnet_id': subnet_v6['subnet']['id']}],
@@ -495,6 +508,7 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
                 ports_rpc = self.rpc.security_group_rules_for_devices(
                     ctx, devices=devices)
                 port_rpc = ports_rpc[port_id1]
+                source_port, dest_port, ethertype = sg_db_rpc.DHCP_RULE_PORT[6]
                 expected = [{'direction': 'egress', 'ethertype': const.IPv4,
                              'security_group_id': sg1_id},
                             {'direction': 'egress', 'ethertype': const.IPv6,
@@ -517,6 +531,14 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
                              'ethertype': const.IPv6,
                              'source_ip_prefix': fake_gateway,
                              'source_port_range_min': const.ICMPV6_TYPE_RA},
+                            {'direction': 'ingress',
+                             'ethertype': ethertype,
+                             'port_range_max': dest_port,
+                             'port_range_min': dest_port,
+                             'protocol': const.PROTO_NAME_UDP,
+                             'source_ip_prefix': dhcp_lla_ip,
+                             'source_port_range_max': source_port,
+                             'source_port_range_min': source_port}
                             ]
                 self.assertEqual(port_rpc['security_group_rules'],
                                  expected)