]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Get OVS port details from port ID
authorGary Kotton <gkotton@redhat.com>
Thu, 16 Aug 2012 10:06:55 +0000 (06:06 -0400)
committerGary Kotton <gkotton@redhat.com>
Mon, 20 Aug 2012 06:18:03 +0000 (02:18 -0400)
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
quantum/plugins/openvswitch/agent/ovs_quantum_agent.py
quantum/tests/unit/test_ovs_lib.py

index 67f06580e2aaf180c16d03bddd2aade3457a3aed..e491b5edb8b7bca2b9a59cc52b7bce96c4d50ed5 100644 (file)
@@ -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<vif_mac>([a-fA-F\d]{2}:){5}([a-fA-F\d]{2}))"'
+        iface = 'iface-id="(?P<vif_id>[^"]+)"'
+        name = 'name\s*:\s"(?P<port_name>[^"]*)"'
+        port = 'ofport\s*:\s(?P<ofport>\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
index 336ea4c9c25aa485b19caef622a68dab50eb3757..9e89be82b448e39075f4e455e3b1c7e4be0f239a 100755 (executable)
@@ -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
index 7172597c0e6fdf0141976013d6eab8b54640e94a..73c6123fe3a416f51195979d044e368d28c3d2c7 100644 (file)
@@ -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)