diff mbox series

[ovs-dev,v4] utilities: Add a GDB macro to dump ct conns.

Message ID 20240913031401.1726-1-i@liuyulong.me
State Accepted
Commit ec0f3772f4ac2cc423a21fa26c7973196948d0bb
Delegated to: Eelco Chaudron
Headers show
Series [ovs-dev,v4] utilities: Add a GDB macro to dump ct conns. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

LIU Yulong Sept. 13, 2024, 3:14 a.m. UTC
Add a new GDB macro called ovs_dump_conntrack_conns, which can
be used to dump all conn structure in a conntrack. For example

(gdb) ovs_dump_conntrack_conns
usage: ovs_dump_conntrack_conns <struct conntrack *> {short}

(gdb) ovs_dump_conntrack_conns 0x5606339c25e0
(struct conn *) 0x7f32c000a8c0: expiration = 26162886419, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
(struct conn *) 0x7f32c00489d0: expiration = 26162900867, mark = 0, dl_type = 8, zone = 3, nw_proto = 1 '\001'
(struct conn *) 0x7f32c0153bb0: expiration = 26249266420, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'

(gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
(struct conn *) 0x7f32c000a8c0
(struct conn *) 0x7f32c00489d0
(struct conn *) 0x7f32c0153bb0

Signed-off-by: LIU Yulong <i@liuyulong.me>
---
v1: initial version
v2: address comments from reviewers
    print details of struct conn
    add short param
v3: address pep8 check warnnings
v4: align the new data structure of struct conn {}
---
 utilities/gdb/ovs_gdb.py | 64 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

Comments

Eelco Chaudron Sept. 13, 2024, 9:01 a.m. UTC | #1
On 13 Sep 2024, at 5:14, LIU Yulong wrote:

> Add a new GDB macro called ovs_dump_conntrack_conns, which can
> be used to dump all conn structure in a conntrack. For example
>
> (gdb) ovs_dump_conntrack_conns
> usage: ovs_dump_conntrack_conns <struct conntrack *> {short}
>
> (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
> (struct conn *) 0x7f32c000a8c0: expiration = 26162886419, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
> (struct conn *) 0x7f32c00489d0: expiration = 26162900867, mark = 0, dl_type = 8, zone = 3, nw_proto = 1 '\001'
> (struct conn *) 0x7f32c0153bb0: expiration = 26249266420, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
>
> (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
> (struct conn *) 0x7f32c000a8c0
> (struct conn *) 0x7f32c00489d0
> (struct conn *) 0x7f32c0153bb0
>
> Signed-off-by: LIU Yulong <i@liuyulong.me>

Thanks LIU for the v4, it looks good to me with one small nit below, which I can apply on commit.

Acked-by: Eelco Chaudron <echaudro@redhat.com>

> ---
> v1: initial version
> v2: address comments from reviewers
>     print details of struct conn
>     add short param
> v3: address pep8 check warnnings
> v4: align the new data structure of struct conn {}
> ---
>  utilities/gdb/ovs_gdb.py | 64 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>
> diff --git a/utilities/gdb/ovs_gdb.py b/utilities/gdb/ovs_gdb.py
> index 982395dd1..53acc6c4b 100644
> --- a/utilities/gdb/ovs_gdb.py
> +++ b/utilities/gdb/ovs_gdb.py
> @@ -37,6 +37,7 @@
>  #    - ovs_dump_udpif_keys {<udpif_name>|<udpif_address>} {short}
>  #    - ovs_show_fdb {[<bridge_name>] {dbg} {hash}}
>  #    - ovs_show_upcall {dbg}
> +#    - ovs_dump_conntrack_conns <struct conntrack *> {short}
>  #
>  #  Example:
>  #    $ gdb $(which ovs-vswitchd) $(pidof ovs-vswitchd)
> @@ -1550,6 +1551,68 @@ class CmdDumpPackets(gdb.Command):
>          return packet
>
>
> +#
> +# Implements the GDB "ovs_dump_conntrack_conns" command
> +#
> +class CmdDumpDpConntrackConn(gdb.Command):
> +    """Dump all connections in a conntrack set
> +    Usage:
> +      ovs_dump_conntrack_conns <struct conntrack *> {short}
> +
> +      <struct conntrack *> : Pointer to conntrack
> +      short                : Only dump conn structure addresses,
> +                             no content details
> +
> +    Example dumping all <struct conn> connections:
> +
> +    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
> +    (struct conn *) 0x7f32c000a8c0: expiration = ... nw_proto = 1
> +    (struct conn *) 0x7f32c00489d0: expiration = ... nw_proto = 6
> +    (struct conn *) 0x7f32c0153bb0: expiration = ... nw_proto = 17
> +
> +    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
> +    (struct conn *) 0x7f32c000a8c0
> +    (struct conn *) 0x7f32c00489d0
> +    (struct conn *) 0x7f32c0153bb0
> +    """
> +    def __init__(self):
> +        super(CmdDumpDpConntrackConn, self).__init__(
> +            "ovs_dump_conntrack_conns",
> +            gdb.COMMAND_DATA)
> +
> +    @staticmethod
> +    def display_single_conn(conn, dir_, indent=0, short=False):
> +        indent = " " * indent
> +        if short:
> +            print("{}(struct conn *) {}".format(indent, conn))
> +        else:
> +            print("{}(struct conn *) {}: expiration = {}, mark = {}, "
> +                  "dl_type = {}, zone = {}, nw_proto = {}".format(
> +                      indent, conn, conn['expiration'],
> +                      conn['mark'], conn['key_node'][dir_]['key']['dl_type'],
> +                      conn['key_node'][dir_]['key']['zone'],
> +                      conn['key_node'][dir_]['key']['nw_proto']))
> +
> +    def invoke(self, arg, from_tty):
> +        arg_list = gdb.string_to_argv(arg)
> +        if len(arg_list) == 0:

We do not check if the 2nd parameter is garbage (or more exists). So I would add the following:

     def invoke(self, arg, from_tty):
         arg_list = gdb.string_to_argv(arg)
-        if len(arg_list) == 0:
+        if len(arg_list) not in (1, 2) or \
+           (len(arg_list) == 2 and arg_list[1] != "short"):
             print("usage: ovs_dump_conntrack_conns <struct conntrack *> "

> +            print("usage: ovs_dump_conntrack_conns <struct conntrack *> "
> +                  "{short}")
> +            return
> +
> +        ct = gdb.parse_and_eval(arg_list[0]).cast(
> +            gdb.lookup_type('struct conntrack').pointer())
> +
> +        for key_node in ForEachCMAP(ct["conns"],
> +                                    "struct conn_key_node", "cm_node"):
> +            node = container_of(
> +                key_node,
> +                gdb.lookup_type('struct conn').pointer(),
> +                "key_node")
> +            self.display_single_conn(node, key_node['dir'],
> +                                     short="short" in arg_list[1:])
> +
> +
>  #
>  # Initialize all GDB commands
>  #
> @@ -1571,3 +1634,4 @@ CmdDumpSmap()
>  CmdDumpUdpifKeys()
>  CmdShowFDB()
>  CmdShowUpcall()
> +CmdDumpDpConntrackConn()
> -- 
> 2.28.0.windows.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Mike Pattrick Sept. 13, 2024, 3:30 p.m. UTC | #2
On Fri, Sep 13, 2024 at 5:01 AM Eelco Chaudron <echaudro@redhat.com> wrote:
>
>
>
> On 13 Sep 2024, at 5:14, LIU Yulong wrote:
>
> > Add a new GDB macro called ovs_dump_conntrack_conns, which can
> > be used to dump all conn structure in a conntrack. For example
> >
> > (gdb) ovs_dump_conntrack_conns
> > usage: ovs_dump_conntrack_conns <struct conntrack *> {short}
> >
> > (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
> > (struct conn *) 0x7f32c000a8c0: expiration = 26162886419, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
> > (struct conn *) 0x7f32c00489d0: expiration = 26162900867, mark = 0, dl_type = 8, zone = 3, nw_proto = 1 '\001'
> > (struct conn *) 0x7f32c0153bb0: expiration = 26249266420, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
> >
> > (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
> > (struct conn *) 0x7f32c000a8c0
> > (struct conn *) 0x7f32c00489d0
> > (struct conn *) 0x7f32c0153bb0
> >
> > Signed-off-by: LIU Yulong <i@liuyulong.me>
>
> Thanks LIU for the v4, it looks good to me with one small nit below, which I can apply on commit.
>
> Acked-by: Eelco Chaudron <echaudro@redhat.com>

Acked-by: Mike Pattrick <mkp@redhat.com>

>
> > ---
> > v1: initial version
> > v2: address comments from reviewers
> >     print details of struct conn
> >     add short param
> > v3: address pep8 check warnnings
> > v4: align the new data structure of struct conn {}
> > ---
> >  utilities/gdb/ovs_gdb.py | 64 ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 64 insertions(+)
> >
> > diff --git a/utilities/gdb/ovs_gdb.py b/utilities/gdb/ovs_gdb.py
> > index 982395dd1..53acc6c4b 100644
> > --- a/utilities/gdb/ovs_gdb.py
> > +++ b/utilities/gdb/ovs_gdb.py
> > @@ -37,6 +37,7 @@
> >  #    - ovs_dump_udpif_keys {<udpif_name>|<udpif_address>} {short}
> >  #    - ovs_show_fdb {[<bridge_name>] {dbg} {hash}}
> >  #    - ovs_show_upcall {dbg}
> > +#    - ovs_dump_conntrack_conns <struct conntrack *> {short}
> >  #
> >  #  Example:
> >  #    $ gdb $(which ovs-vswitchd) $(pidof ovs-vswitchd)
> > @@ -1550,6 +1551,68 @@ class CmdDumpPackets(gdb.Command):
> >          return packet
> >
> >
> > +#
> > +# Implements the GDB "ovs_dump_conntrack_conns" command
> > +#
> > +class CmdDumpDpConntrackConn(gdb.Command):
> > +    """Dump all connections in a conntrack set
> > +    Usage:
> > +      ovs_dump_conntrack_conns <struct conntrack *> {short}
> > +
> > +      <struct conntrack *> : Pointer to conntrack
> > +      short                : Only dump conn structure addresses,
> > +                             no content details
> > +
> > +    Example dumping all <struct conn> connections:
> > +
> > +    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
> > +    (struct conn *) 0x7f32c000a8c0: expiration = ... nw_proto = 1
> > +    (struct conn *) 0x7f32c00489d0: expiration = ... nw_proto = 6
> > +    (struct conn *) 0x7f32c0153bb0: expiration = ... nw_proto = 17
> > +
> > +    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
> > +    (struct conn *) 0x7f32c000a8c0
> > +    (struct conn *) 0x7f32c00489d0
> > +    (struct conn *) 0x7f32c0153bb0
> > +    """
> > +    def __init__(self):
> > +        super(CmdDumpDpConntrackConn, self).__init__(
> > +            "ovs_dump_conntrack_conns",
> > +            gdb.COMMAND_DATA)
> > +
> > +    @staticmethod
> > +    def display_single_conn(conn, dir_, indent=0, short=False):
> > +        indent = " " * indent
> > +        if short:
> > +            print("{}(struct conn *) {}".format(indent, conn))
> > +        else:
> > +            print("{}(struct conn *) {}: expiration = {}, mark = {}, "
> > +                  "dl_type = {}, zone = {}, nw_proto = {}".format(
> > +                      indent, conn, conn['expiration'],
> > +                      conn['mark'], conn['key_node'][dir_]['key']['dl_type'],
> > +                      conn['key_node'][dir_]['key']['zone'],
> > +                      conn['key_node'][dir_]['key']['nw_proto']))
> > +
> > +    def invoke(self, arg, from_tty):
> > +        arg_list = gdb.string_to_argv(arg)
> > +        if len(arg_list) == 0:
>
> We do not check if the 2nd parameter is garbage (or more exists). So I would add the following:
>
>      def invoke(self, arg, from_tty):
>          arg_list = gdb.string_to_argv(arg)
> -        if len(arg_list) == 0:
> +        if len(arg_list) not in (1, 2) or \
> +           (len(arg_list) == 2 and arg_list[1] != "short"):
>              print("usage: ovs_dump_conntrack_conns <struct conntrack *> "
>
> > +            print("usage: ovs_dump_conntrack_conns <struct conntrack *> "
> > +                  "{short}")
> > +            return
> > +
> > +        ct = gdb.parse_and_eval(arg_list[0]).cast(
> > +            gdb.lookup_type('struct conntrack').pointer())
> > +
> > +        for key_node in ForEachCMAP(ct["conns"],
> > +                                    "struct conn_key_node", "cm_node"):
> > +            node = container_of(
> > +                key_node,
> > +                gdb.lookup_type('struct conn').pointer(),
> > +                "key_node")
> > +            self.display_single_conn(node, key_node['dir'],
> > +                                     short="short" in arg_list[1:])
> > +
> > +
> >  #
> >  # Initialize all GDB commands
> >  #
> > @@ -1571,3 +1634,4 @@ CmdDumpSmap()
> >  CmdDumpUdpifKeys()
> >  CmdShowFDB()
> >  CmdShowUpcall()
> > +CmdDumpDpConntrackConn()
> > --
> > 2.28.0.windows.1
> >
> > _______________________________________________
> > dev mailing list
> > dev@openvswitch.org
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
Eelco Chaudron Sept. 16, 2024, 9:42 a.m. UTC | #3
On 13 Sep 2024, at 5:14, LIU Yulong wrote:

> Add a new GDB macro called ovs_dump_conntrack_conns, which can
> be used to dump all conn structure in a conntrack. For example
>
> (gdb) ovs_dump_conntrack_conns
> usage: ovs_dump_conntrack_conns <struct conntrack *> {short}
>
> (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
> (struct conn *) 0x7f32c000a8c0: expiration = 26162886419, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
> (struct conn *) 0x7f32c00489d0: expiration = 26162900867, mark = 0, dl_type = 8, zone = 3, nw_proto = 1 '\001'
> (struct conn *) 0x7f32c0153bb0: expiration = 26249266420, mark = 0, dl_type = 8, zone = 3, nw_proto = 6 '\006'
>
> (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
> (struct conn *) 0x7f32c000a8c0
> (struct conn *) 0x7f32c00489d0
> (struct conn *) 0x7f32c0153bb0
>
> Signed-off-by: LIU Yulong <i@liuyulong.me>

LIU, thanks for the patch, and Mike thanks for the Review.

This patch was applied to main.

Cheers,

Eelco
diff mbox series

Patch

diff --git a/utilities/gdb/ovs_gdb.py b/utilities/gdb/ovs_gdb.py
index 982395dd1..53acc6c4b 100644
--- a/utilities/gdb/ovs_gdb.py
+++ b/utilities/gdb/ovs_gdb.py
@@ -37,6 +37,7 @@ 
 #    - ovs_dump_udpif_keys {<udpif_name>|<udpif_address>} {short}
 #    - ovs_show_fdb {[<bridge_name>] {dbg} {hash}}
 #    - ovs_show_upcall {dbg}
+#    - ovs_dump_conntrack_conns <struct conntrack *> {short}
 #
 #  Example:
 #    $ gdb $(which ovs-vswitchd) $(pidof ovs-vswitchd)
@@ -1550,6 +1551,68 @@  class CmdDumpPackets(gdb.Command):
         return packet
 
 
+#
+# Implements the GDB "ovs_dump_conntrack_conns" command
+#
+class CmdDumpDpConntrackConn(gdb.Command):
+    """Dump all connections in a conntrack set
+    Usage:
+      ovs_dump_conntrack_conns <struct conntrack *> {short}
+
+      <struct conntrack *> : Pointer to conntrack
+      short                : Only dump conn structure addresses,
+                             no content details
+
+    Example dumping all <struct conn> connections:
+
+    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0
+    (struct conn *) 0x7f32c000a8c0: expiration = ... nw_proto = 1
+    (struct conn *) 0x7f32c00489d0: expiration = ... nw_proto = 6
+    (struct conn *) 0x7f32c0153bb0: expiration = ... nw_proto = 17
+
+    (gdb) ovs_dump_conntrack_conns 0x5606339c25e0 short
+    (struct conn *) 0x7f32c000a8c0
+    (struct conn *) 0x7f32c00489d0
+    (struct conn *) 0x7f32c0153bb0
+    """
+    def __init__(self):
+        super(CmdDumpDpConntrackConn, self).__init__(
+            "ovs_dump_conntrack_conns",
+            gdb.COMMAND_DATA)
+
+    @staticmethod
+    def display_single_conn(conn, dir_, indent=0, short=False):
+        indent = " " * indent
+        if short:
+            print("{}(struct conn *) {}".format(indent, conn))
+        else:
+            print("{}(struct conn *) {}: expiration = {}, mark = {}, "
+                  "dl_type = {}, zone = {}, nw_proto = {}".format(
+                      indent, conn, conn['expiration'],
+                      conn['mark'], conn['key_node'][dir_]['key']['dl_type'],
+                      conn['key_node'][dir_]['key']['zone'],
+                      conn['key_node'][dir_]['key']['nw_proto']))
+
+    def invoke(self, arg, from_tty):
+        arg_list = gdb.string_to_argv(arg)
+        if len(arg_list) == 0:
+            print("usage: ovs_dump_conntrack_conns <struct conntrack *> "
+                  "{short}")
+            return
+
+        ct = gdb.parse_and_eval(arg_list[0]).cast(
+            gdb.lookup_type('struct conntrack').pointer())
+
+        for key_node in ForEachCMAP(ct["conns"],
+                                    "struct conn_key_node", "cm_node"):
+            node = container_of(
+                key_node,
+                gdb.lookup_type('struct conn').pointer(),
+                "key_node")
+            self.display_single_conn(node, key_node['dir'],
+                                     short="short" in arg_list[1:])
+
+
 #
 # Initialize all GDB commands
 #
@@ -1571,3 +1634,4 @@  CmdDumpSmap()
 CmdDumpUdpifKeys()
 CmdShowFDB()
 CmdShowUpcall()
+CmdDumpDpConntrackConn()