Let me updated the diff.
On Mon, 06 Jul 2020 17:54:30 +0900 (JST)
YASUOKA Masahiko <[email protected]> wrote:
> On Tue, 30 Jun 2020 02:42:02 +0200
> Klemens Nanni <[email protected]> wrote:
>> On Tue, Jun 30, 2020 at 09:00:30AM +0900, YASUOKA Masahiko wrote:
>>> inet_makenetandmask() had required another treatment.
>>>
>>> Also -prefixlen 0 for -inet has a bug
>>>
>>> % doas ./obj/route -T100 add -inet 0.0.0.0 -prefixlen 0 127.0.0.1
>>> add net 0.0.0.0: gateway 127.0.0.1
>>> % netstat -nrf inet -T 100
>>> Routing tables
>>>
>>> Internet:
>>> Destination Gateway Flags Refs Use Mtu Prio
>>> Iface
>>> 0.0.0.0/32 127.0.0.1 UGS 0 0 32768 8
>>> lo100
>>>
>>> /0 becomes /32. The diff following also fixes the problem.
>> Yes, this looks correct to me; regress is also happy (again).
>>
>> OK kn
>
> Thanks,
>
> I'm going to commit the diff. ok or comments, are still welcome.
>
>
> Stop using make_addr() which trims trailing zeros of the netmask, set
> family and length field. This fixes route(8) to handle "::/0"
> properly. Also fix "route add -inet 0.0.0.0 -prefixlen 0 (gateway)"
> to work properly.
>
> Index: sbin/route/route.c
> ===================================================================
> RCS file: /cvs/src/sbin/route/route.c,v
> retrieving revision 1.247
> diff -u -p -r1.247 route.c
> --- sbin/route/route.c 15 Jan 2020 10:26:25 -0000 1.247
> +++ sbin/route/route.c 6 Jul 2020 08:45:06 -0000
(snip)
> @@ -781,12 +780,9 @@ inet_makenetandmask(u_int32_t net, struc
> sin->sin_addr.s_addr = htonl(net);
> sin = &so_mask.sin;
> sin->sin_addr.s_addr = htonl(mask);
> - sin->sin_len = 0;
> - sin->sin_family = 0;
> + sin->sin_family = AF_INET;
> cp = (char *)(&sin->sin_addr + 1);
> - while (*--cp == '\0' && cp > (char *)sin)
> - continue;
> - sin->sin_len = 1 + cp - (char *)sin;
> + sin->sin_len = sizeof(struct sockaddr_in);
> }
>
> /*
"cp" becomes unused. The updated diff removes "cp" as well.
Index: sbin/route/route.c
===================================================================
RCS file: /cvs/src/sbin/route/route.c,v
retrieving revision 1.247
diff -u -p -r1.247 route.c
--- sbin/route/route.c 15 Jan 2020 10:26:25 -0000 1.247
+++ sbin/route/route.c 6 Jul 2020 08:57:25 -0000
@@ -107,7 +107,6 @@ void print_rtmsg(struct rt_msghdr *, in
void pmsg_common(struct rt_msghdr *);
void pmsg_addrs(char *, int);
void bprintf(FILE *, int, char *);
-void mask_addr(union sockunion *, union sockunion *, int);
int getaddr(int, int, char *, struct hostent **);
void getmplslabel(char *, int);
int rtmsg(int, int, int, uint8_t);
@@ -767,7 +766,6 @@ void
inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits)
{
u_int32_t mask;
- char *cp;
rtm_addrs |= RTA_NETMASK;
if (bits == 0 && net == 0)
@@ -781,12 +779,8 @@ inet_makenetandmask(u_int32_t net, struc
sin->sin_addr.s_addr = htonl(net);
sin = &so_mask.sin;
sin->sin_addr.s_addr = htonl(mask);
- sin->sin_len = 0;
- sin->sin_family = 0;
- cp = (char *)(&sin->sin_addr + 1);
- while (*--cp == '\0' && cp > (char *)sin)
- continue;
- sin->sin_len = 1 + cp - (char *)sin;
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(struct sockaddr_in);
}
/*
@@ -1001,7 +995,8 @@ prefixlen(int af, char *s)
memset(&so_mask, 0, sizeof(so_mask));
so_mask.sin.sin_family = AF_INET;
so_mask.sin.sin_len = sizeof(struct sockaddr_in);
- so_mask.sin.sin_addr.s_addr = htonl(0xffffffff << (32 - len));
+ if (len != 0)
+ so_mask.sin.sin_addr.s_addr = htonl(0xffffffff << (32 -
len));
break;
case AF_INET6:
so_mask.sin6.sin6_family = AF_INET6;
@@ -1088,8 +1083,6 @@ rtmsg(int cmd, int flags, int fmask, uin
rtm.rtm_mpls = mpls_flags;
rtm.rtm_hdrlen = sizeof(rtm);
- if (rtm_addrs & RTA_NETMASK)
- mask_addr(&so_dst, &so_mask, RTA_DST);
/* store addresses in ascending order of RTA values */
NEXTADDR(RTA_DST, so_dst);
NEXTADDR(RTA_GATEWAY, so_gate);
@@ -1118,34 +1111,6 @@ rtmsg(int cmd, int flags, int fmask, uin
}
#undef rtm
return (0);
-}
-
-void
-mask_addr(union sockunion *addr, union sockunion *mask, int which)
-{
- int olen = mask->sa.sa_len;
- char *cp1 = olen + (char *)mask, *cp2;
-
- for (mask->sa.sa_len = 0; cp1 > (char *)mask; )
- if (*--cp1 != '\0') {
- mask->sa.sa_len = 1 + cp1 - (char *)mask;
- break;
- }
- if ((rtm_addrs & which) == 0)
- return;
- switch (addr->sa.sa_family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- return;
- }
- cp1 = mask->sa.sa_len + 1 + (char *)addr;
- cp2 = addr->sa.sa_len + 1 + (char *)addr;
- while (cp2 > cp1)
- *--cp2 = '\0';
- cp2 = mask->sa.sa_len + 1 + (char *)mask;
- while (cp1 > addr->sa.sa_data)
- *--cp1 &= *--cp2;
}
char *msgtypes[] = {