Skip to content

Commit e1ba18d

Browse files
committed
BSD: Fix netmask sockaddr family and length for incoming route msgs
Netmask family and length are ignored by traditional userland tools such as route and netstat and are assumed to match the destination sockaddr. On the wire, sa_family is 0 (AF_UNSPEC) for default routes or 255 for subnet/prefix routes. Default routes also have zero length netmask. In both cases we can just sub in the values from the destination address. This is important, because if we feed the same values back we receive back into RTM_DELETE or RTM_ADD then the kernel doesn't react very well. This is currently true for all BSD kernels.
1 parent ab2d7cd commit e1ba18d

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

src/if-bsd.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -887,10 +887,27 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm)
887887

888888
rt->rt_flags = (unsigned int)rtm->rtm_flags;
889889
if_copysa(&rt->rt_dest, rti_info[RTAX_DST]);
890+
890891
if (rtm->rtm_addrs & RTA_NETMASK) {
891892
if_copysa(&rt->rt_netmask, rti_info[RTAX_NETMASK]);
892-
if (rt->rt_netmask.sa_family == 255) /* Why? */
893-
rt->rt_netmask.sa_family = rt->rt_dest.sa_family;
893+
/*
894+
* Netmask family and length are ignored by traditional
895+
* userland tools such as route and netstat and are assumed
896+
* to match the destination sockaddr.
897+
* On the wire, sa_family is 0 (AF_UNSPEC)
898+
* for default routes or 255 for subnet/prefix routes.
899+
* Default routes also have zero length netmask.
900+
*
901+
* In both cases we can just sub in the values from
902+
* the destination address.
903+
* This is important, because if we feed the same values
904+
* back we receive back into RTM_DELETE or RTM_ADD then
905+
* the kernel doesn't react very well.
906+
*
907+
* This is currently true for all BSD kernels.
908+
*/
909+
rt->rt_netmask.sa_family = rt->rt_dest.sa_family;
910+
rt->rt_netmask.sa_len = rt->rt_dest.sa_len;
894911
}
895912

896913
/* dhcpcd likes an unspecified gateway to indicate via the link.

src/sa.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,11 +419,6 @@ sa_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
419419
assert(sa1 != NULL);
420420
assert(sa2 != NULL);
421421

422-
/* Treat AF_UNSPEC as the unspecified address. */
423-
if ((sa1->sa_family == AF_UNSPEC || sa2->sa_family == AF_UNSPEC) &&
424-
sa_is_unspecified(sa1) && sa_is_unspecified(sa2))
425-
return 0;
426-
427422
if (sa1->sa_family != sa2->sa_family)
428423
return sa1->sa_family - sa2->sa_family;
429424

0 commit comments

Comments
 (0)