Linux Kernel Selftest development
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py
@ 2026-05-13 12:12 Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 1/5] selftests: openvswitch: convert %-formatting to f-strings Minxi Hou
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

This series cleans up all pylint warnings in ovs-dpctl.py,
bringing the score from 7.62/10 to 10.00/10.

This series applies on top of:
  [PATCH net-next v10 1/2] selftests: openvswitch: add vlan() and
  encap() flow string parsing
  https://lore.kernel.org/netdev/20260512070841.1183581-2-houminxi@gmail.com/

Patch 1 converts 86 %-format strings to f-strings.
Patch 2 fixes misc warnings (unused import, bare except, unused
variables, redundant expressions).
Patch 3 renames classes to PascalCase and variables to snake_case.
Patch 4 adds one-line docstrings to all definitions.
Patch 5 suppresses complexity warnings from pyroute2 constraints.

Tested with vng on x86_64, all OVS selftests pass.

Minxi Hou (5):
  selftests: openvswitch: convert %-formatting to f-strings
  selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py
  selftests: openvswitch: rename classes and variables in ovs-dpctl.py
  selftests: openvswitch: add missing docstrings in ovs-dpctl.py
  selftests: openvswitch: suppress pylint complexity warnings

 .../selftests/net/openvswitch/ovs-dpctl.py    | 794 ++++++++++--------
 1 file changed, 428 insertions(+), 366 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next 1/5] selftests: openvswitch: convert %-formatting to f-strings
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
@ 2026-05-13 12:12 ` Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 2/5] selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py Minxi Hou
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

Convert all %-formatting instances to f-strings to fix C0209
pylint warnings. No behavior change.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
 .../selftests/net/openvswitch/ovs-dpctl.py    | 274 ++++++++----------
 1 file changed, 123 insertions(+), 151 deletions(-)

diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 3b6a26e265a4..3671fe16b5a7 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -65,7 +65,7 @@ OVS_FLOW_CMD_SET = 4
 UINT32_MAX = 0xFFFFFFFF
 
 def macstr(mac):
-    outstr = ":".join(["%02X" % i for i in mac])
+    outstr = ":".join([f"{i:02X}" for i in mac])
     return outstr
 
 
@@ -146,7 +146,7 @@ def parse_flags(flag_str, flag_vals):
         if flag in flag_vals:
             if maskResult & flag_vals[flag]:
                 raise KeyError(
-                    "Flag %s set once, cannot be set in multiples" % flag
+                    f"Flag {flag} set once, cannot be set in multiples"
                 )
 
             if setFlag:
@@ -154,7 +154,7 @@ def parse_flags(flag_str, flag_vals):
 
             maskResult |= flag_vals[flag]
         else:
-            raise KeyError("Missing flag value: %s" % flag)
+            raise KeyError(f"Missing flag value: {flag}")
 
         flag_str = flag_str[flag_len:]
 
@@ -211,7 +211,7 @@ def convert_ipv6(data):
     elif not mask:
         mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
     elif mask.isdigit():
-        mask = ipaddress.IPv6Network("::/" + mask).hostmask
+        mask = ipaddress.IPv6Network(f"::/{mask}").hostmask
 
     return ipaddress.IPv6Address(ip).packed, ipaddress.IPv6Address(mask).packed
 
@@ -342,13 +342,13 @@ def parse_attrs(actstr, attr_desc):
                 del attr_desc[i]
 
         if not found:
-            raise ValueError("Unknown attribute: '%s'" % actstr)
+            raise ValueError(f"Unknown attribute: '{actstr}'")
 
         actstr = actstr[strspn(actstr, ", ") :]
 
     if actstr[0] != ")":
         raise ValueError("Action string contains extra garbage or has "
-                         "unbalanced parenthesis: '%s'" % actstr)
+                         f"unbalanced parenthesis: '{actstr}'")
 
     return attrs, actstr[1:]
 
@@ -403,14 +403,13 @@ class ovsactions(nla):
         )
 
         def dpstr(self, more=False):
-            args = "group=%d" % self.get_attr("OVS_PSAMPLE_ATTR_GROUP")
+            args = f"group={self.get_attr('OVS_PSAMPLE_ATTR_GROUP')}"
 
             cookie = self.get_attr("OVS_PSAMPLE_ATTR_COOKIE")
             if cookie:
-                args += ",cookie(%s)" % \
-                        "".join(format(x, "02x") for x in cookie)
+                args += f",cookie({''.join(format(x, '02x') for x in cookie)})"
 
-            return "psample(%s)" % args
+            return f"psample({args})"
 
         def parse(self, actstr):
             desc = (
@@ -441,15 +440,15 @@ class ovsactions(nla):
         def dpstr(self, more=False):
             args = []
 
-            args.append("sample={:.2f}%".format(
-                100 * self.get_attr("OVS_SAMPLE_ATTR_PROBABILITY") /
-                UINT32_MAX))
+            prob = 100 * self.get_attr(
+                "OVS_SAMPLE_ATTR_PROBABILITY") / UINT32_MAX
+            args.append(f"sample={prob:.2f}%")
 
             actions = self.get_attr("OVS_SAMPLE_ATTR_ACTIONS")
             if actions:
-                args.append("actions(%s)" % actions.dpstr(more))
+                args.append(f"actions({actions.dpstr(more)})")
 
-            return "sample(%s)" % ",".join(args)
+            return f"sample({','.join(args)})"
 
         def parse(self, actstr):
             def parse_nested_actions(actstr):
@@ -518,26 +517,20 @@ class ovsactions(nla):
                     "OVS_NAT_ATTR_IP_MAX"
                 ):
                     if self.get_attr("OVS_NAT_ATTR_IP_MIN"):
-                        print_str += "=%s," % str(
-                            self.get_attr("OVS_NAT_ATTR_IP_MIN")
-                        )
+                        print_str += f"={self.get_attr('OVS_NAT_ATTR_IP_MIN')!s},"
 
                     if self.get_attr("OVS_NAT_ATTR_IP_MAX"):
-                        print_str += "-%s," % str(
-                            self.get_attr("OVS_NAT_ATTR_IP_MAX")
-                        )
+                        print_str += f"-{self.get_attr('OVS_NAT_ATTR_IP_MAX')!s},"
                 else:
                     print_str += ","
 
                 if self.get_attr("OVS_NAT_ATTR_PROTO_MIN"):
-                    print_str += "proto_min=%d," % self.get_attr(
-                        "OVS_NAT_ATTR_PROTO_MIN"
-                    )
+                    val = self.get_attr("OVS_NAT_ATTR_PROTO_MIN")
+                    print_str += f"proto_min={val},"
 
                 if self.get_attr("OVS_NAT_ATTR_PROTO_MAX"):
-                    print_str += "proto_max=%d," % self.get_attr(
-                        "OVS_NAT_ATTR_PROTO_MAX"
-                    )
+                    val = self.get_attr("OVS_NAT_ATTR_PROTO_MAX")
+                    print_str += f"proto_max={val},"
 
                 if self.get_attr("OVS_NAT_ATTR_PERSISTENT"):
                     print_str += "persistent,"
@@ -554,22 +547,18 @@ class ovsactions(nla):
             if self.get_attr("OVS_CT_ATTR_COMMIT") is not None:
                 print_str += "commit,"
             if self.get_attr("OVS_CT_ATTR_ZONE") is not None:
-                print_str += "zone=%d," % self.get_attr("OVS_CT_ATTR_ZONE")
+                print_str += f"zone={self.get_attr('OVS_CT_ATTR_ZONE')},"
             if self.get_attr("OVS_CT_ATTR_HELPER") is not None:
-                print_str += "helper=%s," % self.get_attr("OVS_CT_ATTR_HELPER")
+                print_str += f"helper={self.get_attr('OVS_CT_ATTR_HELPER')},"
             if self.get_attr("OVS_CT_ATTR_NAT") is not None:
                 print_str += self.get_attr("OVS_CT_ATTR_NAT").dpstr(more)
                 print_str += ","
             if self.get_attr("OVS_CT_ATTR_FORCE_COMMIT") is not None:
                 print_str += "force,"
             if self.get_attr("OVS_CT_ATTR_EVENTMASK") is not None:
-                print_str += "emask=0x%X," % self.get_attr(
-                    "OVS_CT_ATTR_EVENTMASK"
-                )
+                print_str += f"emask=0x{self.get_attr('OVS_CT_ATTR_EVENTMASK'):X},"
             if self.get_attr("OVS_CT_ATTR_TIMEOUT") is not None:
-                print_str += "timeout=%s" % self.get_attr(
-                    "OVS_CT_ATTR_TIMEOUT"
-                )
+                print_str += f"timeout={self.get_attr('OVS_CT_ATTR_TIMEOUT')}"
             print_str += ")"
             return print_str
 
@@ -586,17 +575,15 @@ class ovsactions(nla):
         def dpstr(self, more=False):
             print_str = "userspace("
             if self.get_attr("OVS_USERSPACE_ATTR_PID") is not None:
-                print_str += "pid=%d," % self.get_attr(
-                    "OVS_USERSPACE_ATTR_PID"
-                )
+                print_str += f"pid={self.get_attr('OVS_USERSPACE_ATTR_PID')},"
             if self.get_attr("OVS_USERSPACE_ATTR_USERDATA") is not None:
                 print_str += "userdata="
                 for f in self.get_attr("OVS_USERSPACE_ATTR_USERDATA"):
-                    print_str += "%x." % f
+                    print_str += f"{f:x}."
             if self.get_attr("OVS_USERSPACE_ATTR_EGRESS_TUN_PORT") is not None:
-                print_str += "egress_tun_port=%d" % self.get_attr(
-                    "OVS_USERSPACE_ATTR_EGRESS_TUN_PORT"
-                )
+                val = self.get_attr(
+                    "OVS_USERSPACE_ATTR_EGRESS_TUN_PORT")
+                print_str += f"egress_tun_port={val}"
             print_str += ")"
             return print_str
 
@@ -624,13 +611,13 @@ class ovsactions(nla):
                 print_str += ","
 
             if field[0] == "OVS_ACTION_ATTR_OUTPUT":
-                print_str += "%d" % int(self.get_attr(field[0]))
+                print_str += f"{self.get_attr(field[0])}"
             elif field[0] == "OVS_ACTION_ATTR_RECIRC":
-                print_str += "recirc(0x%x)" % int(self.get_attr(field[0]))
+                print_str += f"recirc(0x{self.get_attr(field[0]):x})"
             elif field[0] == "OVS_ACTION_ATTR_TRUNC":
-                print_str += "trunc(%d)" % int(self.get_attr(field[0]))
+                print_str += f"trunc({self.get_attr(field[0])})"
             elif field[0] == "OVS_ACTION_ATTR_DROP":
-                print_str += "drop(%d)" % int(self.get_attr(field[0]))
+                print_str += f"drop({self.get_attr(field[0])})"
             elif field[0] == "OVS_ACTION_ATTR_CT_CLEAR":
                 print_str += "ct_clear"
             elif field[0] == "OVS_ACTION_ATTR_POP_VLAN":
@@ -641,8 +628,8 @@ class ovsactions(nla):
                 tci = datum["vlan_tci"]
                 vid = tci & 0x0FFF
                 pcp = (tci >> 13) & 0x7
-                print_str += "push_vlan(vid=%d,pcp=%d" \
-                    ",tpid=0x%04x)" % (vid, pcp, tpid)
+                print_str += (f"push_vlan(vid={vid},pcp={pcp}"
+                              f",tpid=0x{tpid:04x})")
             elif field[0] == "OVS_ACTION_ATTR_POP_ETH":
                 print_str += "pop_eth"
             elif field[0] == "OVS_ACTION_ATTR_POP_NSH":
@@ -750,32 +737,27 @@ class ovsactions(nla):
                 for kv in actstr[:paren].split(","):
                     if "=" not in kv:
                         raise ValueError(
-                            "push_vlan(): bad field '%s'"
-                            % kv.strip())
+                            f"push_vlan(): bad field '{kv.strip()}'")
                     k = kv[:kv.index("=")].strip()
                     v = kv[kv.index("=") + 1:].strip()
                     if k == "vid":
                         vid = int(v, 0)
                         if vid < 0 or vid > 0xFFF:
                             raise ValueError(
-                                "push_vlan(): vid=%d out of "
-                                "range (0-4095)" % vid)
+                                f"push_vlan(): vid={vid} out of range (0-4095)")
                     elif k == "pcp":
                         pcp = int(v, 0)
                         if pcp < 0 or pcp > 7:
                             raise ValueError(
-                                "push_vlan(): pcp=%d out of "
-                                "range (0-7)" % pcp)
+                                f"push_vlan(): pcp={pcp} out of range (0-7)")
                     elif k == "tpid":
                         tpid = int(v, 0)
                         if tpid < 0 or tpid > 0xFFFF:
                             raise ValueError(
-                                "push_vlan(): tpid=0x%x out "
-                                "of range (0-0xffff)" % tpid)
+                                f"push_vlan(): tpid=0x{tpid:x} out of range (0-0xffff)")
                     else:
                         raise ValueError(
-                            "push_vlan(): unknown key '%s'"
-                            % k)
+                            f"push_vlan(): unknown key '{k}'")
                 tci = (vid & 0x0FFF) | ((pcp & 0x7) << 13) \
                     | 0x1000
                 pvact = self.push_vlan()
@@ -802,7 +784,7 @@ class ovsactions(nla):
                 actstr = k.parse(actstr, None)
                 self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
                 if not actstr.startswith(")"):
-                    actstr = ")" + actstr
+                    actstr = f"){actstr}"
                 parsed = True
             elif parse_starts_block(actstr, "set_masked(", False):
                 parencount += 1
@@ -812,7 +794,7 @@ class ovsactions(nla):
                 actstr = k.parse(actstr, m)
                 self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
                 if not actstr.startswith(")"):
-                    actstr = ")" + actstr
+                    actstr = f"){actstr}"
                 parsed = True
             elif parse_starts_block(actstr, "ct(", False):
                 parencount += 1
@@ -943,7 +925,7 @@ class ovsactions(nla):
                 parencount -= 1
                 actstr = actstr[strspn(actstr, " "):]
                 if len(actstr) and actstr[0] != ")":
-                    raise ValueError("Action str: '%s' unbalanced" % actstr)
+                    raise ValueError(f"Action str: '{actstr}' unbalanced")
                 actstr = actstr[1:]
 
             if len(actstr) and actstr[0] == ")":
@@ -952,7 +934,7 @@ class ovsactions(nla):
             actstr = actstr[strspn(actstr, ", ") :]
 
             if not parsed:
-                raise ValueError("Action str: '%s' not supported" % actstr)
+                raise ValueError(f"Action str: '{actstr}' not supported")
 
         return (totallen - len(actstr))
 
@@ -1071,20 +1053,20 @@ class ovskey(nla):
             return flowstr, k, m
 
         def dpstr(self, masked=None, more=False):
-            outstr = self.proto_str + "("
+            outstr = f"{self.proto_str}("
             first = False
             for f in self.fields_map:
                 if first:
                     outstr += ","
                 if masked is None:
-                    outstr += "%s=" % f[0]
+                    outstr += f"{f[0]}="
                     if isinstance(f[2], str):
                         outstr += f[2] % self[f[1]]
                     else:
                         outstr += f[2](self[f[1]])
                     first = True
                 elif more or f[3](masked[f[1]]) != 0:
-                    outstr += "%s=" % f[0]
+                    outstr += f"{f[0]}="
                     if isinstance(f[2], str):
                         outstr += f[2] % self[f[1]]
                     else:
@@ -1658,23 +1640,23 @@ class ovskey(nla):
             for k in self["attrs"]:
                 noprint = False
                 if k[0] == "OVS_TUNNEL_KEY_ATTR_ID":
-                    print_str += "tun_id=%d" % k[1]
+                    print_str += f"tun_id={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV4_SRC":
-                    print_str += "src=%s" % k[1]
+                    print_str += f"src={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV4_DST":
-                    print_str += "dst=%s" % k[1]
+                    print_str += f"dst={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV6_SRC":
-                    print_str += "ipv6_src=%s" % k[1]
+                    print_str += f"ipv6_src={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV6_DST":
-                    print_str += "ipv6_dst=%s" % k[1]
+                    print_str += f"ipv6_dst={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_TOS":
-                    print_str += "tos=%d" % k[1]
+                    print_str += f"tos={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_TTL":
-                    print_str += "ttl=%d" % k[1]
+                    print_str += f"ttl={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_TP_SRC":
-                    print_str += "tp_src=%d" % k[1]
+                    print_str += f"tp_src={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_TP_DST":
-                    print_str += "tp_dst=%d" % k[1]
+                    print_str += f"tp_dst={k[1]}"
                 elif k[0] == "OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT":
                     noprint = True
                     flagsattrs.append("df")
@@ -1689,7 +1671,7 @@ class ovskey(nla):
                     print_str += ","
 
             if len(flagsattrs):
-                print_str += "flags(" + "|".join(flagsattrs) + ")"
+                print_str += f"flags({'|'.join(flagsattrs)})"
             print_str += ")"
             return print_str
 
@@ -1712,8 +1694,8 @@ class ovskey(nla):
         pcp = (tci >> 13) & 0x7
         cfi = (tci >> 12) & 0x1
         if cfi:
-            return "vid=%d,pcp=%d,cfi=%d" % (vid, pcp, cfi)
-        return "tci=0x%04x" % tci
+            return f"vid={vid},pcp={pcp},cfi={cfi}"
+        return f"tci=0x{tci:04x}"
 
     @staticmethod
     def _parse_vlan_from_flowstr(flowstr):
@@ -1757,7 +1739,7 @@ class ovskey(nla):
             eq = flowstr.find('=')
             if eq == -1:
                 raise ValueError(
-                    "vlan(): expected key=value, got '%s'" % flowstr)
+                    f"vlan(): expected key=value, got '{flowstr}'")
             key = flowstr[:eq].strip()
             flowstr = flowstr[eq + 1:]
 
@@ -1771,13 +1753,12 @@ class ovskey(nla):
             flowstr = flowstr[end:]
 
             if not val:
-                raise ValueError("vlan(): empty value for key '%s'" % key)
+                raise ValueError(f"vlan(): empty value for key '{key}'")
             try:
                 v = int(val, 0)
             except ValueError as exc:
                 raise ValueError(
-                    "vlan(): invalid value '%s' for key '%s'"
-                    % (val, key)) from exc
+                    f"vlan(): invalid value '{val}' for key '{key}'") from exc
 
             if key == 'tci':
                 if has_tci:
@@ -1785,7 +1766,7 @@ class ovskey(nla):
                 if has_vid or has_pcp or has_cfi:
                     raise ValueError(_tci_mix_err)
                 if v > 0xFFFF or v < 0:
-                    raise ValueError("vlan(): tci=0x%x out of range" % v)
+                    raise ValueError(f"vlan(): tci=0x{v:x} out of range")
                 tci = v
                 mask = 0xFFFF
                 has_tci = True
@@ -1795,7 +1776,7 @@ class ovskey(nla):
                 if has_vid:
                     raise ValueError("vlan(): duplicate 'vid'")
                 if v < 0 or v > 0xFFF:
-                    raise ValueError("vlan(): vid=%d out of range (0-4095)" % v)
+                    raise ValueError(f"vlan(): vid={v} out of range (0-4095)")
                 tci |= v
                 mask |= 0x0FFF
                 has_vid = True
@@ -1805,7 +1786,7 @@ class ovskey(nla):
                 if has_pcp:
                     raise ValueError("vlan(): duplicate 'pcp'")
                 if v < 0 or v > 7:
-                    raise ValueError("vlan(): pcp=%d out of range (0-7)" % v)
+                    raise ValueError(f"vlan(): pcp={v} out of range (0-7)")
                 tci |= (v & 0x7) << 13
                 mask |= 0xE000
                 has_pcp = True
@@ -1820,7 +1801,7 @@ class ovskey(nla):
                 mask |= ovskey._VLAN_CFI_MASK
                 has_cfi = True
             else:
-                raise ValueError("vlan(): unknown key '%s'" % key)
+                raise ValueError(f"vlan(): unknown key '{key}'")
 
         flowstr = flowstr[1:]  # skip ')'
         # Catch immediate '))' (user error).  A ')' after ',' is consumed
@@ -1856,7 +1837,7 @@ class ovskey(nla):
                 depth -= 1
                 if depth < 0:
                     raise ValueError(
-                        "encap(): unmatched ')' at position %d" % i)
+                        f"encap(): unmatched ')' at position {i}")
                 if depth == 0:
                     end = i
                     break
@@ -1879,8 +1860,7 @@ class ovskey(nla):
         remaining = inner_key.parse(inner_str, inner_mask)
         if remaining and re.search(r'[^\s,)]', remaining):
             raise ValueError(
-                "encap(): unrecognized trailing "
-                "content '%s'" % remaining.strip())
+                f"encap(): unrecognized trailing content '{remaining.strip()}'")
 
         return flowstr, inner_key, inner_mask
 
@@ -1951,7 +1931,7 @@ class ovskey(nla):
                 lambda x: parse_flags(x, None),
             ),
         ):
-            fld = field[1] + "("
+            fld = f"{field[1]}("
             if not flowstr.startswith(fld):
                 continue
 
@@ -2089,15 +2069,15 @@ class ovskey(nla):
                 else:
                     if m is None or field[3](m):
                         val = fmt(v) if callable(fmt) else fmt % v
-                        print_str += field[1] + "(" + val + "),"
+                        print_str += f"{field[1]}({val}),"
                     elif more or m != 0:
                         if field[0] == "OVS_KEY_ATTR_VLAN":
-                            val = "tci=0x%04x/0x%04x" % (v, m)
+                            val = f"tci=0x{v:04x}/0x{m:04x}"
                         elif callable(fmt):
-                            val = fmt(v) + "/" + fmt(m)
+                            val = f"{fmt(v)}/{fmt(m)}"
                         else:
-                            val = (fmt % v) + "/" + (fmt % m)
-                        print_str += field[1] + "(" + val + "),"
+                            val = f"{fmt % v}/{fmt % m}"
+                        print_str += f"{field[1]}({val}),"
 
         return print_str
 
@@ -2179,7 +2159,7 @@ class OvsPacket(GenericNetlinkSocket):
                     elif msg["cmd"] == OvsPacket.OVS_PACKET_CMD_EXECUTE:
                         up.execute(msg)
                     else:
-                        print("Unknown cmd: %d" % msg["cmd"])
+                        print(f"Unknown cmd: {msg['cmd']}")
             except NetlinkError as ne:
                 raise ne
 
@@ -2363,7 +2343,7 @@ class OvsVport(GenericNetlinkSocket):
             return "vxlan"
         elif vport_type == OvsVport.OVS_VPORT_TYPE_GENEVE:
             return "geneve"
-        raise ValueError("Unknown vport type:%d" % vport_type)
+        raise ValueError(f"Unknown vport type:{vport_type}")
 
     def str_to_type(vport_type):
         if vport_type == "netdev":
@@ -2376,7 +2356,7 @@ class OvsVport(GenericNetlinkSocket):
             return OvsVport.OVS_VPORT_TYPE_VXLAN
         elif vport_type == "geneve":
             return OvsVport.OVS_VPORT_TYPE_GENEVE
-        raise ValueError("Unknown vport type: '%s'" % vport_type)
+        raise ValueError(f"Unknown vport type: '{vport_type}'")
 
     def __init__(self, packet=OvsPacket()):
         GenericNetlinkSocket.__init__(self)
@@ -2550,16 +2530,14 @@ class OvsFlow(GenericNetlinkSocket):
             ufid = self.get_attr("OVS_FLOW_ATTR_UFID")
             ufid_str = ""
             if ufid is not None:
-                ufid_str = (
-                    "ufid:{:08x}-{:04x}-{:04x}-{:04x}-{:04x}{:08x}".format(
-                        ufid[0],
-                        ufid[1] >> 16,
-                        ufid[1] & 0xFFFF,
-                        ufid[2] >> 16,
-                        ufid[2] & 0,
-                        ufid[3],
-                    )
-                )
+                u0 = ufid[0]
+                u1h = ufid[1] >> 16
+                u1l = ufid[1] & 0xFFFF
+                u2h = ufid[2] >> 16
+                u2l = ufid[2] & 0
+                u3 = ufid[3]
+                ufid_str = (f"ufid:{u0:08x}-{u1h:04x}-{u1l:04x}"
+                            f"-{u2h:04x}-{u2l:04x}{u3:08x}")
 
             key_field = self.get_attr("OVS_FLOW_ATTR_KEY")
             keymsg = None
@@ -2579,7 +2557,7 @@ class OvsFlow(GenericNetlinkSocket):
             print_str = ""
 
             if more:
-                print_str += ufid_str + ","
+                print_str += f"{ufid_str},"
 
             if keymsg is not None:
                 print_str += keymsg.dpstr(maskmsg, more)
@@ -2588,10 +2566,9 @@ class OvsFlow(GenericNetlinkSocket):
             if stats is None:
                 print_str += " packets:0, bytes:0,"
             else:
-                print_str += " packets:%d, bytes:%d," % (
-                    stats["packets"],
-                    stats["bytes"],
-                )
+                pkts = stats["packets"]
+                nbytes = stats["bytes"]
+                print_str += f" packets:{pkts}, bytes:{nbytes},"
 
             used = self.get_attr("OVS_FLOW_ATTR_USED")
             print_str += " used:"
@@ -2601,7 +2578,7 @@ class OvsFlow(GenericNetlinkSocket):
                 used_time = int(used)
                 cur_time_sec = time.clock_gettime(time.CLOCK_MONOTONIC)
                 used_time = (cur_time_sec * 1000) - used_time
-                print_str += "{}s,".format(used_time / 1000)
+                print_str += f"{used_time / 1000}s,"
 
             print_str += " actions:"
             if (
@@ -2769,7 +2746,7 @@ class OvsFlow(GenericNetlinkSocket):
         pktdata = packetmsg.get_attr("OVS_PACKET_ATTR_PACKET")
         pktpres = "yes" if pktdata is not None else "no"
 
-        print("MISS upcall[%d/%s]: %s" % (seq, pktpres, keystr), flush=True)
+        print(f"MISS upcall[{seq}/{pktpres}]: {keystr}", flush=True)
 
     def execute(self, packetmsg):
         print("userspace execute command", flush=True)
@@ -2803,16 +2780,16 @@ class psample_sample(genlmsg):
         data = ""
         for (attr, value) in self["attrs"]:
             if attr == "PSAMPLE_ATTR_SAMPLE_GROUP":
-                fields.append("group:%d" % value)
+                fields.append(f"group:{value}")
             if attr == "PSAMPLE_ATTR_SAMPLE_RATE":
-                fields.append("rate:%d" % value)
+                fields.append(f"rate:{value}")
             if attr == "PSAMPLE_ATTR_USER_COOKIE":
                 value = "".join(format(x, "02x") for x in value)
-                fields.append("cookie:%s" % value)
+                fields.append(f"cookie:{value}")
             if attr == "PSAMPLE_ATTR_DATA" and len(value) > 0:
-                data = "data:%s" % "".join(format(x, "02x") for x in value)
+                data = f"data:{''.join(format(x, '02x') for x in value)}"
 
-        return ("%s %s" % (",".join(fields), data)).strip()
+        return (f"{','.join(fields)} {data}").strip()
 
 
 class psample_msg(Marshal):
@@ -2846,23 +2823,22 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
     user_features = dp_lookup_rep.get_attr("OVS_DP_ATTR_USER_FEATURES")
     masks_cache_size = dp_lookup_rep.get_attr("OVS_DP_ATTR_MASKS_CACHE_SIZE")
 
-    print("%s:" % dp_name)
-    print(
-        "  lookups: hit:%d missed:%d lost:%d"
-        % (base_stats["hit"], base_stats["missed"], base_stats["lost"])
-    )
-    print("  flows:%d" % base_stats["flows"])
+    print(f"{dp_name}:")
+    hit = base_stats["hit"]
+    missed = base_stats["missed"]
+    lost = base_stats["lost"]
+    print(f"  lookups: hit:{hit} missed:{missed} lost:{lost}")
+    print(f"  flows:{base_stats['flows']}")
     pkts = base_stats["hit"] + base_stats["missed"]
     avg = (megaflow_stats["mask_hit"] / pkts) if pkts != 0 else 0.0
-    print(
-        "  masks: hit:%d total:%d hit/pkt:%f"
-        % (megaflow_stats["mask_hit"], megaflow_stats["masks"], avg)
-    )
+    mhit = megaflow_stats["mask_hit"]
+    mtotal = megaflow_stats["masks"]
+    print(f"  masks: hit:{mhit} total:{mtotal} hit/pkt:{avg:f}")
     print("  caches:")
-    print("    masks-cache: size:%d" % masks_cache_size)
+    print(f"    masks-cache: size:{masks_cache_size}")
 
     if user_features is not None:
-        print("  features: 0x%X" % user_features)
+        print(f"  features: 0x{user_features:X}")
 
     # port print out
     for iface in ndb.interfaces:
@@ -2873,16 +2849,12 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
             if vpo:
                 dpo = vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT")
                 if dpo:
-                    opts += " tnl-dport:%s" % dpo
-            print(
-                "  port %d: %s (%s%s)"
-                % (
-                    rep.get_attr("OVS_VPORT_ATTR_PORT_NO"),
-                    rep.get_attr("OVS_VPORT_ATTR_NAME"),
-                    OvsVport.type_to_str(rep.get_attr("OVS_VPORT_ATTR_TYPE")),
-                    opts,
-                )
-            )
+                    opts += f" tnl-dport:{dpo}"
+            port_no = rep.get_attr("OVS_VPORT_ATTR_PORT_NO")
+            name = rep.get_attr("OVS_VPORT_ATTR_NAME")
+            vtype = OvsVport.type_to_str(
+                rep.get_attr("OVS_VPORT_ATTR_TYPE"))
+            print(f"  port {port_no}: {name} ({vtype}{opts})")
 
 
 def main(argv):
@@ -3014,14 +2986,14 @@ def main(argv):
         if not found:
             msg = "No DP found"
             if args.showdp is not None:
-                msg += ":'%s'" % args.showdp
+                msg += f":'{args.showdp}'"
             print(msg)
     elif hasattr(args, "adddp"):
         rep = ovsdp.create(args.adddp, args.upcall, args.versioning, ovspk)
         if rep is None:
-            print("DP '%s' already exists" % args.adddp)
+            print(f"DP '{args.adddp}' already exists")
         else:
-            print("DP '%s' added" % args.adddp)
+            print(f"DP '{args.adddp}' added")
         if args.upcall:
             ovspk.upcall_handler(ovsflow)
     elif hasattr(args, "deldp"):
@@ -3029,12 +3001,12 @@ def main(argv):
     elif hasattr(args, "addif"):
         rep = ovsdp.info(args.dpname, 0)
         if rep is None:
-            print("DP '%s' not found." % args.dpname)
+            print(f"DP '{args.dpname}' not found.")
             return 1
         dpindex = rep["dpifindex"]
         rep = ovsvp.attach(rep["dpifindex"], args.addif, args.ptype,
                            args.dport, args.lwt)
-        msg = "vport '%s'" % args.addif
+        msg = f"vport '{args.addif}'"
         if rep and rep["header"]["error"] is None:
             msg += " added."
         else:
@@ -3046,10 +3018,10 @@ def main(argv):
     elif hasattr(args, "delif"):
         rep = ovsdp.info(args.dpname, 0)
         if rep is None:
-            print("DP '%s' not found." % args.dpname)
+            print(f"DP '{args.dpname}' not found.")
             return 1
         rep = ovsvp.detach(rep["dpifindex"], args.delif)
-        msg = "vport '%s'" % args.delif
+        msg = f"vport '{args.delif}'"
         if rep and rep["header"]["error"] is None:
             msg += " removed."
         else:
@@ -3060,7 +3032,7 @@ def main(argv):
     elif hasattr(args, "dumpdp"):
         rep = ovsdp.info(args.dumpdp, 0)
         if rep is None:
-            print("DP '%s' not found." % args.dumpdp)
+            print(f"DP '{args.dumpdp}' not found.")
             return 1
         rep = ovsflow.dump(rep["dpifindex"])
         for flow in rep:
@@ -3068,7 +3040,7 @@ def main(argv):
     elif hasattr(args, "flbr"):
         rep = ovsdp.info(args.flbr, 0)
         if rep is None:
-            print("DP '%s' not found." % args.flbr)
+            print(f"DP '{args.flbr}' not found.")
             return 1
         flow = OvsFlow.ovs_flow_msg()
         flow.parse(args.flow, args.acts, rep["dpifindex"])
@@ -3076,7 +3048,7 @@ def main(argv):
     elif hasattr(args, "flsbr"):
         rep = ovsdp.info(args.flsbr, 0)
         if rep is None:
-            print("DP '%s' not found." % args.flsbr)
+            print(f"DP '{args.flsbr}' not found.")
         ovsflow.del_flows(rep["dpifindex"])
 
     return 0
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 2/5] selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 1/5] selftests: openvswitch: convert %-formatting to f-strings Minxi Hou
@ 2026-05-13 12:12 ` Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 3/5] selftests: openvswitch: rename classes and variables " Minxi Hou
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

Fix miscellaneous pylint warnings with no behavior change:
  - W0611: remove unused import struct
  - W0702: replace bare except with except Exception
  - C0325: remove superfluous parentheses after return
  - R1705: remove unnecessary elif after return
  - W0108: replace unnecessary lambda with int
  - R1714: merge comparisons with in operator
  - W0719: replace raise Exception with raise ValueError
  - C1802: use implicit boolean test instead of len()
  - C0121: use is None instead of == None
  - R1719: simplify if-expression to bool test
  - R1703: simplify if/else to assignment expression
  - W0612: remove unused variables (keybits, maskbits, lst)
  - replace unused loop variable with underscore

Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
 .../selftests/net/openvswitch/ovs-dpctl.py    | 50 ++++++++-----------
 1 file changed, 21 insertions(+), 29 deletions(-)

diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 3671fe16b5a7..5ce054768f48 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -11,7 +11,6 @@ import logging
 import math
 import multiprocessing
 import re
-import struct
 import sys
 import time
 import types
@@ -125,10 +124,7 @@ def parse_flags(flag_str, flag_vals):
         maskResult = int(digits, 0)
 
     while len(flag_str) > 0 and (flag_str[0] == "+" or flag_str[0] == "-"):
-        if flag_str[0] == "+":
-            setFlag = True
-        elif flag_str[0] == "-":
-            setFlag = False
+        setFlag = flag_str[0] == "+"
 
         flag_str = flag_str[1:]
 
@@ -221,10 +217,9 @@ def convert_int(size):
 
         if not value:
             return 0, 0
-        elif not mask:
+        if not mask:
             return int(value, 0), pow(2, size) - 1
-        else:
-            return int(value, 0), int(mask, 0)
+        return int(value, 0), int(mask, 0)
 
     return convert_int_sized
 
@@ -688,11 +683,11 @@ class ovsactions(nla):
                     parsed = True
                 else:
                     actstr = actstr[len("drop"): ]
-                    return (totallen - len(actstr))
+                    return totallen - len(actstr)
 
             elif parse_starts_block(actstr, r"^(\d+)", False, True):
                 actstr, output = parse_extract_field(
-                    actstr, None, r"(\d+)", lambda x: int(x), False, "0"
+                    actstr, None, r"(\d+)", int, False, "0"
                 )
                 self["attrs"].append(["OVS_ACTION_ATTR_OUTPUT", output])
                 parsed = True
@@ -773,7 +768,6 @@ class ovsactions(nla):
                 subacts = ovsactions()
                 actstr = actstr[len("clone("):]
                 parsedLen = subacts.parse(actstr)
-                lst = []
                 self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
                 actstr = actstr[parsedLen:]
                 parsed = True
@@ -929,14 +923,14 @@ class ovsactions(nla):
                 actstr = actstr[1:]
 
             if len(actstr) and actstr[0] == ")":
-                return (totallen - len(actstr))
+                return totallen - len(actstr)
 
             actstr = actstr[strspn(actstr, ", ") :]
 
             if not parsed:
                 raise ValueError(f"Action str: '{actstr}' not supported")
 
-        return (totallen - len(actstr))
+        return totallen - len(actstr)
 
 
 class ovskey(nla):
@@ -1020,8 +1014,6 @@ class ovskey(nla):
             if flowstr.startswith("("):
                 flowstr = flowstr[1:]
 
-            keybits = b""
-            maskbits = b""
             for f in self.fields_map:
                 if flowstr.startswith(f[1]):
                     # the following assumes that the field looks
@@ -1030,7 +1022,7 @@ class ovskey(nla):
                     flowstr = flowstr[len(f[1]) + 1 :]
                     splitchar = 0
                     for c in flowstr:
-                        if c == "," or c == ")":
+                        if c in (",", ")"):
                             break
                         splitchar += 1
                     data = flowstr[:splitchar]
@@ -1587,7 +1579,7 @@ class ovskey(nla):
             for prefix, regex, typ, attr_name, mask_val, default_val, v46_flag in fields:
                 flowstr, value = parse_extract_field(flowstr, prefix, regex, typ, False)
                 if not attr_name:
-                    raise Exception("Bad list value in tunnel fields")
+                    raise ValueError("Bad list value in tunnel fields")
 
                 if value is None and attr_name in forced_include:
                     value = default_val
@@ -1670,7 +1662,7 @@ class ovskey(nla):
                 if not noprint:
                     print_str += ","
 
-            if len(flagsattrs):
+            if flagsattrs:
                 print_str += f"flags({'|'.join(flagsattrs)})"
             print_str += ")"
             return print_str
@@ -2250,7 +2242,7 @@ class OvsDatapath(GenericNetlinkSocket):
 
             nproc = multiprocessing.cpu_count()
             procarray = []
-            for i in range(1, nproc):
+            for _ in range(1, nproc):
                 procarray += [int(p.epid)]
             msg["attrs"].append(["OVS_DP_ATTR_UPCALL_PID", procarray])
         msg["attrs"].append(["OVS_DP_ATTR_USER_FEATURES", dpfeatures])
@@ -2335,26 +2327,26 @@ class OvsVport(GenericNetlinkSocket):
     def type_to_str(vport_type):
         if vport_type == OvsVport.OVS_VPORT_TYPE_NETDEV:
             return "netdev"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_INTERNAL:
+        if vport_type == OvsVport.OVS_VPORT_TYPE_INTERNAL:
             return "internal"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_GRE:
+        if vport_type == OvsVport.OVS_VPORT_TYPE_GRE:
             return "gre"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_VXLAN:
+        if vport_type == OvsVport.OVS_VPORT_TYPE_VXLAN:
             return "vxlan"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_GENEVE:
+        if vport_type == OvsVport.OVS_VPORT_TYPE_GENEVE:
             return "geneve"
         raise ValueError(f"Unknown vport type:{vport_type}")
 
     def str_to_type(vport_type):
         if vport_type == "netdev":
             return OvsVport.OVS_VPORT_TYPE_NETDEV
-        elif vport_type == "internal":
+        if vport_type == "internal":
             return OvsVport.OVS_VPORT_TYPE_INTERNAL
-        elif vport_type == "gre":
+        if vport_type == "gre":
             return OvsVport.OVS_VPORT_TYPE_GRE
-        elif vport_type == "vxlan":
+        if vport_type == "vxlan":
             return OvsVport.OVS_VPORT_TYPE_VXLAN
-        elif vport_type == "geneve":
+        if vport_type == "geneve":
             return OvsVport.OVS_VPORT_TYPE_GENEVE
         raise ValueError(f"Unknown vport type: '{vport_type}'")
 
@@ -2463,7 +2455,7 @@ class OvsVport(GenericNetlinkSocket):
         msg["dpifindex"] = dpindex
         msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_ifname])
 
-        if p == None:
+        if p is None:
             p = self.upcall_packet
         else:
             self.upcall_packet = p
@@ -3036,7 +3028,7 @@ def main(argv):
             return 1
         rep = ovsflow.dump(rep["dpifindex"])
         for flow in rep:
-            print(flow.dpstr(True if args.verbose > 0 else False))
+            print(flow.dpstr(args.verbose > 0))
     elif hasattr(args, "flbr"):
         rep = ovsdp.info(args.flbr, 0)
         if rep is None:
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 3/5] selftests: openvswitch: rename classes and variables in ovs-dpctl.py
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 1/5] selftests: openvswitch: convert %-formatting to f-strings Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 2/5] selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py Minxi Hou
@ 2026-05-13 12:12 ` Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 4/5] selftests: openvswitch: add missing docstrings " Minxi Hou
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

Rename classes to PascalCase and variables to snake_case to fix
C0103 pylint warnings. Update nla_map type strings and
nlmsg_atoms registrations to match the new class names.

pyroute2 nla_map resolution uses getattr(self, type_string), so
renaming the class and its nla_map string together is safe.

Other fixes:
  - Add @staticmethod to type_to_str() and str_to_type() (E0213)

Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
 .../selftests/net/openvswitch/ovs-dpctl.py    | 374 +++++++++---------
 1 file changed, 188 insertions(+), 186 deletions(-)

diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 5ce054768f48..6a9cf48948fd 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -107,11 +107,11 @@ def intparse(statestr, defmask="0xffffffff"):
 
 
 def parse_flags(flag_str, flag_vals):
-    bitResult = 0
-    maskResult = 0
+    bit_result = 0
+    mask_result = 0
 
     if len(flag_str) == 0:
-        return flag_str, bitResult, maskResult
+        return flag_str, bit_result, mask_result
 
     if flag_str[0].isdigit():
         idx = 0
@@ -120,11 +120,11 @@ def parse_flags(flag_str, flag_vals):
         digits = flag_str[:idx]
         flag_str = flag_str[idx:]
 
-        bitResult = int(digits, 0)
-        maskResult = int(digits, 0)
+        bit_result = int(digits, 0)
+        mask_result = int(digits, 0)
 
     while len(flag_str) > 0 and (flag_str[0] == "+" or flag_str[0] == "-"):
-        setFlag = flag_str[0] == "+"
+        set_flag = flag_str[0] == "+"
 
         flag_str = flag_str[1:]
 
@@ -140,21 +140,21 @@ def parse_flags(flag_str, flag_vals):
         flag = flag_str[0:flag_len]
 
         if flag in flag_vals:
-            if maskResult & flag_vals[flag]:
+            if mask_result & flag_vals[flag]:
                 raise KeyError(
                     f"Flag {flag} set once, cannot be set in multiples"
                 )
 
-            if setFlag:
-                bitResult |= flag_vals[flag]
+            if set_flag:
+                bit_result |= flag_vals[flag]
 
-            maskResult |= flag_vals[flag]
+            mask_result |= flag_vals[flag]
         else:
             raise KeyError(f"Missing flag value: {flag}")
 
         flag_str = flag_str[flag_len:]
 
-    return flag_str, bitResult, maskResult
+    return flag_str, bit_result, mask_result
 
 
 def parse_ct_state(statestr):
@@ -348,7 +348,7 @@ def parse_attrs(actstr, attr_desc):
     return attrs, actstr[1:]
 
 
-class ovs_dp_msg(genlmsg):
+class OvsDpMsg(genlmsg):
     # include the OVS version
     # We need a custom header rather than just being able to rely on
     # genlmsg because fields ends up not expressing everything correctly
@@ -356,23 +356,23 @@ class ovs_dp_msg(genlmsg):
     fields = genlmsg.fields + (("dpifindex", "I"),)
 
 
-class ovsactions(nla):
+class OvsActions(nla):
     nla_flags = NLA_F_NESTED
 
     nla_map = (
         ("OVS_ACTION_ATTR_UNSPEC", "none"),
         ("OVS_ACTION_ATTR_OUTPUT", "uint32"),
-        ("OVS_ACTION_ATTR_USERSPACE", "userspace"),
-        ("OVS_ACTION_ATTR_SET", "ovskey"),
-        ("OVS_ACTION_ATTR_PUSH_VLAN", "push_vlan"),
+        ("OVS_ACTION_ATTR_USERSPACE", "Userspace"),
+        ("OVS_ACTION_ATTR_SET", "OvsKey"),
+        ("OVS_ACTION_ATTR_PUSH_VLAN", "PushVlan"),
         ("OVS_ACTION_ATTR_POP_VLAN", "flag"),
-        ("OVS_ACTION_ATTR_SAMPLE", "sample"),
+        ("OVS_ACTION_ATTR_SAMPLE", "Sample"),
         ("OVS_ACTION_ATTR_RECIRC", "uint32"),
         ("OVS_ACTION_ATTR_HASH", "none"),
         ("OVS_ACTION_ATTR_PUSH_MPLS", "none"),
         ("OVS_ACTION_ATTR_POP_MPLS", "flag"),
-        ("OVS_ACTION_ATTR_SET_MASKED", "ovskey"),
-        ("OVS_ACTION_ATTR_CT", "ctact"),
+        ("OVS_ACTION_ATTR_SET_MASKED", "OvsKey"),
+        ("OVS_ACTION_ATTR_CT", "CtAct"),
         ("OVS_ACTION_ATTR_TRUNC", "uint32"),
         ("OVS_ACTION_ATTR_PUSH_ETH", "none"),
         ("OVS_ACTION_ATTR_POP_ETH", "flag"),
@@ -385,10 +385,10 @@ class ovsactions(nla):
         ("OVS_ACTION_ATTR_ADD_MPLS", "none"),
         ("OVS_ACTION_ATTR_DEC_TTL", "none"),
         ("OVS_ACTION_ATTR_DROP", "uint32"),
-        ("OVS_ACTION_ATTR_PSAMPLE", "psample"),
+        ("OVS_ACTION_ATTR_PSAMPLE", "Psample"),
     )
 
-    class psample(nla):
+    class Psample(nla):
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -420,16 +420,16 @@ class ovsactions(nla):
 
             return actstr
 
-    class push_vlan(nla):
+    class PushVlan(nla):
         fields = (("vlan_tpid", "!H"), ("vlan_tci", "!H"))
 
-    class sample(nla):
+    class Sample(nla):
         nla_flags = NLA_F_NESTED
 
         nla_map = (
             ("OVS_SAMPLE_ATTR_UNSPEC", "none"),
             ("OVS_SAMPLE_ATTR_PROBABILITY", "uint32"),
-            ("OVS_SAMPLE_ATTR_ACTIONS", "ovsactions"),
+            ("OVS_SAMPLE_ATTR_ACTIONS", "OvsActions"),
         )
 
         def dpstr(self, more=False):
@@ -447,7 +447,7 @@ class ovsactions(nla):
 
         def parse(self, actstr):
             def parse_nested_actions(actstr):
-                subacts = ovsactions()
+                subacts = OvsActions()
                 parsed_len = subacts.parse(actstr)
                 return subacts, actstr[parsed_len :]
 
@@ -456,7 +456,7 @@ class ovsactions(nla):
                 return int(math.floor(UINT32_MAX * (percent / 100.0) + .5))
 
             desc = (
-                ("sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate),
+                ("Sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate),
                 ("actions", "OVS_SAMPLE_ATTR_ACTIONS", parse_nested_actions),
             )
             attrs, actstr = parse_attrs(actstr, desc)
@@ -466,7 +466,7 @@ class ovsactions(nla):
 
             return actstr
 
-    class ctact(nla):
+    class CtAct(nla):
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -476,13 +476,13 @@ class ovsactions(nla):
             ("OVS_CT_ATTR_MARK", "none"),
             ("OVS_CT_ATTR_LABELS", "none"),
             ("OVS_CT_ATTR_HELPER", "asciiz"),
-            ("OVS_CT_ATTR_NAT", "natattr"),
+            ("OVS_CT_ATTR_NAT", "NatAttr"),
             ("OVS_CT_ATTR_FORCE_COMMIT", "flag"),
             ("OVS_CT_ATTR_EVENTMASK", "uint32"),
             ("OVS_CT_ATTR_TIMEOUT", "asciiz"),
         )
 
-        class natattr(nla):
+        class NatAttr(nla):
             nla_flags = NLA_F_NESTED
 
             nla_map = (
@@ -557,7 +557,7 @@ class ovsactions(nla):
             print_str += ")"
             return print_str
 
-    class userspace(nla):
+    class Userspace(nla):
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -755,7 +755,7 @@ class ovsactions(nla):
                             f"push_vlan(): unknown key '{k}'")
                 tci = (vid & 0x0FFF) | ((pcp & 0x7) << 13) \
                     | 0x1000
-                pvact = self.push_vlan()
+                pvact = self.PushVlan()
                 pvact["vlan_tpid"] = tpid
                 pvact["vlan_tci"] = tci
                 self["attrs"].append(
@@ -765,15 +765,15 @@ class ovsactions(nla):
 
             elif parse_starts_block(actstr, "clone(", False):
                 parencount += 1
-                subacts = ovsactions()
+                subacts = OvsActions()
                 actstr = actstr[len("clone("):]
-                parsedLen = subacts.parse(actstr)
+                parsed_len = subacts.parse(actstr)
                 self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
-                actstr = actstr[parsedLen:]
+                actstr = actstr[parsed_len:]
                 parsed = True
             elif parse_starts_block(actstr, "set(", False):
                 parencount += 1
-                k = ovskey()
+                k = OvsKey()
                 actstr = actstr[len("set("):]
                 actstr = k.parse(actstr, None)
                 self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
@@ -782,8 +782,8 @@ class ovsactions(nla):
                 parsed = True
             elif parse_starts_block(actstr, "set_masked(", False):
                 parencount += 1
-                k = ovskey()
-                m = ovskey()
+                k = OvsKey()
+                m = OvsKey()
                 actstr = actstr[len("set_masked("):]
                 actstr = k.parse(actstr, m)
                 self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
@@ -793,7 +793,7 @@ class ovsactions(nla):
             elif parse_starts_block(actstr, "ct(", False):
                 parencount += 1
                 actstr = actstr[len("ct(") :]
-                ctact = ovsactions.ctact()
+                ctact = OvsActions.CtAct()
 
                 for scan in (
                     ("commit", "OVS_CT_ATTR_COMMIT", None),
@@ -820,7 +820,7 @@ class ovsactions(nla):
                     # sub-action and this lets it sit anywhere in the ct() action
                     if actstr.startswith("nat"):
                         actstr = actstr[3:]
-                        natact = ovsactions.ctact.natattr()
+                        natact = OvsActions.CtAct.NatAttr()
 
                         if actstr.startswith("("):
                             parencount += 1
@@ -884,19 +884,19 @@ class ovsactions(nla):
                 parsed = True
 
             elif parse_starts_block(actstr, "sample(", False):
-                sampleact = self.sample()
+                sampleact = self.Sample()
                 actstr = sampleact.parse(actstr[len("sample(") : ])
                 self["attrs"].append(["OVS_ACTION_ATTR_SAMPLE", sampleact])
                 parsed = True
 
             elif parse_starts_block(actstr, "psample(", False):
-                psampleact = self.psample()
+                psampleact = self.Psample()
                 actstr = psampleact.parse(actstr[len("psample(") : ])
                 self["attrs"].append(["OVS_ACTION_ATTR_PSAMPLE", psampleact])
                 parsed = True
 
             elif parse_starts_block(actstr, "userspace(", False):
-                uact = self.userspace()
+                uact = self.Userspace()
                 actstr = uact.parse(actstr[len("userspace(") : ])
                 self["attrs"].append(["OVS_ACTION_ATTR_USERSPACE", uact])
                 parsed = True
@@ -933,37 +933,37 @@ class ovsactions(nla):
         return totallen - len(actstr)
 
 
-class ovskey(nla):
+class OvsKey(nla):
     nla_flags = NLA_F_NESTED
     nla_map = (
         ("OVS_KEY_ATTR_UNSPEC", "none"),
-        ("OVS_KEY_ATTR_ENCAP", "encap_ovskey"),
+        ("OVS_KEY_ATTR_ENCAP", "EncapOvsKey"),
         ("OVS_KEY_ATTR_PRIORITY", "uint32"),
         ("OVS_KEY_ATTR_IN_PORT", "uint32"),
-        ("OVS_KEY_ATTR_ETHERNET", "ethaddr"),
+        ("OVS_KEY_ATTR_ETHERNET", "EthAddr"),
         ("OVS_KEY_ATTR_VLAN", "be16"),
         ("OVS_KEY_ATTR_ETHERTYPE", "be16"),
-        ("OVS_KEY_ATTR_IPV4", "ovs_key_ipv4"),
-        ("OVS_KEY_ATTR_IPV6", "ovs_key_ipv6"),
-        ("OVS_KEY_ATTR_TCP", "ovs_key_tcp"),
-        ("OVS_KEY_ATTR_UDP", "ovs_key_udp"),
-        ("OVS_KEY_ATTR_ICMP", "ovs_key_icmp"),
-        ("OVS_KEY_ATTR_ICMPV6", "ovs_key_icmpv6"),
-        ("OVS_KEY_ATTR_ARP", "ovs_key_arp"),
-        ("OVS_KEY_ATTR_ND", "ovs_key_nd"),
+        ("OVS_KEY_ATTR_IPV4", "OvsKeyIpv4"),
+        ("OVS_KEY_ATTR_IPV6", "OvsKeyIpv6"),
+        ("OVS_KEY_ATTR_TCP", "OvsKeyTcp"),
+        ("OVS_KEY_ATTR_UDP", "OvsKeyUdp"),
+        ("OVS_KEY_ATTR_ICMP", "OvsKeyIcmp"),
+        ("OVS_KEY_ATTR_ICMPV6", "OvsKeyIcmpv6"),
+        ("OVS_KEY_ATTR_ARP", "OvsKeyArp"),
+        ("OVS_KEY_ATTR_ND", "OvsKeyNd"),
         ("OVS_KEY_ATTR_SKB_MARK", "uint32"),
-        ("OVS_KEY_ATTR_TUNNEL", "ovs_key_tunnel"),
-        ("OVS_KEY_ATTR_SCTP", "ovs_key_sctp"),
+        ("OVS_KEY_ATTR_TUNNEL", "OvsKeyTunnel"),
+        ("OVS_KEY_ATTR_SCTP", "OvsKeySctp"),
         ("OVS_KEY_ATTR_TCP_FLAGS", "be16"),
         ("OVS_KEY_ATTR_DP_HASH", "uint32"),
         ("OVS_KEY_ATTR_RECIRC_ID", "uint32"),
-        ("OVS_KEY_ATTR_MPLS", "array(ovs_key_mpls)"),
+        ("OVS_KEY_ATTR_MPLS", "array(OvsKeyMpls)"),
         ("OVS_KEY_ATTR_CT_STATE", "uint32"),
         ("OVS_KEY_ATTR_CT_ZONE", "uint16"),
         ("OVS_KEY_ATTR_CT_MARK", "uint32"),
         ("OVS_KEY_ATTR_CT_LABELS", "none"),
-        ("OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4", "ovs_key_ct_tuple_ipv4"),
-        ("OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6", "ovs_key_ct_tuple_ipv6"),
+        ("OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4", "OvsKeyCtTupleIpv4"),
+        ("OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6", "OvsKeyCtTupleIpv6"),
         ("OVS_KEY_ATTR_NSH", "none"),
         ("OVS_KEY_ATTR_PACKET_TYPE", "none"),
         ("OVS_KEY_ATTR_ND_EXTENSIONS", "none"),
@@ -971,7 +971,7 @@ class ovskey(nla):
         ("OVS_KEY_ATTR_IPV6_EXTENSIONS", "none"),
     )
 
-    class ovs_key_proto(nla):
+    class OvsKeyProto(nla):
         fields = (
             ("src", "!H"),
             ("dst", "!H"),
@@ -1003,12 +1003,12 @@ class ovskey(nla):
                 init=init,
             )
 
-        def parse(self, flowstr, typeInst):
+        def parse(self, flowstr, type_inst):
             if not flowstr.startswith(self.proto_str):
                 return None, None
 
-            k = typeInst()
-            m = typeInst()
+            k = type_inst()
+            m = type_inst()
 
             flowstr = flowstr[len(self.proto_str) :]
             if flowstr.startswith("("):
@@ -1072,7 +1072,7 @@ class ovskey(nla):
             outstr += ")"
             return outstr
 
-    class ethaddr(ovs_key_proto):
+    class EthAddr(OvsKeyProto):
         fields = (
             ("src", "!6s"),
             ("dst", "!6s"),
@@ -1103,7 +1103,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "eth",
                 data=data,
@@ -1113,7 +1113,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_ipv4(ovs_key_proto):
+    class OvsKeyIpv4(OvsKeyProto):
         fields = (
             ("src", "!I"),
             ("dst", "!I"),
@@ -1156,7 +1156,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "ipv4",
                 data=data,
@@ -1166,7 +1166,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_ipv6(ovs_key_proto):
+    class OvsKeyIpv6(OvsKeyProto):
         fields = (
             ("src", "!16s"),
             ("dst", "!16s"),
@@ -1207,7 +1207,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "ipv6",
                 data=data,
@@ -1217,7 +1217,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_tcp(ovs_key_proto):
+    class OvsKeyTcp(OvsKeyProto):
         def __init__(
             self,
             data=None,
@@ -1226,7 +1226,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "tcp",
                 data=data,
@@ -1236,7 +1236,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_udp(ovs_key_proto):
+    class OvsKeyUdp(OvsKeyProto):
         def __init__(
             self,
             data=None,
@@ -1245,7 +1245,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "udp",
                 data=data,
@@ -1255,7 +1255,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_sctp(ovs_key_proto):
+    class OvsKeySctp(OvsKeyProto):
         def __init__(
             self,
             data=None,
@@ -1264,7 +1264,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "sctp",
                 data=data,
@@ -1274,7 +1274,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_icmp(ovs_key_proto):
+    class OvsKeyIcmp(OvsKeyProto):
         fields = (
             ("type", "B"),
             ("code", "B"),
@@ -1293,7 +1293,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "icmp",
                 data=data,
@@ -1303,7 +1303,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_icmpv6(ovs_key_icmp):
+    class OvsKeyIcmpv6(OvsKeyIcmp):
         def __init__(
             self,
             data=None,
@@ -1312,7 +1312,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "icmpv6",
                 data=data,
@@ -1322,7 +1322,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_arp(ovs_key_proto):
+    class OvsKeyArp(OvsKeyProto):
         fields = (
             ("sip", "!I"),
             ("tip", "!I"),
@@ -1372,7 +1372,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "arp",
                 data=data,
@@ -1382,7 +1382,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_nd(ovs_key_proto):
+    class OvsKeyNd(OvsKeyProto):
         fields = (
             ("target", "!16s"),
             ("sll", "!6s"),
@@ -1408,7 +1408,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "nd",
                 data=data,
@@ -1418,7 +1418,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_ct_tuple_ipv4(ovs_key_proto):
+    class OvsKeyCtTupleIpv4(OvsKeyProto):
         fields = (
             ("src", "!I"),
             ("dst", "!I"),
@@ -1455,7 +1455,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "ct_tuple4",
                 data=data,
@@ -1465,7 +1465,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_ct_tuple_ipv6(nla):
+    class OvsKeyCtTupleIpv6(nla):
         fields = (
             ("src", "!16s"),
             ("dst", "!16s"),
@@ -1500,7 +1500,7 @@ class ovskey(nla):
             length=None,
             init=None,
         ):
-            ovskey.ovs_key_proto.__init__(
+            OvsKey.OvsKeyProto.__init__(
                 self,
                 "ct_tuple6",
                 data=data,
@@ -1510,7 +1510,7 @@ class ovskey(nla):
                 init=init,
             )
 
-    class ovs_key_tunnel(nla):
+    class OvsKeyTunnel(nla):
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -1537,9 +1537,9 @@ class ovskey(nla):
             if not flowstr.startswith("tunnel("):
                 return None, None
 
-            k = ovskey.ovs_key_tunnel()
+            k = OvsKey.OvsKeyTunnel()
             if mask is not None:
-                mask = ovskey.ovs_key_tunnel()
+                mask = OvsKey.OvsKeyTunnel()
 
             flowstr = flowstr[len("tunnel("):]
 
@@ -1667,7 +1667,7 @@ class ovskey(nla):
             print_str += ")"
             return print_str
 
-    class ovs_key_mpls(nla):
+    class OvsKeyMpls(nla):
         fields = (("lse", ">I"),)
 
     # 802.1Q CFI (Canonical Format Indicator) bit, always set for Ethernet
@@ -1789,8 +1789,8 @@ class ovskey(nla):
                     raise ValueError("vlan(): duplicate 'cfi'")
                 if v != 1:
                     raise ValueError("vlan(): cfi must be 1 for Ethernet")
-                tci |= ovskey._VLAN_CFI_MASK
-                mask |= ovskey._VLAN_CFI_MASK
+                tci |= OvsKey._VLAN_CFI_MASK
+                mask |= OvsKey._VLAN_CFI_MASK
                 has_cfi = True
             else:
                 raise ValueError(f"vlan(): unknown key '{key}'")
@@ -1807,8 +1807,8 @@ class ovskey(nla):
             raise ValueError("vlan(): no fields specified, "
                              "use vlan(vid=X[,pcp=Y,cfi=Z]) or vlan(tci=X)")
         if not has_tci:
-            tci |= ovskey._VLAN_CFI_MASK
-            mask |= ovskey._VLAN_CFI_MASK
+            tci |= OvsKey._VLAN_CFI_MASK
+            mask |= OvsKey._VLAN_CFI_MASK
         return flowstr, tci, mask
 
     @staticmethod
@@ -1847,8 +1847,8 @@ class ovskey(nla):
         if flowstr.lstrip().startswith(')'):
             raise ValueError("encap(): unmatched ')' after encap()")
 
-        inner_key = encap_ovskey()
-        inner_mask = encap_ovskey()
+        inner_key = EncapOvsKey()
+        inner_mask = EncapOvsKey()
         remaining = inner_key.parse(inner_str, inner_mask)
         if remaining and re.search(r'[^\s,)]', remaining):
             raise ValueError(
@@ -1861,7 +1861,7 @@ class ovskey(nla):
             ("OVS_KEY_ATTR_PRIORITY", "skb_priority", intparse),
             ("OVS_KEY_ATTR_SKB_MARK", "skb_mark", intparse),
             ("OVS_KEY_ATTR_RECIRC_ID", "recirc_id", intparse),
-            ("OVS_KEY_ATTR_TUNNEL", "tunnel", ovskey.ovs_key_tunnel),
+            ("OVS_KEY_ATTR_TUNNEL", "tunnel", OvsKey.OvsKeyTunnel),
             ("OVS_KEY_ATTR_DP_HASH", "dp_hash", intparse),
             ("OVS_KEY_ATTR_CT_STATE", "ct_state", parse_ct_state),
             ("OVS_KEY_ATTR_CT_ZONE", "ct_zone", intparse),
@@ -1870,7 +1870,7 @@ class ovskey(nla):
             (
                 "OVS_KEY_ATTR_ETHERNET",
                 "eth",
-                ovskey.ethaddr,
+                OvsKey.EthAddr,
             ),
             (
                 "OVS_KEY_ATTR_ETHERTYPE",
@@ -1880,42 +1880,42 @@ class ovskey(nla):
             (
                 "OVS_KEY_ATTR_VLAN",
                 "vlan",
-                ovskey._parse_vlan_from_flowstr,
+                OvsKey._parse_vlan_from_flowstr,
             ),
             (
                 "OVS_KEY_ATTR_ENCAP",
                 "encap",
-                ovskey._parse_encap_from_flowstr,
+                OvsKey._parse_encap_from_flowstr,
             ),
             (
                 "OVS_KEY_ATTR_IPV4",
                 "ipv4",
-                ovskey.ovs_key_ipv4,
+                OvsKey.OvsKeyIpv4,
             ),
             (
                 "OVS_KEY_ATTR_IPV6",
                 "ipv6",
-                ovskey.ovs_key_ipv6,
+                OvsKey.OvsKeyIpv6,
             ),
             (
                 "OVS_KEY_ATTR_ARP",
                 "arp",
-                ovskey.ovs_key_arp,
+                OvsKey.OvsKeyArp,
             ),
             (
                 "OVS_KEY_ATTR_TCP",
                 "tcp",
-                ovskey.ovs_key_tcp,
+                OvsKey.OvsKeyTcp,
             ),
             (
                 "OVS_KEY_ATTR_UDP",
                 "udp",
-                ovskey.ovs_key_udp,
+                OvsKey.OvsKeyUdp,
             ),
             (
                 "OVS_KEY_ATTR_ICMP",
                 "icmp",
-                ovskey.ovs_key_icmp,
+                OvsKey.OvsKeyIcmp,
             ),
             (
                 "OVS_KEY_ATTR_TCP_FLAGS",
@@ -2024,7 +2024,7 @@ class ovskey(nla):
                 True,
             ),
             ("OVS_KEY_ATTR_ETHERNET", None, None, False, False),
-            ("OVS_KEY_ATTR_VLAN", "vlan", ovskey._vlan_dpstr,
+            ("OVS_KEY_ATTR_VLAN", "vlan", OvsKey._vlan_dpstr,
                 lambda x: False, True),
             ("OVS_KEY_ATTR_ENCAP", None, None, False, False),
             (
@@ -2074,7 +2074,7 @@ class ovskey(nla):
         return print_str
 
 
-class encap_ovskey(ovskey):
+class EncapOvsKey(OvsKey):
     """Inner flow key attributes valid inside 802.1Q ENCAP.
 
     Only L2-L4 key attributes (slots 0-21) appear inside ENCAP.
@@ -2087,27 +2087,27 @@ class encap_ovskey(ovskey):
     """
     nla_map = (
         ("OVS_KEY_ATTR_UNSPEC", "none"),
-        ("OVS_KEY_ATTR_ENCAP", "none"),  # placeholder, parsed by ovskey
+        ("OVS_KEY_ATTR_ENCAP", "none"),  # placeholder, parsed by OvsKey
         ("OVS_KEY_ATTR_PRIORITY", "none"),  # skb metadata, not in ENCAP
         ("OVS_KEY_ATTR_IN_PORT", "none"),  # skb metadata, not in ENCAP
-        ("OVS_KEY_ATTR_ETHERNET", "ethaddr"),
+        ("OVS_KEY_ATTR_ETHERNET", "EthAddr"),
         ("OVS_KEY_ATTR_VLAN", "be16"),
         ("OVS_KEY_ATTR_ETHERTYPE", "be16"),
-        ("OVS_KEY_ATTR_IPV4", "ovs_key_ipv4"),
-        ("OVS_KEY_ATTR_IPV6", "ovs_key_ipv6"),
-        ("OVS_KEY_ATTR_TCP", "ovs_key_tcp"),
-        ("OVS_KEY_ATTR_UDP", "ovs_key_udp"),
-        ("OVS_KEY_ATTR_ICMP", "ovs_key_icmp"),
-        ("OVS_KEY_ATTR_ICMPV6", "ovs_key_icmpv6"),
-        ("OVS_KEY_ATTR_ARP", "ovs_key_arp"),
-        ("OVS_KEY_ATTR_ND", "ovs_key_nd"),
+        ("OVS_KEY_ATTR_IPV4", "OvsKeyIpv4"),
+        ("OVS_KEY_ATTR_IPV6", "OvsKeyIpv6"),
+        ("OVS_KEY_ATTR_TCP", "OvsKeyTcp"),
+        ("OVS_KEY_ATTR_UDP", "OvsKeyUdp"),
+        ("OVS_KEY_ATTR_ICMP", "OvsKeyIcmp"),
+        ("OVS_KEY_ATTR_ICMPV6", "OvsKeyIcmpv6"),
+        ("OVS_KEY_ATTR_ARP", "OvsKeyArp"),
+        ("OVS_KEY_ATTR_ND", "OvsKeyNd"),
         ("OVS_KEY_ATTR_SKB_MARK", "none"),  # metadata, not in ENCAP
         ("OVS_KEY_ATTR_TUNNEL", "none"),  # tunnel metadata, not in ENCAP
-        ("OVS_KEY_ATTR_SCTP", "ovs_key_sctp"),
+        ("OVS_KEY_ATTR_SCTP", "OvsKeySctp"),
         ("OVS_KEY_ATTR_TCP_FLAGS", "be16"),
         ("OVS_KEY_ATTR_DP_HASH", "none"),  # metadata, not in ENCAP
         ("OVS_KEY_ATTR_RECIRC_ID", "none"),  # metadata, not in ENCAP
-        ("OVS_KEY_ATTR_MPLS", "array(ovs_key_mpls)"),
+        ("OVS_KEY_ATTR_MPLS", "array(OvsKeyMpls)"),
     )
 
 
@@ -2116,12 +2116,12 @@ class OvsPacket(GenericNetlinkSocket):
     OVS_PACKET_CMD_ACTION = 2  # USERSPACE action
     OVS_PACKET_CMD_EXECUTE = 3  # Apply actions to packet
 
-    class ovs_packet_msg(ovs_dp_msg):
+    class OvsPacketMsg(OvsDpMsg):
         nla_map = (
             ("OVS_PACKET_ATTR_UNSPEC", "none"),
             ("OVS_PACKET_ATTR_PACKET", "array(uint8)"),
-            ("OVS_PACKET_ATTR_KEY", "ovskey"),
-            ("OVS_PACKET_ATTR_ACTIONS", "ovsactions"),
+            ("OVS_PACKET_ATTR_KEY", "OvsKey"),
+            ("OVS_PACKET_ATTR_ACTIONS", "OvsActions"),
             ("OVS_PACKET_ATTR_USERDATA", "none"),
             ("OVS_PACKET_ATTR_EGRESS_TUN_KEY", "none"),
             ("OVS_PACKET_ATTR_UNUSED1", "none"),
@@ -2134,7 +2134,7 @@ class OvsPacket(GenericNetlinkSocket):
 
     def __init__(self):
         GenericNetlinkSocket.__init__(self)
-        self.bind(OVS_PACKET_FAMILY, OvsPacket.ovs_packet_msg)
+        self.bind(OVS_PACKET_FAMILY, OvsPacket.OvsPacketMsg)
 
     def upcall_handler(self, up=None):
         print("listening on upcall packet handler:", self.epid)
@@ -2160,7 +2160,7 @@ class OvsDatapath(GenericNetlinkSocket):
     OVS_DP_F_VPORT_PIDS = 1 << 1
     OVS_DP_F_DISPATCH_UPCALL_PER_CPU = 1 << 3
 
-    class dp_cmd_msg(ovs_dp_msg):
+    class DpCmdMsg(OvsDpMsg):
         """
         Message class that will be used to communicate with the kernel module.
         """
@@ -2169,15 +2169,15 @@ class OvsDatapath(GenericNetlinkSocket):
             ("OVS_DP_ATTR_UNSPEC", "none"),
             ("OVS_DP_ATTR_NAME", "asciiz"),
             ("OVS_DP_ATTR_UPCALL_PID", "array(uint32)"),
-            ("OVS_DP_ATTR_STATS", "dpstats"),
-            ("OVS_DP_ATTR_MEGAFLOW_STATS", "megaflowstats"),
+            ("OVS_DP_ATTR_STATS", "DpStats"),
+            ("OVS_DP_ATTR_MEGAFLOW_STATS", "MegaflowStats"),
             ("OVS_DP_ATTR_USER_FEATURES", "uint32"),
             ("OVS_DP_ATTR_PAD", "none"),
             ("OVS_DP_ATTR_MASKS_CACHE_SIZE", "uint32"),
             ("OVS_DP_ATTR_PER_CPU_PIDS", "array(uint32)"),
         )
 
-        class dpstats(nla):
+        class DpStats(nla):
             fields = (
                 ("hit", "=Q"),
                 ("missed", "=Q"),
@@ -2185,7 +2185,7 @@ class OvsDatapath(GenericNetlinkSocket):
                 ("flows", "=Q"),
             )
 
-        class megaflowstats(nla):
+        class MegaflowStats(nla):
             fields = (
                 ("mask_hit", "=Q"),
                 ("masks", "=I"),
@@ -2196,10 +2196,10 @@ class OvsDatapath(GenericNetlinkSocket):
 
     def __init__(self):
         GenericNetlinkSocket.__init__(self)
-        self.bind(OVS_DATAPATH_FAMILY, OvsDatapath.dp_cmd_msg)
+        self.bind(OVS_DATAPATH_FAMILY, OvsDatapath.DpCmdMsg)
 
     def info(self, dpname, ifindex=0):
-        msg = OvsDatapath.dp_cmd_msg()
+        msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_GET
         msg["version"] = OVS_DATAPATH_VERSION
         msg["reserved"] = 0
@@ -2220,23 +2220,23 @@ class OvsDatapath(GenericNetlinkSocket):
         return reply
 
     def create(
-        self, dpname, shouldUpcall=False, versionStr=None, p=OvsPacket()
+        self, dpname, should_upcall=False, version_str=None, p=OvsPacket()
     ):
-        msg = OvsDatapath.dp_cmd_msg()
+        msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_NEW
-        if versionStr is None:
+        if version_str is None:
             msg["version"] = OVS_DATAPATH_VERSION
         else:
-            msg["version"] = int(versionStr.split(":")[0], 0)
+            msg["version"] = int(version_str.split(":")[0], 0)
         msg["reserved"] = 0
         msg["dpifindex"] = 0
         msg["attrs"].append(["OVS_DP_ATTR_NAME", dpname])
 
         dpfeatures = 0
-        if versionStr is not None and versionStr.find(":") != -1:
-            dpfeatures = int(versionStr.split(":")[1], 0)
+        if version_str is not None and version_str.find(":") != -1:
+            dpfeatures = int(version_str.split(":")[1], 0)
         else:
-            if versionStr is None or versionStr.find(":") == -1:
+            if version_str is None or version_str.find(":") == -1:
                 dpfeatures |= OvsDatapath.OVS_DP_F_DISPATCH_UPCALL_PER_CPU
                 dpfeatures &= ~OvsDatapath.OVS_DP_F_VPORT_PIDS
 
@@ -2246,7 +2246,7 @@ class OvsDatapath(GenericNetlinkSocket):
                 procarray += [int(p.epid)]
             msg["attrs"].append(["OVS_DP_ATTR_UPCALL_PID", procarray])
         msg["attrs"].append(["OVS_DP_ATTR_USER_FEATURES", dpfeatures])
-        if not shouldUpcall:
+        if not should_upcall:
             msg["attrs"].append(["OVS_DP_ATTR_UPCALL_PID", [0]])
 
         try:
@@ -2263,7 +2263,7 @@ class OvsDatapath(GenericNetlinkSocket):
         return reply
 
     def destroy(self, dpname):
-        msg = OvsDatapath.dp_cmd_msg()
+        msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_DEL
         msg["version"] = OVS_DATAPATH_VERSION
         msg["reserved"] = 0
@@ -2291,28 +2291,28 @@ class OvsVport(GenericNetlinkSocket):
     OVS_VPORT_TYPE_VXLAN = 4
     OVS_VPORT_TYPE_GENEVE = 5
 
-    class ovs_vport_msg(ovs_dp_msg):
+    class OvsVportMsg(OvsDpMsg):
         nla_map = (
             ("OVS_VPORT_ATTR_UNSPEC", "none"),
             ("OVS_VPORT_ATTR_PORT_NO", "uint32"),
             ("OVS_VPORT_ATTR_TYPE", "uint32"),
             ("OVS_VPORT_ATTR_NAME", "asciiz"),
-            ("OVS_VPORT_ATTR_OPTIONS", "vportopts"),
+            ("OVS_VPORT_ATTR_OPTIONS", "VportOpts"),
             ("OVS_VPORT_ATTR_UPCALL_PID", "array(uint32)"),
-            ("OVS_VPORT_ATTR_STATS", "vportstats"),
+            ("OVS_VPORT_ATTR_STATS", "VportStats"),
             ("OVS_VPORT_ATTR_PAD", "none"),
             ("OVS_VPORT_ATTR_IFINDEX", "uint32"),
             ("OVS_VPORT_ATTR_NETNSID", "uint32"),
         )
 
-        class vportopts(nla):
+        class VportOpts(nla):
             nla_map = (
                 ("OVS_TUNNEL_ATTR_UNSPEC", "none"),
                 ("OVS_TUNNEL_ATTR_DST_PORT", "uint16"),
                 ("OVS_TUNNEL_ATTR_EXTENSION", "none"),
             )
 
-        class vportstats(nla):
+        class VportStats(nla):
             fields = (
                 ("rx_packets", "=Q"),
                 ("tx_packets", "=Q"),
@@ -2324,6 +2324,7 @@ class OvsVport(GenericNetlinkSocket):
                 ("tx_dropped", "=Q"),
             )
 
+    @staticmethod
     def type_to_str(vport_type):
         if vport_type == OvsVport.OVS_VPORT_TYPE_NETDEV:
             return "netdev"
@@ -2337,6 +2338,7 @@ class OvsVport(GenericNetlinkSocket):
             return "geneve"
         raise ValueError(f"Unknown vport type:{vport_type}")
 
+    @staticmethod
     def str_to_type(vport_type):
         if vport_type == "netdev":
             return OvsVport.OVS_VPORT_TYPE_NETDEV
@@ -2352,11 +2354,11 @@ class OvsVport(GenericNetlinkSocket):
 
     def __init__(self, packet=OvsPacket()):
         GenericNetlinkSocket.__init__(self)
-        self.bind(OVS_VPORT_FAMILY, OvsVport.ovs_vport_msg)
+        self.bind(OVS_VPORT_FAMILY, OvsVport.OvsVportMsg)
         self.upcall_packet = packet
 
     def info(self, vport_name, dpifindex=0, portno=None):
-        msg = OvsVport.ovs_vport_msg()
+        msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_GET
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2381,7 +2383,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def attach(self, dpindex, vport_ifname, ptype, dport, lwt):
-        msg = OvsVport.ovs_vport_msg()
+        msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_NEW
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2394,11 +2396,11 @@ class OvsVport(GenericNetlinkSocket):
             ["OVS_VPORT_ATTR_UPCALL_PID", [self.upcall_packet.epid]]
         )
 
-        TUNNEL_DEFAULTS = [("geneve", 6081),
+        tunnel_defaults = [("geneve", 6081),
                            ("gre", 0),
                            ("vxlan", 4789)]
 
-        for tnl in TUNNEL_DEFAULTS:
+        for tnl in tunnel_defaults:
             if ptype == tnl[0]:
                 if not dport:
                     dport = tnl[1]
@@ -2408,7 +2410,7 @@ class OvsVport(GenericNetlinkSocket):
                         # GRE tunnels have no options.
                         break
 
-                    vportopt = OvsVport.ovs_vport_msg.vportopts()
+                    vportopt = OvsVport.OvsVportMsg.VportOpts()
                     vportopt["attrs"].append(
                         ["OVS_TUNNEL_ATTR_DST_PORT", dport]
                     )
@@ -2447,7 +2449,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def reset_upcall(self, dpindex, vport_ifname, p=None):
-        msg = OvsVport.ovs_vport_msg()
+        msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_SET
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2472,7 +2474,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def detach(self, dpindex, vport_ifname):
-        msg = OvsVport.ovs_vport_msg()
+        msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_DEL
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2497,22 +2499,22 @@ class OvsVport(GenericNetlinkSocket):
 
 
 class OvsFlow(GenericNetlinkSocket):
-    class ovs_flow_msg(ovs_dp_msg):
+    class OvsFlowMsg(OvsDpMsg):
         nla_map = (
             ("OVS_FLOW_ATTR_UNSPEC", "none"),
-            ("OVS_FLOW_ATTR_KEY", "ovskey"),
-            ("OVS_FLOW_ATTR_ACTIONS", "ovsactions"),
-            ("OVS_FLOW_ATTR_STATS", "flowstats"),
+            ("OVS_FLOW_ATTR_KEY", "OvsKey"),
+            ("OVS_FLOW_ATTR_ACTIONS", "OvsActions"),
+            ("OVS_FLOW_ATTR_STATS", "FlowStats"),
             ("OVS_FLOW_ATTR_TCP_FLAGS", "uint8"),
             ("OVS_FLOW_ATTR_USED", "uint64"),
             ("OVS_FLOW_ATTR_CLEAR", "none"),
-            ("OVS_FLOW_ATTR_MASK", "ovskey"),
+            ("OVS_FLOW_ATTR_MASK", "OvsKey"),
             ("OVS_FLOW_ATTR_PROBE", "none"),
             ("OVS_FLOW_ATTR_UFID", "array(uint32)"),
             ("OVS_FLOW_ATTR_UFID_FLAGS", "uint32"),
         )
 
-        class flowstats(nla):
+        class FlowStats(nla):
             fields = (
                 ("packets", "=Q"),
                 ("bytes", "=Q"),
@@ -2585,9 +2587,9 @@ class OvsFlow(GenericNetlinkSocket):
             return print_str
 
         def parse(self, flowstr, actstr, dpidx=0):
-            OVS_UFID_F_OMIT_KEY = 1 << 0
-            OVS_UFID_F_OMIT_MASK = 1 << 1
-            OVS_UFID_F_OMIT_ACTIONS = 1 << 2
+            ovs_ufid_f_omit_key = 1 << 0
+            ovs_ufid_f_omit_mask = 1 << 1
+            ovs_ufid_f_omit_actions = 1 << 2
 
             self["cmd"] = 0
             self["version"] = 0
@@ -2602,18 +2604,18 @@ class OvsFlow(GenericNetlinkSocket):
                 flowstr = flowstr[count + 1 :]
             else:
                 ufidstr = str(uuid.uuid4())
-            uuidRawObj = uuid.UUID(ufidstr).fields
+            uuid_raw_obj = uuid.UUID(ufidstr).fields
 
             self["attrs"].append(
                 [
                     "OVS_FLOW_ATTR_UFID",
                     [
-                        uuidRawObj[0],
-                        uuidRawObj[1] << 16 | uuidRawObj[2],
-                        uuidRawObj[3] << 24
-                        | uuidRawObj[4] << 16
-                        | uuidRawObj[5] & (0xFF << 32) >> 32,
-                        uuidRawObj[5] & (0xFFFFFFFF),
+                        uuid_raw_obj[0],
+                        uuid_raw_obj[1] << 16 | uuid_raw_obj[2],
+                        uuid_raw_obj[3] << 24
+                        | uuid_raw_obj[4] << 16
+                        | uuid_raw_obj[5] & (0xFF << 32) >> 32,
+                        uuid_raw_obj[5] & (0xFFFFFFFF),
                     ],
                 ]
             )
@@ -2621,27 +2623,27 @@ class OvsFlow(GenericNetlinkSocket):
                 [
                     "OVS_FLOW_ATTR_UFID_FLAGS",
                     int(
-                        OVS_UFID_F_OMIT_KEY
-                        | OVS_UFID_F_OMIT_MASK
-                        | OVS_UFID_F_OMIT_ACTIONS
+                        ovs_ufid_f_omit_key
+                        | ovs_ufid_f_omit_mask
+                        | ovs_ufid_f_omit_actions
                     ),
                 ]
             )
 
-            k = ovskey()
-            m = ovskey()
+            k = OvsKey()
+            m = OvsKey()
             k.parse(flowstr, m)
             self["attrs"].append(["OVS_FLOW_ATTR_KEY", k])
             self["attrs"].append(["OVS_FLOW_ATTR_MASK", m])
 
-            a = ovsactions()
+            a = OvsActions()
             a.parse(actstr)
             self["attrs"].append(["OVS_FLOW_ATTR_ACTIONS", a])
 
     def __init__(self):
         GenericNetlinkSocket.__init__(self)
 
-        self.bind(OVS_FLOW_FAMILY, OvsFlow.ovs_flow_msg)
+        self.bind(OVS_FLOW_FAMILY, OvsFlow.OvsFlowMsg)
 
     def add_flow(self, dpifindex, flowmsg):
         """
@@ -2678,7 +2680,7 @@ class OvsFlow(GenericNetlinkSocket):
         into the OvsDatapath lookup
         """
 
-        flowmsg = OvsFlow.ovs_flow_msg()
+        flowmsg = OvsFlow.OvsFlowMsg()
         flowmsg["cmd"] = OVS_FLOW_CMD_DEL
         flowmsg["version"] = OVS_DATAPATH_VERSION
         flowmsg["reserved"] = 0
@@ -2706,7 +2708,7 @@ class OvsFlow(GenericNetlinkSocket):
         flowpsec is a string which represents a flow in the dpctl
         format.
         """
-        msg = OvsFlow.ovs_flow_msg()
+        msg = OvsFlow.OvsFlowMsg()
 
         msg["cmd"] = OVS_FLOW_CMD_GET
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2747,7 +2749,7 @@ class OvsFlow(GenericNetlinkSocket):
         print("userspace action command", flush=True)
 
 
-class psample_sample(genlmsg):
+class PsampleSample(genlmsg):
     nla_map = (
         ("PSAMPLE_ATTR_IIFINDEX", "none"),
         ("PSAMPLE_ATTR_OIFINDEX", "none"),
@@ -2784,19 +2786,19 @@ class psample_sample(genlmsg):
         return (f"{','.join(fields)} {data}").strip()
 
 
-class psample_msg(Marshal):
+class PsampleMsg(Marshal):
     PSAMPLE_CMD_SAMPLE = 0
     PSAMPLE_CMD_GET_GROUP = 1
     PSAMPLE_CMD_NEW_GROUP = 2
     PSAMPLE_CMD_DEL_GROUP = 3
     PSAMPLE_CMD_SET_FILTER = 4
-    msg_map = {PSAMPLE_CMD_SAMPLE: psample_sample}
+    msg_map = {PSAMPLE_CMD_SAMPLE: PsampleSample}
 
 
 class PsampleEvent(EventSocket):
     genl_family = "psample"
     mcast_groups = ["packets"]
-    marshal_class = psample_msg
+    marshal_class = PsampleMsg
 
     def read_samples(self):
         print("listening for psample events", flush=True)
@@ -2850,9 +2852,9 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
 
 
 def main(argv):
-    nlmsg_atoms.encap_ovskey = encap_ovskey
-    nlmsg_atoms.ovskey = ovskey
-    nlmsg_atoms.ovsactions = ovsactions
+    nlmsg_atoms.EncapOvsKey = EncapOvsKey
+    nlmsg_atoms.OvsKey = OvsKey
+    nlmsg_atoms.OvsActions = OvsActions
 
     # version check for pyroute2
     prverscheck = pyroute2.__version__.split(".")
@@ -3034,7 +3036,7 @@ def main(argv):
         if rep is None:
             print(f"DP '{args.flbr}' not found.")
             return 1
-        flow = OvsFlow.ovs_flow_msg()
+        flow = OvsFlow.OvsFlowMsg()
         flow.parse(args.flow, args.acts, rep["dpifindex"])
         ovsflow.add_flow(rep["dpifindex"], flow)
     elif hasattr(args, "flsbr"):
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 4/5] selftests: openvswitch: add missing docstrings in ovs-dpctl.py
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
                   ` (2 preceding siblings ...)
  2026-05-13 12:12 ` [PATCH net-next 3/5] selftests: openvswitch: rename classes and variables " Minxi Hou
@ 2026-05-13 12:12 ` Minxi Hou
  2026-05-13 12:12 ` [PATCH net-next 5/5] selftests: openvswitch: suppress pylint complexity warnings Minxi Hou
  2026-05-15  6:53 ` [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Aaron Conole
  5 siblings, 0 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

Add one-line docstrings to all module, class, and method
definitions to fix C0114, C0115, and C0116 pylint warnings.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
 .../selftests/net/openvswitch/ovs-dpctl.py    | 94 ++++++++++++++++++-
 1 file changed, 91 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 6a9cf48948fd..3683796ba2e2 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
+"""OVS datapath control utility for kernel selftests."""
 
 # Controls the openvswitch module.  Part of the kselftest suite, but
 # can be used for some diagnostic purpose as well.
@@ -64,11 +65,13 @@ OVS_FLOW_CMD_SET = 4
 UINT32_MAX = 0xFFFFFFFF
 
 def macstr(mac):
+    """Format MAC address bytes as colon-separated hex string."""
     outstr = ":".join([f"{i:02X}" for i in mac])
     return outstr
 
 
 def strcspn(str1, str2):
+    """Return index of first char in str1 that is in str2."""
     tot = 0
     for char in str1:
         if str2.find(char) != -1:
@@ -78,6 +81,7 @@ def strcspn(str1, str2):
 
 
 def strspn(str1, str2):
+    """Return index of first char in str1 that is not in str2."""
     tot = 0
     for char in str1:
         if str2.find(char) == -1:
@@ -87,6 +91,7 @@ def strspn(str1, str2):
 
 
 def intparse(statestr, defmask="0xffffffff"):
+    """Parse an integer with optional mask from a state string."""
     totalparse = strspn(statestr, "0123456789abcdefABCDEFx/")
     # scan until "/"
     count = strspn(statestr, "x0123456789abcdefABCDEF")
@@ -107,6 +112,7 @@ def intparse(statestr, defmask="0xffffffff"):
 
 
 def parse_flags(flag_str, flag_vals):
+    """Parse flag string into bitmask and mask values."""
     bit_result = 0
     mask_result = 0
 
@@ -158,6 +164,7 @@ def parse_flags(flag_str, flag_vals):
 
 
 def parse_ct_state(statestr):
+    """Parse conntrack state flags string."""
     ct_flags = {
         "new": 1 << 0,
         "est": 1 << 1,
@@ -173,6 +180,7 @@ def parse_ct_state(statestr):
 
 
 def convert_mac(data):
+    """Convert MAC address string with optional mask to bytes."""
     def to_bytes(mac):
         mac_split = mac.split(":")
         ret = bytearray([int(i, 16) for i in mac_split])
@@ -188,6 +196,7 @@ def convert_mac(data):
     return to_bytes(mac_str), to_bytes(mask_str)
 
 def convert_ipv4(data):
+    """Convert IPv4 address string with optional mask to integers."""
     ip, _, mask = data.partition('/')
 
     if not ip:
@@ -200,6 +209,7 @@ def convert_ipv4(data):
     return int(ipaddress.IPv4Address(ip)), int(ipaddress.IPv4Address(mask))
 
 def convert_ipv6(data):
+    """Convert IPv6 address string with optional mask to packed bytes."""
     ip, _, mask = data.partition('/')
 
     if not ip:
@@ -212,6 +222,7 @@ def convert_ipv6(data):
     return ipaddress.IPv6Address(ip).packed, ipaddress.IPv6Address(mask).packed
 
 def convert_int(size):
+    """Return a converter for integer fields of the given bit size."""
     def convert_int_sized(data):
         value, _, mask = data.partition('/')
 
@@ -224,6 +235,7 @@ def convert_int(size):
     return convert_int_sized
 
 def parse_starts_block(block_str, scanstr, returnskipped, scanregex=False):
+    """Check if block_str starts with scanstr, optionally skip it."""
     if scanregex:
         m = re.search(scanstr, block_str)
         if m is None:
@@ -250,6 +262,7 @@ def parse_starts_block(block_str, scanstr, returnskipped, scanregex=False):
 def parse_extract_field(
     block_str, fieldstr, scanfmt, convert, masked=False, defval=None
 ):
+    """Extract a field value from block_str using regex scanfmt."""
     if fieldstr and not block_str.startswith(fieldstr):
         return block_str, defval
 
@@ -349,6 +362,7 @@ def parse_attrs(actstr, attr_desc):
 
 
 class OvsDpMsg(genlmsg):
+    """OVS datapath generic netlink message."""
     # include the OVS version
     # We need a custom header rather than just being able to rely on
     # genlmsg because fields ends up not expressing everything correctly
@@ -357,6 +371,7 @@ class OvsDpMsg(genlmsg):
 
 
 class OvsActions(nla):
+    """OVS datapath actions netlink attribute."""
     nla_flags = NLA_F_NESTED
 
     nla_map = (
@@ -389,6 +404,7 @@ class OvsActions(nla):
     )
 
     class Psample(nla):
+        """Packet sampling action attributes."""
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -398,6 +414,7 @@ class OvsActions(nla):
         )
 
         def dpstr(self, more=False):
+            """Format psample attributes as dpctl string."""
             args = f"group={self.get_attr('OVS_PSAMPLE_ATTR_GROUP')}"
 
             cookie = self.get_attr("OVS_PSAMPLE_ATTR_COOKIE")
@@ -407,6 +424,7 @@ class OvsActions(nla):
             return f"psample({args})"
 
         def parse(self, actstr):
+            """Parse psample attributes from dpctl string."""
             desc = (
                 ("group", "OVS_PSAMPLE_ATTR_GROUP", int),
                 ("cookie", "OVS_PSAMPLE_ATTR_COOKIE",
@@ -421,9 +439,11 @@ class OvsActions(nla):
             return actstr
 
     class PushVlan(nla):
+        """Push VLAN action fields (tpid + tci)."""
         fields = (("vlan_tpid", "!H"), ("vlan_tci", "!H"))
 
     class Sample(nla):
+        """Sample action attributes."""
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -433,6 +453,7 @@ class OvsActions(nla):
         )
 
         def dpstr(self, more=False):
+            """Format sample attributes as dpctl string."""
             args = []
 
             prob = 100 * self.get_attr(
@@ -446,6 +467,7 @@ class OvsActions(nla):
             return f"sample({','.join(args)})"
 
         def parse(self, actstr):
+            """Parse sample attributes from dpctl string."""
             def parse_nested_actions(actstr):
                 subacts = OvsActions()
                 parsed_len = subacts.parse(actstr)
@@ -456,7 +478,7 @@ class OvsActions(nla):
                 return int(math.floor(UINT32_MAX * (percent / 100.0) + .5))
 
             desc = (
-                ("Sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate),
+                ("sample", "OVS_SAMPLE_ATTR_PROBABILITY", percent_to_rate),
                 ("actions", "OVS_SAMPLE_ATTR_ACTIONS", parse_nested_actions),
             )
             attrs, actstr = parse_attrs(actstr, desc)
@@ -467,6 +489,7 @@ class OvsActions(nla):
             return actstr
 
     class CtAct(nla):
+        """Conntrack action attributes."""
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -483,6 +506,7 @@ class OvsActions(nla):
         )
 
         class NatAttr(nla):
+            """NAT sub-action attributes."""
             nla_flags = NLA_F_NESTED
 
             nla_map = (
@@ -499,6 +523,7 @@ class OvsActions(nla):
             )
 
             def dpstr(self, more=False):
+                """Format NAT attributes as dpctl string."""
                 print_str = "nat("
 
                 if self.get_attr("OVS_NAT_ATTR_SRC"):
@@ -537,6 +562,7 @@ class OvsActions(nla):
                 return print_str
 
         def dpstr(self, more=False):
+            """Format conntrack attributes as dpctl string."""
             print_str = "ct("
 
             if self.get_attr("OVS_CT_ATTR_COMMIT") is not None:
@@ -558,6 +584,7 @@ class OvsActions(nla):
             return print_str
 
     class Userspace(nla):
+        """Userspace action attributes."""
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -568,6 +595,7 @@ class OvsActions(nla):
         )
 
         def dpstr(self, more=False):
+            """Format userspace attributes as dpctl string."""
             print_str = "userspace("
             if self.get_attr("OVS_USERSPACE_ATTR_PID") is not None:
                 print_str += f"pid={self.get_attr('OVS_USERSPACE_ATTR_PID')},"
@@ -583,6 +611,7 @@ class OvsActions(nla):
             return print_str
 
         def parse(self, actstr):
+            """Parse userspace attributes from dpctl string."""
             attrs_desc = (
                 ("pid", "OVS_USERSPACE_ATTR_PID", int),
                 ("userdata", "OVS_USERSPACE_ATTR_USERDATA",
@@ -597,6 +626,7 @@ class OvsActions(nla):
             return actstr
 
     def dpstr(self, more=False):
+        """Format all actions as dpctl string."""
         print_str = ""
 
         for field in self["attrs"]:
@@ -652,12 +682,13 @@ class OvsActions(nla):
                 else:
                     try:
                         print_str += datum.dpstr(more)
-                    except:
-                        print_str += "{ATTR: %s not decoded}" % field[0]
+                    except Exception:
+                        print_str += f"{{ATTR: {field[0]} not decoded}}"
 
         return print_str
 
     def parse(self, actstr):
+        """Parse actions from dpctl string."""
         totallen = len(actstr)
         while len(actstr) != 0:
             parsed = False
@@ -934,6 +965,7 @@ class OvsActions(nla):
 
 
 class OvsKey(nla):
+    """OVS flow key netlink attribute."""
     nla_flags = NLA_F_NESTED
     nla_map = (
         ("OVS_KEY_ATTR_UNSPEC", "none"),
@@ -972,6 +1004,7 @@ class OvsKey(nla):
     )
 
     class OvsKeyProto(nla):
+        """Protocol key fields (ethertype)."""
         fields = (
             ("src", "!H"),
             ("dst", "!H"),
@@ -1004,6 +1037,7 @@ class OvsKey(nla):
             )
 
         def parse(self, flowstr, type_inst):
+            """Parse protocol key from dpctl string."""
             if not flowstr.startswith(self.proto_str):
                 return None, None
 
@@ -1045,6 +1079,7 @@ class OvsKey(nla):
             return flowstr, k, m
 
         def dpstr(self, masked=None, more=False):
+            """Format protocol key as dpctl string."""
             outstr = f"{self.proto_str}("
             first = False
             for f in self.fields_map:
@@ -1073,6 +1108,7 @@ class OvsKey(nla):
             return outstr
 
     class EthAddr(OvsKeyProto):
+        """Ethernet address key fields."""
         fields = (
             ("src", "!6s"),
             ("dst", "!6s"),
@@ -1114,6 +1150,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyIpv4(OvsKeyProto):
+        """IPv4 key fields."""
         fields = (
             ("src", "!I"),
             ("dst", "!I"),
@@ -1167,6 +1204,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyIpv6(OvsKeyProto):
+        """IPv6 key fields."""
         fields = (
             ("src", "!16s"),
             ("dst", "!16s"),
@@ -1218,6 +1256,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyTcp(OvsKeyProto):
+        """TCP key fields (src/dst port)."""
         def __init__(
             self,
             data=None,
@@ -1237,6 +1276,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyUdp(OvsKeyProto):
+        """UDP key fields (src/dst port)."""
         def __init__(
             self,
             data=None,
@@ -1256,6 +1296,7 @@ class OvsKey(nla):
             )
 
     class OvsKeySctp(OvsKeyProto):
+        """SCTP key fields (src/dst port)."""
         def __init__(
             self,
             data=None,
@@ -1275,6 +1316,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyIcmp(OvsKeyProto):
+        """ICMP key fields (type/code)."""
         fields = (
             ("type", "B"),
             ("code", "B"),
@@ -1304,6 +1346,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyIcmpv6(OvsKeyIcmp):
+        """ICMPv6 key fields (type/code)."""
         def __init__(
             self,
             data=None,
@@ -1323,6 +1366,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyArp(OvsKeyProto):
+        """ARP key fields."""
         fields = (
             ("sip", "!I"),
             ("tip", "!I"),
@@ -1383,6 +1427,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyNd(OvsKeyProto):
+        """Neighbor discovery key fields."""
         fields = (
             ("target", "!16s"),
             ("sll", "!6s"),
@@ -1419,6 +1464,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyCtTupleIpv4(OvsKeyProto):
+        """Conntrack original tuple key (IPv4)."""
         fields = (
             ("src", "!I"),
             ("dst", "!I"),
@@ -1466,6 +1512,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyCtTupleIpv6(nla):
+        """Conntrack original tuple key (IPv6)."""
         fields = (
             ("src", "!16s"),
             ("dst", "!16s"),
@@ -1511,6 +1558,7 @@ class OvsKey(nla):
             )
 
     class OvsKeyTunnel(nla):
+        """Tunnel key fields."""
         nla_flags = NLA_F_NESTED
 
         nla_map = (
@@ -1534,6 +1582,7 @@ class OvsKey(nla):
         )
 
         def parse(self, flowstr, mask=None):
+            """Parse tunnel key from dpctl string."""
             if not flowstr.startswith("tunnel("):
                 return None, None
 
@@ -1626,6 +1675,7 @@ class OvsKey(nla):
             return flowstr, k, mask
 
         def dpstr(self, mask=None, more=False):
+            """Format tunnel key as dpctl string."""
             print_str = "tunnel("
 
             flagsattrs = []
@@ -1668,6 +1718,7 @@ class OvsKey(nla):
             return print_str
 
     class OvsKeyMpls(nla):
+        """MPLS key fields."""
         fields = (("lse", ">I"),)
 
     # 802.1Q CFI (Canonical Format Indicator) bit, always set for Ethernet
@@ -1857,6 +1908,7 @@ class OvsKey(nla):
         return flowstr, inner_key, inner_mask
 
     def parse(self, flowstr, mask=None):
+        """Parse flow key from dpctl string."""
         for field in (
             ("OVS_KEY_ATTR_PRIORITY", "skb_priority", intparse),
             ("OVS_KEY_ATTR_SKB_MARK", "skb_mark", intparse),
@@ -1943,6 +1995,7 @@ class OvsKey(nla):
         return flowstr
 
     def dpstr(self, mask=None, more=False):
+        """Format flow key as dpctl string."""
         print_str = ""
 
         for field in (
@@ -2112,11 +2165,13 @@ class EncapOvsKey(OvsKey):
 
 
 class OvsPacket(GenericNetlinkSocket):
+    """OVS packet command message."""
     OVS_PACKET_CMD_MISS = 1  # Flow table miss
     OVS_PACKET_CMD_ACTION = 2  # USERSPACE action
     OVS_PACKET_CMD_EXECUTE = 3  # Apply actions to packet
 
     class OvsPacketMsg(OvsDpMsg):
+        """OVS packet message header."""
         nla_map = (
             ("OVS_PACKET_ATTR_UNSPEC", "none"),
             ("OVS_PACKET_ATTR_PACKET", "array(uint8)"),
@@ -2137,6 +2192,7 @@ class OvsPacket(GenericNetlinkSocket):
         self.bind(OVS_PACKET_FAMILY, OvsPacket.OvsPacketMsg)
 
     def upcall_handler(self, up=None):
+        """Listen for packet upcall messages."""
         print("listening on upcall packet handler:", self.epid)
         while True:
             try:
@@ -2157,6 +2213,7 @@ class OvsPacket(GenericNetlinkSocket):
 
 
 class OvsDatapath(GenericNetlinkSocket):
+    """OVS datapath management."""
     OVS_DP_F_VPORT_PIDS = 1 << 1
     OVS_DP_F_DISPATCH_UPCALL_PER_CPU = 1 << 3
 
@@ -2178,6 +2235,7 @@ class OvsDatapath(GenericNetlinkSocket):
         )
 
         class DpStats(nla):
+            """Datapath statistics."""
             fields = (
                 ("hit", "=Q"),
                 ("missed", "=Q"),
@@ -2186,6 +2244,7 @@ class OvsDatapath(GenericNetlinkSocket):
             )
 
         class MegaflowStats(nla):
+            """Megaflow cache statistics."""
             fields = (
                 ("mask_hit", "=Q"),
                 ("masks", "=I"),
@@ -2199,6 +2258,7 @@ class OvsDatapath(GenericNetlinkSocket):
         self.bind(OVS_DATAPATH_FAMILY, OvsDatapath.DpCmdMsg)
 
     def info(self, dpname, ifindex=0):
+        """Get datapath information by name."""
         msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_GET
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2222,6 +2282,7 @@ class OvsDatapath(GenericNetlinkSocket):
     def create(
         self, dpname, should_upcall=False, version_str=None, p=OvsPacket()
     ):
+        """Create a new datapath."""
         msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_NEW
         if version_str is None:
@@ -2263,6 +2324,7 @@ class OvsDatapath(GenericNetlinkSocket):
         return reply
 
     def destroy(self, dpname):
+        """Destroy a datapath."""
         msg = OvsDatapath.DpCmdMsg()
         msg["cmd"] = OVS_DP_CMD_DEL
         msg["version"] = OVS_DATAPATH_VERSION
@@ -2285,6 +2347,7 @@ class OvsDatapath(GenericNetlinkSocket):
 
 
 class OvsVport(GenericNetlinkSocket):
+    """OVS virtual port management."""
     OVS_VPORT_TYPE_NETDEV = 1
     OVS_VPORT_TYPE_INTERNAL = 2
     OVS_VPORT_TYPE_GRE = 3
@@ -2292,6 +2355,7 @@ class OvsVport(GenericNetlinkSocket):
     OVS_VPORT_TYPE_GENEVE = 5
 
     class OvsVportMsg(OvsDpMsg):
+        """Vport info message."""
         nla_map = (
             ("OVS_VPORT_ATTR_UNSPEC", "none"),
             ("OVS_VPORT_ATTR_PORT_NO", "uint32"),
@@ -2306,6 +2370,7 @@ class OvsVport(GenericNetlinkSocket):
         )
 
         class VportOpts(nla):
+            """Vport options attributes."""
             nla_map = (
                 ("OVS_TUNNEL_ATTR_UNSPEC", "none"),
                 ("OVS_TUNNEL_ATTR_DST_PORT", "uint16"),
@@ -2313,6 +2378,7 @@ class OvsVport(GenericNetlinkSocket):
             )
 
         class VportStats(nla):
+            """Vport traffic statistics."""
             fields = (
                 ("rx_packets", "=Q"),
                 ("tx_packets", "=Q"),
@@ -2326,6 +2392,7 @@ class OvsVport(GenericNetlinkSocket):
 
     @staticmethod
     def type_to_str(vport_type):
+        """Convert vport type integer to string."""
         if vport_type == OvsVport.OVS_VPORT_TYPE_NETDEV:
             return "netdev"
         if vport_type == OvsVport.OVS_VPORT_TYPE_INTERNAL:
@@ -2340,6 +2407,7 @@ class OvsVport(GenericNetlinkSocket):
 
     @staticmethod
     def str_to_type(vport_type):
+        """Convert vport type string to integer."""
         if vport_type == "netdev":
             return OvsVport.OVS_VPORT_TYPE_NETDEV
         if vport_type == "internal":
@@ -2358,6 +2426,7 @@ class OvsVport(GenericNetlinkSocket):
         self.upcall_packet = packet
 
     def info(self, vport_name, dpifindex=0, portno=None):
+        """Get vport information by name or port number."""
         msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_GET
@@ -2383,6 +2452,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def attach(self, dpindex, vport_ifname, ptype, dport, lwt):
+        """Attach a new vport to a datapath."""
         msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_NEW
@@ -2449,6 +2519,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def reset_upcall(self, dpindex, vport_ifname, p=None):
+        """Reset vport upcall PID."""
         msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_SET
@@ -2474,6 +2545,7 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def detach(self, dpindex, vport_ifname):
+        """Remove a vport from a datapath."""
         msg = OvsVport.OvsVportMsg()
 
         msg["cmd"] = OVS_VPORT_CMD_DEL
@@ -2495,11 +2567,14 @@ class OvsVport(GenericNetlinkSocket):
         return reply
 
     def upcall_handler(self, handler=None):
+        """Start upcall handler for packet events."""
         self.upcall_packet.upcall_handler(handler)
 
 
 class OvsFlow(GenericNetlinkSocket):
+    """OVS flow table management."""
     class OvsFlowMsg(OvsDpMsg):
+        """Flow info message."""
         nla_map = (
             ("OVS_FLOW_ATTR_UNSPEC", "none"),
             ("OVS_FLOW_ATTR_KEY", "OvsKey"),
@@ -2515,12 +2590,14 @@ class OvsFlow(GenericNetlinkSocket):
         )
 
         class FlowStats(nla):
+            """Flow packet and byte counters."""
             fields = (
                 ("packets", "=Q"),
                 ("bytes", "=Q"),
             )
 
         def dpstr(self, more=False):
+            """Format flow as dpctl string."""
             ufid = self.get_attr("OVS_FLOW_ATTR_UFID")
             ufid_str = ""
             if ufid is not None:
@@ -2587,6 +2664,7 @@ class OvsFlow(GenericNetlinkSocket):
             return print_str
 
         def parse(self, flowstr, actstr, dpidx=0):
+            """Parse flow from dpctl string."""
             ovs_ufid_f_omit_key = 1 << 0
             ovs_ufid_f_omit_mask = 1 << 1
             ovs_ufid_f_omit_actions = 1 << 2
@@ -2731,6 +2809,7 @@ class OvsFlow(GenericNetlinkSocket):
         return rep
 
     def miss(self, packetmsg):
+        """Handle flow table miss upcall."""
         seq = packetmsg["header"]["sequence_number"]
         keystr = "(none)"
         key_field = packetmsg.get_attr("OVS_PACKET_ATTR_KEY")
@@ -2743,13 +2822,16 @@ class OvsFlow(GenericNetlinkSocket):
         print(f"MISS upcall[{seq}/{pktpres}]: {keystr}", flush=True)
 
     def execute(self, packetmsg):
+        """Handle packet execute command."""
         print("userspace execute command", flush=True)
 
     def action(self, packetmsg):
+        """Handle userspace action upcall."""
         print("userspace action command", flush=True)
 
 
 class PsampleSample(genlmsg):
+    """Psample generic netlink event handler."""
     nla_map = (
         ("PSAMPLE_ATTR_IIFINDEX", "none"),
         ("PSAMPLE_ATTR_OIFINDEX", "none"),
@@ -2770,6 +2852,7 @@ class PsampleSample(genlmsg):
     )
 
     def dpstr(self):
+        """Format psample attributes as string."""
         fields = []
         data = ""
         for (attr, value) in self["attrs"]:
@@ -2787,6 +2870,7 @@ class PsampleSample(genlmsg):
 
 
 class PsampleMsg(Marshal):
+    """Psample generic netlink message."""
     PSAMPLE_CMD_SAMPLE = 0
     PSAMPLE_CMD_GET_GROUP = 1
     PSAMPLE_CMD_NEW_GROUP = 2
@@ -2796,11 +2880,13 @@ class PsampleMsg(Marshal):
 
 
 class PsampleEvent(EventSocket):
+    """Psample event listener."""
     genl_family = "psample"
     mcast_groups = ["packets"]
     marshal_class = PsampleMsg
 
     def read_samples(self):
+        """Read psample events in a loop."""
         print("listening for psample events", flush=True)
         while True:
             try:
@@ -2811,6 +2897,7 @@ class PsampleEvent(EventSocket):
 
 
 def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
+    """Print full OVS datapath information."""
     dp_name = dp_lookup_rep.get_attr("OVS_DP_ATTR_NAME")
     base_stats = dp_lookup_rep.get_attr("OVS_DP_ATTR_STATS")
     megaflow_stats = dp_lookup_rep.get_attr("OVS_DP_ATTR_MEGAFLOW_STATS")
@@ -2852,6 +2939,7 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
 
 
 def main(argv):
+    """Entry point for ovs-dpctl utility."""
     nlmsg_atoms.EncapOvsKey = EncapOvsKey
     nlmsg_atoms.OvsKey = OvsKey
     nlmsg_atoms.OvsActions = OvsActions
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 5/5] selftests: openvswitch: suppress pylint complexity warnings
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
                   ` (3 preceding siblings ...)
  2026-05-13 12:12 ` [PATCH net-next 4/5] selftests: openvswitch: add missing docstrings " Minxi Hou
@ 2026-05-13 12:12 ` Minxi Hou
  2026-05-15  6:53 ` [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Aaron Conole
  5 siblings, 0 replies; 8+ messages in thread
From: Minxi Hou @ 2026-05-13 12:12 UTC (permalink / raw)
  To: netdev
  Cc: dev, linux-kselftest, linux-kernel, aconole, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah,
	Minxi Hou

Add file-level pylint:disable comments for warnings caused by
pyroute2 framework constraints that cannot be fixed without
restructuring the netlink attribute hierarchy.

After this patch, pylint reports 0 warnings (10.00/10).

Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
 tools/testing/selftests/net/openvswitch/ovs-dpctl.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 3683796ba2e2..bbc88e3cfc8a 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -1,6 +1,14 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
 """OVS datapath control utility for kernel selftests."""
+# pylint: disable=invalid-name,too-many-lines
+# pylint: disable=too-many-ancestors,too-many-arguments
+# pylint: disable=too-many-positional-arguments,too-many-branches
+# pylint: disable=too-many-locals,too-many-statements
+# pylint: disable=too-many-return-statements,too-many-nested-blocks
+# pylint: disable=unused-argument,broad-exception-caught
+# pylint: disable=no-member,not-callable
+# pylint: disable=non-parent-init-called,super-init-not-called
 
 # Controls the openvswitch module.  Part of the kselftest suite, but
 # can be used for some diagnostic purpose as well.
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py
  2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
                   ` (4 preceding siblings ...)
  2026-05-13 12:12 ` [PATCH net-next 5/5] selftests: openvswitch: suppress pylint complexity warnings Minxi Hou
@ 2026-05-15  6:53 ` Aaron Conole
  2026-05-15  8:47   ` 侯敏熙
  5 siblings, 1 reply; 8+ messages in thread
From: Aaron Conole @ 2026-05-15  6:53 UTC (permalink / raw)
  To: Minxi Hou
  Cc: netdev, dev, linux-kselftest, linux-kernel, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah

Minxi Hou <houminxi@gmail.com> writes:

> This series cleans up all pylint warnings in ovs-dpctl.py,
> bringing the score from 7.62/10 to 10.00/10.
>
> This series applies on top of:
>   [PATCH net-next v10 1/2] selftests: openvswitch: add vlan() and
>   encap() flow string parsing
>   https://lore.kernel.org/netdev/20260512070841.1183581-2-houminxi@gmail.com/
>
> Patch 1 converts 86 %-format strings to f-strings.
> Patch 2 fixes misc warnings (unused import, bare except, unused
> variables, redundant expressions).
> Patch 3 renames classes to PascalCase and variables to snake_case.
> Patch 4 adds one-line docstrings to all definitions.
> Patch 5 suppresses complexity warnings from pyroute2 constraints.
>
> Tested with vng on x86_64, all OVS selftests pass.
>
> Minxi Hou (5):
>   selftests: openvswitch: convert %-formatting to f-strings
>   selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py
>   selftests: openvswitch: rename classes and variables in ovs-dpctl.py
>   selftests: openvswitch: add missing docstrings in ovs-dpctl.py
>   selftests: openvswitch: suppress pylint complexity warnings
>
>  .../selftests/net/openvswitch/ovs-dpctl.py    | 794 ++++++++++--------
>  1 file changed, 428 insertions(+), 366 deletions(-)

Thinking about this series, it might be better to go a bit further and
just drop the pyroute2 in favor of using ynl to generate the netlink
encode/decode.  The value that ovs-dpctl.py brings is the ability to
interoperate with the ovs-vswitchd odp encoding.  That we are using
pyroute2 to do the actual 'wire' format of netlink is incidental.

Some of the work would still be needed (I think some of the f-string
adjustments) but that would allow trimming a good chunk of the code and
let us just rely on the in-tree ynl rather than pyroute2 dependency.

WDYT?  Ilya and I can work with you offline if you are interested in
pursuing this approach.  I think it should make the overall code much
better to work with, too.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py
  2026-05-15  6:53 ` [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Aaron Conole
@ 2026-05-15  8:47   ` 侯敏熙
  0 siblings, 0 replies; 8+ messages in thread
From: 侯敏熙 @ 2026-05-15  8:47 UTC (permalink / raw)
  To: Aaron Conole
  Cc: netdev, dev, linux-kselftest, linux-kernel, echaudro, i.maximets,
	i.maximets, davem, edumazet, kuba, pabeni, horms, shuah

Hello Aaron

Thanks for the suggestion, Aaron.  I dug into this a bit and I think
it's worth doing.

The good news is that 3 of 4 OVS families already have ynl specs
in-tree (ovs_datapath, ovs_flow, ovs_vport).  The flow spec is pretty
thorough -- covers all the key/action/tunnel nested attrs.  pyynl
handles genetlink, dump, and nested encode/decode, so the library side
looks solid.  There's even an OVS C sample under tools/net/ynl/samples/.

Gaps I found:

  - No ovs_packet.yaml spec.  We'd need to write one for upcall
    handling (MISS/ACTION/EXECUTE).  Shouldn't be too bad, maybe
    100 lines based on the other specs.

  - The existing specs are missing a few operation defs (flow DEL/SET,
    vport SET, datapath SET).  Small additions.

  - ovs-dpctl.py also uses pyroute2.iproute for tunnel interface
    creation and NDB for interface lookup.  Those aren't OVS netlink,
    so we'd either keep a minimal pyroute2 dep for just that or
    shell out to `ip`.

  - The ODP string parser (~1500 lines for flow key/action encoding)
    is orthogonal to the netlink wire format, so that stays regardless.

I think the natural order would be: start with datapath ops (simplest,
spec already complete), then vport, then flow (bulk of the work), then
packet/upcall after writing the spec.  The f-string fixes from my
current series still apply.

Minxi

Aaron Conole <aconole@redhat.com> 于2026年5月15日周五 14:53写道:
>
> Minxi Hou <houminxi@gmail.com> writes:
>
> > This series cleans up all pylint warnings in ovs-dpctl.py,
> > bringing the score from 7.62/10 to 10.00/10.
> >
> > This series applies on top of:
> >   [PATCH net-next v10 1/2] selftests: openvswitch: add vlan() and
> >   encap() flow string parsing
> >   https://lore.kernel.org/netdev/20260512070841.1183581-2-houminxi@gmail.com/
> >
> > Patch 1 converts 86 %-format strings to f-strings.
> > Patch 2 fixes misc warnings (unused import, bare except, unused
> > variables, redundant expressions).
> > Patch 3 renames classes to PascalCase and variables to snake_case.
> > Patch 4 adds one-line docstrings to all definitions.
> > Patch 5 suppresses complexity warnings from pyroute2 constraints.
> >
> > Tested with vng on x86_64, all OVS selftests pass.
> >
> > Minxi Hou (5):
> >   selftests: openvswitch: convert %-formatting to f-strings
> >   selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py
> >   selftests: openvswitch: rename classes and variables in ovs-dpctl.py
> >   selftests: openvswitch: add missing docstrings in ovs-dpctl.py
> >   selftests: openvswitch: suppress pylint complexity warnings
> >
> >  .../selftests/net/openvswitch/ovs-dpctl.py    | 794 ++++++++++--------
> >  1 file changed, 428 insertions(+), 366 deletions(-)
>
> Thinking about this series, it might be better to go a bit further and
> just drop the pyroute2 in favor of using ynl to generate the netlink
> encode/decode.  The value that ovs-dpctl.py brings is the ability to
> interoperate with the ovs-vswitchd odp encoding.  That we are using
> pyroute2 to do the actual 'wire' format of netlink is incidental.
>
> Some of the work would still be needed (I think some of the f-string
> adjustments) but that would allow trimming a good chunk of the code and
> let us just rely on the in-tree ynl rather than pyroute2 dependency.
>
> WDYT?  Ilya and I can work with you offline if you are interested in
> pursuing this approach.  I think it should make the overall code much
> better to work with, too.
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-05-15  8:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 12:12 [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Minxi Hou
2026-05-13 12:12 ` [PATCH net-next 1/5] selftests: openvswitch: convert %-formatting to f-strings Minxi Hou
2026-05-13 12:12 ` [PATCH net-next 2/5] selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py Minxi Hou
2026-05-13 12:12 ` [PATCH net-next 3/5] selftests: openvswitch: rename classes and variables " Minxi Hou
2026-05-13 12:12 ` [PATCH net-next 4/5] selftests: openvswitch: add missing docstrings " Minxi Hou
2026-05-13 12:12 ` [PATCH net-next 5/5] selftests: openvswitch: suppress pylint complexity warnings Minxi Hou
2026-05-15  6:53 ` [PATCH net-next 0/5] selftests: openvswitch: pylint cleanup for ovs-dpctl.py Aaron Conole
2026-05-15  8:47   ` 侯敏熙

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox