From 81937f4a2049461a821878b32db088147fbb6a78 Mon Sep 17 00:00:00 2001 From: Aaron Rosen Date: Thu, 6 Sep 2012 00:32:04 -0400 Subject: [PATCH] openvswitch plugin does not remove inbound unicast flow in br-tun Fixes bug 1044565 In addition to adding port_unbound call when using rpc Change-Id: Ie924f94bcedebbe24f3aa0a52d1682bc944a0aec --- .../openvswitch/agent/ovs_quantum_agent.py | 45 ++++++++++++------- .../tests/unit/openvswitch/test_ovs_tunnel.py | 6 ++- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py index 90d7542c2..6dddc6f4d 100755 --- a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py +++ b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py @@ -52,14 +52,14 @@ DEAD_VLAN_TAG = "4095" # attributes set). class LocalVLANMapping: def __init__(self, vlan, network_type, physical_network, segmentation_id, - vif_ids=None): - if vif_ids is None: - vif_ids = [] + vif_ports=None): + if vif_ports is None: + vif_ports = {} self.vlan = vlan self.network_type = network_type self.physical_network = physical_network self.segmentation_id = segmentation_id - self.vif_ids = vif_ids + self.vif_ports = vif_ports def __str__(self): return ("lv-id = %s type = %s phys-net = %s phys-id = %s" % @@ -185,6 +185,11 @@ class OVSQuantumAgent(object): self.topic, consumers) + def get_net_uuid(self, vif_id): + for network_id, vlan_mapping in self.local_vlan_map.iteritems(): + if vif_id in vlan_mapping.vif_ports: + return network_id + def network_delete(self, context, **kwargs): LOG.debug("network_delete received") network_id = kwargs.get('network_id') @@ -333,7 +338,7 @@ class OVSQuantumAgent(object): self.provision_local_vlan(net_uuid, network_type, physical_network, segmentation_id) lvm = self.local_vlan_map[net_uuid] - lvm.vif_ids.append(port.vif_id) + lvm.vif_ports[port.vif_id] = port if network_type == constants.TYPE_GRE: # inbound unicast @@ -346,28 +351,34 @@ class OVSQuantumAgent(object): if int(port.ofport) != -1: self.int_br.delete_flows(in_port=port.ofport) - def port_unbound(self, port, net_uuid): + def port_unbound(self, vif_id, net_uuid=None): '''Unbind port. Removes corresponding local vlan mapping object if this is its last VIF. - :param port: a ovslib.VifPort object. + :param vif_id: the id of the vif :param net_uuid: the net_uuid this port is associated with.''' - if net_uuid not in self.local_vlan_map: + if net_uuid is None: + net_uuid = self.get_net_uuid(vif_id) + + if not self.local_vlan_map.get(net_uuid): LOG.info('port_unbound() net_uuid %s not in local_vlan_map' % net_uuid) return lvm = self.local_vlan_map[net_uuid] + if lvm.network_type == 'gre': + # remove inbound unicast flow + self.tun_br.delete_flows(tun_id=lvm.segmentation_id, + dl_dst=lvm.vif_ports[vif_id].vif_mac) - # REVISIT(rkukura): Does inbound unicast flow need to be removed here? - - if port.vif_id in lvm.vif_ids: - lvm.vif_ids.remove(port.vif_id) + if vif_id in lvm.vif_ports: + del lvm.vif_ports[vif_id] else: - LOG.info('port_unbound: vid_id %s not in list' % port.vif_id) + LOG.info('port_unbound: vid_id %s not in local_vlan_map' % + port.vif_id) - if not lvm.vif_ids: + if not lvm.vif_ports: self.reclaim_local_vlan(net_uuid, lvm) def port_dead(self, port): @@ -546,7 +557,7 @@ class OVSQuantumAgent(object): LOG.info("Removing binding to net-id = " + old_net_uuid + " for " + str(p) + " added to dead vlan") - self.port_unbound(p, old_net_uuid) + self.port_unbound(p.vif_id, old_net_uuid) if p.vif_id in all_bindings: all_bindings[p.vif_id].status = ( q_const.PORT_STATUS_DOWN) @@ -578,8 +589,7 @@ class OVSQuantumAgent(object): q_const.PORT_STATUS_DOWN) old_port = old_local_bindings.get(vif_id) if old_port: - self.port_unbound(old_vif_ports[vif_id], - old_port.network_id) + self.port_unbound(vif_id, old_port.network_id) # commit any DB changes and expire # data loaded from the database db.commit() @@ -658,6 +668,7 @@ class OVSQuantumAgent(object): # Nothing to do regarding local networking else: LOG.debug("Device %s not defined on plugin", device) + self.port_unbound(device) return resync def process_network_ports(self, port_info): diff --git a/quantum/tests/unit/openvswitch/test_ovs_tunnel.py b/quantum/tests/unit/openvswitch/test_ovs_tunnel.py index 1b37ead4e..9db8aaddc 100644 --- a/quantum/tests/unit/openvswitch/test_ovs_tunnel.py +++ b/quantum/tests/unit/openvswitch/test_ovs_tunnel.py @@ -28,12 +28,13 @@ NET_UUID = '3faeebfe-5d37-11e1-a64b-000c29d5f0a7' LS_ID = '42' LV_ID = 42 LV_IDS = [42, 43] -LVM = ovs_quantum_agent.LocalVLANMapping(LV_ID, 'gre', None, LS_ID, LV_IDS) VIF_ID = '404deaec-5d37-11e1-a64b-000c29d5f0a8' VIF_MAC = '3c:09:24:1e:78:23' OFPORT_NUM = 1 VIF_PORT = ovs_lib.VifPort('port', OFPORT_NUM, VIF_ID, VIF_MAC, 'switch') +VIF_PORTS = {LV_ID: VIF_PORT} +LVM = ovs_quantum_agent.LocalVLANMapping(LV_ID, 'gre', None, LS_ID, VIF_PORTS) BCAST_MAC = "01:00:00:00:00:00/01:00:00:00:00:00" @@ -140,6 +141,7 @@ class TunnelTest(unittest.TestCase): self.mox.VerifyAll() def testPortUnbound(self): + self.mock_tun_bridge.delete_flows(dl_dst=VIF_MAC, tun_id=LS_ID) self.mox.ReplayAll() a = ovs_quantum_agent.OVSQuantumAgent(self.INT_BRIDGE, self.TUN_BRIDGE, @@ -147,7 +149,7 @@ class TunnelTest(unittest.TestCase): 'sudo', 2, 2, False) a.available_local_vlans = set([LV_ID]) a.local_vlan_map[NET_UUID] = LVM - a.port_unbound(VIF_PORT, NET_UUID) + a.port_unbound(VIF_ID, NET_UUID) self.mox.VerifyAll() def testPortDead(self): -- 2.45.2