git: d98954e22981 - main - routing: Bring back the ability to specify transmit interface via its name.
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Aug 29 20:13:44 UTC 2021
The branch main has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=d98954e229812eee2fa6bf97714fecbbdcc56e4c
commit d98954e229812eee2fa6bf97714fecbbdcc56e4c
Author: Alexander V. Chernikov <melifaro at FreeBSD.org>
AuthorDate: 2021-08-29 19:51:28 +0000
Commit: Alexander V. Chernikov <melifaro at FreeBSD.org>
CommitDate: 2021-08-29 20:05:14 +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
MFC after: 1 week
---
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 4f7eb6f64210..e4ed7d1a2fd1 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -502,6 +502,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.
*
@@ -511,12 +543,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;
@@ -526,13 +557,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);
More information about the dev-commits-src-main
mailing list