[ovs-dev] [PATCH ovn 3/3] ovn-detrace: Add support for other types of SB cookies.
Dumitru Ceara
dceara at redhat.com
Fri Nov 8 11:15:41 UTC 2019
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 <dceara at redhat.com>
---
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
More information about the dev
mailing list