Re: [ovs-dev] [PATCH v1 08/12] python: ovs: flowviz: Add Openflow cookie format.

2024-02-29 Thread Eelco Chaudron



On 19 Feb 2024, at 9:14, Adrian Moreno wrote:

> When anaylizing OVN issues, it might be useful to see what OpenFlow
> flows were generated from each logical flow. In order to make it simpler
> to visualize this, add a cookie format that simply sorts the flows first
> by cookie, then by table.
>
> Example:
> $ export OVN_NB_DB=...
> $ export OVN_SB_DB=...
> $ ovs-vsctl dump-flows br-int | ovs-flowviz openflow cookie
> --ovn-filter="acl.*icmp4"
> $ ovs-vsctl dump-flows br-int | ovs-flowviz openflow cookie
> --ovn-detrace
>
> Acked-by: Eelco Chaudron 
> Signed-off-by: Adrian Moreno 

Ack on the additional change.

Acked-by: Eelco Chaudron 

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


[ovs-dev] [PATCH v1 08/12] python: ovs: flowviz: Add Openflow cookie format.

2024-02-19 Thread Adrian Moreno
When anaylizing OVN issues, it might be useful to see what OpenFlow
flows were generated from each logical flow. In order to make it simpler
to visualize this, add a cookie format that simply sorts the flows first
by cookie, then by table.

Example:
$ export OVN_NB_DB=...
$ export OVN_SB_DB=...
$ ovs-vsctl dump-flows br-int | ovs-flowviz openflow cookie
--ovn-filter="acl.*icmp4"
$ ovs-vsctl dump-flows br-int | ovs-flowviz openflow cookie
--ovn-detrace

Acked-by: Eelco Chaudron 
Signed-off-by: Adrian Moreno 
---
 python/ovs/flowviz/ofp/cli.py   | 57 +-
 python/ovs/flowviz/ofp/logic.py | 61 +
 2 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/python/ovs/flowviz/ofp/cli.py b/python/ovs/flowviz/ofp/cli.py
index 6b1435ea1..9658d00d3 100644
--- a/python/ovs/flowviz/ofp/cli.py
+++ b/python/ovs/flowviz/ofp/cli.py
@@ -18,7 +18,7 @@ import click
 
 from ovs.flowviz.main import maincli
 from ovs.flowviz.ofp.html import HTMLProcessor
-from ovs.flowviz.ofp.logic import LogicFlowProcessor
+from ovs.flowviz.ofp.logic import CookieProcessor, LogicFlowProcessor
 from ovs.flowviz.process import (
 OpenFlowFactory,
 JSONProcessor,
@@ -182,6 +182,61 @@ def logic(
 processor.print(show_flows)
 
 
+@openflow.command()
+@click.option(
+"-d",
+"--ovn-detrace",
+"ovn_detrace_flag",
+is_flag=True,
+show_default=True,
+help="Use ovn-detrace to extract cookie information",
+)
+@click.option(
+"--ovn-detrace-path",
+default="/usr/bin",
+type=click.Path(),
+help="Use an alternative path to where ovn_detrace.py is located. "
+"Instead of using this option you can just set PYTHONPATH accordingly",
+show_default=True,
+callback=ovn_detrace_callback,
+)
+@click.option(
+"--ovnnb-db",
+default=os.getenv("OVN_NB_DB") or "unix:/var/run/ovn/ovnnb_db.sock",
+help="Specify the OVN NB database string (implies -d). "
+"If the OVN_NB_DB environment variable is set, it's used as default. "
+"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
+callback=ovn_detrace_callback,
+)
+@click.option(
+"--ovnsb-db",
+default=os.getenv("OVN_SB_DB") or "unix:/var/run/ovn/ovnsb_db.sock",
+help="Specify the OVN NB database string (implies -d). "
+"If the OVN_NB_DB environment variable is set, it's used as default. "
+"Otherwise, the default is unix:/var/run/ovn/ovnnb_db.sock",
+callback=ovn_detrace_callback,
+)
+@click.option(
+"-o",
+"--ovn-filter",
+help="Specify a filter to be run on ovn-detrace information (implied -d). "
+"Format: python regular expression "
+"(see https://docs.python.org/3/library/re.html)",
+callback=ovn_detrace_callback,
+)
+@click.pass_obj
+def cookie(
+opts, ovn_detrace_flag, ovn_detrace_path, ovnnb_db, ovnsb_db, ovn_filter
+):
+"""Print the flow tables sorted by cookie."""
+if ovn_detrace_flag:
+opts["ovn_detrace_flag"] = True
+
+processor = CookieProcessor(opts)
+processor.process()
+processor.print()
+
+
 @openflow.command()
 @click.pass_obj
 def html(opts):
diff --git a/python/ovs/flowviz/ofp/logic.py b/python/ovs/flowviz/ofp/logic.py
index db2124374..9d244d137 100644
--- a/python/ovs/flowviz/ofp/logic.py
+++ b/python/ovs/flowviz/ofp/logic.py
@@ -301,3 +301,64 @@ cookie_style_gen = hash_pallete(
 saturation=[0.5],
 value=[0.5 + x / 10 * (0.85 - 0.5) for x in range(0, 10)],
 )
+
+
+class CookieProcessor(OpenFlowFactory, FileProcessor):
+"""Processor that sorts flows into cookies and tables."""
+
+def __init__(self, opts):
+super().__init__(opts)
+self.data = dict()
+self.ovn_detrace = (
+OVNDetrace(opts) if opts.get("ovn_detrace_flag") else None
+)
+
+def start_file(self, name, filename):
+self.cookies = dict()
+
+def stop_file(self, name, filename):
+self.data[name] = self.cookies
+
+def process_flow(self, flow, name):
+"""Sort the flows by table and logical flow."""
+cookie = flow.info.get("cookie") or 0
+if not self.cookies.get(cookie):
+self.cookies[cookie] = dict()
+
+table = flow.info.get("table") or 0
+if not self.cookies[cookie].get(table):
+self.cookies[cookie][table] = list()
+self.cookies[cookie][table].append(flow)
+
+def print(self):
+ofconsole = ConsoleFormatter(opts=self.opts)
+console = ofconsole.console
+for name, cookies in self.data.items():
+console.print("\n")
+console.print(file_header(name))
+tree = Tree("Ofproto Cookie Tree")
+
+for cookie, tables in cookies.items():
+ovn_info = None
+if self.ovn_detrace:
+ovn_info = self.ovn_detrace.get_ovn_info(cookie)
+if self.opts.get("ovn_filter"):
+ovn_regexp =