Browse Source

DVR: Ensure that only one fg device can exist at a time in fip ns

Change-Id: I3e78c8d497f9187ba64dcce317f8c709067a11e6
Closes-Bug: #1597561
tags/9.0.0.0b2
Carl Baldwin 3 years ago
parent
commit
537e2f540a
2 changed files with 76 additions and 2 deletions
  1. +12
    -2
      neutron/agent/l3/dvr_fip_ns.py
  2. +64
    -0
      neutron/tests/functional/agent/l3/test_dvr_router.py

+ 12
- 2
neutron/agent/l3/dvr_fip_ns.py View File

@@ -110,6 +110,18 @@ class FipNamespace(namespaces.Namespace):
prefix=FIP_EXT_DEV_PREFIX,
mtu=ex_gw_port.get('mtu'))

# Remove stale fg devices
ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
devices = ip_wrapper.get_devices()
for device in devices:
name = device.name
if name.startswith(FIP_EXT_DEV_PREFIX) and name != interface_name:
ext_net_bridge = self.agent_conf.external_network_bridge
self.driver.unplug(name,
bridge=ext_net_bridge,
namespace=ns_name,
prefix=FIP_EXT_DEV_PREFIX)

ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips'])
self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name,
clean_connections=True)
@@ -117,8 +129,6 @@ class FipNamespace(namespaces.Namespace):
self.update_gateway_port(ex_gw_port)

cmd = ['sysctl', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % interface_name]
# TODO(Carl) mlavelle's work has self.ip_wrapper
ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
ip_wrapper.netns.execute(cmd, check_exit_code=False)

def create(self):

+ 64
- 0
neutron/tests/functional/agent/l3/test_dvr_router.py View File

@@ -21,6 +21,7 @@ from neutron_lib import constants as l3_constants
import testtools

from neutron.agent.l3 import agent as neutron_l3_agent
from neutron.agent.l3 import dvr_fip_ns
from neutron.agent.l3 import dvr_snat_ns
from neutron.agent.l3 import namespaces
from neutron.agent.linux import ip_lib
@@ -84,6 +85,69 @@ class TestDvrRouter(framework.L3AgentTestFramework):
self._assert_dvr_floating_ips(router)
self._assert_snat_namespace_does_not_exist(router)

def test_dvr_router_fips_stale_gw_port(self):
self.agent.conf.agent_mode = 'dvr'

# Create the router with external net
dvr_router_kwargs = {'ip_address': '19.4.4.3',
'subnet_cidr': '19.4.4.0/24',
'gateway_ip': '19.4.4.1',
'gateway_mac': 'ca:fe:de:ab:cd:ef'}
router_info = self.generate_dvr_router_info(**dvr_router_kwargs)
external_gw_port = router_info['gw_port']
ext_net_id = router_info['_floatingips'][0]['floating_network_id']
self.mock_plugin_api.get_external_network_id.return_value(ext_net_id)

# Create the fip namespace up front
stale_fip_ns = dvr_fip_ns.FipNamespace(ext_net_id,
self.agent.conf,
self.agent.driver,
self.agent.use_ipv6)
stale_fip_ns.create()

# Add a stale fg port to the namespace
fixed_ip = external_gw_port['fixed_ips'][0]
float_subnet = external_gw_port['subnets'][0]
fip_gw_port_ip = str(netaddr.IPAddress(fixed_ip['ip_address']) + 10)
prefixlen = netaddr.IPNetwork(float_subnet['cidr']).prefixlen
stale_agent_gw_port = {
'subnets': [{'cidr': float_subnet['cidr'],
'gateway_ip': float_subnet['gateway_ip'],
'id': fixed_ip['subnet_id']}],
'network_id': external_gw_port['network_id'],
'device_owner': l3_constants.DEVICE_OWNER_AGENT_GW,
'mac_address': 'fa:16:3e:80:8f:89',
portbindings.HOST_ID: self.agent.conf.host,
'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'],
'ip_address': fip_gw_port_ip,
'prefixlen': prefixlen}],
'id': framework._uuid(),
'device_id': framework._uuid()}
stale_fip_ns.create_gateway_port(stale_agent_gw_port)

stale_dev_exists = self.device_exists_with_ips_and_mac(
stale_agent_gw_port,
stale_fip_ns.get_ext_device_name,
stale_fip_ns.get_name())
self.assertTrue(stale_dev_exists)

# Create the router, this shouldn't allow the duplicate port to stay
router = self.manage_router(self.agent, router_info)

# Assert the device no longer exists
stale_dev_exists = self.device_exists_with_ips_and_mac(
stale_agent_gw_port,
stale_fip_ns.get_ext_device_name,
stale_fip_ns.get_name())
self.assertFalse(stale_dev_exists)

# Validate things are looking good and clean up
self._validate_fips_for_external_network(
router, router.fip_ns.get_name())
ext_gateway_port = router_info['gw_port']
self._delete_router(self.agent, router.router_id)
self._assert_fip_namespace_deleted(ext_gateway_port)

def test_dvr_router_fips_for_multiple_ext_networks(self):
agent_mode = 'dvr'
# Create the first router fip with external net1

Loading…
Cancel
Save