Merge "OFAgent: Avoid re-wiring ports unnecessarily"
This commit is contained in:
commit
ec82d2006b
@ -664,19 +664,21 @@ class OFANeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
physical_network, segmentation_id)
|
physical_network, segmentation_id)
|
||||||
lvm = self.local_vlan_map[net_uuid]
|
lvm = self.local_vlan_map[net_uuid]
|
||||||
lvm.vif_ports[port.vif_id] = port
|
lvm.vif_ports[port.vif_id] = port
|
||||||
|
# Do not bind a port if it's already bound
|
||||||
self.int_br.set_db_attribute("Port", port.port_name, "tag",
|
cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag")
|
||||||
str(lvm.vlan))
|
if cur_tag != str(lvm.vlan):
|
||||||
if int(port.ofport) != -1:
|
self.int_br.set_db_attribute("Port", port.port_name, "tag",
|
||||||
match = self.int_br.ofparser.OFPMatch(in_port=port.ofport)
|
str(lvm.vlan))
|
||||||
msg = self.int_br.ofparser.OFPFlowMod(
|
if int(port.ofport) != -1:
|
||||||
self.int_br.datapath,
|
match = self.int_br.ofparser.OFPMatch(in_port=port.ofport)
|
||||||
table_id=ryu_ofp13.OFPTT_ALL,
|
msg = self.int_br.ofparser.OFPFlowMod(
|
||||||
command=ryu_ofp13.OFPFC_DELETE,
|
self.int_br.datapath,
|
||||||
out_group=ryu_ofp13.OFPG_ANY,
|
table_id=ryu_ofp13.OFPTT_ALL,
|
||||||
out_port=ryu_ofp13.OFPP_ANY,
|
command=ryu_ofp13.OFPFC_DELETE,
|
||||||
match=match)
|
out_group=ryu_ofp13.OFPG_ANY,
|
||||||
self.ryu_send_msg(msg)
|
out_port=ryu_ofp13.OFPP_ANY,
|
||||||
|
match=match)
|
||||||
|
self.ryu_send_msg(msg)
|
||||||
|
|
||||||
def port_unbound(self, vif_id, net_uuid=None):
|
def port_unbound(self, vif_id, net_uuid=None):
|
||||||
"""Unbind port.
|
"""Unbind port.
|
||||||
@ -705,12 +707,15 @@ class OFANeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
|
|
||||||
:param port: a ovs_lib.VifPort object.
|
:param port: a ovs_lib.VifPort object.
|
||||||
"""
|
"""
|
||||||
self.int_br.set_db_attribute("Port", port.port_name, "tag",
|
# Don't kill a port if it's already dead
|
||||||
DEAD_VLAN_TAG)
|
cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag")
|
||||||
match = self.int_br.ofparser.OFPMatch(in_port=int(port.ofport))
|
if cur_tag != DEAD_VLAN_TAG:
|
||||||
msg = self.int_br.ofparser.OFPFlowMod(self.int_br.datapath,
|
self.int_br.set_db_attribute("Port", port.port_name, "tag",
|
||||||
priority=2, match=match)
|
DEAD_VLAN_TAG)
|
||||||
self.ryu_send_msg(msg)
|
match = self.int_br.ofparser.OFPMatch(in_port=port.ofport)
|
||||||
|
msg = self.int_br.ofparser.OFPFlowMod(self.int_br.datapath,
|
||||||
|
priority=2, match=match)
|
||||||
|
self.ryu_send_msg(msg)
|
||||||
|
|
||||||
def setup_integration_br(self):
|
def setup_integration_br(self):
|
||||||
"""Setup the integration bridge.
|
"""Setup the integration bridge.
|
||||||
|
@ -244,34 +244,71 @@ class TestOFANeutronAgent(OFAAgentTestCase):
|
|||||||
|
|
||||||
self.agent.sg_agent = mock.Mock()
|
self.agent.sg_agent = mock.Mock()
|
||||||
|
|
||||||
def _mock_port_bound(self, ofport=None):
|
def _mock_port_bound(self, ofport=None, new_local_vlan=None,
|
||||||
|
old_local_vlan=None):
|
||||||
port = mock.Mock()
|
port = mock.Mock()
|
||||||
port.ofport = ofport
|
port.ofport = ofport
|
||||||
net_uuid = 'my-net-uuid'
|
net_uuid = 'my-net-uuid'
|
||||||
with mock.patch.object(self.mod_agent.OVSBridge,
|
if old_local_vlan is not None:
|
||||||
'set_db_attribute',
|
self.agent.local_vlan_map[net_uuid] = (
|
||||||
return_value=True):
|
self.mod_agent.LocalVLANMapping(
|
||||||
with mock.patch.object(self.agent,
|
old_local_vlan, None, None, None))
|
||||||
'ryu_send_msg') as ryu_send_msg_func:
|
with contextlib.nested(
|
||||||
self.agent.port_bound(port, net_uuid, 'local', None, None)
|
mock.patch.object(self.mod_agent.OVSBridge,
|
||||||
self.assertEqual(ryu_send_msg_func.called, ofport != -1)
|
'set_db_attribute', return_value=True),
|
||||||
|
mock.patch.object(self.mod_agent.OVSBridge,
|
||||||
|
'db_get_val', return_value=str(old_local_vlan)),
|
||||||
|
mock.patch.object(self.agent, 'ryu_send_msg')
|
||||||
|
) as (set_ovs_db_func, get_ovs_db_func, ryu_send_msg_func):
|
||||||
|
self.agent.port_bound(port, net_uuid, 'local', None, None)
|
||||||
|
get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag")
|
||||||
|
if new_local_vlan != old_local_vlan:
|
||||||
|
set_ovs_db_func.assert_called_once_with(
|
||||||
|
"Port", mock.ANY, "tag", str(new_local_vlan))
|
||||||
|
if ofport != -1:
|
||||||
|
ryu_send_msg_func.assert_called_once_with(
|
||||||
|
self.ofparser.OFPFlowMod.return_value)
|
||||||
|
else:
|
||||||
|
self.assertFalse(ryu_send_msg_func.called)
|
||||||
|
else:
|
||||||
|
self.assertFalse(set_ovs_db_func.called)
|
||||||
|
self.assertFalse(ryu_send_msg_func.called)
|
||||||
|
|
||||||
def test_port_bound_deletes_flows_for_valid_ofport(self):
|
def test_port_bound_deletes_flows_for_valid_ofport(self):
|
||||||
self._mock_port_bound(ofport=1)
|
self._mock_port_bound(ofport=1, new_local_vlan=1)
|
||||||
|
|
||||||
def test_port_bound_ignores_flows_for_invalid_ofport(self):
|
def test_port_bound_ignores_flows_for_invalid_ofport(self):
|
||||||
self._mock_port_bound(ofport=-1)
|
self._mock_port_bound(ofport=-1, new_local_vlan=1)
|
||||||
|
|
||||||
|
def test_port_bound_does_not_rewire_if_already_bound(self):
|
||||||
|
self._mock_port_bound(ofport=-1, new_local_vlan=1, old_local_vlan=1)
|
||||||
|
|
||||||
|
def _test_port_dead(self, cur_tag=None):
|
||||||
|
port = mock.Mock()
|
||||||
|
port.ofport = 1
|
||||||
|
with contextlib.nested(
|
||||||
|
mock.patch.object(self.mod_agent.OVSBridge,
|
||||||
|
'set_db_attribute', return_value=True),
|
||||||
|
mock.patch.object(self.mod_agent.OVSBridge,
|
||||||
|
'db_get_val', return_value=cur_tag),
|
||||||
|
mock.patch.object(self.agent, 'ryu_send_msg')
|
||||||
|
) as (set_ovs_db_func, get_ovs_db_func, ryu_send_msg_func):
|
||||||
|
self.agent.port_dead(port)
|
||||||
|
get_ovs_db_func.assert_called_once_with("Port", mock.ANY, "tag")
|
||||||
|
if cur_tag == self.mod_agent.DEAD_VLAN_TAG:
|
||||||
|
self.assertFalse(set_ovs_db_func.called)
|
||||||
|
self.assertFalse(ryu_send_msg_func.called)
|
||||||
|
else:
|
||||||
|
set_ovs_db_func.assert_called_once_with(
|
||||||
|
"Port", mock.ANY, "tag", str(self.mod_agent.DEAD_VLAN_TAG))
|
||||||
|
ryu_send_msg_func.assert_called_once_with(
|
||||||
|
self.ofparser.OFPFlowMod.return_value)
|
||||||
|
|
||||||
def test_port_dead(self):
|
def test_port_dead(self):
|
||||||
with mock.patch.object(self.mod_agent.OVSBridge,
|
self._test_port_dead()
|
||||||
'set_db_attribute',
|
|
||||||
return_value=True):
|
def test_port_dead_with_port_already_dead(self):
|
||||||
with mock.patch.object(self.agent,
|
self._test_port_dead(self.mod_agent.DEAD_VLAN_TAG)
|
||||||
'ryu_send_msg') as ryu_send_msg_func:
|
|
||||||
port = mock.Mock()
|
|
||||||
port.ofport = 2
|
|
||||||
self.agent.port_dead(port)
|
|
||||||
self.assertTrue(ryu_send_msg_func.called)
|
|
||||||
|
|
||||||
def mock_update_ports(self, vif_port_set=None, registered_ports=None):
|
def mock_update_ports(self, vif_port_set=None, registered_ports=None):
|
||||||
with mock.patch.object(self.agent.int_br, 'get_vif_port_set',
|
with mock.patch.object(self.agent.int_br, 'get_vif_port_set',
|
||||||
|
Loading…
Reference in New Issue
Block a user