Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Sep 2021 21:30:46 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: f3d69003374a - stable/13 - routing: Bring back the ability to specify transmit interface via its name.
Message-ID:  <202109072130.187LUkIq046292@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by melifaro:

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

commit f3d69003374a291e2ccb4a1ecc318e90827bac09
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-08-29 19:51:28 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2021-09-07 21:25:24 +0000

    routing: Bring back the ability to specify transmit interface via its name.
    
    Some software references outgoing interfaces by specifying name instead of
     index.
    
    Use rti_ifp from rt_addrinfo if provided instead of always using
     address interface when constructing nexthop.
    
    PR:             255678
    Reported by:    martin.larsson2 at gmail.com
    
    (cherry picked from commit d98954e229812eee2fa6bf97714fecbbdcc56e4c)
---
 sys/net/route.c          | 45 ++++++++++++++++++++++++++++++++++++---------
 sys/net/route/nhop_ctl.c |  2 +-
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/sys/net/route.c b/sys/net/route.c
index 2416aa9a983f..a24438563f50 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -500,6 +500,38 @@ rt_flushifroutes(struct ifnet *ifp)
 	rib_foreach_table_walk_del(AF_UNSPEC, rt_ifdelroute, ifp);
 }
 
+/*
+ * Tries to extract interface from RTAX_IFP passed in rt_addrinfo.
+ * Interface can be specified ether as interface index (sdl_index) or
+ * the interface name (sdl_data).
+ *
+ * Returns found ifp or NULL
+ */
+static struct ifnet *
+info_get_ifp(struct rt_addrinfo *info)
+{
+	const struct sockaddr_dl *sdl;
+
+	sdl = (const struct sockaddr_dl *)info->rti_info[RTAX_IFP];
+	if (sdl->sdl_family != AF_LINK)
+		return (NULL);
+
+	if (sdl->sdl_index != 0)
+		return (ifnet_byindex(sdl->sdl_index));
+	if (sdl->sdl_nlen > 0) {
+		char if_name[IF_NAMESIZE];
+		if (sdl->sdl_nlen + offsetof(struct sockaddr_dl, sdl_data) > sdl->sdl_len)
+			return (NULL);
+		if (sdl->sdl_nlen >= IF_NAMESIZE)
+			return (NULL);
+		bzero(if_name, sizeof(if_name));
+		memcpy(if_name, sdl->sdl_data, sdl->sdl_nlen);
+		return (ifunit(if_name));
+	}
+
+	return (NULL);
+}
+
 /*
  * Look up rt_addrinfo for a specific fib.
  *
@@ -509,12 +541,11 @@ rt_flushifroutes(struct ifnet *ifp)
 int
 rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
 {
-	const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr;
+	const struct sockaddr *dst, *gateway, *ifaaddr;
 	int error, flags;
 
 	dst = info->rti_info[RTAX_DST];
 	gateway = info->rti_info[RTAX_GATEWAY];
-	ifpaddr = info->rti_info[RTAX_IFP];
 	ifaaddr = info->rti_info[RTAX_IFA];
 	flags = info->rti_flags;
 
@@ -524,13 +555,9 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
 	 */
 	error = 0;
 
-	/* If we have interface specified by the ifindex in the address, use it */
-	if (info->rti_ifp == NULL && ifpaddr != NULL &&
-	    ifpaddr->sa_family == AF_LINK) {
-	    const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr;
-	    if (sdl->sdl_index != 0)
-		    info->rti_ifp = ifnet_byindex(sdl->sdl_index);
-	}
+	/* If we have interface specified by RTAX_IFP address, try to use it */
+	if ((info->rti_ifp == NULL) && (info->rti_info[RTAX_IFP] != NULL))
+		info->rti_ifp = info_get_ifp(info);
 	/*
 	 * If we have source address specified, try to find it
 	 * TODO: avoid enumerating all ifas on all interfaces.
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 92b43871d604..21aefcc7a83b 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -286,7 +286,7 @@ fill_nhop_from_info(struct nhop_priv *nh_priv, struct rt_addrinfo *info)
 	if ((error = set_nhop_gw_from_info(nh, info)) != 0)
 		return (error);
 
-	nh->nh_ifp = info->rti_ifa->ifa_ifp;
+	nh->nh_ifp = (info->rti_ifp != NULL) ? info->rti_ifp : info->rti_ifa->ifa_ifp;
 	nh->nh_ifa = info->rti_ifa;
 	/* depends on the gateway */
 	nh->nh_aifp = get_aifp(nh);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109072130.187LUkIq046292>