1 # Copyright (c) 2010 Citrix Systems, Inc.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 from OVEStandard import *
17 from OVEConfig import *
20 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}')
23 def paramToLongString(cls, param):
24 if isinstance(param, (types.ListType, types.TupleType)) and len(param) > 1:
29 return text.replace(', ', ',\n')
32 def paramToString(cls, param):
33 if isinstance(param, (types.ListType, types.TupleType)) and len(param) > 1:
37 if OVEConfig.Inst().truncateUuids:
38 text = cls.UUID_RE.sub('\\1...', text)
40 return text.replace(', ', ',\n')
43 def flowDecodeHeadings(self):
65 def getFlowColumn(cls, name):
66 lowerName = name.lower()
67 for i, columnName in enumerate(cls.flowDecodeHeadings()):
68 if lowerName == columnName.lower():
86 # Parsing of ovs-dpctl dump-flows output should be localised in this method and flowDecodeHeadings
88 def decodeFlows(cls, srcLines):
92 # Comment out lines, starting from the bottom, until it works, then fix the one you stopped at
94 r'tunnel([^:]*):'+ # Tunnel: tunnel00000000
95 r'in_port([^:]+):' + # in_port: in_port0002
96 r'vlan([^:]+):' + #VLAN: vlan65535
97 r'([^ ]*) ' + # PCP: pcp0
98 r'mac(.{17})->' + # Source MAC: mac00:16:76:c8:1f:c9->
99 r'(.{17}) ' + # Dest MAC: mac00:16:76:c8:1f:c9
100 r'type([^ ]+) ' + #Type: type05ff
101 r'proto([^ ]+) ' + #Proto: proto0
102 r'(tos[^ ]+) ' + #Tos: tos0
103 r'ip(\d+\.\d+\.\d+\.\d+)->' + # Source IP: ip1.2.3.4->
104 r'(\d+\.\d+\.\d+\.\d+) ' + # Dest IP: 1.2.3.4
105 r'port(\d+)->' + # Source port: port0->
106 r'(\d+),\s*' + # Dest port: 0
107 r'packets:(\d*),\s*' + # Packets: packets:3423,
108 r'bytes:(\d*),\s*' + # Bytes: bytes:272024,
109 r'used:([^,]+),\s*' + # Used: used:0.870s,
110 r'actions:(\w+)\s*' + # Actions: actions:drop
113 for line in srcLines.split('\n'):
115 match = flowRe.match(line)
117 OVELog("Could not decode flow record '"+line+"'. Abandoning")
120 tunnel, inport, vlan, pcp, srcmac, destmac, type, proto, tos, srcip, destip, srcport, destport, packets, bytes, used, actions = match.groups()
124 type = cls.ETHERTYPE_TRANS.get(type, type)
125 proto = cls.ETHERPROTO_TRANS.get(proto, proto)
126 srcport = int(srcport)
127 destport = int(destport)
128 packets = long(packets)
130 # Order below needs to match that in flowDecodeHeadings
131 retVal.append((type, proto, inport, vlan, srcmac, destmac, srcip, destip, srcport, destport, packets, bytes, used, tos, pcp, tunnel, actions))
135 COLOURS = [Qt.black, Qt.darkBlue, Qt.darkRed, Qt.darkGreen, Qt.darkMagenta, Qt.darkCyan, Qt.darkGray, Qt.darkYellow, Qt.blue, Qt.gray, Qt.magenta, Qt.red]
138 def intToColour(cls, value):
139 return cls.COLOURS[value % len(cls.COLOURS)]