From 588d37cc39c9b9e21a3e997490e2e035a8a9ce73 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 11 Aug 2014 09:02:22 +0900 Subject: [PATCH] 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 --- .../ofagent/agent/ofa_neutron_agent.py | 26 +++++++++++++++++-- .../unit/ofagent/test_ofa_neutron_agent.py | 6 ++--- 2 files changed, 27 insertions(+), 5 deletions(-) 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() -- 2.45.2