From: Roy Marples Date: Tue, 31 Jul 2007 09:50:48 +0000 (+0000) Subject: Fix static routes X-Git-Tag: v3.2.3~222 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2774c970bd495ccd02ffd71dcb42fa0c99f19908;p=thirdparty%2Fdhcpcd.git Fix static routes --- diff --git a/ChangeLog b/ChangeLog index 23d7f91a..81954986 100644 --- 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). diff --git a/Makefile b/Makefile index 9a97fd78..ef0fb73d 100644 --- 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 268ad5d3..52571c4f 100644 --- 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; diff --git a/interface.c b/interface.c index 58ca80ac..3420b5de 100644 --- a/interface.c +++ b/interface.c @@ -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));