Fix DVR flow problems for IPv6 subnet
This code fixes DVR flow problems by changing proto='ip' to proto='ipv6' and changing nw_dst to ipv6_dst. When DVR is enabled, RADVD is spawned by l3 agent on each compute node. This code also prevent IPv6 Router Advertisement from sending to other compute nodes. Change-Id: Id94acd85ea124eff6cfdfbfc546f5dd4ca81ef43 Closes-Bug: 1398244 Closes-Bug: 1398627 Partial-Bug: 1376325
This commit is contained in:
parent
197838bb7d
commit
727417e71e
|
@ -388,23 +388,27 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
ofports = ','.join(map(str, ldm.get_compute_ofports().values()))
|
||||
if csnat_ofport != constants.OFPORT_INVALID:
|
||||
ofports = str(csnat_ofport) + ',' + ofports
|
||||
ip_version = subnet_info['ip_version']
|
||||
if ofports:
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
"output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC, local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
|
||||
self.tun_br.add_flow(table=constants.DVR_PROCESS,
|
||||
priority=3,
|
||||
dl_vlan=local_vlan,
|
||||
proto='arp',
|
||||
nw_dst=subnet_info['gateway_ip'],
|
||||
actions="drop")
|
||||
args = {'table': constants.DVR_PROCESS,
|
||||
'priority': 3,
|
||||
'dl_vlan': local_vlan,
|
||||
'actions': "drop"}
|
||||
if ip_version == 4:
|
||||
args['proto'] = 'arp'
|
||||
args['nw_dst'] = subnet_info['gateway_ip']
|
||||
else:
|
||||
args['proto'] = 'icmp6'
|
||||
args['icmp_type'] = n_const.ICMPV6_TYPE_RA
|
||||
args['dl_src'] = subnet_info['gateway_mac']
|
||||
|
||||
self.tun_br.add_flow(**args)
|
||||
self.tun_br.add_flow(table=constants.DVR_PROCESS,
|
||||
priority=2,
|
||||
dl_vlan=local_vlan,
|
||||
|
@ -477,14 +481,12 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
|
||||
if csnat_ofport != constants.OFPORT_INVALID:
|
||||
ofports = str(csnat_ofport) + ',' + ofports
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
ip_version = subnet_info['ip_version']
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC, local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
|
||||
def _bind_centralized_snat_port_on_dvr_subnet(self, port, fixed_ips,
|
||||
device_owner, local_vlan):
|
||||
|
@ -532,14 +534,15 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
ofports = ','.join(map(str, ldm.get_compute_ofports().values()))
|
||||
ofports = str(ldm.get_csnat_ofport()) + ',' + ofports
|
||||
ip_subnet = subnet_info['cidr']
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
|
||||
# TODO(xuhanp) remove the IPv6 related add_flow once SNAT is not
|
||||
# used for IPv6 DVR.
|
||||
ip_version = subnet_info['ip_version']
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC, local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
|
||||
def bind_port_to_dvr(self, port, network_type, fixed_ips,
|
||||
device_owner, local_vlan_id):
|
||||
|
@ -592,32 +595,39 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
dl_vlan=local_vlan,
|
||||
dl_dst=ovsport.get_mac())
|
||||
ldm.remove_all_compute_ofports()
|
||||
|
||||
ip_version = subnet_info['ip_version']
|
||||
if ldm.get_csnat_ofport() != -1:
|
||||
# If there is a csnat port on this agent, preserve
|
||||
# the local_dvr_map state
|
||||
ofports = str(ldm.get_csnat_ofport())
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
|
||||
else:
|
||||
# removed port is a distributed router interface
|
||||
self.int_br.delete_flows(table=constants.DVR_TO_SRC_MAC,
|
||||
proto='ip', dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet)
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet, None, None)
|
||||
self.int_br.delete_flows(**args)
|
||||
# remove subnet from local_dvr_map as no dvr (or) csnat
|
||||
# ports available on this agent anymore
|
||||
self.local_dvr_map.pop(sub_uuid, None)
|
||||
|
||||
self.tun_br.delete_flows(table=constants.DVR_PROCESS,
|
||||
dl_vlan=local_vlan,
|
||||
proto='arp',
|
||||
nw_dst=subnet_info['gateway_ip'])
|
||||
args = {'table': constants.DVR_PROCESS,
|
||||
'dl_vlan': local_vlan}
|
||||
if ip_version == 4:
|
||||
args['proto'] = 'arp'
|
||||
args['nw_dst'] = subnet_info['gateway_ip']
|
||||
else:
|
||||
args['proto'] = 'icmp6'
|
||||
args['icmp_type'] = n_const.ICMPV6_TYPE_RA
|
||||
args['dl_src'] = subnet_info['gateway_mac']
|
||||
|
||||
self.tun_br.delete_flows(**args)
|
||||
ovsport.remove_subnet(sub_uuid)
|
||||
|
||||
self.tun_br.delete_flows(table=constants.DVR_PROCESS,
|
||||
|
@ -649,7 +659,7 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
ldm.remove_compute_ofport(port.vif_id)
|
||||
ofports = ','.join(map(str, ldm.get_compute_ofports().values()))
|
||||
ip_subnet = subnet_info['cidr']
|
||||
|
||||
ip_version = subnet_info['ip_version']
|
||||
# first remove this vm port rule
|
||||
self.int_br.delete_flows(table=constants.DVR_TO_SRC_MAC,
|
||||
dl_vlan=local_vlan,
|
||||
|
@ -658,33 +668,29 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
# If there is a csnat port on this agent, preserve
|
||||
# the local_dvr_map state
|
||||
ofports = str(ldm.get_csnat_ofport()) + ',' + ofports
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
else:
|
||||
if ofports:
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'],
|
||||
ofports))
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
else:
|
||||
# remove the flow altogether, as no ports (both csnat/
|
||||
# compute) are available on this subnet in this
|
||||
# agent
|
||||
self.int_br.delete_flows(table=constants.DVR_TO_SRC_MAC,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet)
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet, None, None)
|
||||
self.int_br.delete_flows(**args)
|
||||
|
||||
# release port state
|
||||
self.local_ports.pop(port.vif_id, None)
|
||||
|
||||
|
@ -708,22 +714,23 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
self.int_br.delete_flows(table=constants.DVR_TO_SRC_MAC,
|
||||
dl_vlan=local_vlan,
|
||||
dl_dst=ovsport.get_mac())
|
||||
|
||||
ofports = ','.join(map(str, ldm.get_compute_ofports().values()))
|
||||
ip_version = subnet_info['ip_version']
|
||||
if ofports:
|
||||
self.int_br.add_flow(table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
" output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports))
|
||||
# TODO(xuhanp) remove the IPv6 related add_flow once SNAT is not
|
||||
# used for IPv6 DVR.
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet,
|
||||
2, ("strip_vlan,mod_dl_src:%s,output:%s" %
|
||||
(subnet_info['gateway_mac'], ofports)))
|
||||
self.int_br.add_flow(**args)
|
||||
else:
|
||||
self.int_br.delete_flows(table=constants.DVR_TO_SRC_MAC,
|
||||
proto='ip',
|
||||
dl_vlan=local_vlan,
|
||||
nw_dst=ip_subnet)
|
||||
args = self._get_flow_args_by_version(
|
||||
ip_version, constants.DVR_TO_SRC_MAC,
|
||||
local_vlan, ip_subnet, None, None)
|
||||
self.int_br.delete_flows(**args)
|
||||
|
||||
if not ldm.is_dvr_owned():
|
||||
# if not owned by DVR (only used for csnat), remove this
|
||||
# subnet state altogether
|
||||
|
@ -732,6 +739,27 @@ class OVSDVRNeutronAgent(dvr_rpc.DVRAgentRpcApiMixin):
|
|||
# release port state
|
||||
self.local_ports.pop(port.vif_id, None)
|
||||
|
||||
def _get_flow_args_by_version(self, ip_version, table,
|
||||
vlan, subnet, priority, actions):
|
||||
"""
|
||||
Get flow args for DVR by IP version.
|
||||
priority and actions are optional to support both add_flows
|
||||
and delete_flows
|
||||
"""
|
||||
args = {'table': table,
|
||||
'dl_vlan': vlan}
|
||||
if ip_version == 4:
|
||||
args['proto'] = 'ip'
|
||||
args['nw_dst'] = subnet
|
||||
else:
|
||||
args['proto'] = 'ipv6'
|
||||
args['ipv6_dst'] = subnet
|
||||
if priority:
|
||||
args['priority'] = priority
|
||||
if actions:
|
||||
args['actions'] = actions
|
||||
return args
|
||||
|
||||
def unbind_port_from_dvr(self, vif_port, local_vlan_id):
|
||||
if not self.in_distributed_mode():
|
||||
return
|
||||
|
|
|
@ -219,6 +219,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
|
||||
return_value={'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
'ip_version': 4,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
@ -241,8 +242,14 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
self.assertTrue(add_flow_tun_fn.called)
|
||||
self.assertTrue(delete_flows_int_fn.called)
|
||||
|
||||
def _test_port_bound_for_dvr(self, device_owner):
|
||||
def _test_port_bound_for_dvr(self, device_owner, ip_version=4):
|
||||
self._setup_for_dvr_test()
|
||||
if ip_version == 4:
|
||||
gateway_ip = '1.1.1.1'
|
||||
cidr = '1.1.1.0/24'
|
||||
else:
|
||||
gateway_ip = '2001:100::1'
|
||||
cidr = '2001:100::0/64'
|
||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||
'set_db_attribute',
|
||||
return_value=True):
|
||||
|
@ -253,8 +260,9 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_subnet_for_dvr',
|
||||
return_value={
|
||||
'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
'gateway_ip': gateway_ip,
|
||||
'cidr': cidr,
|
||||
'ip_version': ip_version,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
@ -274,24 +282,96 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
None, None, self._fixed_ips,
|
||||
n_const.DEVICE_OWNER_DVR_INTERFACE,
|
||||
False)
|
||||
expected = [
|
||||
mock.call(
|
||||
table=constants.TUN_TABLE['vxlan'],
|
||||
priority=1, tun_id=None,
|
||||
actions="mod_vlan_vid:%s,"
|
||||
"resubmit(,%s)" %
|
||||
(self.agent.local_vlan_map[self._net_uuid].vlan,
|
||||
constants.DVR_NOT_LEARN)),
|
||||
mock.call(
|
||||
table=constants.DVR_PROCESS, priority=2,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
dl_dst=self._port.vif_mac,
|
||||
actions='drop'),
|
||||
mock.call(
|
||||
table=constants.DVR_PROCESS, priority=1,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
dl_src=self._port.vif_mac,
|
||||
actions="mod_dl_src:%s,resubmit(,%s)" % (
|
||||
self.agent.dvr_agent.dvr_mac_address,
|
||||
constants.PATCH_LV_TO_TUN))]
|
||||
if ip_version == 4:
|
||||
expected.insert(1, mock.call(
|
||||
proto='arp',
|
||||
nw_dst=gateway_ip, actions='drop',
|
||||
priority=3, table=constants.DVR_PROCESS,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan)))
|
||||
else:
|
||||
expected.insert(1, mock.call(
|
||||
icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
|
||||
dl_src='aa:bb:cc:11:22:33', actions='drop',
|
||||
priority=3, table=constants.DVR_PROCESS,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan)))
|
||||
|
||||
self.assertEqual(expected, add_flow_tun_fn.call_args_list)
|
||||
self.agent.port_bound(self._compute_port, self._net_uuid,
|
||||
'vxlan', None, None,
|
||||
self._compute_fixed_ips,
|
||||
device_owner, False)
|
||||
self.assertTrue(add_flow_tun_fn.called)
|
||||
self.assertTrue(add_flow_int_fn.called)
|
||||
expected = [
|
||||
mock.call(table=constants.DVR_TO_SRC_MAC, priority=4,
|
||||
dl_dst=self._compute_port.vif_mac,
|
||||
dl_vlan=self.agent.local_vlan_map[self._net_uuid].vlan,
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
"output:%s" %
|
||||
('aa:bb:cc:11:22:33', self._compute_port.ofport))
|
||||
]
|
||||
if ip_version == 4:
|
||||
expected.append(mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2, proto='ip',
|
||||
nw_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
"output:%s" %
|
||||
('aa:bb:cc:11:22:33', self._compute_port.ofport)))
|
||||
else:
|
||||
expected.append(mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
priority=2, proto='ipv6',
|
||||
ipv6_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
actions="strip_vlan,mod_dl_src:%s,"
|
||||
"output:%s" %
|
||||
('aa:bb:cc:11:22:33', self._compute_port.ofport)))
|
||||
self.assertEqual(expected, add_flow_int_fn.call_args_list)
|
||||
self.assertTrue(delete_flows_int_fn.called)
|
||||
|
||||
def test_port_bound_for_dvr_with_compute_ports(self):
|
||||
self._test_port_bound_for_dvr(device_owner="compute:None")
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner="compute:None")
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner="compute:None", ip_version=6)
|
||||
|
||||
def test_port_bound_for_dvr_with_lbaas_vip_ports(self):
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
|
||||
|
||||
def test_port_bound_for_dvr_with_dhcp_ports(self):
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_DHCP)
|
||||
self._test_port_bound_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
|
||||
|
||||
def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
|
||||
self._setup_for_dvr_test()
|
||||
|
@ -306,6 +386,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
|
||||
return_value={'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
'ip_version': 4,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
@ -329,7 +410,19 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
self.assertTrue(delete_flows_int_fn.called)
|
||||
|
||||
def test_treat_devices_removed_for_dvr_interface(self, ofport=10):
|
||||
self._test_treat_devices_removed_for_dvr_interface(ofport)
|
||||
self._test_treat_devices_removed_for_dvr_interface(
|
||||
ofport, ip_version=6)
|
||||
|
||||
def _test_treat_devices_removed_for_dvr_interface(self, ofport=10,
|
||||
ip_version=4):
|
||||
self._setup_for_dvr_test()
|
||||
if ip_version == 4:
|
||||
gateway_ip = '1.1.1.1'
|
||||
cidr = '1.1.1.0/24'
|
||||
else:
|
||||
gateway_ip = '2001:100::1'
|
||||
cidr = '2001:100::0/64'
|
||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||
'set_db_attribute',
|
||||
return_value=True):
|
||||
|
@ -339,8 +432,9 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
return_value=str(self._old_local_vlan)),
|
||||
mock.patch.object(
|
||||
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
|
||||
return_value={'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
return_value={'gateway_ip': gateway_ip,
|
||||
'cidr': cidr,
|
||||
'ip_version': ip_version,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
@ -374,11 +468,58 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
delete_flows_int_fn,
|
||||
delete_flows_tun_fn):
|
||||
self.agent.treat_devices_removed([self._port.vif_id])
|
||||
self.assertTrue(delete_flows_int_fn.called)
|
||||
self.assertTrue(delete_flows_tun_fn.called)
|
||||
if ip_version == 4:
|
||||
expected = [mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
nw_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
proto='ip')]
|
||||
else:
|
||||
expected = [mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
ipv6_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
proto='ipv6')]
|
||||
self.assertEqual(expected,
|
||||
delete_flows_int_fn.call_args_list)
|
||||
if ip_version == 4:
|
||||
expected = [mock.call(
|
||||
proto='arp',
|
||||
nw_dst=gateway_ip,
|
||||
table=constants.DVR_PROCESS,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan))]
|
||||
else:
|
||||
expected = [mock.call(
|
||||
icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
|
||||
dl_src='aa:bb:cc:11:22:33',
|
||||
table=constants.DVR_PROCESS,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan))]
|
||||
expected.extend([
|
||||
mock.call(
|
||||
table=constants.DVR_PROCESS,
|
||||
dl_dst=self._port.vif_mac,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan)),
|
||||
mock.call(
|
||||
table=constants.DVR_PROCESS,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan),
|
||||
dl_src=self._port.vif_mac)
|
||||
])
|
||||
self.assertEqual(expected, delete_flows_tun_fn.call_args_list)
|
||||
|
||||
def _test_treat_devices_removed_for_dvr(self, device_owner):
|
||||
def _test_treat_devices_removed_for_dvr(self, device_owner, ip_version=4):
|
||||
self._setup_for_dvr_test()
|
||||
if ip_version == 4:
|
||||
gateway_ip = '1.1.1.1'
|
||||
cidr = '1.1.1.0/24'
|
||||
else:
|
||||
gateway_ip = '2001:100::1'
|
||||
cidr = '2001:100::0/64'
|
||||
with mock.patch('neutron.agent.linux.ovs_lib.OVSBridge.'
|
||||
'set_db_attribute',
|
||||
return_value=True):
|
||||
|
@ -388,8 +529,9 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
return_value=str(self._old_local_vlan)),
|
||||
mock.patch.object(
|
||||
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
|
||||
return_value={'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
return_value={'gateway_ip': gateway_ip,
|
||||
'cidr': cidr,
|
||||
'ip_version': ip_version,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
@ -427,18 +569,45 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
update_dev_down_fn,
|
||||
delete_flows_int_fn):
|
||||
self.agent.treat_devices_removed([self._compute_port.vif_id])
|
||||
self.assertTrue(delete_flows_int_fn.called)
|
||||
expected = [
|
||||
mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
dl_dst=self._compute_port.vif_mac,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan))]
|
||||
if ip_version == 4:
|
||||
expected.append(mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
proto='ip', nw_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan))
|
||||
)
|
||||
else:
|
||||
expected.append(mock.call(
|
||||
table=constants.DVR_TO_SRC_MAC,
|
||||
proto='ipv6', ipv6_dst=cidr,
|
||||
dl_vlan=(
|
||||
self.agent.local_vlan_map[self._net_uuid].vlan))
|
||||
)
|
||||
self.assertEqual(expected, delete_flows_int_fn.call_args_list)
|
||||
|
||||
def test_treat_devices_removed_for_dvr_with_compute_ports(self):
|
||||
self._test_treat_devices_removed_for_dvr(device_owner="compute:None")
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner="compute:None")
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner="compute:None", ip_version=6)
|
||||
|
||||
def test_treat_devices_removed_for_dvr_with_lbaas_vip_ports(self):
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
|
||||
|
||||
def test_treat_devices_removed_for_dvr_with_dhcp_ports(self):
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_DHCP)
|
||||
self._test_treat_devices_removed_for_dvr(
|
||||
device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
|
||||
|
||||
def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
|
||||
self._setup_for_dvr_test()
|
||||
|
@ -453,6 +622,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||
self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
|
||||
return_value={'gateway_ip': '1.1.1.1',
|
||||
'cidr': '1.1.1.0/24',
|
||||
'ip_version': 4,
|
||||
'gateway_mac': 'aa:bb:cc:11:22:33'}),
|
||||
mock.patch.object(self.agent.dvr_agent.plugin_rpc,
|
||||
'get_ports_on_host_by_subnet',
|
||||
|
|
Loading…
Reference in New Issue