The branch main has been updated by melifaro:

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

commit 8170a7d43835047f9c1548a081eea45116473995
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2021-02-11 23:24:27 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2021-02-12 19:45:35 +0000

    Fix interface route addition with net/bird.
    
    The case of adding interface route by specifying interface
     address as the gateway was missed during code refactoring.
    Re-add it back by copying non-AF_LINK gateway data when RTF_GATEWAY
     is not set.
    
    Reviewed by:    donner
    MFC after:      3 days
---
 sys/net/route/nhop_ctl.c | 50 +++++++++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 542380afd64b..7de553799fab 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -219,42 +219,44 @@ set_nhop_gw_from_info(struct nhop_object *nh, struct 
rt_addrinfo *info)
        gw = info->rti_info[RTAX_GATEWAY];
        KASSERT(gw != NULL, ("gw is NULL"));
 
-       if (info->rti_flags & RTF_GATEWAY) {
-               if (gw->sa_len > sizeof(struct sockaddr_in6)) {
-                       DPRINTF("nhop SA size too big: AF %d len %u",
-                           gw->sa_family, gw->sa_len);
-                       return (ENOMEM);
-               }
-               memcpy(&nh->gw_sa, gw, gw->sa_len);
-       } else {
+       if ((gw->sa_family == AF_LINK) && !(info->rti_flags & RTF_GATEWAY)) {
 
                /*
-                * Interface route. Currently the route.c code adds
-                * sa of type AF_LINK, which is 56 bytes long. The only
-                * meaningful data there is the interface index. It is used
-                * used is the IPv6 loopback output, where we need to preserve
-                * the original interface to maintain proper scoping.
+                * Interface route with interface specified by the interface
+                * index in sockadd_dl structure. It is used in the IPv6 
loopback
+                * output code, where we need to preserve the original interface
+                * to maintain proper scoping.
                 * Despite the fact that nexthop code stores original interface
                 * in the separate field (nh_aifp, see below), write AF_LINK
                 * compatible sa with shorter total length.
                 */
-               struct sockaddr_dl *sdl;
-               struct ifnet *ifp;
-
-               /* Fetch and validate interface index */
-               sdl = (struct sockaddr_dl *)gw;
-               if (sdl->sdl_family != AF_LINK) {
-                       DPRINTF("unsupported AF: %d", sdl->sdl_family);
-                       return (ENOTSUP);
-               }
-               ifp = ifnet_byindex(sdl->sdl_index);
+               struct sockaddr_dl *sdl = (struct sockaddr_dl *)gw;
+               struct ifnet *ifp = ifnet_byindex(sdl->sdl_index);
                if (ifp == NULL) {
                        DPRINTF("invalid ifindex %d", sdl->sdl_index);
                        return (EINVAL);
                }
                fill_sdl_from_ifp(&nh->gwl_sa, ifp);
-       }
+       } else {
 
+               /*
+                * Multiple options here:
+                *
+                * 1) RTF_GATEWAY with IPv4/IPv6 gateway data
+                * 2) Interface route with IPv4/IPv6 address of the
+                *   matching interface. Some routing daemons do that
+                *   instead of specifying ifindex in AF_LINK.
+                *
+                * In both cases, save the original nexthop to make the callers
+                *   happy.
+                */
+               if (gw->sa_len > sizeof(struct sockaddr_in6)) {
+                       DPRINTF("nhop SA size too big: AF %d len %u",
+                           gw->sa_family, gw->sa_len);
+                       return (ENOMEM);
+               }
+               memcpy(&nh->gw_sa, gw, gw->sa_len);
+       }
        return (0);
 }
 
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to