git: 8170a7d43835 - main - Fix interface route addition with net/bird.

Alexander V. Chernikov melifaro at FreeBSD.org
Fri Feb 12 19:45:48 UTC 2021


The branch main has been updated by melifaro:

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

commit 8170a7d43835047f9c1548a081eea45116473995
Author:     Alexander V. Chernikov <melifaro at FreeBSD.org>
AuthorDate: 2021-02-11 23:24:27 +0000
Commit:     Alexander V. Chernikov <melifaro at 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);
 }
 


More information about the dev-commits-src-all mailing list