Commit eb25a7da639e ("Improve debuggability of OVN to OpenFlow
translations.") added cookies for Port_Binding, Mac_Binding,
Multicast_Group, Chassis records to the OpenfFlow entries they
generate.

Add support for parsing such cookies in ovn-detrace too.
Also, refactor ovn-detrace to allow a more generic way of defining
cookie handlers.

Signed-off-by: Dumitru Ceara <[email protected]>
---
 utilities/ovn-detrace.in |  166 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 117 insertions(+), 49 deletions(-)

diff --git a/utilities/ovn-detrace.in b/utilities/ovn-detrace.in
index 34b6b0e..79c6d3b 100755
--- a/utilities/ovn-detrace.in
+++ b/utilities/ovn-detrace.in
@@ -98,48 +98,112 @@ class OVSDB(object):
     def find_row_by_partial_uuid(self, table_name, value):
         return self._find_row(table_name, lambda row: value in str(row.uuid))
 
-
-def get_lflow_from_cookie(ovnsb_db, cookie):
-    return ovnsb_db.find_row_by_partial_uuid('Logical_Flow', cookie)
-
-
-def print_lflow(lflow, prefix):
-    ldp_uuid = lflow.logical_datapath.uuid
-    ldp_name = str(lflow.logical_datapath.external_ids.get('name'))
-
-    print '%sLogical datapath: "%s" (%s) [%s]' % (prefix,
-                                                  ldp_name,
-                                                  ldp_uuid,
-                                                  lflow.pipeline)
-    print "%sLogical flow: table=%s (%s), priority=%s, " \
-          "match=(%s), actions=(%s)" % (prefix,
-                                        lflow.table_id,
-                                        lflow.external_ids.get('stage-name'),
-                                        lflow.priority,
-                                        str(lflow.match).strip('"'),
-                                        str(lflow.actions).strip('"'))
-
-
-def print_lflow_nb_hint(lflow, prefix, ovnnb_db):
-    external_ids = lflow.external_ids
-    if external_ids.get('stage-name') in ['ls_in_acl',
-                                          'ls_out_acl']:
-        acl_hint = external_ids.get('stage-hint')
-        if not acl_hint:
-            return
-        acl = ovnnb_db.find_row_by_partial_uuid('ACL', acl_hint)
-        if not acl:
+class CookieHandler(object):
+    def __init__(self, db, table):
+        self._db = db
+        self._table = table
+
+    def get_record(self, cookie):
+        return self._db.find_row_by_partial_uuid(self._table, cookie)
+
+    def print_record(self, record, prefix):
+        pass
+
+    def print_hint(self, record, prefix, db):
+        pass
+
+def datapath_str(datapath):
+    return '"%s" (%s)' % (str(datapath.external_ids.get('name')),
+                          datapath.uuid)
+
+def chassis_str(chassis):
+    if len(chassis) == 0:
+        return ''
+    ch = chassis[0]
+    return 'chassis-name "%s", chassis-str "%s"' % (ch.name, ch.hostname)
+
+class LogicalFlowHandler(CookieHandler):
+    def __init__(self, ovnsb_db):
+        super(LogicalFlowHandler, self).__init__(ovnsb_db, 'Logical_Flow')
+
+    def print_record(self, lflow, prefix):
+        print('%sLogical datapath: %s [%s]' %
+            (prefix, datapath_str(lflow.logical_datapath), lflow.pipeline))
+        print('%sLogical flow: table=%s (%s), priority=%s, '
+              'match=(%s), actions=(%s)' %
+                (prefix, lflow.table_id, lflow.external_ids.get('stage-name'),
+                 lflow.priority,
+                 str(lflow.match).strip('"'),
+                 str(lflow.actions).strip('"')))
+
+    def print_hint(self, lflow, prefix, ovnnb_db):
+        external_ids = lflow.external_ids
+        if external_ids.get('stage-name') in ['ls_in_acl',
+                                              'ls_out_acl']:
+            acl_hint = external_ids.get('stage-hint')
+            if not acl_hint:
+                return
+            acl = ovnnb_db.find_row_by_partial_uuid('ACL', acl_hint)
+            if not acl:
+                return
+            output = '%sACL: %s, priority=%s, ' \
+                     'match=(%s), %s' % (prefix,
+                                         acl.direction,
+                                         acl.priority,
+                                         acl.match.strip('"'),
+                                         acl.action)
+            if acl.log:
+                output += ' (log)'
+            print(output)
+
+class PortBindingHandler(CookieHandler):
+    def __init__(self, ovnsb_db):
+        super(PortBindingHandler, self).__init__(ovnsb_db, 'Port_Binding')
+
+    def print_record(self, pb, prefix):
+        ldp_uuid = pb.datapath.uuid
+        ldp_name = str(pb.datapath.external_ids.get('name'))
+
+        print('%sLogical datapath: %s' % (prefix, datapath_str(pb.datapath)))
+        print('%sPort Binding: logical_port "%s", tunnel_key %ld, %s' %
+                (prefix, pb.logical_port, pb.tunnel_key,
+                 chassis_str(pb.chassis)))
+
+class MacBindingHandler(CookieHandler):
+    def __init__(self, ovnsb_db):
+        super(MacBindingHandler, self).__init__(ovnsb_db, 'MAC_Binding')
+
+    def print_record(self, mb, prefix):
+        print('%sLogical datapath: %s' % (prefix, datapath_str(mb.datapath)))
+        print('%sMAC Binding: ip "%s", logical_port "%s", mac "%s"' %
+                (prefix, mb.ip, mb.logical_port, mb.mac))
+
+class MulticastGroupHandler(CookieHandler):
+    def __init__(self, ovnsb_db):
+        super(MulticastGroupHandler, self).__init__(ovnsb_db,
+                                                    'Multicast_Group')
+
+    def print_record(self, mc, prefix):
+        mc_ports = ', '.join([pb.logical_port for pb in mc.ports])
+
+        print('%sLogical datapath: %s' % (prefix, datapath_str(mc.datapath)))
+        print('%sMulticast Group: name "%s", tunnel_key %ld ports: (%s)' %
+                (prefix, mc.name, mc.tunnel_key, mc_ports))
+
+class ChassisHandler(CookieHandler):
+    def __init__(self, ovnsb_db):
+        super(ChassisHandler, self).__init__(ovnsb_db, 'Chassis')
+
+    def print_record(self, chassis, prefix):
+        print('%sChassis: %s' % (prefix, chassis_str([chassis])))
+
+def print_sb_record_from_cookie(ovnnb_db, ovnsb_db, cookie_handlers, cookie):
+    for handler in cookie_handlers:
+        sb_record = handler.get_record(cookie)
+        if sb_record:
+            handler.print_record(sb_record, "  * ")
+            handler.print_hint(sb_record,   "   * ", ovnnb_db)
             return
-        output = "%sACL: %s, priority=%s, " \
-                 "match=(%s), %s" % (prefix,
-                                     acl.direction,
-                                     acl.priority,
-                                     acl.match.strip('"'),
-                                     acl.action)
-        if acl.log:
-            output += ' (log)'
-        print output
-
 
 def main():
     try:
@@ -183,6 +247,14 @@ def main():
     ovsdb_ovnsb = OVSDB(ovnsb_db, 'OVN_Southbound')
     ovsdb_ovnnb = OVSDB(ovnnb_db, 'OVN_Northbound')
 
+    cookie_handlers = [
+        LogicalFlowHandler(ovsdb_ovnsb),
+        PortBindingHandler(ovsdb_ovnsb),
+        MacBindingHandler(ovsdb_ovnsb),
+        MulticastGroupHandler(ovsdb_ovnsb),
+        ChassisHandler(ovsdb_ovnsb)
+    ]
+
     regex_cookie = re.compile(r'^.*cookie 0x([0-9a-fA-F]+)')
     regex_table_id = re.compile(r'^[0-9]+\.')
     cookie = None
@@ -194,14 +266,10 @@ def main():
 
         line = line.strip()
 
-        if cookie:
-            # print lflow info when the current flow block ends
-            if regex_table_id.match(line):
-                lflow = get_lflow_from_cookie(ovsdb_ovnsb, cookie)
-                if lflow:
-                    print_lflow(lflow, "  * ")
-                    print_lflow_nb_hint(lflow, "    * ", ovsdb_ovnnb)
-                    cookie = None
+        # Print SB record info when the current flow block ends.
+        if cookie and regex_table_id.match(line):
+            print_sb_record_from_cookie(ovsdb_ovnnb, ovsdb_ovnsb,
+                                        cookie_handlers, cookie)
 
         print line
 

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to