From 044ece27b79c810e6c15131b6a553b649e666678 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Thu, 16 Aug 2012 06:06:55 -0400 Subject: [PATCH] Get OVS port details from port ID Fixes bug 1037443 This address the issue when a Quantum interface does not start with the prefix "tap" (for example interfaces created by the l3 agent) Change-Id: Ie2c98940d921606906015914ce6b23d3095e91f2 --- quantum/agent/linux/ovs_lib.py | 34 ++++++++++++-- .../openvswitch/agent/ovs_quantum_agent.py | 47 ++++++++++--------- quantum/tests/unit/test_ovs_lib.py | 15 ++++++ 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/quantum/agent/linux/ovs_lib.py b/quantum/agent/linux/ovs_lib.py index 67f06580e..e491b5edb 100644 --- a/quantum/agent/linux/ovs_lib.py +++ b/quantum/agent/linux/ovs_lib.py @@ -19,6 +19,7 @@ # @author: Dave Lapsley, Nicira Networks, Inc. import logging +import re import shlex import signal import subprocess @@ -47,6 +48,17 @@ class OVSBridge: def __init__(self, br_name, root_helper): self.br_name = br_name self.root_helper = root_helper + self.re_id = self.re_compile_id() + + def re_compile_id(self): + external = 'external_ids\s*' + mac = 'attached-mac="(?P([a-fA-F\d]{2}:){5}([a-fA-F\d]{2}))"' + iface = 'iface-id="(?P[^"]+)"' + name = 'name\s*:\s"(?P[^"]*)"' + port = 'ofport\s*:\s(?P\d+)' + _re = ('%(external)s:\s{ ( %(mac)s,? | %(iface)s,? | . )* }' + ' \s+ %(name)s \s+ %(port)s' % locals()) + return re.compile(_re, re.M | re.X) def run_vsctl(self, args): full_args = ["ovs-vsctl", "--timeout=2"] + args @@ -221,8 +233,20 @@ class OVSBridge: edge_ports.add(iface_id) return edge_ports - def get_vif_port(self, port_name): - external_ids = self.db_get_map("Interface", port_name, "external_ids") - ofport = self.db_get_val("Interface", port_name, "ofport") - return VifPort(port_name, ofport, external_ids["iface-id"], - external_ids["attached-mac"], self) + def get_vif_port_by_id(self, port_id): + args = ['--', '--columns=external_ids,name,ofport', + 'find', 'Interface', + 'external_ids:iface-id="%s"' % port_id] + result = self.run_vsctl(args) + if not result: + return + match = self.re_id.search(result) + try: + vif_mac = match.group('vif_mac') + vif_id = match.group('vif_id') + port_name = match.group('port_name') + ofport = int(match.group('ofport')) + return VifPort(port_name, ofport, vif_id, vif_mac, self) + except Exception, e: + LOG.info("Unable to parse regex results. Exception: %s", e) + return diff --git a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py index 336ea4c9c..9e89be82b 100755 --- a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py +++ b/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py @@ -115,16 +115,17 @@ class OVSRpcCallbacks(): def port_update(self, context, **kwargs): LOG.debug("port_update received") port = kwargs.get('port') - port_name = 'tap%s' % port['id'][0:11] - vif_port = self.int_br.get_vif_port(port_name) - if port['admin_state_up']: - vlan_id = kwargs.get('vlan_id') - # create the networking for the port - self.int_br.set_db_attribute("Port", vif_port.port_name, - "tag", str(vlan_id)) - self.int_br.delete_flows(in_port=vif_port.ofport) - else: - self.int_br.clear_db_attribute("Port", vif_port.port_name, "tag") + vif_port = self.int_br.get_vif_port_by_id(port['id']) + if vif_port: + if port['admin_state_up']: + vlan_id = kwargs.get('vlan_id') + # create the networking for the port + self.int_br.set_db_attribute("Port", vif_port.port_name, + "tag", str(vlan_id)) + self.int_br.delete_flows(in_port=vif_port.ofport) + else: + self.int_br.clear_db_attribute("Port", vif_port.port_name, + "tag") def tunnel_update(self, context, **kwargs): LOG.debug("tunnel_update received") @@ -316,12 +317,12 @@ class OVSQuantumAgent(object): continue if 'port_id' in details: LOG.info("Port %s updated. Details: %s", device, details) - port_name = 'tap%s' % details['port_id'][0:11] - port = self.int_br.get_vif_port(port_name) - if details['admin_state_up']: - self.port_bound(port, details['vlan_id']) - else: - self.port_unbound(port, True) + port = self.int_br.get_vif_port_by_id(details['port_id']) + if port: + if details['admin_state_up']: + self.port_bound(port, details['vlan_id']) + else: + self.port_unbound(port, True) else: LOG.debug("Device %s not defined on plugin", device) return resync @@ -734,13 +735,13 @@ class OVSQuantumTunnelAgent(object): continue if 'port_id' in details: LOG.info("Port %s updated. Details: %s", device, details) - port_name = 'tap%s' % details['port_id'][0:11] - port = self.int_br.get_vif_port(port_name) - if details['admin_state_up']: - self.port_bound(port, details['network_id'], - details['vlan_id']) - else: - self.port_unbound(port, details['network_id']) + port = self.int_br.get_vif_port_by_id(details['port_id']) + if port: + if details['admin_state_up']: + self.port_bound(port, details['network_id'], + details['vlan_id']) + else: + self.port_unbound(port, details['network_id']) else: LOG.debug("Device %s not defined on plugin", device) return resync diff --git a/quantum/tests/unit/test_ovs_lib.py b/quantum/tests/unit/test_ovs_lib.py index 7172597c0..73c6123fe 100644 --- a/quantum/tests/unit/test_ovs_lib.py +++ b/quantum/tests/unit/test_ovs_lib.py @@ -277,3 +277,18 @@ class OVS_Lib_Test(unittest.TestCase): self.mox.ReplayAll() self.br.clear_db_attribute("Port", pname, "tag") self.mox.VerifyAll() + + def test_port_id_regex(self): + result = ('external_ids : {attached-mac="fa:16:3e:23:5b:f2",' + ' iface-id="5c1321a7-c73f-4a77-95e6-9f86402e5c8f",' + ' iface-status=active}\nname :' + ' "dhc5c1321a7-c7"\nofport : 2\n') + match = self.br.re_id.search(result) + vif_mac = match.group('vif_mac') + vif_id = match.group('vif_id') + port_name = match.group('port_name') + ofport = int(match.group('ofport')) + self.assertEqual(vif_mac, 'fa:16:3e:23:5b:f2') + self.assertEqual(vif_id, '5c1321a7-c73f-4a77-95e6-9f86402e5c8f') + self.assertEqual(port_name, 'dhc5c1321a7-c7') + self.assertEqual(ofport, 2) -- 2.45.2