]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix static routes
authorRoy Marples <roy@marples.name>
Tue, 31 Jul 2007 09:50:48 +0000 (09:50 +0000)
committerRoy Marples <roy@marples.name>
Tue, 31 Jul 2007 09:50:48 +0000 (09:50 +0000)
ChangeLog
Makefile
dhcp.c
interface.c

index 23d7f91a86f3cc23aa17c0d4e56a4ace86de6e3a..81954986fc29a83146bad5628996d285d7600a3e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+Use a generic route logger.
+Fix static route netmask calculation and applicaton.
 Use --nodeps when restarting services.
 Simply CIDR calculation, thanks to Francois-Xavier Le Bail.
 Don't free the dhcp object on RENEW (fixes a segfault).
index 9a97fd78e5867252f061e88e2edee6b7a570dec5..ef0fb73d2b406fb071f039b5cb04177af5cc108d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION = 3.1.1
+VERSION = 3.1.2
 CFLAGS ?= -O2 -pipe
 
 # Should work for both GNU make and BSD make
diff --git a/dhcp.c b/dhcp.c
index 268ad5d3345fe550b2f2b578b9e1bc451ba4cc29..52571c4fbae9c2b7143c2f99c4eadf8c3da3d664 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -492,6 +492,33 @@ static char *decode_sipservers (const unsigned char *data, int length)
        return (sip);
 }
 
+/* This calculates the netmask that we should use for static routes.
+ * This IS different from the calculation used to calculate the netmask
+ * for an interface address. */
+static unsigned long route_netmask (unsigned long ip_in)
+{
+       unsigned long p = ntohl (ip_in);
+       unsigned long t;
+
+       if (IN_CLASSA (p))
+               t = ~IN_CLASSA_NET;
+       else {
+               if (IN_CLASSB (p))
+                       t = ~IN_CLASSB_NET;
+               else {
+                       if (IN_CLASSC (p))
+                               t = ~IN_CLASSC_NET;
+                       else
+                               t = 0;
+               }
+       }
+
+       while (t & p)
+               t >>= 1;
+
+       return (htonl (~t));
+}
+
 int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
 {
        const unsigned char *p = message->options;
@@ -705,7 +732,7 @@ parse_start:
                                        memcpy (&static_routesp->destination.s_addr, p + i, 4);
                                        memcpy (&static_routesp->gateway.s_addr, p + i + 4, 4);
                                        static_routesp->netmask.s_addr =
-                                               get_netmask (static_routesp->destination.s_addr); 
+                                               route_netmask (static_routesp->destination.s_addr); 
                                }
                                break;
 
index 58ca80ac3705bc260c338acbfe2aad0ec111ace1..3420b5de404a52531c19e4eef4c266a64e4d4d7a 100644 (file)
@@ -441,6 +441,52 @@ int set_mtu (const char *ifname, short int mtu)
        return (r == 0 ? 0 : -1);
 }
 
+static void log_route( 
+                                         struct in_addr destination,
+                                         struct in_addr netmask,
+                                         struct in_addr gateway,
+                                         int metric,
+                                         int change, int del)
+{
+       char *dstd = xstrdup (inet_ntoa (destination));
+
+#ifdef __linux__
+#define METRIC " metric %d"
+#else
+#define METRIC ""
+       metric = 0;
+#endif
+
+       if (gateway.s_addr == destination.s_addr ||
+               gateway.s_addr == INADDR_ANY)
+               logger (LOG_INFO, "%s route to %s/%d" METRIC,
+                               change ? "changing" : del ? "removing" : "adding",
+                               dstd, inet_ntocidr (netmask)
+#ifdef __linux__
+                               , metric
+#endif
+                          );
+       else if (destination.s_addr == INADDR_ANY)
+               logger (LOG_INFO, "%s default route via %s" METRIC,
+                               change ? "changing" : del ? "removing" : "adding",
+                               inet_ntoa (gateway)
+
+#ifdef __linux__
+                               , metric
+#endif
+                          );
+       else
+               logger (LOG_INFO, "%s route to %s/%d via %s" METRIC,
+                               change ? "changing" : del ? "removing" : "adding",
+                               dstd, inet_ntocidr (netmask), inet_ntoa (gateway)
+#ifdef __linux__
+                               , metric
+#endif
+                          );
+
+       free (dstd);
+}
+
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) \
 || defined(__APPLE__)
 static int do_address (const char *ifname, struct in_addr address,
@@ -494,7 +540,6 @@ static int do_route (const char *ifname,
                                         int change, int del)
 {
        int s;
-       char *dstd;
        struct rtm 
        {
                struct rt_msghdr hdr;
@@ -517,24 +562,7 @@ static int do_route (const char *ifname,
        if (! ifname)
                return -1;
 
-       /* Do something with metric to satisfy compiler warnings */
-       metric = 0;
-
-       dstd = xstrdup (inet_ntoa (destination));
-       if (gateway.s_addr == destination.s_addr)
-               logger (LOG_INFO, "%s route to %s/%d",
-                               change ? "changing" : del ? "removing" : "adding",
-                               dstd, inet_ntocidr (netmask));
-       else if (destination.s_addr == INADDR_ANY)
-               logger (LOG_INFO, "%s default route via %s",
-                               change ? "changing" : del ? "removing" : "adding",
-                               inet_ntoa (gateway));
-       else
-               logger (LOG_INFO, "%s route to %s/%d via %s",
-                               change ? "changing" : del ? "removing" : "adding",
-                               dstd, inet_ntocidr (netmask), inet_ntoa (gateway));
-       if (dstd)
-               free (dstd);
+       log_route (destination, netmask, gateway, metric, change, del);
 
        if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1) {
                logger (LOG_ERR, "socket: %s", strerror (errno));
@@ -546,12 +574,7 @@ static int do_route (const char *ifname,
        rtm.hdr.rtm_version = RTM_VERSION;
        rtm.hdr.rtm_seq = ++seq;
        rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
-
        rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC;
-       if (netmask.s_addr == INADDR_BROADCAST)
-               rtm.hdr.rtm_flags |= RTF_HOST;
-       else
-               rtm.hdr.rtm_flags |= RTF_GATEWAY;
 
        /* This order is important */
        rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
@@ -567,11 +590,16 @@ static int do_route (const char *ifname,
 
        ADDADDR (destination);
 
-       if (netmask.s_addr == INADDR_BROADCAST) {
+       if (netmask.s_addr == INADDR_BROADCAST ||
+               gateway.s_addr == INADDR_ANY)
+       {
                /* Make us a link layer socket */
                unsigned char hwaddr[HWADDR_LEN];
                int hwlen = 0;
 
+               if (netmask.s_addr == INADDR_BROADCAST) 
+                       rtm.hdr.rtm_flags |= RTF_HOST;
+
                _do_interface (ifname, hwaddr, &hwlen, NULL, false, false);
                memset (&su, 0, sizeof (struct sockaddr_storage));
                su.sdl.sdl_len = sizeof (struct sockaddr_dl);
@@ -586,6 +614,7 @@ static int do_route (const char *ifname,
                memcpy (bp, &su, l);
                bp += l;
        } else {
+               rtm.hdr.rtm_flags |= RTF_GATEWAY;
                ADDADDR (gateway);
        }
 
@@ -838,7 +867,6 @@ static int do_route (const char *ifname,
                                         struct in_addr gateway,
                                         int metric, int change, int del)
 {
-       char *dstd;
        unsigned int ifindex;
        struct
        {
@@ -847,26 +875,11 @@ static int do_route (const char *ifname,
                char buffer[256];
        }
        nlm;
-       int cidr = inet_ntocidr (netmask);
 
        if (! ifname)
                return -1;
 
-       dstd = xstrdup (inet_ntoa (destination));
-       if (gateway.s_addr == destination.s_addr)
-               logger (LOG_INFO, "%s route to %s/%d metric %d",
-                               change ? "changing" : del ? "removing" : "adding",
-                               dstd, cidr, metric);
-       else if (destination.s_addr == INADDR_ANY && netmask.s_addr == INADDR_ANY)
-               logger (LOG_INFO, "%s default route via %s metric %d",
-                               change ? "changing" : del ? "removing" : "adding",
-                               inet_ntoa (gateway), metric);
-       else
-               logger (LOG_INFO, "%s route to %s/%d via %s metric %d",
-                               change ? "changing" : del ? "removing" : "adding",
-                               dstd, cidr, inet_ntoa (gateway), metric);
-       if (dstd)
-               free (dstd);
+       log_route (destination, netmask, gateway, metric, change, del);
 
        memset (&nlm, 0, sizeof (nlm));
 
@@ -885,7 +898,7 @@ static int do_route (const char *ifname,
        else {
                nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
                nlm.rt.rtm_protocol = RTPROT_BOOT;
-               if (gateway.s_addr == INADDR_ANY)
+               if (netmask.s_addr == INADDR_BROADCAST)
                        nlm.rt.rtm_scope = RT_SCOPE_LINK;
                else
                        nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE;
@@ -895,7 +908,8 @@ static int do_route (const char *ifname,
        nlm.rt.rtm_dst_len = inet_ntocidr (netmask);
        add_attr_l (&nlm.hdr, sizeof (nlm), RTA_DST, &destination.s_addr,
                                sizeof (destination.s_addr));
-       if (gateway.s_addr != INADDR_ANY && gateway.s_addr != destination.s_addr)
+       if (netmask.s_addr != INADDR_BROADCAST &&
+               destination.s_addr != gateway.s_addr)
                add_attr_l (&nlm.hdr, sizeof (nlm), RTA_GATEWAY, &gateway.s_addr,
                                        sizeof (gateway.s_addr));