Two new command line arguments are added to ovn-detrace: - "--ovs": which will instruct ovn-detrace to connect to the local OVS db.sock and try to decode input/output ofport values and pretty print the corresponding OVS interfaces. - "--ovsdb": which allows the user to point ovn-detrace to other OVS DB remotes (useful when ovn-trace is not run on the hypervisor where ofproto-trace was run.
Signed-off-by: Dumitru Ceara <dce...@redhat.com> --- utilities/ovn-detrace.1.in | 11 +++++ utilities/ovn-detrace.in | 105 +++++++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/utilities/ovn-detrace.1.in b/utilities/ovn-detrace.1.in index 2f662d4..b899b63 100644 --- a/utilities/ovn-detrace.1.in +++ b/utilities/ovn-detrace.1.in @@ -33,6 +33,17 @@ Otherwise, the default is \fBunix:@RUNDIR@/ovnnb_db.sock\fR, but this default is unlikely to be useful outside of single-machine OVN test environments. . +.IP "\fB\-\-ovs=\fR" +Also decode flow information (like OVS ofport) from the flows by connecting +to the OVS DB. +. +.IP "\fB\-\-ovsdb=\fIserver\fR" +The OVS DB remote to contact if \fB\-\-ovs\f is present. If the +\fBOVS_RUNDIR\fR environment variable is set, its value is used as the +default. Otherwise, the default is \fBunix:@RUNDIR@/db.sock\fR, but this +default is unlikely to be useful outside of single-machine OVN test +environments. +. .SH "SEE ALSO" . .BR ovs\-appctl (8), ovn\-sbctl (8), ovn-\-nbctl (8), ovn\-trace (8) diff --git a/utilities/ovn-detrace.in b/utilities/ovn-detrace.in index c645658..52f6f4f 100755 --- a/utilities/ovn-detrace.in +++ b/utilities/ovn-detrace.in @@ -28,6 +28,7 @@ try: from ovs import jsonrpc from ovs.poller import Poller from ovs.stream import Stream + from ovs import dirs except Exception: print("ERROR: Please install the correct Open vSwitch python support") print(" libraries (@VERSION@).") @@ -49,7 +50,8 @@ The following options are also available: -h, --help display this help message -V, --version display version information --ovnsb=DATABASE use DATABASE as southbound DB - --ovnnb=DATABASE use DATABASE as northbound DB\ + --ovnnb=DATABASE use DATABASE as northbound DB + --ovsdb=DATABASE use DATABASE as OVS DB\ """ % {'argv0': argv0}) sys.exit(0) @@ -102,15 +104,15 @@ class OVSDB(object): def get_table(self, table_name): return self._idl_conn.tables[table_name] - def _find_row(self, table_name, find_fn): + def _find_rows(self, table_name, find_fn): return filter(find_fn, self.get_table(table_name).rows.values()) def _find_rows_by_name(self, table_name, value): - return self._find_row(table_name, lambda row: row.name == value) + return self._find_rows(table_name, lambda row: row.name == value) def find_rows_by_partial_uuid(self, table_name, value): - return self._find_row(table_name, - lambda row: str(row.uuid).startswith(value)) + return self._find_rows(table_name, + lambda row: str(row.uuid).startswith(value)) class CookieHandler(object): def __init__(self, db, table): @@ -118,9 +120,7 @@ class CookieHandler(object): self._table = table def get_records(self, cookie): - # Adjust cookie to include leading zeroes if needed. - cookie = cookie.zfill(8) - return self._db.find_rows_by_partial_uuid(self._table, cookie) + return [] def print_record(self, record): pass @@ -128,7 +128,16 @@ class CookieHandler(object): def print_hint(self, record, db): pass -class LogicalFlowHandler(CookieHandler): +class CookieHandlerByUUUID(CookieHandler): + def __init__(self, db, table): + super(CookieHandlerByUUUID, self).__init__(db, table) + + def get_records(self, cookie): + # Adjust cookie to include leading zeroes if needed. + cookie = cookie.zfill(8) + return self._db.find_rows_by_partial_uuid(self._table, cookie) + +class LogicalFlowHandler(CookieHandlerByUUUID): def __init__(self, ovnsb_db): super(LogicalFlowHandler, self).__init__(ovnsb_db, 'Logical_Flow') @@ -163,7 +172,7 @@ class LogicalFlowHandler(CookieHandler): output += ' (log)' print_h(output) -class PortBindingHandler(CookieHandler): +class PortBindingHandler(CookieHandlerByUUUID): def __init__(self, ovnsb_db): super(PortBindingHandler, self).__init__(ovnsb_db, 'Port_Binding') @@ -173,7 +182,7 @@ class PortBindingHandler(CookieHandler): (pb.logical_port, pb.tunnel_key, chassis_str(pb.chassis))) -class MacBindingHandler(CookieHandler): +class MacBindingHandler(CookieHandlerByUUUID): def __init__(self, ovnsb_db): super(MacBindingHandler, self).__init__(ovnsb_db, 'MAC_Binding') @@ -182,7 +191,7 @@ class MacBindingHandler(CookieHandler): print_p('MAC Binding: ip "%s", logical_port "%s", mac "%s"' % (mb.ip, mb.logical_port, mb.mac)) -class MulticastGroupHandler(CookieHandler): +class MulticastGroupHandler(CookieHandlerByUUUID): def __init__(self, ovnsb_db): super(MulticastGroupHandler, self).__init__(ovnsb_db, 'Multicast_Group') @@ -194,31 +203,47 @@ class MulticastGroupHandler(CookieHandler): print_p('Multicast Group: name "%s", tunnel_key %ld ports: (%s)' % (mc.name, mc.tunnel_key, mc_ports)) -class ChassisHandler(CookieHandler): +class ChassisHandler(CookieHandlerByUUUID): def __init__(self, ovnsb_db): super(ChassisHandler, self).__init__(ovnsb_db, 'Chassis') def print_record(self, chassis): print_p('Chassis: %s' % (chassis_str([chassis]))) -def print_sb_record_from_cookie(ovnnb_db, ovnsb_db, cookie_handlers, cookie): +class OvsInterfaceHandler(CookieHandler): + def __init__(self, ovs_db): + super(OvsInterfaceHandler, self).__init__(ovs_db, 'Interface') + + def get_records(self, ofport): + return self._db._find_rows(self._table, + lambda intf: len(intf.ofport) > 0 and + str(intf.ofport[0]) == ofport) + + def print_record(self, intf): + print_p('OVS Interface: %s (%s)' % + (intf.name, intf.external_ids.get('iface-id'))) + +def print_record_from_cookie(ovnnb_db, cookie_handlers, cookie): for handler in cookie_handlers: - for i, sb_record in enumerate(handler.get_records(cookie)): + for i, record in enumerate(handler.get_records(cookie)): if i > 0: handler.print('[Duplicate uuid cookie]') - handler.print_record(sb_record) - handler.print_hint(sb_record, ovnnb_db) + handler.print_record(record) + handler.print_hint(record, ovnnb_db) def main(): try: options, args = getopt.gnu_getopt(sys.argv[1:], 'hV', - ['help', 'version', 'ovnsb=', 'ovnnb=']) + ['help', 'version', 'ovs', + 'ovnsb=', 'ovnnb=', 'ovsdb=']) except getopt.GetoptError, geo: sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) sys.exit(1) ovnsb_db = None ovnnb_db = None + ovs_db = None + ovs = False for key, value in options: if key in ['-h', '--help']: @@ -229,6 +254,10 @@ def main(): ovnsb_db = value elif key in ['--ovnnb']: ovnnb_db = value + elif key in ['--ovsdb']: + ovs_db = value + elif key in ['--ovs']: + ovs = True else: sys.exit(0) @@ -238,6 +267,8 @@ def main(): sys.exit(1) ovn_rundir = os.getenv('OVN_RUNDIR', '@OVN_RUNDIR@') + ovs_rundir = os.getenv('OVS_RUNDIR', dirs.RUNDIR) + if not ovnsb_db: ovnsb_db = os.getenv('OVN_SB_DB') if not ovnsb_db: @@ -247,6 +278,8 @@ def main(): ovnnb_db = os.getenv('OVN_NB_DB') if not ovnnb_db: ovnnb_db = 'unix:%s/ovnnb_db.sock' % ovn_rundir + if ovs and not ovs_db: + ovs_db = 'unix:%s/db.sock' % ovs_rundir ovsdb_ovnsb = OVSDB(ovnsb_db, 'OVN_Southbound') ovsdb_ovnnb = OVSDB(ovnnb_db, 'OVN_Northbound') @@ -260,25 +293,41 @@ def main(): ] regex_cookie = re.compile(r'^.*cookie 0x([0-9a-fA-F]+)') + regex_handlers = [ + (regex_cookie, cookie_handlers) + ] + + if ovs: + ovsdb_ovs = OVSDB(ovs_db, 'Open_vSwitch') + regex_inport = re.compile(r'^ *[0-9]+\. *in_port=([0-9])+') + regex_outport = re.compile(r'^ *output:([0-9]+)') + ofport_handlers = [ + OvsInterfaceHandler(ovsdb_ovs) + ] + regex_handlers += [ + (regex_outport, ofport_handlers), + (regex_inport, ofport_handlers) + ] + regex_table_id = re.compile(r'^ *[0-9]+\.') - cookie = None + cookies = [] while True: line = sys.stdin.readline() - if cookie: - # Print SB record info when the current flow block ends. + if len(cookies) > 0: + # Print record info when the current flow block ends. if regex_table_id.match(line) or line.strip() == '': - print_sb_record_from_cookie(ovsdb_ovnnb, ovsdb_ovnsb, - cookie_handlers, cookie) - cookie = None + for cookie, handlers in cookies: + print_record_from_cookie(ovsdb_ovnnb, handlers, cookie) + cookies = [] print(line.strip()) if line == '': break - m = regex_cookie.match(line) - if not m: - continue - cookie = m.group(1) + for regex, handlers in regex_handlers: + m = regex.match(line) + if m: + cookies.append((m.group(1), handlers)) if __name__ == "__main__": -- 1.8.3.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev