Index: interface.c =================================================================== --- interface.c (revision 260) +++ interface.c (working copy) @@ -441,6 +441,51 @@ 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) + 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 +539,6 @@ int change, int del) { int s; - char *dstd; struct rtm { struct rt_msghdr hdr; @@ -517,25 +561,8 @@ if (! ifname) return -1; - /* Do something with metric to satisfy compiler warnings */ - metric = 0; + log_route (destination, netmask, gateway, metric, change, del); - 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); - if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1) { logger (LOG_ERR, "socket: %s", strerror (errno)); return -1; @@ -546,12 +573,7 @@ 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; @@ -585,8 +607,11 @@ l = SA_SIZE (&(su.sa)); memcpy (bp, &su, l); bp += l; + + rtm.hdr.rtm_flags |= RTF_HOST; } else { ADDADDR (gateway); + rtm.hdr.rtm_flags |= RTF_GATEWAY; } ADDADDR (netmask); @@ -838,7 +863,6 @@ struct in_addr gateway, int metric, int change, int del) { - char *dstd; unsigned int ifindex; struct { @@ -847,26 +871,11 @@ 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 +894,7 @@ 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 +904,7 @@ 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) add_attr_l (&nlm.hdr, sizeof (nlm), RTA_GATEWAY, &gateway.s_addr, sizeof (gateway.s_addr)); Index: dhcp.c =================================================================== --- dhcp.c (revision 257) +++ dhcp.c (working copy) @@ -492,6 +492,33 @@ 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 @@ 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: ChangeLog =================================================================== --- ChangeLog (revision 259) +++ ChangeLog (working copy) @@ -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).