git: 28921c4f7de6 - main - carp: allow commands to use interface name rather than index

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Fri, 31 Mar 2023 11:36:42 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=28921c4f7de6d8641b4deaa8942526309018668a

commit 28921c4f7de6d8641b4deaa8942526309018668a
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-03-30 23:34:03 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-03-31 09:29:58 +0000

    carp: allow commands to use interface name rather than index
    
    Get/set commands can now choose to provide the interface name rather
    than the interface index. This allows userspace to avoid a call to
    if_nametoindex().
    
    Suggested by:   melifaro
    Reviewed by:    melifaro
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D39359
---
 lib/libifconfig/libifconfig_carp.c | 18 ++----------------
 sys/netinet/ip_carp.c              | 16 ++++++++++++----
 sys/netinet/ip_carp_nl.h           |  1 +
 3 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/lib/libifconfig/libifconfig_carp.c b/lib/libifconfig/libifconfig_carp.c
index 5729362ffef9..501ca81782eb 100644
--- a/lib/libifconfig/libifconfig_carp.c
+++ b/lib/libifconfig/libifconfig_carp.c
@@ -73,17 +73,10 @@ _ifconfig_carp_get(ifconfig_handle_t *h, const char *name,
 	struct nlmsghdr *hdr;
 	size_t i = 0;
 	uint32_t seq_id;
-	unsigned int ifindex;
 	int family_id;
 
 	ifconfig_error_clear(h);
 
-	ifindex = if_nametoindex(name);
-	if (ifindex == 0) {
-		ifconfig_error(h, NETLINK, ENOENT);
-		return (-1);
-	}
-
 	if (! snl_init(&ss, NETLINK_GENERIC)) {
 		ifconfig_error(h, NETLINK, ENOTSUP);
 		return (-1);
@@ -100,7 +93,7 @@ _ifconfig_carp_get(ifconfig_handle_t *h, const char *name,
 	hdr = snl_create_genl_msg_request(&nw, family_id, CARP_NL_CMD_GET);
 	hdr->nlmsg_flags |= NLM_F_DUMP;
 
-	snl_add_msg_attr_u32(&nw, CARP_NL_IFINDEX, ifindex);
+	snl_add_msg_attr_string(&nw, CARP_NL_IFNAME, name);
 
 	if (vhid != 0)
 		snl_add_msg_attr_u32(&nw, CARP_NL_VHID, vhid);
@@ -153,18 +146,11 @@ ifconfig_carp_set_info(ifconfig_handle_t *h, const char *name,
 	struct snl_state ss = {};
 	struct snl_writer nw;
 	struct nlmsghdr *hdr;
-	unsigned int ifindex;
 	int family_id;
 	uint32_t seq_id;
 
 	ifconfig_error_clear(h);
 
-	ifindex = if_nametoindex(name);
-	if (ifindex == 0) {
-		ifconfig_error(h, NETLINK, ENOENT);
-		return (-1);
-	}
-
 	if (! snl_init(&ss, NETLINK_GENERIC)) {
 		ifconfig_error(h, NETLINK, ENOTSUP);
 		return (-1);
@@ -183,7 +169,7 @@ ifconfig_carp_set_info(ifconfig_handle_t *h, const char *name,
 	snl_add_msg_attr_u32(&nw, CARP_NL_STATE, carpr->carpr_state);
 	snl_add_msg_attr_s32(&nw, CARP_NL_ADVBASE, carpr->carpr_advbase);
 	snl_add_msg_attr_s32(&nw, CARP_NL_ADVSKEW, carpr->carpr_advskew);
-	snl_add_msg_attr_u32(&nw, CARP_NL_IFINDEX, ifindex);
+	snl_add_msg_attr_string(&nw, CARP_NL_IFNAME, name);
 	snl_add_msg_attr(&nw, CARP_NL_ADDR, sizeof(carpr->carpr_addr),
 	    &carpr->carpr_addr);
 	snl_add_msg_attr(&nw, CARP_NL_ADDR6, sizeof(carpr->carpr_addr6),
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 2e1c8e084b4b..a6a89d0f87d8 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -2301,6 +2301,7 @@ carp_nl_send(void *arg, struct carp_softc *sc, int priv)
 
 struct nl_carp_parsed {
 	unsigned int	ifindex;
+	char		*ifname;
 	uint32_t	state;
 	uint32_t	vhid;
 	int32_t		advbase;
@@ -2322,6 +2323,7 @@ static const struct nlattr_parser nla_p_set[] = {
 	{ .type = CARP_NL_IFINDEX, .off = _OUT(ifindex), .cb = nlattr_get_uint32 },
 	{ .type = CARP_NL_ADDR, .off = _OUT(addr), .cb = nlattr_get_in_addr },
 	{ .type = CARP_NL_ADDR6, .off = _OUT(addr6), .cb = nlattr_get_in6_addr },
+	{ .type = CARP_NL_IFNAME, .off = _OUT(ifname), .cb = nlattr_get_string },
 };
 static const struct nlfield_parser nlf_p_set[] = {
 };
@@ -2337,7 +2339,7 @@ carp_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	struct carp_nl_send_args args;
 	struct carpreq carpr = { };
 	struct epoch_tracker et;
-	if_t ifp;
+	if_t ifp = NULL;
 	int error;
 
 	error = nl_parse_nlmsg(hdr, &carp_parser, npt, &attrs);
@@ -2345,7 +2347,10 @@ carp_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
 		return (error);
 
 	NET_EPOCH_ENTER(et);
-	ifp = ifnet_byindex_ref(attrs.ifindex);
+	if (attrs.ifname != NULL)
+		ifp = ifunit_ref(attrs.ifname);
+	else if (attrs.ifindex != 0)
+		ifp = ifnet_byindex_ref(attrs.ifindex);
 	NET_EPOCH_EXIT(et);
 
 	if ((error = carp_is_supported_if(ifp)) != 0)
@@ -2379,7 +2384,7 @@ carp_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	struct nl_carp_parsed attrs = { };
 	struct carpkreq carpr;
 	struct epoch_tracker et;
-	if_t ifp;
+	if_t ifp = NULL;
 	int error;
 
 	error = nl_parse_nlmsg(hdr, &carp_parser, npt, &attrs);
@@ -2398,7 +2403,10 @@ carp_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt)
 		return (EINVAL);
 
 	NET_EPOCH_ENTER(et);
-	ifp = ifnet_byindex_ref(attrs.ifindex);
+	if (attrs.ifname != NULL)
+		ifp = ifunit_ref(attrs.ifname);
+	else if (attrs.ifindex != 0)
+		ifp = ifnet_byindex_ref(attrs.ifindex);
 	NET_EPOCH_EXIT(et);
 
 	if ((error = carp_is_supported_if(ifp)) != 0)
diff --git a/sys/netinet/ip_carp_nl.h b/sys/netinet/ip_carp_nl.h
index 60e8c569a05d..89720af3e0dc 100644
--- a/sys/netinet/ip_carp_nl.h
+++ b/sys/netinet/ip_carp_nl.h
@@ -31,6 +31,7 @@ enum carp_nl_type_t {
 	CARP_NL_IFINDEX		= 6,	/* u32 */
 	CARP_NL_ADDR		= 7,	/* in_addr_t */
 	CARP_NL_ADDR6		= 8,	/* in6_addr_t */
+	CARP_NL_IFNAME		= 9,	/* string */
 };
 
 #endif