[ovs-dev] [debian 5/7] ovsdbmonitor: Update to work with recent ovs-dpctl output.

Ben Pfaff blp at nicira.com
Tue May 3 17:17:32 UTC 2011


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 |    6 ++-
 ovsdb/ovsdbmonitor/OVEUtil.py       |   76 ++++++++++++++++------------------
 2 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/ovsdb/ovsdbmonitor/OVEFlowWindow.py b/ovsdb/ovsdbmonitor/OVEFlowWindow.py
index ebcf466..e5a29a9 100644
--- a/ovsdb/ovsdbmonitor/OVEFlowWindow.py
+++ b/ovsdb/ovsdbmonitor/OVEFlowWindow.py
@@ -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:
diff --git a/ovsdb/ovsdbmonitor/OVEUtil.py b/ovsdb/ovsdbmonitor/OVEUtil.py
index 340d9b1..774bed2 100644
--- a/ovsdb/ovsdbmonitor/OVEUtil.py
+++ b/ovsdb/ovsdbmonitor/OVEUtil.py
@@ -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
         
-- 
1.7.4.4




More information about the dev mailing list