Allow DHCPv6 reply from server to client
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
This commit is contained in:
parent
465f83fc24
commit
fc619a29c9
@ -27,13 +27,11 @@ from neutron.openstack.common import log as logging
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
IP_MASK = {q_const.IPv4: 32,
|
|
||||||
q_const.IPv6: 128}
|
|
||||||
|
|
||||||
|
|
||||||
DIRECTION_IP_PREFIX = {'ingress': 'source_ip_prefix',
|
DIRECTION_IP_PREFIX = {'ingress': 'source_ip_prefix',
|
||||||
'egress': 'dest_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):
|
class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
|
||||||
"""Mixin class to add agent-based security group implementation."""
|
"""Mixin class to add agent-based security group implementation."""
|
||||||
@ -282,7 +280,14 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
|
|||||||
ips[network_id] = []
|
ips[network_id] = []
|
||||||
|
|
||||||
for port, ip in query:
|
for port, ip in query:
|
||||||
|
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)
|
ips[port['network_id']].append(ip)
|
||||||
|
|
||||||
return ips
|
return ips
|
||||||
|
|
||||||
def _select_ra_ips_for_network_ids(self, context, network_ids):
|
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):
|
def _add_ingress_dhcp_rule(self, port, ips):
|
||||||
dhcp_ips = ips.get(port['network_id'])
|
dhcp_ips = ips.get(port['network_id'])
|
||||||
for dhcp_ip in dhcp_ips:
|
for dhcp_ip in dhcp_ips:
|
||||||
if not netaddr.IPAddress(dhcp_ip).version == 4:
|
source_port, dest_port, ethertype = DHCP_RULE_PORT[
|
||||||
return
|
netaddr.IPAddress(dhcp_ip).version]
|
||||||
|
|
||||||
dhcp_rule = {'direction': 'ingress',
|
dhcp_rule = {'direction': 'ingress',
|
||||||
'ethertype': q_const.IPv4,
|
'ethertype': ethertype,
|
||||||
'protocol': 'udp',
|
'protocol': 'udp',
|
||||||
'port_range_min': 68,
|
'port_range_min': dest_port,
|
||||||
'port_range_max': 68,
|
'port_range_max': dest_port,
|
||||||
'source_port_range_min': 67,
|
'source_port_range_min': source_port,
|
||||||
'source_port_range_max': 67}
|
'source_port_range_max': source_port,
|
||||||
dhcp_rule['source_ip_prefix'] = "%s/%s" % (dhcp_ip,
|
'source_ip_prefix': dhcp_ip}
|
||||||
IP_MASK[q_const.IPv4])
|
|
||||||
port['security_group_rules'].append(dhcp_rule)
|
port['security_group_rules'].append(dhcp_rule)
|
||||||
|
|
||||||
def _add_ingress_ra_rule(self, port, ips):
|
def _add_ingress_ra_rule(self, port, ips):
|
||||||
|
@ -52,6 +52,7 @@ class BigSwitchTestBase(object):
|
|||||||
# The mock interferes with HTTP(S) connection caching
|
# The mock interferes with HTTP(S) connection caching
|
||||||
cfg.CONF.set_override('cache_connections', False, 'RESTPROXY')
|
cfg.CONF.set_override('cache_connections', False, 'RESTPROXY')
|
||||||
cfg.CONF.set_override('service_plugins', ['bigswitch_l3'])
|
cfg.CONF.set_override('service_plugins', ['bigswitch_l3'])
|
||||||
|
cfg.CONF.set_override('add_meta_server_route', False, 'RESTPROXY')
|
||||||
|
|
||||||
def setup_patches(self):
|
def setup_patches(self):
|
||||||
self.plugin_notifier_p = mock.patch(NOTIFIER)
|
self.plugin_notifier_p = mock.patch(NOTIFIER)
|
||||||
|
@ -44,7 +44,8 @@ FAKE_PREFIX = {const.IPv4: '10.0.0.0/24',
|
|||||||
FAKE_IP = {const.IPv4: '10.0.0.1',
|
FAKE_IP = {const.IPv4: '10.0.0.1',
|
||||||
const.IPv6: 'fe80::1',
|
const.IPv6: 'fe80::1',
|
||||||
'IPv6_GLOBAL': '2001:0db8::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.'
|
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.deserialize(self.fmt, res)
|
||||||
self.assertEqual(res.status_int, webob.exc.HTTPCreated.code)
|
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(
|
res1 = self._create_port(
|
||||||
self.fmt, n['network']['id'],
|
self.fmt, n['network']['id'],
|
||||||
fixed_ips=[{'subnet_id': subnet_v6['subnet']['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(
|
ports_rpc = self.rpc.security_group_rules_for_devices(
|
||||||
ctx, devices=devices)
|
ctx, devices=devices)
|
||||||
port_rpc = ports_rpc[port_id1]
|
port_rpc = ports_rpc[port_id1]
|
||||||
|
source_port, dest_port, ethertype = sg_db_rpc.DHCP_RULE_PORT[6]
|
||||||
expected = [{'direction': 'egress', 'ethertype': const.IPv4,
|
expected = [{'direction': 'egress', 'ethertype': const.IPv4,
|
||||||
'security_group_id': sg1_id},
|
'security_group_id': sg1_id},
|
||||||
{'direction': 'egress', 'ethertype': const.IPv6,
|
{'direction': 'egress', 'ethertype': const.IPv6,
|
||||||
@ -517,6 +531,14 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
|
|||||||
'ethertype': const.IPv6,
|
'ethertype': const.IPv6,
|
||||||
'source_ip_prefix': fake_gateway,
|
'source_ip_prefix': fake_gateway,
|
||||||
'source_port_range_min': const.ICMPV6_TYPE_RA},
|
'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'],
|
self.assertEqual(port_rpc['security_group_rules'],
|
||||||
expected)
|
expected)
|
||||||
|
Loading…
Reference in New Issue
Block a user