]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
ofagent: Local arp responder for VLAN
authorYAMAMOTO Takashi <yamamoto@valinux.co.jp>
Thu, 26 Jun 2014 07:07:23 +0000 (16:07 +0900)
committerYAMAMOTO Takashi <yamamoto@valinux.co.jp>
Tue, 2 Sep 2014 00:40:41 +0000 (00:40 +0000)
Implement local arp responder for non-tunnel network types.
Enable it for VLAN by requesting l2pop for VLAN.

Related: blueprint ofagent-l2pop
Related: blueprint ofagent-merge-bridges
Change-Id: I2f200a1ae2bd769ea1f83fe65e58e82325ed92b0

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

index b8de015f58ae21144e23dbf539cab9a6e815b980..8be7fa5cb4fc424bb3a4c82be5dc6d200c7fc9c5 100644 (file)
@@ -223,6 +223,8 @@ class OFANeutronAgent(n_rpc.RpcCallback,
         self.available_local_vlans = set(xrange(ofa_const.LOCAL_VLAN_MIN,
                                                 ofa_const.LOCAL_VLAN_MAX))
         self.tunnel_types = tunnel_types or []
+        l2pop_network_types = list(set(self.tunnel_types +
+                                       [p_const.TYPE_VLAN]))
         self.agent_state = {
             'binary': 'neutron-ofa-agent',
             'host': cfg.CONF.host,
@@ -230,7 +232,8 @@ class OFANeutronAgent(n_rpc.RpcCallback,
             'configurations': {'bridge_mappings': bridge_mappings,
                                'tunnel_types': self.tunnel_types,
                                'tunneling_ip': local_ip,
-                               'l2_population': True},
+                               'l2_population': True,
+                               'l2pop_network_types': l2pop_network_types},
             'agent_type': n_const.AGENT_TYPE_OFA,
             'start_flag': True}
 
@@ -340,23 +343,29 @@ 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):
-            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)
+            if lvm.network_type in self.tunnel_types:
+                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)
+            else:
+                self._fdb_add_arp(lvm, agent_ports)
 
     def fdb_remove(self, context, fdb_entries):
         LOG.debug("fdb_remove received")
         for lvm, agent_ports in self.get_agent_ports(fdb_entries,
                                                      self.local_vlan_map):
-            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)
+            if lvm.network_type in self.tunnel_types:
+                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)
+            else:
+                self._fdb_remove_arp(lvm, agent_ports)
 
     @log.log
     def _fdb_add_arp(self, lvm, agent_ports):
index e6df86bd2c11e862c0b02641d1ca2b4f3f68b5ff..b9b83655dc52da5defcfef80b43afba74448e182 100644 (file)
@@ -504,7 +504,7 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase):
             self.agent.port_unbound("vif1")
             self.assertTrue(reclvl_fn.called)
 
-    def _prepare_l2_pop_ofports(self):
+    def _prepare_l2_pop_ofports(self, network_type=None):
         LVM = collections.namedtuple('LVM', 'net, vlan, segid, ip')
         self.lvms = [LVM(net='net1', vlan=11, segid=21, ip='1.1.1.1'),
                      LVM(net='net2', vlan=12, segid=22, ip='2.2.2.2')]
@@ -513,16 +513,19 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase):
                                                        self.tunnel_type)
         self.tun_name2 = self._create_tunnel_port_name(self.lvms[1].ip,
                                                        self.tunnel_type)
+        if network_type is None:
+            network_type = self.tunnel_type
         lvm1 = mock.Mock()
-        lvm1.network_type = self.tunnel_type
+        lvm1.network_type = network_type
         lvm1.vlan = self.lvms[0].vlan
         lvm1.segmentation_id = self.lvms[0].segid
         lvm1.tun_ofports = set([1])
         lvm2 = mock.Mock()
-        lvm2.network_type = self.tunnel_type
+        lvm2.network_type = network_type
         lvm2.vlan = self.lvms[1].vlan
         lvm2.segmentation_id = self.lvms[1].segid
         lvm2.tun_ofports = set([1, 2])
+        self.agent.tunnel_types = [self.tunnel_type]
         self.agent.local_vlan_map = {self.lvms[0].net: lvm1,
                                      self.lvms[1].net: lvm2}
         self.agent.tun_ofports = {self.tunnel_type:
@@ -637,9 +640,13 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase):
         fdb_entry = {self.lvms[0].net:
                      {'network_type': self.tunnel_type,
                       'segment_id': 'tun1',
-                      'ports': {self.lvms[0].ip: [['mac1', 'ip1']],
-                                self.lvms[1].ip: [['mac2', 'ip2']]}}}
-        with mock.patch.object(self.agent, 'setup_tunnel_port'):
+                      'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
+                                                  ['mac1', 'ip1']],
+                                self.lvms[1].ip: [['mac2', 'ip2']],
+                                '192.0.2.1': [n_const.FLOODING_ENTRY,
+                                              ['mac3', 'ip3']]}}}
+        with mock.patch.object(self.agent,
+                               'setup_tunnel_port') as setup_tun_fn:
             self.agent.fdb_add(None, fdb_entry)
             calls = [
                 mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
@@ -648,15 +655,46 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase):
                           'ip2', 'mac2')
             ]
             self.ryuapp.add_arp_table_entry.assert_has_calls(calls)
+            setup_tun_fn.assert_called_once_with(self.agent.int_br,
+                                                 '192.0.2.1', 'gre')
+
+    def _test_add_arp_table_entry_non_tunnel(self, network_type):
+        self._prepare_l2_pop_ofports(network_type=network_type)
+        fdb_entry = {self.lvms[0].net:
+                     {'network_type': network_type,
+                      'segment_id': 'tun1',
+                      'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
+                                                  ['mac1', 'ip1']],
+                                self.lvms[1].ip: [['mac2', 'ip2']],
+                                '192.0.2.1': [n_const.FLOODING_ENTRY,
+                                              ['mac3', 'ip3']]}}}
+        with mock.patch.object(self.agent,
+                               'setup_tunnel_port') as setup_tun_fn:
+            self.agent.fdb_add(None, fdb_entry)
+            calls = [
+                mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
+                          'ip1', 'mac1'),
+                mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
+                          'ip2', 'mac2')
+            ]
+            self.ryuapp.add_arp_table_entry.assert_has_calls(calls)
+            self.assertFalse(setup_tun_fn.called)
+
+    def test_add_arp_table_entry_vlan(self):
+        self._test_add_arp_table_entry_non_tunnel('vlan')
 
     def test_del_arp_table_entry(self):
         self._prepare_l2_pop_ofports()
         fdb_entry = {self.lvms[0].net:
                      {'network_type': self.tunnel_type,
                       'segment_id': 'tun1',
-                      'ports': {self.lvms[0].ip: [['mac1', 'ip1']],
-                                self.lvms[1].ip: [['mac2', 'ip2']]}}}
-        with mock.patch.object(self.agent, 'cleanup_tunnel_port'):
+                      'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
+                                                  ['mac1', 'ip1']],
+                                self.lvms[1].ip: [['mac2', 'ip2']],
+                                '192.0.2.1': [n_const.FLOODING_ENTRY,
+                                              ['mac3', 'ip3']]}}}
+        with mock.patch.object(self.agent,
+                               'cleanup_tunnel_port') as cleanup_tun_fn:
             self.agent.fdb_remove(None, fdb_entry)
             calls = [
                 mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
@@ -665,6 +703,32 @@ class TestOFANeutronAgent(ofa_test_base.OFAAgentTestBase):
                           'ip2')
             ]
             self.ryuapp.del_arp_table_entry.assert_has_calls(calls)
+            cleanup_tun_fn.assert_called_once_with(self.agent.int_br, 1, 'gre')
+
+    def _test_del_arp_table_entry_non_tunnel(self, network_type):
+        self._prepare_l2_pop_ofports(network_type=network_type)
+        fdb_entry = {self.lvms[0].net:
+                     {'network_type': network_type,
+                      'segment_id': 'tun1',
+                      'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
+                                                  ['mac1', 'ip1']],
+                                self.lvms[1].ip: [['mac2', 'ip2']],
+                                '192.0.2.1': [n_const.FLOODING_ENTRY,
+                                              ['mac3', 'ip3']]}}}
+        with mock.patch.object(self.agent,
+                               'cleanup_tunnel_port') as cleanup_tun_fn:
+            self.agent.fdb_remove(None, fdb_entry)
+            calls = [
+                mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
+                          'ip1'),
+                mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
+                          'ip2')
+            ]
+            self.ryuapp.del_arp_table_entry.assert_has_calls(calls)
+            self.assertFalse(cleanup_tun_fn.called)
+
+    def test_del_arp_table_entry_vlan(self):
+        self._test_del_arp_table_entry_non_tunnel('vlan')
 
     def test_recl_lv_port_to_preserve(self):
         self._prepare_l2_pop_ofports()