Add one-line docstrings to the module and all classes and methods that pylint flags with C0114, C0115, and C0116 (87 instances). Each docstring describes the command or attribute group the code actually implements.
Signed-off-by: Minxi Hou <[email protected]> --- .../selftests/net/openvswitch/ovs-dpctl.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py index 502e6eb4c4b4a..dc88cb1b20c13 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 a flags string into bit and mask values.""" bitResult = 0 maskResult = 0 @@ -158,6 +164,7 @@ def parse_flags(flag_str, flag_vals): def parse_ct_state(statestr): + """Parse a conntrack state string into flag bits.""" ct_flags = { "new": 1 << 0, "est": 1 << 1, @@ -173,6 +180,7 @@ def parse_ct_state(statestr): def convert_mac(data): + """Convert a MAC address string with optional mask to a bytes pair.""" 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 an IPv4 address/mask string to an integer tuple.""" 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 an IPv6 address/mask string to a packed bytes tuple.""" 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 parser for fixed-width integers with optional mask.""" 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 for and optionally consume a prefix in block_str.""" 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 and convert one field from a flow string.""" if fieldstr and not block_str.startswith(fieldstr): return block_str, defval @@ -349,6 +362,7 @@ def parse_attrs(actstr, attr_desc): class ovs_dp_msg(genlmsg): + """Datapath generic netlink message with OVS version and dpifindex.""" # 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 ovs_dp_msg(genlmsg): class ovsactions(nla): + """OVS action attribute list (OVS_ACTION_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -399,6 +414,7 @@ class ovsactions(nla): ) class psample(nla): + """psample action attributes (OVS_PSAMPLE_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -408,6 +424,7 @@ class ovsactions(nla): ) def dpstr(self, more=False): + """Format the psample action as a dpctl string.""" args = f"group={int(self.get_attr('OVS_PSAMPLE_ATTR_GROUP'))}" cookie = self.get_attr("OVS_PSAMPLE_ATTR_COOKIE") @@ -417,6 +434,7 @@ class ovsactions(nla): return f"psample({args})" def parse(self, actstr): + """Parse a psample() action string.""" desc = ( ("group", "OVS_PSAMPLE_ATTR_GROUP", int), ("cookie", "OVS_PSAMPLE_ATTR_COOKIE", @@ -431,9 +449,11 @@ class ovsactions(nla): return actstr class push_vlan(nla): + """push_vlan action attributes (vlan_tpid/vlan_tci).""" fields = (("vlan_tpid", "!H"), ("vlan_tci", "!H")) class sample(nla): + """Sample action attributes (OVS_SAMPLE_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -443,6 +463,7 @@ class ovsactions(nla): ) def dpstr(self, more=False): + """Format the sample action as a dpctl string.""" args = [] prob = 100 * self.get_attr( @@ -456,6 +477,7 @@ class ovsactions(nla): return f"sample({','.join(args)})" def parse(self, actstr): + """Parse a sample() action string.""" def parse_nested_actions(actstr): subacts = ovsactions() parsed_len = subacts.parse(actstr) @@ -477,6 +499,7 @@ class ovsactions(nla): return actstr class ctact(nla): + """Conntrack action attributes (OVS_CT_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -493,6 +516,7 @@ class ovsactions(nla): ) class natattr(nla): + """NAT attributes for the conntrack action (OVS_NAT_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -509,6 +533,7 @@ class ovsactions(nla): ) def dpstr(self, more=False): + """Format the NAT attributes as a dpctl string.""" print_str = "nat(" if self.get_attr("OVS_NAT_ATTR_SRC"): @@ -547,6 +572,7 @@ class ovsactions(nla): return print_str def dpstr(self, more=False): + """Format the conntrack action as a dpctl string.""" print_str = "ct(" if self.get_attr("OVS_CT_ATTR_COMMIT") is not None: @@ -568,6 +594,7 @@ class ovsactions(nla): return print_str class userspace(nla): + """Userspace action attributes (OVS_USERSPACE_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -578,6 +605,7 @@ class ovsactions(nla): ) def dpstr(self, more=False): + """Format the userspace action as a dpctl string.""" print_str = "userspace(" if self.get_attr("OVS_USERSPACE_ATTR_PID") is not None: print_str += f"pid={int(self.get_attr('OVS_USERSPACE_ATTR_PID'))}," @@ -593,6 +621,7 @@ class ovsactions(nla): return print_str def parse(self, actstr): + """Parse a userspace() action string.""" attrs_desc = ( ("pid", "OVS_USERSPACE_ATTR_PID", int), ("userdata", "OVS_USERSPACE_ATTR_USERDATA", @@ -607,6 +636,7 @@ class ovsactions(nla): return actstr def dpstr(self, more=False): + """Format the action list as a dpctl string.""" print_str = "" for field in self["attrs"]: @@ -675,6 +705,7 @@ class ovsactions(nla): return print_str def parse(self, actstr): + """Parse a dpctl action string into attributes.""" totallen = len(actstr) while len(actstr) != 0: parsed = False @@ -971,6 +1002,7 @@ ovsactions.dec_ttl.actions = ovsactions class ovskey(nla): + """OVS flow key attributes (OVS_KEY_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( ("OVS_KEY_ATTR_UNSPEC", "none"), @@ -1009,6 +1041,7 @@ class ovskey(nla): ) class ovs_key_proto(nla): + """Base class for protocol-specific flow key fields.""" fields = ( ("src", "!H"), ("dst", "!H"), @@ -1041,6 +1074,7 @@ class ovskey(nla): ) def parse(self, flowstr, typeInst): + """Parse this protocol's key and mask fields from a flow string.""" if not flowstr.startswith(self.proto_str): return None, None @@ -1082,6 +1116,7 @@ class ovskey(nla): return flowstr, k, m def dpstr(self, masked=None, more=False): + """Format this protocol's key fields as a dpctl string.""" outstr = f"{self.proto_str}(" first = False for f in self.fields_map: @@ -1110,6 +1145,7 @@ class ovskey(nla): return outstr class ethaddr(ovs_key_proto): + """Ethernet address flow key (OVS_KEY_ATTR_ETHERNET).""" fields = ( ("src", "!6s"), ("dst", "!6s"), @@ -1151,6 +1187,7 @@ class ovskey(nla): ) class ovs_key_ipv4(ovs_key_proto): + """IPv4 flow key (OVS_KEY_ATTR_IPV4).""" fields = ( ("src", "!I"), ("dst", "!I"), @@ -1204,6 +1241,7 @@ class ovskey(nla): ) class ovs_key_ipv6(ovs_key_proto): + """IPv6 flow key (OVS_KEY_ATTR_IPV6).""" fields = ( ("src", "!16s"), ("dst", "!16s"), @@ -1260,6 +1298,7 @@ class ovskey(nla): ) class ovs_key_tcp(ovs_key_proto): + """TCP port flow key (OVS_KEY_ATTR_TCP).""" def __init__( self, data=None, @@ -1279,6 +1318,7 @@ class ovskey(nla): ) class ovs_key_udp(ovs_key_proto): + """UDP port flow key (OVS_KEY_ATTR_UDP).""" def __init__( self, data=None, @@ -1298,6 +1338,7 @@ class ovskey(nla): ) class ovs_key_sctp(ovs_key_proto): + """SCTP port flow key (OVS_KEY_ATTR_SCTP).""" def __init__( self, data=None, @@ -1317,6 +1358,7 @@ class ovskey(nla): ) class ovs_key_icmp(ovs_key_proto): + """ICMP flow key (OVS_KEY_ATTR_ICMP).""" fields = ( ("type", "B"), ("code", "B"), @@ -1348,6 +1390,7 @@ class ovskey(nla): ) class ovs_key_icmpv6(ovs_key_icmp): + """ICMPv6 flow key (OVS_KEY_ATTR_ICMPV6).""" def __init__( self, data=None, @@ -1367,6 +1410,7 @@ class ovskey(nla): ) class ovs_key_arp(ovs_key_proto): + """ARP flow key (OVS_KEY_ATTR_ARP).""" fields = ( ("sip", "!I"), ("tip", "!I"), @@ -1427,6 +1471,7 @@ class ovskey(nla): ) class ovs_key_nd(ovs_key_proto): + """IPv6 Neighbor Discovery flow key (OVS_KEY_ATTR_ND).""" fields = ( ("target", "!16s"), ("sll", "!6s"), @@ -1463,6 +1508,7 @@ class ovskey(nla): ) class ovs_key_ct_tuple_ipv4(ovs_key_proto): + """IPv4 conntrack tuple key (OVS_KEY_ATTR_CT_TUPLE_IPV4).""" fields = ( ("src", "!I"), ("dst", "!I"), @@ -1510,6 +1556,7 @@ class ovskey(nla): ) class ovs_key_ct_tuple_ipv6(nla): + """IPv6 conntrack tuple key (OVS_KEY_ATTR_CT_TUPLE_IPV6).""" fields = ( ("src", "!16s"), ("dst", "!16s"), @@ -1555,6 +1602,7 @@ class ovskey(nla): ) class ovs_key_tunnel(nla): + """Tunnel flow key attributes (OVS_TUNNEL_KEY_ATTR_*).""" nla_flags = NLA_F_NESTED nla_map = ( @@ -1578,6 +1626,7 @@ class ovskey(nla): ) def parse(self, flowstr, mask=None): + """Parse a tunnel() key string.""" if not flowstr.startswith("tunnel("): return None, None @@ -1670,6 +1719,7 @@ class ovskey(nla): return flowstr, k, mask def dpstr(self, mask=None, more=False): + """Format the tunnel key as a dpctl string.""" print_str = "tunnel(" flagsattrs = [] @@ -1712,6 +1762,7 @@ class ovskey(nla): return print_str class ovs_key_mpls(nla): + """MPLS flow key (OVS_KEY_ATTR_MPLS).""" fields = (("lse", ">I"),) # 802.1Q CFI (Canonical Format Indicator) bit, always set for Ethernet @@ -1901,6 +1952,7 @@ class ovskey(nla): return flowstr, inner_key, inner_mask def parse(self, flowstr, mask=None): + """Parse a flow key string into key and mask attributes.""" for field in ( ("OVS_KEY_ATTR_PRIORITY", "skb_priority", intparse), ("OVS_KEY_ATTR_SKB_MARK", "skb_mark", intparse), @@ -1997,6 +2049,7 @@ class ovskey(nla): return flowstr def dpstr(self, mask=None, more=False): + """Format the flow key as a dpctl string.""" print_str = "" for field in ( @@ -2166,11 +2219,13 @@ class encap_ovskey(ovskey): class OvsPacket(GenericNetlinkSocket): + """OVS packet command socket (miss/action/execute upcalls).""" 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 ovs_packet_msg(ovs_dp_msg): + """Packet command message attributes (OVS_PACKET_ATTR_*).""" nla_map = ( ("OVS_PACKET_ATTR_UNSPEC", "none"), ("OVS_PACKET_ATTR_PACKET", "array(uint8)"), @@ -2191,6 +2246,7 @@ class OvsPacket(GenericNetlinkSocket): self.bind(OVS_PACKET_FAMILY, OvsPacket.ovs_packet_msg) def upcall_handler(self, up=None): + """Listen for packet upcalls and dispatch them to the handler.""" print("listening on upcall packet handler:", self.epid) while True: try: @@ -2211,6 +2267,7 @@ class OvsPacket(GenericNetlinkSocket): class OvsDatapath(GenericNetlinkSocket): + """OVS datapath command socket (create/destroy/lookup).""" OVS_DP_F_VPORT_PIDS = 1 << 1 OVS_DP_F_DISPATCH_UPCALL_PER_CPU = 1 << 3 @@ -2232,6 +2289,7 @@ class OvsDatapath(GenericNetlinkSocket): ) class dpstats(nla): + """Datapath statistics (OVS_DP_ATTR_STATS).""" fields = ( ("hit", "=Q"), ("missed", "=Q"), @@ -2240,6 +2298,7 @@ class OvsDatapath(GenericNetlinkSocket): ) class megaflowstats(nla): + """Datapath megaflow statistics (OVS_DP_ATTR_MEGAFLOW_STATS).""" fields = ( ("mask_hit", "=Q"), ("masks", "=I"), @@ -2253,6 +2312,7 @@ class OvsDatapath(GenericNetlinkSocket): self.bind(OVS_DATAPATH_FAMILY, OvsDatapath.dp_cmd_msg) def info(self, dpname, ifindex=0): + """Look up a datapath by name.""" msg = OvsDatapath.dp_cmd_msg() msg["cmd"] = OVS_DP_CMD_GET msg["version"] = OVS_DATAPATH_VERSION @@ -2276,6 +2336,7 @@ class OvsDatapath(GenericNetlinkSocket): def create( self, dpname, shouldUpcall=False, versionStr=None, p=OvsPacket() ): + """Create a new datapath.""" msg = OvsDatapath.dp_cmd_msg() msg["cmd"] = OVS_DP_CMD_NEW if versionStr is None: @@ -2317,6 +2378,7 @@ class OvsDatapath(GenericNetlinkSocket): return reply def destroy(self, dpname): + """Destroy a datapath.""" msg = OvsDatapath.dp_cmd_msg() msg["cmd"] = OVS_DP_CMD_DEL msg["version"] = OVS_DATAPATH_VERSION @@ -2339,10 +2401,12 @@ class OvsDatapath(GenericNetlinkSocket): class OvsVport(GenericNetlinkSocket): + """OVS vport command socket (attach/detach/lookup).""" OVS_VPORT_TYPE_NETDEV = 1 OVS_VPORT_TYPE_INTERNAL = 2 class ovs_vport_msg(ovs_dp_msg): + """Vport command message attributes (OVS_VPORT_ATTR_*).""" nla_map = ( ("OVS_VPORT_ATTR_UNSPEC", "none"), ("OVS_VPORT_ATTR_PORT_NO", "uint32"), @@ -2357,6 +2421,7 @@ class OvsVport(GenericNetlinkSocket): ) class vportstats(nla): + """Vport statistics (OVS_VPORT_ATTR_STATS).""" fields = ( ("rx_packets", "=Q"), ("tx_packets", "=Q"), @@ -2370,6 +2435,7 @@ class OvsVport(GenericNetlinkSocket): @staticmethod def type_to_str(vport_type): + """Convert a vport type constant to its string name.""" if vport_type == OvsVport.OVS_VPORT_TYPE_NETDEV: return "netdev" if vport_type == OvsVport.OVS_VPORT_TYPE_INTERNAL: @@ -2379,6 +2445,7 @@ class OvsVport(GenericNetlinkSocket): @staticmethod def str_to_type(vport_type): + """Convert a vport type string to its constant.""" if vport_type in ["netdev", "gre", "vxlan", "geneve"]: return OvsVport.OVS_VPORT_TYPE_NETDEV if vport_type == "internal": @@ -2392,6 +2459,7 @@ class OvsVport(GenericNetlinkSocket): self.upcall_packet = packet def info(self, vport_name, dpifindex=0, portno=None): + """Get info about a vport.""" msg = OvsVport.ovs_vport_msg() msg["cmd"] = OVS_VPORT_CMD_GET @@ -2417,6 +2485,7 @@ class OvsVport(GenericNetlinkSocket): return reply def attach(self, dpindex, vport_ifname, ptype, dport): + """Create a vport and attach it to a datapath.""" msg = OvsVport.ovs_vport_msg() msg["cmd"] = OVS_VPORT_CMD_NEW @@ -2470,6 +2539,7 @@ class OvsVport(GenericNetlinkSocket): return reply def reset_upcall(self, dpindex, vport_ifname, p=None): + """Reset a vport's upcall pid.""" msg = OvsVport.ovs_vport_msg() msg["cmd"] = OVS_VPORT_CMD_SET @@ -2495,6 +2565,7 @@ class OvsVport(GenericNetlinkSocket): return reply def detach(self, dpindex, vport_ifname): + """Remove a vport from a datapath.""" msg = OvsVport.ovs_vport_msg() msg["cmd"] = OVS_VPORT_CMD_DEL @@ -2516,11 +2587,14 @@ class OvsVport(GenericNetlinkSocket): return reply def upcall_handler(self, handler=None): + """Delegate upcall handling to the packet socket.""" self.upcall_packet.upcall_handler(handler) class OvsFlow(GenericNetlinkSocket): + """OVS flow command socket (add/modify/delete/dump flows).""" class ovs_flow_msg(ovs_dp_msg): + """Flow command message attributes (OVS_FLOW_ATTR_*).""" nla_map = ( ("OVS_FLOW_ATTR_UNSPEC", "none"), ("OVS_FLOW_ATTR_KEY", "ovskey"), @@ -2536,12 +2610,14 @@ class OvsFlow(GenericNetlinkSocket): ) class flowstats(nla): + """Flow statistics (OVS_FLOW_ATTR_STATS).""" fields = ( ("packets", "=Q"), ("bytes", "=Q"), ) def dpstr(self, more=False): + """Format the flow message as a dpctl string.""" ufid = self.get_attr("OVS_FLOW_ATTR_UFID") ufid_str = "" if ufid is not None: @@ -2608,6 +2684,7 @@ class OvsFlow(GenericNetlinkSocket): return print_str def parse(self, flowstr, actstr, dpidx=0): + """Parse flow and action strings into a flow message.""" OVS_UFID_F_OMIT_KEY = 1 << 0 OVS_UFID_F_OMIT_MASK = 1 << 1 OVS_UFID_F_OMIT_ACTIONS = 1 << 2 @@ -2772,6 +2849,7 @@ class OvsFlow(GenericNetlinkSocket): return rep def miss(self, packetmsg): + """Handle a flow-table miss upcall.""" seq = packetmsg["header"]["sequence_number"] keystr = "(none)" key_field = packetmsg.get_attr("OVS_PACKET_ATTR_KEY") @@ -2784,13 +2862,16 @@ class OvsFlow(GenericNetlinkSocket): print(f"MISS upcall[{int(seq)}/{pktpres}]: {keystr}", flush=True) def execute(self, packetmsg): + """Handle a userspace execute upcall.""" print("userspace execute command", flush=True) def action(self, packetmsg): + """Handle a userspace action upcall.""" print("userspace action command", flush=True) class psample_sample(genlmsg): + """psample sample event message (PSAMPLE_ATTR_*).""" nla_map = ( ("PSAMPLE_ATTR_IIFINDEX", "none"), ("PSAMPLE_ATTR_OIFINDEX", "none"), @@ -2811,6 +2892,7 @@ class psample_sample(genlmsg): ) def dpstr(self): + """Format the psample event as a string.""" fields = [] data = "" for (attr, value) in self["attrs"]: @@ -2828,6 +2910,7 @@ class psample_sample(genlmsg): class psample_msg(Marshal): + """psample generic netlink message marshaller.""" PSAMPLE_CMD_SAMPLE = 0 PSAMPLE_CMD_GET_GROUP = 1 PSAMPLE_CMD_NEW_GROUP = 2 @@ -2837,11 +2920,13 @@ class psample_msg(Marshal): class PsampleEvent(EventSocket): + """Socket listening for psample multicast events.""" genl_family = "psample" mcast_groups = ["packets"] marshal_class = psample_msg def read_samples(self): + """Print psample events as they arrive.""" print("listening for psample events", flush=True) while True: try: @@ -2852,6 +2937,7 @@ class PsampleEvent(EventSocket): def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()): + """Print full datapath state: stats, vports, and flows.""" 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") @@ -2887,6 +2973,7 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()): def main(argv): + """Entry point: parse arguments and run the ovs-dpctl command.""" nlmsg_atoms.encap_ovskey = encap_ovskey nlmsg_atoms.ovskey = ovskey nlmsg_atoms.ovsactions = ovsactions -- 2.55.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
