]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
ofagent: Enable local arp responder for local VMs
authorYAMAMOTO Takashi <yamamoto@valinux.co.jp>
Mon, 11 Aug 2014 00:02:22 +0000 (09:02 +0900)
committerYAMAMOTO Takashi <yamamoto@valinux.co.jp>
Mon, 1 Sep 2014 00:24:54 +0000 (00:24 +0000)
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

neutron/plugins/ofagent/agent/ofa_neutron_agent.py
neutron/tests/unit/ofagent/test_ofa_neutron_agent.py

index fe73319110b60c83bfd08d6b582fce7f8b96df1e..b8de015f58ae21144e23dbf539cab9a6e815b980 100644 (file)
@@ -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)
index 18edc97cfc8e823b275ee9da701c8bcdf2cbc43f..e6df86bd2c11e862c0b02641d1ca2b4f3f68b5ff 100644 (file)
@@ -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()