git: 122487801670 - main - netlink: export carp VHID when dumping interface addresses.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Wed, 10 May 2023 09:57:49 UTC
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=1224878016704f3e5a6b6953f3caed3e7840cefd

commit 1224878016704f3e5a6b6953f3caed3e7840cefd
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-05-10 08:44:47 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-05-10 09:57:01 +0000

    netlink: export carp VHID when dumping interface addresses.
    
    MFC after:      2 weeks
---
 sys/netlink/netlink_snl_route_parsers.h |  9 ++++++++-
 sys/netlink/route/iface.c               | 12 ++++++++++++
 sys/netlink/route/ifaddrs.h             | 10 +++++++++-
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/sys/netlink/netlink_snl_route_parsers.h b/sys/netlink/netlink_snl_route_parsers.h
index 504b9c8737df..e50ad717e17f 100644
--- a/sys/netlink/netlink_snl_route_parsers.h
+++ b/sys/netlink/netlink_snl_route_parsers.h
@@ -302,15 +302,22 @@ struct snl_parsed_addr {
 	struct sockaddr	*ifa_address;
 	struct sockaddr	*ifa_broadcast;
 	char		*ifa_label;
+	uint32_t	ifaf_vhid;
 };
 
 #define	_IN(_field)	offsetof(struct ifaddrmsg, _field)
 #define	_OUT(_field)	offsetof(struct snl_parsed_addr, _field)
+static const struct snl_attr_parser _nla_p_addr_fbsd[] = {
+	{ .type = IFAF_VHID, .off = _OUT(ifaf_vhid), .cb = snl_attr_get_uint32 },
+};
+SNL_DECLARE_ATTR_PARSER(_addr_fbsd_parser, _nla_p_addr_fbsd);
+
 static const struct snl_attr_parser _nla_p_addr_s[] = {
 	{ .type = IFA_ADDRESS, .off = _OUT(ifa_address), .cb = snl_attr_get_ip },
 	{ .type = IFA_LOCAL, .off = _OUT(ifa_local), .cb = snl_attr_get_ip },
 	{ .type = IFA_LABEL, .off = _OUT(ifa_label), .cb = snl_attr_dup_string },
 	{ .type = IFA_BROADCAST, .off = _OUT(ifa_broadcast), .cb = snl_attr_get_ip },
+	{ .type = IFA_FREEBSD, .arg = &_addr_fbsd_parser, .cb = snl_attr_get_nested },
 };
 static const struct snl_field_parser _fp_p_addr_s[] = {
 	{.off_in = _IN(ifa_family), .off_out = _OUT(ifa_family), .cb = snl_field_get_uint8 },
@@ -385,7 +392,7 @@ static const struct snl_hdr_parser *snl_all_route_parsers[] = {
 	&_metrics_mp_nh_parser, &_mpath_nh_parser, &_metrics_parser, &snl_rtm_route_parser,
 	&snl_rtm_link_parser, &snl_rtm_link_parser_simple,
 	&_neigh_fbsd_parser, &snl_rtm_neigh_parser,
-	&snl_rtm_addr_parser, &_nh_fbsd_parser, &snl_nhmsg_parser,
+	&_addr_fbsd_parser, &snl_rtm_addr_parser, &_nh_fbsd_parser, &snl_nhmsg_parser,
 };
 
 #endif
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 816d6ff8632e..cc76410550f4 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -79,6 +79,9 @@ static SLIST_HEAD(, nl_cloner) nl_cloners = SLIST_HEAD_INITIALIZER(nl_cloners);
 static struct sx rtnl_cloner_lock;
 SX_SYSINIT(rtnl_cloner_lock, &rtnl_cloner_lock, "rtnl cloner lock");
 
+/* These are external hooks for CARP. */
+extern int	(*carp_get_vhid_p)(struct ifaddr *);
+
 /*
  * RTM_GETLINK request
  * sendto(3, {{len=32, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1641940952, pid=0},
@@ -795,6 +798,15 @@ dump_iface_addr(struct nl_writer *nw, struct ifnet *ifp, struct ifaddr *ifa,
 
         uint32_t val = 0; // ifa->ifa_flags;
         nlattr_add_u32(nw, IFA_FLAGS, val);
+	/* Store FreeBSD-specific attributes */
+	int off = nlattr_add_nested(nw, IFA_FREEBSD);
+	if (off != 0) {
+		if (ifa->ifa_carp != NULL && carp_get_vhid_p != NULL) {
+			uint32_t vhid  = (uint32_t)(*carp_get_vhid_p)(ifa);
+			nlattr_add_u32(nw, IFAF_VHID, vhid);
+		}
+		nlattr_set_len(nw, off);
+	}
 
 	if (nlmsg_end(nw))
 		return (true);
diff --git a/sys/netlink/route/ifaddrs.h b/sys/netlink/route/ifaddrs.h
index 7ada8f22bf7b..cbf23fe54197 100644
--- a/sys/netlink/route/ifaddrs.h
+++ b/sys/netlink/route/ifaddrs.h
@@ -60,9 +60,17 @@ enum {
 	IFA_FLAGS		= 8, /* not supported */
 	IFA_RT_PRIORITY		= 9, /* not supported */
 	IFA_TARGET_NETNSID	= 10, /* not supported */
+	IFA_FREEBSD		= 11, /* nested, FreeBSD-specific */
 	__IFA_MAX,
 };
-#define IFA_MAX (__IFA_MAX - 1)
+#define IFA_MAX		(__IFA_MAX - 1)
+
+enum {
+	IFAF_UNSPEC,
+	IFAF_VHID		= 1, /* u32: carp vhid */
+	__IFAF_MAX,
+};
+#define IFAF_MAX	(__IFAF_MAX - 1)
 
 /* IFA_FLAGS attribute flags */
 #define IFA_F_SECONDARY		0x0001