Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jan 2021 23:45:37 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d28210b2c2aa - main - Remove remnants of classful behavior in route(8).
Message-ID:  <202101162345.10GNjbUb018692@gitrepo.freebsd.org>

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

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

commit d28210b2c2aaf3200907ed30d296b0d4856dd03c
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-01-16 23:06:32 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2021-01-16 23:45:30 +0000

    Remove remnants of classful behavior in route(8).
    
    Curently route(8) treats some addresses as network addresses:
    
     RTA_DST: inet 10.0.0.0; RTA_NETMASK: inet 255.0.0.0; RTA_IFP: link ;
     RTM_GET: Report Metrics: len 240, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
     locks:  inits:
     sockaddrs: <DST,NETMASK,IFP>
       10.0.0.0 255.0.0.0 link#0
    
    Note added `RTA_NETMASK` in the request.
    
    Host address from the same network is ok:
    
    route -nv get 10.0.0.1
     RTA_DST: inet 10.0.0.1
     RTA_IFP: link
     RTM_GET: Report Metrics: len 224, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,HOST,STATIC>
    ...
       route to: 10.0.0.1
    destination: 10.0.0.0
           mask: 255.255.255.0
    
    This change eliminates network auto-guessing part AND reading network from /etc/networks.
    
    Reviewed By: rgrimes
    
    Differential Revision: https://reviews.freebsd.org/D24401
---
 sbin/route/route.c | 69 +++++++++++-------------------------------------------
 1 file changed, 14 insertions(+), 55 deletions(-)

diff --git a/sbin/route/route.c b/sbin/route/route.c
index 9c9e4b304848..51a0c68746a6 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -120,8 +120,7 @@ static int	flushroutes_fib(int);
 static int	getaddr(int, char *, struct hostent **, int);
 static int	keyword(const char *);
 #ifdef INET
-static void	inet_makenetandmask(u_long, struct sockaddr_in *,
-		    struct sockaddr_in *, u_long);
+static void	inet_makemask(struct sockaddr_in *, u_long);
 #endif
 #ifdef INET6
 static int	inet6_makenetandmask(struct sockaddr_in6 *, const char *);
@@ -1113,40 +1112,15 @@ newroute_fib(int fib, char *cmd, int flags)
 
 #ifdef INET
 static void
-inet_makenetandmask(u_long net, struct sockaddr_in *sin,
-    struct sockaddr_in *sin_mask, u_long bits)
+inet_makemask(struct sockaddr_in *sin_mask, u_long bits)
 {
 	u_long mask = 0;
 
 	rtm_addrs |= RTA_NETMASK;
 
-	/*
-	 * MSB of net should be meaningful. 0/0 is exception.
-	 */
-	if (net > 0)
-		while ((net & 0xff000000) == 0)
-			net <<= 8;
-
-	/*
-	 * If no /xx was specified we must calculate the
-	 * CIDR address.
-	 */
-	if ((bits == 0) && (net != 0)) {
-		u_long i, j;
-
-		for(i = 0, j = 0xff; i < 4; i++)  {
-			if (net & j) {
-				break;
-			}
-			j <<= 8;
-		}
-		/* i holds the first non zero bit */
-		bits = 32 - (i*8);
-	}
 	if (bits != 0)
 		mask = 0xffffffff << (32 - bits);
 
-	sin->sin_addr.s_addr = htonl(net);
 	sin_mask->sin_addr.s_addr = htonl(mask);
 	sin_mask->sin_len = sizeof(struct sockaddr_in);
 	sin_mask->sin_family = AF_INET;
@@ -1186,8 +1160,6 @@ getaddr(int idx, char *str, struct hostent **hpp, int nrflags)
 #if defined(INET)
 	struct sockaddr_in *sin;
 	struct hostent *hp;
-	struct netent *np;
-	u_long val;
 	char *q;
 #elif defined(INET6)
 	char *q;
@@ -1314,34 +1286,21 @@ getaddr(int idx, char *str, struct hostent **hpp, int nrflags)
 
 	q = strchr(str,'/');
 	if (q != NULL && idx == RTAX_DST) {
+		/* A.B.C.D/NUM */
 		*q = '\0';
-		if ((val = inet_network(str)) != INADDR_NONE) {
-			inet_makenetandmask(val, sin,
-			    (struct sockaddr_in *)&so[RTAX_NETMASK],
-			    strtoul(q+1, 0, 0));
-			return (0);
-		}
-		*q = '/';
-	}
-	if ((idx != RTAX_DST || (nrflags & F_FORCENET) == 0) &&
-	    inet_aton(str, &sin->sin_addr)) {
-		val = sin->sin_addr.s_addr;
-		if (idx != RTAX_DST || nrflags & F_FORCEHOST ||
-		    inet_lnaof(sin->sin_addr) != INADDR_ANY)
-			return (1);
-		else {
-			val = ntohl(val);
-			goto netdone;
-		}
-	}
-	if (idx == RTAX_DST && (nrflags & F_FORCEHOST) == 0 &&
-	    ((val = inet_network(str)) != INADDR_NONE ||
-	    ((np = getnetbyname(str)) != NULL && (val = np->n_net) != 0))) {
-netdone:
-		inet_makenetandmask(val, sin,
-		    (struct sockaddr_in *)&so[RTAX_NETMASK], 0);
+		if (inet_aton(str, &sin->sin_addr) == 0)
+			errx(EX_NOHOST, "bad address: %s", str);
+
+		int masklen = strtol(q + 1, NULL, 10);
+		if (masklen < 0 || masklen > 32)
+			errx(EX_NOHOST, "bad mask length: %s", q + 1);
+
+		inet_makemask((struct sockaddr_in *)&so[RTAX_NETMASK],masklen);
 		return (0);
 	}
+	if (inet_aton(str, &sin->sin_addr) != 0)
+		return (1);
+
 	hp = gethostbyname(str);
 	if (hp != NULL) {
 		*hpp = hp;



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