From: YAMAMOTO Takashi Date: Mon, 11 Aug 2014 00:02:22 +0000 (+0900) Subject: ofagent: Enable local arp responder for local VMs X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=588d37cc39c9b9e21a3e997490e2e035a8a9ce73;p=openstack-build%2Fneutron-build.git ofagent: Enable local arp responder for local VMs Because ofagent makes every arp requests packet-in and perform packet-out anyway, just make it respond arp requests for local VMs. It would be simpler and more effective than forwarding requests to the network as it did before this change. Before this change: request: src VM -> switch -> controller -> switch -> target VM reply: target VM -> switch -> src VM After this change: request: src VM -> switch -> controller reply: controller -> switch -> src VM As a bonus, now we can test l2pop and local arp responder with a single node setup, at least for some extents. Related: blueprint ofagent-l2pop Related: blueprint ofagent-merge-bridges Change-Id: I606a238d8c2021ed908fbd89d3488768497f57c5 --- diff --git a/neutron/plugins/ofagent/agent/ofa_neutron_agent.py b/neutron/plugins/ofagent/agent/ofa_neutron_agent.py index fe7331911..b8de015f5 100644 --- a/neutron/plugins/ofagent/agent/ofa_neutron_agent.py +++ b/neutron/plugins/ofagent/agent/ofa_neutron_agent.py @@ -36,6 +36,7 @@ from neutron.agent.linux import utils from neutron.agent import rpc as agent_rpc from neutron.agent import securitygroups_rpc as sg_rpc from neutron.common import constants as n_const +from neutron.common import log from neutron.common import rpc as n_rpc from neutron.common import topics from neutron.common import utils as n_utils @@ -339,7 +340,9 @@ class OFANeutronAgent(n_rpc.RpcCallback, LOG.debug("fdb_add received") for lvm, agent_ports in self.get_agent_ports(fdb_entries, self.local_vlan_map): - agent_ports.pop(self.local_ip, None) + local = agent_ports.pop(self.local_ip, None) + if local: + self._fdb_add_arp(lvm, {self.local_ip: local}) if len(agent_ports): self.fdb_add_tun(context, self.int_br, lvm, agent_ports, self.tun_ofports) @@ -348,11 +351,30 @@ class OFANeutronAgent(n_rpc.RpcCallback, LOG.debug("fdb_remove received") for lvm, agent_ports in self.get_agent_ports(fdb_entries, self.local_vlan_map): - agent_ports.pop(self.local_ip, None) + local = agent_ports.pop(self.local_ip, None) + if local: + self._fdb_remove_arp(lvm, {self.local_ip: local}) if len(agent_ports): self.fdb_remove_tun(context, self.int_br, lvm, agent_ports, self.tun_ofports) + @log.log + def _fdb_add_arp(self, lvm, agent_ports): + for _remote_ip, port_infos in agent_ports.items(): + for port_info in port_infos: + if port_info == n_const.FLOODING_ENTRY: + continue + self.ryuapp.add_arp_table_entry( + lvm.vlan, port_info[1], port_info[0]) + + @log.log + def _fdb_remove_arp(self, lvm, agent_ports): + for _remote_ip, port_infos in agent_ports.items(): + for port_info in port_infos: + if port_info == n_const.FLOODING_ENTRY: + continue + self.ryuapp.del_arp_table_entry(lvm.vlan, port_info[1]) + def add_fdb_flow(self, br, port_info, remote_ip, lvm, ofport): if port_info == n_const.FLOODING_ENTRY: lvm.tun_ofports.add(ofport) diff --git a/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py b/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py index 18edc97cf..e6df86bd2 100644 --- a/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py +++ b/neutron/tests/unit/ofagent/test_ofa_neutron_agent.py @@ -556,11 +556,11 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase): mock.patch.object(self.agent.ryuapp, "del_arp_table_entry"), ) as (add_fn, del_fn): self.agent.fdb_add(None, copy.deepcopy(fdb_entry)) - self.assertFalse(add_fn.called) + add_fn.assert_called_once_with(12, 'ip', 'mac') self.assertFalse(del_fn.called) self.agent.fdb_remove(None, fdb_entry) - self.assertFalse(add_fn.called) - self.assertFalse(del_fn.called) + add_fn.assert_called_once_with(12, 'ip', 'mac') + del_fn.assert_called_once_with(12, 'ip') def test_fdb_add_flows(self): self._prepare_l2_pop_ofports()