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
This commit is contained in:
YAMAMOTO Takashi 2014-08-11 09:02:22 +09:00
parent 8ac9e0b2e0
commit af71312414
2 changed files with 27 additions and 5 deletions

View 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)

View 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()