Page MenuHomeFreeBSD

D40331.id122752.diff
No OneTemporary

D40331.id122752.diff

diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -282,7 +282,6 @@
bool match_if_flags(struct ifconfig_args *args, int if_flags);
int ifconfig(if_ctx *ctx, int iscreate, const struct afswtch *uafp);
bool group_member(const char *ifname, const char *match, const char *nomatch);
-void print_ifcap(struct ifconfig_args *args, int s);
void tunnel_status(int s);
struct afswtch *af_getbyfamily(int af);
void af_other_status(if_ctx *ctx);
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -55,6 +55,7 @@
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/if_strings.h>
#include <net/if_types.h>
#include <net/route.h>
@@ -1633,7 +1634,7 @@
Perror("ioctl (SIOCGIFCAP)");
}
-void
+static void
print_ifcap(struct ifconfig_args *args, int s)
{
if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0)
diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c
--- a/sbin/ifconfig/ifconfig_netlink.c
+++ b/sbin/ifconfig/ifconfig_netlink.c
@@ -48,6 +48,7 @@
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/if_strings.h>
#include <net/if_types.h>
#include "ifconfig.h"
#include "ifconfig_netlink.h"
@@ -346,6 +347,28 @@
}
}
+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)
{
@@ -363,9 +386,7 @@
if (link->ifla_ifalias != NULL)
printf("\tdescription: %s\n", link->ifla_ifalias);
- /* TODO: convert to netlink */
- strlcpy(ifr.ifr_name, link->ifla_ifname, sizeof(ifr.ifr_name));
- print_ifcap(args, ctx->io_s);
+ print_ifcaps(ctx, link);
tunnel_status(ctx->io_s);
if (args->allfamilies | (args->afp != NULL && args->afp->af_af == AF_LINK)) {
diff --git a/sys/net/if.h b/sys/net/if.h
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -221,42 +221,86 @@
* 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 @@
#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.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -82,6 +82,7 @@
#include <net/if_arp.h>
#include <net/if_clone.h>
#include <net/if_dl.h>
+#include <net/if_strings.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/if_media.h>
diff --git a/sys/net/if_strings.h b/sys/net/if_strings.h
new file mode 100644
--- /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_route.h b/sys/netlink/netlink_bitset.h
copy from sys/netlink/netlink_route.h
copy to sys/netlink/netlink_bitset.h
--- a/sys/netlink/netlink_route.h
+++ b/sys/netlink/netlink_bitset.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
+ * Copyright (c) 2023 Alexander V. Chernikov <melifaro@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,20 +24,34 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _NETLINK_NETLINK_ROUTE_H_
-#define _NETLINK_NETLINK_ROUTE_H_
-#include <sys/types.h>
+/*
+ * Generic netlink message header and attributes
+ */
+#ifndef _NETLINK_NETLINK_BITSET_H_
+#define _NETLINK_NETLINK_BITSET_H_
+
+#include <netlink/netlink.h>
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_var.h>
+/* 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)
-#include <netlink/route/common.h>
-#include <netlink/route/ifaddrs.h>
-#include <netlink/route/interface.h>
-#include <netlink/route/neigh.h>
-#include <netlink/route/route.h>
-#include <netlink/route/nexthop.h>
+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
--- a/sys/netlink/netlink_route.h
+++ b/sys/netlink/netlink_route.h
@@ -33,6 +33,7 @@
#include <net/if_types.h>
#include <net/if_var.h>
+#include <netlink/netlink_bitset.h>
#include <netlink/route/common.h>
#include <netlink/route/ifaddrs.h>
#include <netlink/route/interface.h>
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -43,6 +43,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netlink/netlink.h>
+#include <netlink/netlink_bitset.h>
#define _roundup2(x, y) (((x)+((y)-1))&(~((y)-1)))
@@ -732,7 +733,7 @@
}
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,89 @@
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, 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 +1268,7 @@
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
--- a/sys/netlink/netlink_snl_route_parsers.h
+++ b/sys/netlink/netlink_snl_route_parsers.h
@@ -186,12 +186,14 @@
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
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -253,6 +253,33 @@
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 @@
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
--- a/sys/netlink/route/interface.h
+++ b/sys/netlink/route/interface.h
@@ -151,6 +151,7 @@
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)

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 8, 7:05 PM (13 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16530683
Default Alt Text
D40331.id122752.diff (22 KB)

Event Timeline