From c98ec249614b44d8e1a44cb07903338c3056e772 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Mon, 27 May 2013 13:21:42 -0400 Subject: [PATCH] GRE tunnels should include local_ip. This addresses the issue of having one or more multi-homed host. Because you may only specify one local IP for a quantum agent, and other hosts could be routed across different subnets (even for small installations, for various reasons), it's important to also specify the used local_ip when setting up the GRE tunnels. As long as the address is routable on both ends, this will work. If the local_ip is not specified, then traffic will mysteriously be dropped on one end where the IP does not match the expected IP in the GRE tunnel. Bug: https://bugs.launchpad.net/quantum/+bug/1184696 Change-Id: I5d612bf9e4f6652af8b155cdd1748d73ac4539ff Signed-off-by: Adin Scannell --- neutron/agent/linux/ovs_lib.py | 4 +++- .../plugins/openvswitch/agent/ovs_neutron_agent.py | 5 +++-- neutron/tests/unit/openvswitch/test_ovs_lib.py | 12 +++++++++--- neutron/tests/unit/openvswitch/test_ovs_tunnel.py | 3 ++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/neutron/agent/linux/ovs_lib.py b/neutron/agent/linux/ovs_lib.py index 491dd1969e..9da39b0149 100644 --- a/neutron/agent/linux/ovs_lib.py +++ b/neutron/agent/linux/ovs_lib.py @@ -165,7 +165,7 @@ class OVSBridge: flow_str = ",".join(flow_expr_arr) self.run_ofctl("del-flows", [flow_str]) - def add_tunnel_port(self, port_name, remote_ip, + def add_tunnel_port(self, port_name, remote_ip, local_ip, tunnel_type=constants.TYPE_GRE, vxlan_udp_port=constants.VXLAN_UDP_PORT): self.run_vsctl(["add-port", self.br_name, port_name]) @@ -178,6 +178,8 @@ class OVSBridge: vxlan_udp_port) self.set_db_attribute("Interface", port_name, "options:remote_ip", remote_ip) + self.set_db_attribute("Interface", port_name, "options:local_ip", + local_ip) self.set_db_attribute("Interface", port_name, "options:in_key", "flow") self.set_db_attribute("Interface", port_name, "options:out_key", "flow") diff --git a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py index acc27e66b4..4c2d31da36 100644 --- a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py @@ -302,8 +302,8 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): if tunnel_ip == self.local_ip: return tun_name = '%s-%s' % (tunnel_type, tunnel_id) - self.tun_br.add_tunnel_port(tun_name, tunnel_ip, tunnel_type, - self.vxlan_udp_port) + self.tun_br.add_tunnel_port(tun_name, tunnel_ip, self.local_ip, + tunnel_type, self.vxlan_udp_port) def create_rpc_dispatcher(self): '''Get the rpc dispatcher for this manager. @@ -713,6 +713,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin): tun_name = '%s-%s' % (tunnel_type, tunnel_id) self.tun_br.add_tunnel_port(tun_name, tunnel['ip_address'], + self.local_ip, tunnel_type, self.vxlan_udp_port) except Exception as e: diff --git a/neutron/tests/unit/openvswitch/test_ovs_lib.py b/neutron/tests/unit/openvswitch/test_ovs_lib.py index 5e5c79cdcd..1b9486affe 100644 --- a/neutron/tests/unit/openvswitch/test_ovs_lib.py +++ b/neutron/tests/unit/openvswitch/test_ovs_lib.py @@ -185,7 +185,8 @@ class OVS_Lib_Test(base.BaseTestCase): def test_add_tunnel_port(self): pname = "tap99" - ip = "9.9.9.9" + local_ip = "1.1.1.1" + remote_ip = "9.9.9.9" ofport = "6" utils.execute(["ovs-vsctl", self.TO, "add-port", @@ -193,7 +194,10 @@ class OVS_Lib_Test(base.BaseTestCase): utils.execute(["ovs-vsctl", self.TO, "set", "Interface", pname, "type=gre"], root_helper=self.root_helper) utils.execute(["ovs-vsctl", self.TO, "set", "Interface", - pname, "options:remote_ip=" + ip], + pname, "options:remote_ip=" + remote_ip], + root_helper=self.root_helper) + utils.execute(["ovs-vsctl", self.TO, "set", "Interface", + pname, "options:local_ip=" + local_ip], root_helper=self.root_helper) utils.execute(["ovs-vsctl", self.TO, "set", "Interface", pname, "options:in_key=flow"], @@ -206,7 +210,9 @@ class OVS_Lib_Test(base.BaseTestCase): root_helper=self.root_helper).AndReturn(ofport) self.mox.ReplayAll() - self.assertEqual(self.br.add_tunnel_port(pname, ip), ofport) + self.assertEqual( + self.br.add_tunnel_port(pname, remote_ip, local_ip), + ofport) self.mox.VerifyAll() def test_add_patch_port(self): diff --git a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py b/neutron/tests/unit/openvswitch/test_ovs_tunnel.py index 6e3e9a527d..b1186e3301 100644 --- a/neutron/tests/unit/openvswitch/test_ovs_tunnel.py +++ b/neutron/tests/unit/openvswitch/test_ovs_tunnel.py @@ -346,7 +346,8 @@ class TunnelTest(base.BaseTestCase): self.mox.VerifyAll() def testTunnelUpdate(self): - self.mock_tun_bridge.add_tunnel_port('gre-1', '10.0.10.1', 'gre', 4789) + self.mock_tun_bridge.add_tunnel_port('gre-1', '10.0.10.1', '10.0.0.1', + 'gre', 4789) self.mox.ReplayAll() a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE, self.TUN_BRIDGE,