ovsdbmonitor: Update to work with recent ovs-dpctl output.
authorBen Pfaff <blp@nicira.com>
Mon, 2 May 2011 23:27:58 +0000 (16:27 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 23 May 2011 20:41:18 +0000 (13:41 -0700)
The format of "ovs-dpctl dump-flows" has completely changed since
ovsdbmonitor was written.  It seems like no one has tried out ovsdbmonitor
since the rewrite, because it didn't work at all.  This commit fixes the
parser.

ovsdb/ovsdbmonitor/OVEFlowWindow.py
ovsdb/ovsdbmonitor/OVEUtil.py

index ebcf466e878ea2881b4b5e76091eda4288259db0..e5a29a9f05d87928eac0128b725e6c8cab4c2cd7 100644 (file)
@@ -1,3 +1,4 @@
+# Copyright (c) 2011 Nicira Networks.
 # Copyright (c) 2010 Citrix Systems, Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +23,8 @@ from OVECommonWindow import *
 
 from Ui_FlowWindow import *
 
+import re
+
 class OVEFlowWindow(QtGui.QMainWindow, OVECommonWindow):
     LOAD_KEY = 'FlowWindow/window'
     COMMAND_OVS_DPCTL='/usr/bin/ovs-dpctl'
@@ -231,7 +234,6 @@ class OVEFlowWindow(QtGui.QMainWindow, OVECommonWindow):
                         colour = Qt.black
                         
                     for colNum, data in enumerate(flow):
-                        
                         item = None
                         try:
                             item = table.takeItem(rowNum, colNum)
@@ -245,7 +247,7 @@ class OVEFlowWindow(QtGui.QMainWindow, OVECommonWindow):
                         elif colNum == srcMacColumn or colNum == destMacColumn:
                             cols = [int(x, 16) for x in data.split(':')]
                             item.setBackground(QtGui.QColor(255-cols[2]*cols[3] % 192, 255-cols[3]*cols[4] % 192, 255-cols[4]*cols[5] % 192))
-                        elif colNum == srcIPColumn or colNum == destIPColumn:
+                        elif re.match(r'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', str(data)):
                             cols = [int(x) for x in data.split('.')]
                             item.setBackground(QtGui.QColor(255-cols[1]*cols[2] % 192, 255-cols[2]*cols[3] % 192, 255-cols[3]*cols[0] % 192))
                         else:
index 340d9b15f649005883bcbf6aac8380b1d757f1f6..774bed272c943c4c0b5022bbec9ff7c560642fbb 100644 (file)
@@ -1,3 +1,4 @@
+# Copyright (c) 2011 Nicira Networks.
 # Copyright (c) 2010 Citrix Systems, Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +16,7 @@
 from OVEStandard import *
 
 from OVEConfig import *
+import re
 
 class OVEUtil:
     UUID_RE = re.compile(r'([a-f0-9]{8}-[a-f0-9]{2})[a-f0-9]{2}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}')
@@ -87,48 +89,42 @@ class OVEUtil:
     @classmethod
     def decodeFlows(cls, srcLines):
         retVal = []
-        flowRe = re.compile(
-            # To fix this regexp:
-            #  Comment out lines, starting from the bottom, until it works, then fix the one you stopped at
-            '^' +
-            r'tunnel([^:]*):'+ # Tunnel: tunnel00000000
-            r'in_port([^:]+):' + # in_port: in_port0002
-            r'vlan([^:]+):' + #VLAN: vlan65535
-            r'([^ ]*) ' + # PCP: pcp0
-            r'mac(.{17})->' + # Source MAC: mac00:16:76:c8:1f:c9->
-            r'(.{17}) ' + # Dest MAC: mac00:16:76:c8:1f:c9
-            r'type([^ ]+) ' + #Type: type05ff
-            r'proto([^ ]+) ' + #Proto: proto0
-            r'(tos[^ ]+) ' + #Tos: tos0
-            r'ip(\d+\.\d+\.\d+\.\d+)->' + # Source IP: ip1.2.3.4->
-            r'(\d+\.\d+\.\d+\.\d+) ' + # Dest IP: 1.2.3.4
-            r'port(\d+)->' + # Source port: port0->
-            r'(\d+),\s*' + # Dest port: 0
-            r'packets:(\d*),\s*' + # Packets: packets:3423,
-            r'bytes:(\d*),\s*' + # Bytes: bytes:272024,
-            r'used:([^,]+),\s*' + # Used: used:0.870s,
-            r'actions:(\w+)\s*' + # Actions: actions:drop
-            ''
-            )
         for line in srcLines.split('\n'):
             if line != '':
-                match = flowRe.match(line)
-                if not match:
-                    OVELog("Could not decode flow record '"+line+"'.  Abandoning")
-                    return retVal
-                else:
-                    tunnel, inport, vlan, pcp, srcmac, destmac, type, proto, tos, srcip, destip, srcport, destport, packets, bytes, used, actions = match.groups()
-                    tunnel = int(tunnel)
-                    inport = int(inport)
-                    vlan = int(vlan)
-                    type = cls.ETHERTYPE_TRANS.get(type, type)
-                    proto = cls.ETHERPROTO_TRANS.get(proto, proto)
-                    srcport = int(srcport)
-                    destport = int(destport)
-                    packets = long(packets)
-                    bytes = long(bytes)
-                    # Order below needs to match that in flowDecodeHeadings
-                    retVal.append((type, proto, inport, vlan, srcmac, destmac, srcip, destip, srcport, destport, packets, bytes, used, tos, pcp, tunnel, actions))
+                fields = {}
+                for name, val in re.findall(r'([a-zA-Z0-9_+]+)\(([^)]+)\)', line):
+                    if '=' in val:
+                        for setting in val.split(','):
+                            k,v = setting.split('=')
+                            fields['%s.%s' % (name, k)] = v
+                    else:
+                        fields[name] = val
+                for setting in re.split(', ', line)[1:]:
+                    if ':' in setting:
+                        k,v = setting.split(':')
+                        fields[k] = v
+
+                tun_id = fields.get('tun_id', '')
+                in_port = int(fields.get('in_port', 0))
+                eth_src = fields.get('eth.src', '')
+                eth_dst = fields.get('eth.dst', '')
+                vlan_vid = int(fields.get('vlan.vid', 0))
+                vlan_pcp = int(fields.get('vlan.pcp', 0))
+                eth_type = fields.get('eth_type', '')
+                ip_src = fields.get('ipv4.src', fields.get('ipv6.src', ''))
+                ip_dst = fields.get('ipv4.dst', fields.get('ipv6.dst', ''))
+                ip_proto = fields.get('ipv4.proto', fields.get('ipv6.proto', ''))
+                ip_tos = fields.get('ipv4.tos', fields.get('ipv6.tos', ''))
+                tp_src = fields.get('tcp.src', fields.get('udp.src', fields.get('arp.sip', fields.get('icmp.type', fields.get('icmpv6.type', '')))))
+                tp_dst = fields.get('tcp.dst', fields.get('udp.dst', fields.get('arp.tip', fields.get('icmp.code', fields.get('icmpv6.code', '')))))
+
+                packets = fields.get('packets', '')
+                bytes = fields.get('bytes', '')
+                actions = fields.get('actions', '')
+                used = fields.get('used', '')
+
+                # Order below needs to match that in flowDecodeHeadings
+                retVal.append((eth_type, ip_proto, in_port, vlan_vid, eth_src, eth_dst, ip_src, ip_dst, tp_src, tp_dst, packets, bytes, used, ip_tos, vlan_pcp, tun_id, actions))
                     
         return retVal