From nobody Fri Jun 16 15:34:03 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QjNVh4WPkz4d954; Fri, 16 Jun 2023 15:34:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QjNVh0h0yz4Gkm; Fri, 16 Jun 2023 15:34:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686929644; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=V7kU8U1dPCfruFQWwyb2oAWQW7VSJsBUGJt3oIRDjqg=; b=ABg3QAsQvNbjr1XSVUW+n9B+z+nckgAXvzcWm0WxDW3+nmx2fjTc7ItHS/KBDZQmcFRsns fR+8Iw80seOzilkHgZRo9xR6UvdeKuXRQXzu6Gp/9kk58eqVddQS/8dUJsedxITS5ANXTk t9cwFabUyc0WisQLOzSRNSpOK7P+IpKCblR8gJXl5mME1XQrHReg0RBM/+Vl9OXPwoAcLt OVxaairi4z+qJwTJrr4z5J5qYNUO3neBTFH8Zinc1cibGFlQJ6+3+NbF/Do4fUHwm6vcLy rWgzfvHPubUwGJ6TPTYIwQaAuhxEPgCtb4zsRIpIU7mCTtoiFD82BDxBtqJH4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686929644; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=V7kU8U1dPCfruFQWwyb2oAWQW7VSJsBUGJt3oIRDjqg=; b=RbRRYXz8HgjMW7Y/Bjm9BtzKEix7WxSd/K6455hIZyor7cGwpw6vFoAcRlm8We25JHTV8U JTc0YaFsYJqNkWGXUgbPyLtMDOJy8LohaQl+p8+OD2adyNXga1dSvhiDcxapX1/DSzvzae KtRj0OSJzMILBCCDV6uNDbFJ4wkzewnRfQBIPXlHzFQrY+9ZEcB4qnuFdNHVwbytGOBePq AHOVqBY0aZ/e4T+BgfIrbEUDmh2oTXGzx9CjQfcZddh6XAstFrZziovr4VIE2gx7rnpw/y Q1vSpJQAMrHtThQv7hbeikLIc5m366y8TJT7BkSdGpyoNL70f8uZtS/pWZw9lg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1686929644; a=rsa-sha256; cv=none; b=FCsJusVBtJqwgnbvwXWOZF1H09XAPXruwL+cgHEI5w2eMUz6C1w7Ou9+o30MDvZQfML0/j hCc2DnqYmUf1A4udQKF5JGU2x0bCfNkXLUGjvJH5r0tfd3TYlwpoMJbJxSGpi+qFfRTz+C 8heoX2MI6jehT8qbOZmkAqu0UfGA7fzJYeaXpUvqzFv1xC/6PB0gQVQKJWgGyN6hJh5Wky ynzGGHz67EWBaMu86EoefjM3PLaIwCHsP0hGtFwsBph7BFBVXagia40rZRTyZ7si0BdrzL Hk4OtqZnCXmILxVZ+ZuVZP3zTr43OohEGug/WAyhBdsfrT9bkSpoWpouZ8BR8g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QjNVg6pPvzYJQ; Fri, 16 Jun 2023 15:34:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 35GFY3T3057076; Fri, 16 Jun 2023 15:34:03 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 35GFY38a057075; Fri, 16 Jun 2023 15:34:03 GMT (envelope-from git) Date: Fri, 16 Jun 2023 15:34:03 GMT Message-Id: <202306161534.35GFY38a057075@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Alexander V. Chernikov" Subject: git: c344eff91070 - main - netlink: dump interface capabilities with other interface data. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: melifaro X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c344eff91070ccb15e81baf7897224882b417ae4 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=c344eff91070ccb15e81baf7897224882b417ae4 commit c344eff91070ccb15e81baf7897224882b417ae4 Author: Alexander V. Chernikov AuthorDate: 2023-06-16 14:56:39 +0000 Commit: Alexander V. Chernikov CommitDate: 2023-06-16 15:33:49 +0000 netlink: dump interface capabilities with other interface data. This change exports interface capabilities using the standard Netlink attribute type, bitset, and switches `ifconfig(8)` to use it when displaying interface data. Bitset comes in two representations. The first one is "compact", where the bits are exported via two arrays - "mask" listing the "valid" bits and "values, providing the values for those bits. The second one is more verbose, listing each bit as a separate item, with its name, id and value. The latter option is handy when submitting update requests. The support for setting capabilities will be added in the upcoming diffs. Differential Revision: https://reviews.freebsd.org/D40331 --- sbin/ifconfig/ifconfig.c | 6 +- sbin/ifconfig/ifconfig.h | 1 - sbin/ifconfig/ifconfig_netlink.c | 26 +++++- sys/net/if.c | 1 + sys/net/if.h | 146 +++++++++++++++++--------------- sys/net/if_strings.h | 106 +++++++++++++++++++++++ sys/netlink/netlink_bitset.h | 57 +++++++++++++ sys/netlink/netlink_route.h | 1 + sys/netlink/netlink_snl.h | 88 ++++++++++++++++++- sys/netlink/netlink_snl_route_parsers.h | 2 + sys/netlink/route/iface.c | 28 ++++++ sys/netlink/route/interface.h | 1 + 12 files changed, 390 insertions(+), 73 deletions(-) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index f3d16fc052f6..fa22f09f8100 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -55,6 +55,7 @@ static const char rcsid[] = #include #include #include +#include #include #include @@ -1585,6 +1586,8 @@ unsetifdescr(if_ctx *ctx, const char *val __unused, int value __unused) setifdescr(ctx, "", 0); } +#ifdef WITHOUT_NETLINK + #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ @@ -1656,7 +1659,7 @@ print_ifcap_nv(if_ctx *ctx) Perror("ioctl (SIOCGIFCAP)"); } -void +static void print_ifcap(if_ctx *ctx) { struct ifreq ifr = {}; @@ -1675,6 +1678,7 @@ print_ifcap(if_ctx *ctx) } } } +#endif void print_ifstatus(if_ctx *ctx) diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index c97ef447a3b3..e33a2c63aec1 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -275,7 +275,6 @@ bool match_ether(const struct sockaddr_dl *sdl); bool match_if_flags(struct ifconfig_args *args, int if_flags); int ifconfig_ioctl(if_ctx *ctx, int iscreate, const struct afswtch *uafp); bool group_member(const char *ifname, const char *match, const char *nomatch); -void print_ifcap(if_ctx *ctx); void tunnel_status(if_ctx *ctx); struct afswtch *af_getbyfamily(int af); void af_other_status(if_ctx *ctx); diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c index 2460d8c60109..f09023c1477c 100644 --- a/sbin/ifconfig/ifconfig_netlink.c +++ b/sbin/ifconfig/ifconfig_netlink.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "ifconfig.h" #include "ifconfig_netlink.h" @@ -343,6 +344,28 @@ sort_iface_ifaddrs(struct snl_state *ss, struct iface *iface) } } +static void +print_ifcaps(if_ctx *ctx, if_link_t *link) +{ + uint32_t sz_u32 = roundup2(link->iflaf_caps.nla_bitset_size, 32) / 32; + + if (sz_u32 > 0) { + uint32_t *caps = link->iflaf_caps.nla_bitset_value; + + printf("\toptions=%x", caps[0]); + print_bits("IFCAPS", caps, sz_u32, ifcap_bit_names, nitems(ifcap_bit_names)); + putchar('\n'); + } + + if (ctx->args->supmedia && sz_u32 > 0) { + uint32_t *caps = link->iflaf_caps.nla_bitset_mask; + + printf("\tcapabilities=%x", caps[0]); + print_bits("IFCAPS", caps, sz_u32, ifcap_bit_names, nitems(ifcap_bit_names)); + putchar('\n'); + } +} + static void status_nl(if_ctx *ctx, struct iface *iface) { @@ -360,8 +383,7 @@ status_nl(if_ctx *ctx, struct iface *iface) if (link->ifla_ifalias != NULL) printf("\tdescription: %s\n", link->ifla_ifalias); - /* TODO: convert to netlink */ - print_ifcap(ctx); + print_ifcaps(ctx, link); tunnel_status(ctx); if (args->allfamilies | (args->afp != NULL && args->afp->af_af == AF_LINK)) { diff --git a/sys/net/if.c b/sys/net/if.c index 975f4498073e..c5f0a65721fc 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include diff --git a/sys/net/if.h b/sys/net/if.h index 4003b33e5de4..bd2787516f01 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -221,42 +221,86 @@ struct if_data { * to do the right thing. However, having the filter here * avoids replication of the same code in all individual drivers. */ -#define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */ -#define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */ -#define IFCAP_NETCONS 0x00004 /* can be a network console */ -#define IFCAP_VLAN_MTU 0x00008 /* VLAN-compatible MTU */ -#define IFCAP_VLAN_HWTAGGING 0x00010 /* hardware VLAN tag support */ -#define IFCAP_JUMBO_MTU 0x00020 /* 9000 byte MTU supported */ -#define IFCAP_POLLING 0x00040 /* driver supports polling */ -#define IFCAP_VLAN_HWCSUM 0x00080 /* can do IFCAP_HWCSUM on VLANs */ -#define IFCAP_TSO4 0x00100 /* can do TCP Segmentation Offload */ -#define IFCAP_TSO6 0x00200 /* can do TCP6 Segmentation Offload */ -#define IFCAP_LRO 0x00400 /* can do Large Receive Offload */ -#define IFCAP_WOL_UCAST 0x00800 /* wake on any unicast frame */ -#define IFCAP_WOL_MCAST 0x01000 /* wake on any multicast frame */ -#define IFCAP_WOL_MAGIC 0x02000 /* wake on any Magic Packet */ -#define IFCAP_TOE4 0x04000 /* interface can offload TCP */ -#define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */ -#define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ -#define IFCAP_NV 0x20000 /* can do SIOCGIFCAPNV/SIOCSIFCAPNV */ -#define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */ -#define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */ -#define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */ -#define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */ -#define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */ -#define IFCAP_HWSTATS 0x800000 /* manages counters internally */ -#define IFCAP_TXRTLMT 0x1000000 /* hardware supports TX rate limiting */ -#define IFCAP_HWRXTSTMP 0x2000000 /* hardware rx timestamping */ -#define IFCAP_MEXTPG 0x4000000 /* understands M_EXTPG mbufs */ -#define IFCAP_TXTLS4 0x8000000 /* can do TLS encryption and segmentation for TCP */ -#define IFCAP_TXTLS6 0x10000000 /* can do TLS encryption and segmentation for TCP6 */ -#define IFCAP_VXLAN_HWCSUM 0x20000000 /* can do IFCAN_HWCSUM on VXLANs */ -#define IFCAP_VXLAN_HWTSO 0x40000000 /* can do IFCAP_TSO on VXLANs */ -#define IFCAP_TXTLS_RTLMT 0x80000000 /* can do TLS with rate limiting */ + +/* IFCAP values as bit indexes */ + +#define IFCAP_B_RXCSUM 0 /* can offload checksum on RX */ +#define IFCAP_B_TXCSUM 1 /* can offload checksum on TX */ +#define IFCAP_B_NETCONS 2 /* can be a network console */ +#define IFCAP_B_VLAN_MTU 3 /* VLAN-compatible MTU */ +#define IFCAP_B_VLAN_HWTAGGING 4 /* hardware VLAN tag support */ +#define IFCAP_B_JUMBO_MTU 5 /* 9000 byte MTU supported */ +#define IFCAP_B_POLLING 6 /* driver supports polling */ +#define IFCAP_B_VLAN_HWCSUM 7 /* can do IFCAP_HWCSUM on VLANs */ +#define IFCAP_B_TSO4 8 /* can do TCP Segmentation Offload */ +#define IFCAP_B_TSO6 9 /* can do TCP6 Segmentation Offload */ +#define IFCAP_B_LRO 10 /* can do Large Receive Offload */ +#define IFCAP_B_WOL_UCAST 11 /* wake on any unicast frame */ +#define IFCAP_B_WOL_MCAST 12 /* wake on any multicast frame */ +#define IFCAP_B_WOL_MAGIC 13 /* wake on any Magic Packet */ +#define IFCAP_B_TOE4 14 /* interface can offload TCP */ +#define IFCAP_B_TOE6 15 /* interface can offload TCP6 */ +#define IFCAP_B_VLAN_HWFILTER 16 /* interface hw can filter vlan tag */ +#define IFCAP_B_NV 17 /* can do SIOCGIFCAPNV/SIOCSIFCAPNV */ +#define IFCAP_B_VLAN_HWTSO 18 /* can do IFCAP_TSO on VLANs */ +#define IFCAP_B_LINKSTATE 19 /* the runtime link state is dynamic */ +#define IFCAP_B_NETMAP 20 /* netmap mode supported/enabled */ +#define IFCAP_B_RXCSUM_IPV6 21 /* can offload checksum on IPv6 RX */ +#define IFCAP_B_TXCSUM_IPV6 22 /* can offload checksum on IPv6 TX */ +#define IFCAP_B_HWSTATS 23 /* manages counters internally */ +#define IFCAP_B_TXRTLMT 24 /* hardware supports TX rate limiting */ +#define IFCAP_B_HWRXTSTMP 25 /* hardware rx timestamping */ +#define IFCAP_B_MEXTPG 26 /* understands M_EXTPG mbufs */ +#define IFCAP_B_TXTLS4 27 /* can do TLS encryption and segmentation for TCP */ +#define IFCAP_B_TXTLS6 28 /* can do TLS encryption and segmentation for TCP6 */ +#define IFCAP_B_VXLAN_HWCSUM 29 /* can do IFCAN_HWCSUM on VXLANs */ +#define IFCAP_B_VXLAN_HWTSO 30 /* can do IFCAP_TSO on VXLANs */ +#define IFCAP_B_TXTLS_RTLMT 31 /* can do TLS with rate limiting */ +#define IFCAP_B_RXTLS4 32 /* can to TLS receive for TCP */ +#define IFCAP_B_RXTLS6 33 /* can to TLS receive for TCP6 */ +#define __IFCAP_B_SIZE 34 + +#define IFCAP_B_MAX (__IFCAP_B_MAX - 1) +#define IFCAP_B_SIZE (__IFCAP_B_SIZE) + +#define IFCAP_BIT(x) (1 << (x)) + +#define IFCAP_RXCSUM IFCAP_BIT(IFCAP_B_RXCSUM) +#define IFCAP_TXCSUM IFCAP_BIT(IFCAP_B_TXCSUM) +#define IFCAP_NETCONS IFCAP_BIT(IFCAP_B_NETCONS) +#define IFCAP_VLAN_MTU IFCAP_BIT(IFCAP_B_VLAN_MTU) +#define IFCAP_VLAN_HWTAGGING IFCAP_BIT(IFCAP_B_VLAN_HWTAGGING) +#define IFCAP_JUMBO_MTU IFCAP_BIT(IFCAP_B_JUMBO_MTU) +#define IFCAP_POLLING IFCAP_BIT(IFCAP_B_POLLING) +#define IFCAP_VLAN_HWCSUM IFCAP_BIT(IFCAP_B_VLAN_HWCSUM) +#define IFCAP_TSO4 IFCAP_BIT(IFCAP_B_TSO4) +#define IFCAP_TSO6 IFCAP_BIT(IFCAP_B_TSO6) +#define IFCAP_LRO IFCAP_BIT(IFCAP_B_LRO) +#define IFCAP_WOL_UCAST IFCAP_BIT(IFCAP_B_WOL_UCAST) +#define IFCAP_WOL_MCAST IFCAP_BIT(IFCAP_B_WOL_MCAST) +#define IFCAP_WOL_MAGIC IFCAP_BIT(IFCAP_B_WOL_MAGIC) +#define IFCAP_TOE4 IFCAP_BIT(IFCAP_B_TOE4) +#define IFCAP_TOE6 IFCAP_BIT(IFCAP_B_TOE6) +#define IFCAP_VLAN_HWFILTER IFCAP_BIT(IFCAP_B_VLAN_HWFILTER) +#define IFCAP_NV IFCAP_BIT(IFCAP_B_NV) +#define IFCAP_VLAN_HWTSO IFCAP_BIT(IFCAP_B_VLAN_HWTSO) +#define IFCAP_LINKSTATE IFCAP_BIT(IFCAP_B_LINKSTATE) +#define IFCAP_NETMAP IFCAP_BIT(IFCAP_B_NETMAP) +#define IFCAP_RXCSUM_IPV6 IFCAP_BIT(IFCAP_B_RXCSUM_IPV6) +#define IFCAP_TXCSUM_IPV6 IFCAP_BIT(IFCAP_B_TXCSUM_IPV6) +#define IFCAP_HWSTATS IFCAP_BIT(IFCAP_B_HWSTATS) +#define IFCAP_TXRTLMT IFCAP_BIT(IFCAP_B_TXRTLMT) +#define IFCAP_HWRXTSTMP IFCAP_BIT(IFCAP_B_HWRXTSTMP) +#define IFCAP_MEXTPG IFCAP_BIT(IFCAP_B_MEXTPG) +#define IFCAP_TXTLS4 IFCAP_BIT(IFCAP_B_TXTLS4) +#define IFCAP_TXTLS6 IFCAP_BIT(IFCAP_B_TXTLS6) +#define IFCAP_VXLAN_HWCSUM IFCAP_BIT(IFCAP_B_VXLAN_HWCSUM) +#define IFCAP_VXLAN_HWTSO IFCAP_BIT(IFCAP_B_VXLAN_HWTSO) +#define IFCAP_TXTLS_RTLMT IFCAP_BIT(IFCAP_B_TXTLS_RTLMT) /* IFCAP2_* are integers, not bits. */ -#define IFCAP2_RXTLS4 0 -#define IFCAP2_RXTLS6 1 +#define IFCAP2_RXTLS4 (IFCAP_B_RXTLS4 - 32) +#define IFCAP2_RXTLS6 (IFCAP_B_RXTLS6 - 32) #define IFCAP2_BIT(x) (1UL << (x)) @@ -271,40 +315,6 @@ struct if_data { #define IFCAP_CANTCHANGE (IFCAP_NETMAP | IFCAP_NV) #define IFCAP_ALLCAPS 0xffffffff -#define IFCAP_RXCSUM_NAME "RXCSUM" -#define IFCAP_TXCSUM_NAME "TXCSUM" -#define IFCAP_NETCONS_NAME "NETCONS" -#define IFCAP_VLAN_MTU_NAME "VLAN_MTU" -#define IFCAP_VLAN_HWTAGGING_NAME "VLAN_HWTAGGING" -#define IFCAP_JUMBO_MTU_NAME "JUMBO_MTU" -#define IFCAP_POLLING_NAME "POLLING" -#define IFCAP_VLAN_HWCSUM_NAME "VLAN_HWCSUM" -#define IFCAP_TSO4_NAME "TSO4" -#define IFCAP_TSO6_NAME "TSO6" -#define IFCAP_LRO_NAME "LRO" -#define IFCAP_WOL_UCAST_NAME "WOL_UCAST" -#define IFCAP_WOL_MCAST_NAME "WOL_MCAST" -#define IFCAP_WOL_MAGIC_NAME "WOL_MAGIC" -#define IFCAP_TOE4_NAME "TOE4" -#define IFCAP_TOE6_NAME "TOE6" -#define IFCAP_VLAN_HWFILTER_NAME "VLAN_HWFILTER" -#define IFCAP_VLAN_HWTSO_NAME "VLAN_HWTSO" -#define IFCAP_LINKSTATE_NAME "LINKSTATE" -#define IFCAP_NETMAP_NAME "NETMAP" -#define IFCAP_RXCSUM_IPV6_NAME "RXCSUM_IPV6" -#define IFCAP_TXCSUM_IPV6_NAME "TXCSUM_IPV6" -#define IFCAP_HWSTATS_NAME "HWSTATS" -#define IFCAP_TXRTLMT_NAME "TXRTLMT" -#define IFCAP_HWRXTSTMP_NAME "HWRXTSTMP" -#define IFCAP_MEXTPG_NAME "MEXTPG" -#define IFCAP_TXTLS4_NAME "TXTLS4" -#define IFCAP_TXTLS6_NAME "TXTLS6" -#define IFCAP_VXLAN_HWCSUM_NAME "VXLAN_HWCSUM" -#define IFCAP_VXLAN_HWTSO_NAME "VXLAN_HWTSO" -#define IFCAP_TXTLS_RTLMT_NAME "TXTLS_RTLMT" -#define IFCAP2_RXTLS4_NAME "RXTLS4" -#define IFCAP2_RXTLS6_NAME "RXTLS6" - #define IFQ_MAXLEN 50 #define IFNET_SLOWHZ 1 /* granularity is 1 second */ diff --git a/sys/net/if_strings.h b/sys/net/if_strings.h new file mode 100644 index 000000000000..95d85f5370ed --- /dev/null +++ b/sys/net/if_strings.h @@ -0,0 +1,106 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NET_IF_STRINGS_H_ +#define _NET_IF_STRINGS_H_ + +#define IFCAP_RXCSUM_NAME "RXCSUM" +#define IFCAP_TXCSUM_NAME "TXCSUM" +#define IFCAP_NETCONS_NAME "NETCONS" +#define IFCAP_VLAN_MTU_NAME "VLAN_MTU" +#define IFCAP_VLAN_HWTAGGING_NAME "VLAN_HWTAGGING" +#define IFCAP_JUMBO_MTU_NAME "JUMBO_MTU" +#define IFCAP_POLLING_NAME "POLLING" +#define IFCAP_VLAN_HWCSUM_NAME "VLAN_HWCSUM" +#define IFCAP_TSO4_NAME "TSO4" +#define IFCAP_TSO6_NAME "TSO6" +#define IFCAP_LRO_NAME "LRO" +#define IFCAP_WOL_UCAST_NAME "WOL_UCAST" +#define IFCAP_WOL_MCAST_NAME "WOL_MCAST" +#define IFCAP_WOL_MAGIC_NAME "WOL_MAGIC" +#define IFCAP_TOE4_NAME "TOE4" +#define IFCAP_TOE6_NAME "TOE6" +#define IFCAP_VLAN_HWFILTER_NAME "VLAN_HWFILTER" +#define IFCAP_NV_NAME "NV" +#define IFCAP_VLAN_HWTSO_NAME "VLAN_HWTSO" +#define IFCAP_LINKSTATE_NAME "LINKSTATE" +#define IFCAP_NETMAP_NAME "NETMAP" +#define IFCAP_RXCSUM_IPV6_NAME "RXCSUM_IPV6" +#define IFCAP_TXCSUM_IPV6_NAME "TXCSUM_IPV6" +#define IFCAP_HWSTATS_NAME "HWSTATS" +#define IFCAP_TXRTLMT_NAME "TXRTLMT" +#define IFCAP_HWRXTSTMP_NAME "HWRXTSTMP" +#define IFCAP_MEXTPG_NAME "MEXTPG" +#define IFCAP_TXTLS4_NAME "TXTLS4" +#define IFCAP_TXTLS6_NAME "TXTLS6" +#define IFCAP_VXLAN_HWCSUM_NAME "VXLAN_HWCSUM" +#define IFCAP_VXLAN_HWTSO_NAME "VXLAN_HWTSO" +#define IFCAP_TXTLS_RTLMT_NAME "TXTLS_RTLMT" +#define IFCAP_RXTLS4_NAME "RXTLS4" +#define IFCAP_RXTLS6_NAME "RXTLS6" + +#define IFCAP2_RXTLS4_NAME IFCAP_RXTLS4_NAME +#define IFCAP2_RXTLS6_NAME IFCAP_RXTLS6_NAME + +static const char *ifcap_bit_names[] = { + IFCAP_RXCSUM_NAME, + IFCAP_TXCSUM_NAME, + IFCAP_NETCONS_NAME, + IFCAP_VLAN_MTU_NAME, + IFCAP_VLAN_HWTAGGING_NAME, + IFCAP_JUMBO_MTU_NAME, + IFCAP_POLLING_NAME, + IFCAP_VLAN_HWCSUM_NAME, + IFCAP_TSO4_NAME, + IFCAP_TSO6_NAME, + IFCAP_LRO_NAME, + IFCAP_WOL_UCAST_NAME, + IFCAP_WOL_MCAST_NAME, + IFCAP_WOL_MAGIC_NAME, + IFCAP_TOE4_NAME, + IFCAP_TOE6_NAME, + IFCAP_VLAN_HWFILTER_NAME, + IFCAP_NV_NAME, + IFCAP_VLAN_HWTSO_NAME, + IFCAP_LINKSTATE_NAME, + IFCAP_NETMAP_NAME, + IFCAP_RXCSUM_IPV6_NAME, + IFCAP_TXCSUM_IPV6_NAME, + IFCAP_HWSTATS_NAME, + IFCAP_TXRTLMT_NAME, + IFCAP_HWRXTSTMP_NAME, + IFCAP_MEXTPG_NAME, + IFCAP_TXTLS4_NAME, + IFCAP_TXTLS6_NAME, + IFCAP_VXLAN_HWCSUM_NAME, + IFCAP_VXLAN_HWTSO_NAME, + IFCAP_TXTLS_RTLMT_NAME, + IFCAP_RXTLS4_NAME, + IFCAP_RXTLS6_NAME, +}; +_Static_assert(sizeof(ifcap_bit_names) >= IFCAP_B_SIZE * sizeof(char *), + "ifcap bit names missing from ifcap_bit_names"); + +#endif diff --git a/sys/netlink/netlink_bitset.h b/sys/netlink/netlink_bitset.h new file mode 100644 index 000000000000..9a918bd20997 --- /dev/null +++ b/sys/netlink/netlink_bitset.h @@ -0,0 +1,57 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Alexander V. Chernikov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Generic netlink message header and attributes + */ +#ifndef _NETLINK_NETLINK_BITSET_H_ +#define _NETLINK_NETLINK_BITSET_H_ + +#include + +/* Bitset type nested attributes */ +enum { + NLA_BITSET_UNSPEC, + NLA_BITSET_NOMASK = 1, /* flag: mask of valid bits not provided */ + NLA_BITSET_SIZE = 2, /* u32: max valid bit # */ + NLA_BITSET_BITS = 3, /* nested: array of NLA_BITSET_BIT */ + NLA_BITSET_VALUE = 4, /* binary: array of bit values */ + NLA_BITSET_MASK = 5, /* binary: array of valid bits */ + __NLA_BITSET_MAX, +}; +#define NLA_BITSET_MAX (__NLA_BITSET_MAX - 1) + +enum { + NLA_BITSET_BIT_UNSPEC, + NLA_BITSET_BIT_INDEX = 1, /* u32: index of the bit */ + NLA_BITSET_BIT_NAME = 2, /* string: bit description */ + NLA_BITSET_BIT_VALUE = 3, /* flag: provided if bit is set */ + __NLA_BITSET_BIT_MAX, +}; +#define NLA_BITSET_BIT_MAX (__NLA_BITSET_BIT_MAX - 1) + +#endif diff --git a/sys/netlink/netlink_route.h b/sys/netlink/netlink_route.h index 0c328d941bd5..ecdad83312de 100644 --- a/sys/netlink/netlink_route.h +++ b/sys/netlink/netlink_route.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h index 6d97c1afd4ee..0292725bd135 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -43,6 +43,7 @@ #include #include #include +#include #define _roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) @@ -732,7 +733,7 @@ snl_attr_get_nla(struct snl_state *ss __unused, struct nlattr *nla, } static inline bool -snl_attr_dup_nla(struct snl_state *ss __unused, struct nlattr *nla, +snl_attr_dup_nla(struct snl_state *ss, struct nlattr *nla, const void *arg __unused, void *target) { void *ptr = snl_allocz(ss, nla->nla_len); @@ -773,6 +774,90 @@ snl_attr_dup_struct(struct snl_state *ss, struct nlattr *nla, return (false); } +struct snl_attr_bit { + uint32_t bit_index; + char *bit_name; + int bit_value; +}; + +struct snl_attr_bits { + uint32_t num_bits; + struct snl_attr_bit **bits; +}; + +#define _OUT(_field) offsetof(struct snl_attr_bit, _field) +static const struct snl_attr_parser _nla_p_bit[] = { + { .type = NLA_BITSET_BIT_INDEX, .off = _OUT(bit_index), .cb = snl_attr_get_uint32 }, + { .type = NLA_BITSET_BIT_NAME, .off = _OUT(bit_name), .cb = snl_attr_dup_string }, + { .type = NLA_BITSET_BIT_VALUE, .off = _OUT(bit_value), .cb = snl_attr_get_flag }, +}; +#undef _OUT +SNL_DECLARE_ATTR_PARSER_EXT(_nla_bit_parser, sizeof(struct snl_attr_bit), _nla_p_bit, NULL); + +struct snl_attr_bitset { + uint32_t nla_bitset_size; + uint32_t *nla_bitset_mask; + uint32_t *nla_bitset_value; + struct snl_attr_bits bits; +}; + +#define _OUT(_field) offsetof(struct snl_attr_bitset, _field) +static const struct snl_attr_parser _nla_p_bitset[] = { + { .type = NLA_BITSET_SIZE, .off = _OUT(nla_bitset_size), .cb = snl_attr_get_uint32 }, + { .type = NLA_BITSET_BITS, .off = _OUT(bits), .cb = snl_attr_get_parray, .arg = &_nla_bit_parser }, + { .type = NLA_BITSET_VALUE, .off = _OUT(nla_bitset_mask), .cb = snl_attr_dup_nla }, + { .type = NLA_BITSET_MASK, .off = _OUT(nla_bitset_value), .cb = snl_attr_dup_nla }, +}; + +static inline bool +_cb_p_bitset(struct snl_state *ss __unused, void *_target) +{ + struct snl_attr_bitset *target = _target; + + uint32_t sz_bytes = _roundup2(target->nla_bitset_size, 32) / 8; + + if (target->nla_bitset_mask != NULL) { + struct nlattr *nla = (struct nlattr *)target->nla_bitset_mask; + uint32_t data_len = NLA_DATA_LEN(nla); + + if (data_len != sz_bytes || _roundup2(data_len, 4) != data_len) + return (false); + target->nla_bitset_mask = (uint32_t *)NLA_DATA(nla); + } + + if (target->nla_bitset_value != NULL) { + struct nlattr *nla = (struct nlattr *)target->nla_bitset_value; + uint32_t data_len = NLA_DATA_LEN(nla); + + if (data_len != sz_bytes || _roundup2(data_len, 4) != data_len) + return (false); + target->nla_bitset_value = (uint32_t *)NLA_DATA(nla); + } + return (true); +} +#undef _OUT +SNL_DECLARE_ATTR_PARSER_EXT(_nla_bitset_parser, + sizeof(struct snl_attr_bitset), + _nla_p_bitset, _cb_p_bitset); + +/* + * Parses the compact bitset representation. + */ +static inline bool +snl_attr_get_bitset_c(struct snl_state *ss, struct nlattr *nla, + const void *arg __unused, void *_target) +{ + const struct snl_hdr_parser *p = &_nla_bitset_parser; + struct snl_attr_bitset *target = _target; + + /* Assumes target points to the beginning of the structure */ + if (!snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), p, _target)) + return (false); + if (target->nla_bitset_mask == NULL || target->nla_bitset_value == NULL) + return (false); + return (true); +} + static inline void snl_field_get_uint8(struct snl_state *ss __unused, void *src, void *target) { @@ -1184,6 +1269,7 @@ snl_send_msgs(struct snl_writer *nw) static const struct snl_hdr_parser *snl_all_core_parsers[] = { &snl_errmsg_parser, &snl_donemsg_parser, + &_nla_bit_parser, &_nla_bitset_parser, }; #endif diff --git a/sys/netlink/netlink_snl_route_parsers.h b/sys/netlink/netlink_snl_route_parsers.h index 1e9320a4559e..7e4bcad4010b 100644 --- a/sys/netlink/netlink_snl_route_parsers.h +++ b/sys/netlink/netlink_snl_route_parsers.h @@ -186,12 +186,14 @@ struct snl_parsed_link { uint32_t ifla_promiscuity; struct rtnl_link_stats64 *ifla_stats64; struct nlattr *iflaf_orig_hwaddr; + struct snl_attr_bitset iflaf_caps; }; #define _IN(_field) offsetof(struct ifinfomsg, _field) #define _OUT(_field) offsetof(struct snl_parsed_link, _field) static const struct snl_attr_parser _nla_p_link_fbsd[] = { { .type = IFLAF_ORIG_HWADDR, .off = _OUT(iflaf_orig_hwaddr), .cb = snl_attr_dup_nla }, + { .type = IFLAF_CAPS, .off = _OUT(iflaf_caps), .cb = snl_attr_get_bitset_c }, }; SNL_DECLARE_ATTR_PARSER(_link_fbsd_parser, _nla_p_link_fbsd); diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index 16bbe4d000cc..3d7f752fa613 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -253,6 +253,33 @@ dump_sa(struct nl_writer *nw, int attr, const struct sockaddr *sa) return (nlattr_add(nw, attr, addr_len, addr_data)); } +static bool +dump_iface_caps(struct nl_writer *nw, struct ifnet *ifp) +{ + int off = nlattr_add_nested(nw, IFLAF_CAPS); + uint32_t active_caps[roundup2(IFCAP_B_SIZE, 32) / 32] = {}; + uint32_t all_caps[roundup2(IFCAP_B_SIZE, 32) / 32] = {}; + + MPASS(sizeof(active_caps) >= 8); + MPASS(sizeof(all_caps) >= 8); + + if (off == 0) + return (false); + + active_caps[0] = (uint32_t)if_getcapabilities(ifp); + all_caps[0] = (uint32_t)if_getcapenable(ifp); + active_caps[1] = (uint32_t)if_getcapabilities2(ifp); + all_caps[1] = (uint32_t)if_getcapenable2(ifp); + + nlattr_add_u32(nw, NLA_BITSET_SIZE, IFCAP_B_SIZE); + nlattr_add(nw, NLA_BITSET_MASK, sizeof(all_caps), all_caps); + nlattr_add(nw, NLA_BITSET_VALUE, sizeof(active_caps), active_caps); + + nlattr_set_len(nw, off); + + return (true); +} + /* * Dumps interface state, properties and metrics. * @nw: message writer @@ -320,6 +347,7 @@ dump_iface(struct nl_writer *nw, struct ifnet *ifp, const struct nlmsghdr *hdr, int off = nlattr_add_nested(nw, IFLA_FREEBSD); if (off != 0) { get_hwaddr(nw, ifp); + dump_iface_caps(nw, ifp); nlattr_set_len(nw, off); } diff --git a/sys/netlink/route/interface.h b/sys/netlink/route/interface.h index 97270d8234a1..667bf2c96151 100644 --- a/sys/netlink/route/interface.h +++ b/sys/netlink/route/interface.h @@ -151,6 +151,7 @@ enum { IFLAF_UNSPEC = 0, IFLAF_ORIG_IFNAME = 1, /* string, original interface name at creation */ IFLAF_ORIG_HWADDR = 2, /* binary, original hardware address */ + IFLAF_CAPS = 3, /* bitset, interface capabilities */ __IFLAF_MAX }; #define IFLAF_MAX (__IFLAF_MAX - 1)