summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>2015-04-02 17:25:39 -0700
committerarmando-migliaccio <armamig@gmail.com>2015-04-06 19:58:51 -0700
commite585c822e38919451beeb95406c521b09b18e9fc (patch)
tree30e381ed30d93a74e90eb66b673acf10777175ad
parent10286abe752f9baff92f9326bea6d176a46ed8af (diff)
downloadneutron-e585c822e38919451beeb95406c521b09b18e9fc.tar.gz
Fix dynamic arp populate error for dvr routers
Recent refactor to the L3 Agent have introduced this problem. When we create a VM after we attach an interface to a router or when we add an interface with an existing VM to a router, in both cases the arp entries for the dvr serviced ports are not getting populated in the Router Namespace. Closes-Bug: #1438969 Change-Id: I4a82e2435d176f3d9336d7f0dab9726c063840b9 Co-authored-by: Armando Migliaccio <armamig@gmail.com>
-rw-r--r--neutron/agent/l3/dvr_router.py11
-rw-r--r--neutron/agent/linux/ip_lib.py5
-rwxr-xr-xneutron/tests/functional/agent/test_l3_agent.py20
3 files changed, 33 insertions, 3 deletions
diff --git a/neutron/agent/l3/dvr_router.py b/neutron/agent/l3/dvr_router.py
index b18cb9aee4..4d2539ff44 100644
--- a/neutron/agent/l3/dvr_router.py
+++ b/neutron/agent/l3/dvr_router.py
@@ -307,6 +307,14 @@ class DvrRouter(router.RouterInfo):
def internal_network_added(self, port):
super(DvrRouter, self).internal_network_added(port)
+ # NOTE: The following function _set_subnet_arp_info
+ # should be called to dynamically populate the arp
+ # entries for the dvr services ports into the router
+ # namespace. This does not have dependency on the
+ # external_gateway port or the agent_mode.
+ for subnet in port['subnets']:
+ self._set_subnet_arp_info(subnet['id'])
+
ex_gw_port = self.get_ex_gw_port()
if not ex_gw_port:
return
@@ -333,9 +341,6 @@ class DvrRouter(router.RouterInfo):
interface_name,
dvr_snat_ns.SNAT_INT_DEV_PREFIX)
- for subnet in port['subnets']:
- self._set_subnet_arp_info(subnet['id'])
-
def _dvr_internal_network_removed(self, port):
if not self.ex_gw_port:
return
diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py
index 330ea3dd65..119dc9341d 100644
--- a/neutron/agent/linux/ip_lib.py
+++ b/neutron/agent/linux/ip_lib.py
@@ -544,6 +544,11 @@ class IpNeighCommand(IpDeviceCommandBase):
'lladdr', mac_address,
'dev', self.name))
+ def show(self):
+ return self._as_root([],
+ ('show',
+ 'dev', self.name))
+
class IpNetnsCommand(IpCommandBase):
COMMAND = 'netns'
diff --git a/neutron/tests/functional/agent/test_l3_agent.py b/neutron/tests/functional/agent/test_l3_agent.py
index 719ab605af..ec5deb025a 100755
--- a/neutron/tests/functional/agent/test_l3_agent.py
+++ b/neutron/tests/functional/agent/test_l3_agent.py
@@ -1051,6 +1051,26 @@ class TestDvrRouter(L3AgentTestFramework):
self._assert_dvr_snat_gateway(router1)
self.assertFalse(self._namespace_exists(fip_ns))
+ def test_dvr_router_add_internal_network_set_arp_cache(self):
+ # Check that, when the router is set up and there are
+ # existing ports on the the uplinked subnet, the ARP
+ # cache is properly populated.
+ self.agent.conf.agent_mode = 'dvr_snat'
+ router_info = test_l3_agent.prepare_router_data()
+ router_info['distributed'] = True
+ expected_neighbor = '35.4.1.10'
+ port_data = {
+ 'fixed_ips': [{'ip_address': expected_neighbor}],
+ 'mac_address': 'fa:3e:aa:bb:cc:dd',
+ 'device_owner': 'compute:None'
+ }
+ self.agent.plugin_rpc.get_ports_by_subnet.return_value = [port_data]
+ router1 = self._create_router(self.agent, router_info)
+ internal_device = router1.get_internal_device_name(
+ router_info['_interfaces'][0]['id'])
+ neighbors = ip_lib.IPDevice(internal_device, router1.ns_name).neigh
+ self.assertEqual(expected_neighbor, neighbors.show().split()[0])
+
def _assert_rfp_fpr_mtu(self, router, expected_mtu=1500):
dev_mtu = self.get_device_mtu(
router.router_id, router.fip_ns.get_rtr_ext_device_name,