Acked-by: Mark Michelson <mmich...@redhat.com>

On 11/15/19 2:24 PM, Dumitru Ceara wrote:
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__":


_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to