changeset 4294:95fa4f3d6b1a draft

Some systems mark a host route using RTF_HOST and some use an all-ones netmask. For the former, only test netmask for equality if both routes lack the RTF_HOST marking.
author Roy Marples <roy@marples.name>
date Sun, 15 Jul 2018 14:20:16 +0100
parents 63138e0b8d68
children 2174b68b8b32
files src/route.c
diffstat 1 files changed, 18 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/route.c	Mon Jul 02 22:36:44 2018 +0100
+++ b/src/route.c	Sun Jul 15 14:20:16 2018 +0100
@@ -44,6 +44,21 @@
 #include "route.h"
 #include "sa.h"
 
+/*
+ * On some systems, host routes have no need for a netmask.
+ * However DHCP specifies host routes using an all-ones netmask.
+ * This handy function allows easy comparison when the two
+ * differ.
+ */
+static int
+rt_cmp_netmask(const struct rt *rt1, const struct rt *rt2)
+{
+
+	if (rt1->rt_flags & RTF_HOST && rt2->rt_flags & RTF_HOST)
+		return 0;
+	return sa_cmp(&rt1->rt_netmask, &rt2->rt_netmask);
+}
+
 void
 rt_init(struct dhcpcd_ctx *ctx)
 {
@@ -63,14 +78,12 @@
 
 	assert(cmd != NULL);
 	assert(rt != NULL);
-	assert(rt->rt_ifp != NULL);
 
-	ifname = rt->rt_ifp->name;
 	sa_addrtop(&rt->rt_dest, dest, sizeof(dest));
 	prefix = sa_toprefix(&rt->rt_netmask);
 	sa_addrtop(&rt->rt_gateway, gateway, sizeof(gateway));
-
 	gateway_unspec = sa_is_unspecified(&rt->rt_gateway);
+	ifname = rt->rt_ifp == NULL ? "(null)" : rt->rt_ifp->name;
 
 	if (rt->rt_flags & RTF_HOST) {
 		if (gateway_unspec)
@@ -236,7 +249,7 @@
 		    (f->rt_ifp == NULL ||
 		    rt->rt_ifp->metric == f->rt_ifp->metric) &&
 #endif
-		    sa_cmp(&rt->rt_netmask, &f->rt_netmask) == 0)
+		    rt_cmp_netmask(f, rt) == 0)
 			return rt;
 	}
 	return NULL;
@@ -345,7 +358,7 @@
 	    ort->rt_metric == nrt->rt_metric &&
 #endif
 	    sa_cmp(&ort->rt_dest, &nrt->rt_dest) == 0 &&
-	    sa_cmp(&ort->rt_netmask, &nrt->rt_netmask) == 0 &&
+	    rt_cmp_netmask(ort, nrt) == 0 &&
 	    sa_cmp(&ort->rt_gateway, &nrt->rt_gateway) == 0)
 	{
 		if (ort->rt_mtu == nrt->rt_mtu)