The branch stable/13 has been updated by melifaro:

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

commit f3d69003374a291e2ccb4a1ecc318e90827bac09
Author:     Alexander V. Chernikov <[email protected]>
AuthorDate: 2021-08-29 19:51:28 +0000
Commit:     Alexander V. Chernikov <[email protected]>
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);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to