3333#include <stddef.h>
3434#include <stdlib.h>
3535#include <string.h>
36+ #include <syslog.h>
3637#include <unistd.h>
3738
3839#include "config.h"
@@ -255,7 +256,7 @@ rt_is_default(const struct rt *rt)
255256}
256257
257258static void
258- rt_desc (const char * cmd , const struct rt * rt )
259+ rt_desc (int loglevel , const char * cmd , const struct rt * rt )
259260{
260261 char dest [INET_MAX_ADDRSTRLEN ], gateway [INET_MAX_ADDRSTRLEN ];
261262 int prefix ;
@@ -273,25 +274,25 @@ rt_desc(const char *cmd, const struct rt *rt)
273274
274275 if (rt -> rt_flags & RTF_HOST ) {
275276 if (gateway_unspec )
276- loginfox ( "%s: %s host route to %s" ,
277+ logmessage ( loglevel , "%s: %s host route to %s" ,
277278 ifname , cmd , dest );
278279 else
279- loginfox ( "%s: %s host route to %s via %s" ,
280+ logmessage ( loglevel , "%s: %s host route to %s via %s" ,
280281 ifname , cmd , dest , gateway );
281282 } else if (rt_is_default (rt )) {
282283 if (gateway_unspec )
283- loginfox ( "%s: %s default route" ,
284+ logmessage ( loglevel , "%s: %s default route" ,
284285 ifname , cmd );
285286 else
286- loginfox ( "%s: %s default route via %s" ,
287+ logmessage ( loglevel , "%s: %s default route via %s" ,
287288 ifname , cmd , gateway );
288289 } else if (gateway_unspec )
289- loginfox ( "%s: %s%s route to %s/%d" ,
290+ logmessage ( loglevel , "%s: %s%s route to %s/%d" ,
290291 ifname , cmd ,
291292 rt -> rt_flags & RTF_REJECT ? " reject" : "" ,
292293 dest , prefix );
293294 else
294- loginfox ( "%s: %s%s route to %s/%d via %s" ,
295+ logmessage ( loglevel , "%s: %s%s route to %s/%d via %s" ,
295296 ifname , cmd ,
296297 rt -> rt_flags & RTF_REJECT ? " reject" : "" ,
297298 dest , prefix , gateway );
@@ -490,7 +491,7 @@ rt_recvrt(int cmd, const struct rt *rt, pid_t pid)
490491
491492 rb_tree_remove_node (& ctx -> routes , f );
492493 snprintf (buf , sizeof (buf ), "pid %d deleted" , pid );
493- rt_desc (buf , f );
494+ rt_desc (LOG_WARNING , buf , f );
494495 rt_free (f );
495496 }
496497 break ;
@@ -503,8 +504,8 @@ rt_recvrt(int cmd, const struct rt *rt, pid_t pid)
503504}
504505
505506/* Compare miscellaneous route details */
506- static bool
507- rt_cmp_misc (struct rt * nrt , struct rt * ort )
507+ static int
508+ rt_cmp_mtu (struct rt * nrt , struct rt * ort )
508509{
509510#if defined(__FreeBSD__ ) || defined(__DragonFly__ )
510511 /* FreeBSD puts the interface MTU into the route MTU
@@ -514,13 +515,19 @@ rt_cmp_misc(struct rt *nrt, struct rt *ort)
514515 nmtu = nrt -> rt_mtu ? nrt -> rt_mtu : (unsigned int )nrt -> rt_ifp -> mtu ;
515516 omtu = ort -> rt_mtu ? ort -> rt_mtu : (unsigned int )ort -> rt_ifp -> mtu ;
516517 if (omtu != nmtu )
517- return false ;
518+ return 1 ;
518519#else
519520 if (ort -> rt_mtu != nrt -> rt_mtu )
520- return false ;
521+ return 1 ;
521522#endif
522523
524+ return 0 ;
525+ }
526+
523527#ifdef HAVE_ROUTE_LIFETIME
528+ static int
529+ rt_cmp_lifetime (struct rt * nrt , struct rt * ort )
530+ {
524531 /* There might be a minor difference between kernel route
525532 * lifetime and our lifetime due to processing times.
526533 * We allow a small deviation to avoid needless route changes.
@@ -533,23 +540,25 @@ rt_cmp_misc(struct rt *nrt, struct rt *ort)
533540 if (ts .tv_sec < 0 )
534541 ts .tv_sec = - ts .tv_sec ;
535542 if (ts .tv_sec > RTLIFETIME_DEV_MAX )
536- return false ;
543+ return 1 ;
537544 if (nrt -> rt_lifetime > ort -> rt_lifetime )
538545 deviation = nrt -> rt_lifetime - ort -> rt_lifetime ;
539546 else
540547 deviation = ort -> rt_lifetime - nrt -> rt_lifetime ;
541548 if (deviation > RTLIFETIME_DEV_MAX )
542- return false;
543- #endif
549+ return 1 ;
544550
545- return true ;
551+ return 0 ;
546552}
553+ #endif
547554
548555static bool
549556rt_add (rb_tree_t * kroutes , struct rt * nrt , struct rt * ort )
550557{
551558 struct dhcpcd_ctx * ctx ;
552- bool change , kroute , result ;
559+ struct rt * krt ;
560+ int loglevel = LOG_INFO ;
561+ bool change , result ;
553562
554563 assert (nrt != NULL );
555564 ctx = nrt -> rt_ifp -> ctx ;
@@ -569,46 +578,40 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort)
569578 sa_is_unspecified (& nrt -> rt_netmask ))
570579 return false;
571580
572- rt_desc (ort == NULL ? "adding" : "changing" , nrt );
573-
574- change = kroute = result = false;
575- if (ort == NULL ) {
576- ort = rb_tree_find_node (kroutes , nrt );
577- if (ort != NULL &&
578- ((ort -> rt_flags & RTF_REJECT &&
579- nrt -> rt_flags & RTF_REJECT ) ||
580- (ort -> rt_ifp == nrt -> rt_ifp &&
581+ krt = rb_tree_find_node (kroutes , nrt );
582+ if (krt != NULL &&
583+ krt -> rt_ifp == nrt -> rt_ifp &&
584+ /* Only test flags dhcpcd controls */
585+ (krt -> rt_flags & (RTF_HOST | RTF_REJECT )) == nrt -> rt_flags &&
581586#ifdef HAVE_ROUTE_METRIC
582- ort -> rt_metric == nrt -> rt_metric &&
587+ krt -> rt_metric == nrt -> rt_metric &&
583588#endif
584- sa_cmp (& ort -> rt_gateway , & nrt -> rt_gateway ) == 0 )))
585- {
586- if (rt_cmp_misc (nrt , ort ))
587- return true;
588- change = true;
589- kroute = true;
590- }
591- } else if (ort -> rt_dflags & RTDF_FAKE &&
592- !(nrt -> rt_dflags & RTDF_FAKE ) &&
593- ort -> rt_ifp == nrt -> rt_ifp &&
594- #ifdef HAVE_ROUTE_METRIC
595- ort -> rt_metric == nrt -> rt_metric &&
596- #endif
597- sa_cmp (& ort -> rt_dest , & nrt -> rt_dest ) == 0 &&
598- rt_cmp_netmask (ort , nrt ) == 0 &&
599- sa_cmp (& ort -> rt_gateway , & nrt -> rt_gateway ) == 0 )
589+ sa_cmp (& krt -> rt_dest , & nrt -> rt_dest ) == 0 &&
590+ rt_cmp_netmask (krt , nrt ) == 0 &&
591+ sa_cmp (& krt -> rt_gateway , & nrt -> rt_gateway ) == 0 &&
592+ rt_cmp_mtu (krt , nrt ) == 0 )
600593 {
601- if (rt_cmp_misc (nrt , ort ))
594+ #ifdef HAVE_ROUTE_LIFETIME
595+ if (rt_cmp_lifetime (krt , nrt ) == 0 ) {
596+ rt_desc (LOG_DEBUG , "keeping" , krt );
602597 return true;
603- change = true;
598+ } else
599+ loglevel = LOG_DEBUG ;
600+ #else
601+ rt_desc (LOG_DEBUG , "keeping" , krt );
602+ return true;
603+ #endif
604604 }
605605
606+ rt_desc (loglevel , ort == NULL ? "adding" : "changing" , nrt );
607+
608+ change = krt != NULL ;
606609#ifdef RTF_CLONING
607610 /* BSD can set routes to be cloning routes.
608611 * Cloned routes inherit the parent flags.
609612 * As such, we need to delete and re-add the route to flush children
610613 * to correct the flags. */
611- if (change && ort != NULL && ort -> rt_flags & RTF_CLONING )
614+ if (change && krt != NULL && krt -> rt_flags & RTF_CLONING )
612615 change = false;
613616#endif
614617
@@ -625,8 +628,8 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort)
625628 /* With route metrics, we can safely add the new route before
626629 * deleting the old route. */
627630 if (if_route (RTM_ADD , nrt ) != -1 ) {
628- if (ort != NULL ) {
629- if (if_route (RTM_DELETE , ort ) == -1 && errno != ESRCH )
631+ if (krt != NULL ) {
632+ if (if_route (RTM_DELETE , krt ) == -1 && errno != ESRCH )
630633 logerr ("if_route (DEL)" );
631634 }
632635 result = true;
@@ -644,19 +647,17 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort)
644647#ifdef ROUTE_PER_GATEWAY
645648 errno = 0 ;
646649#endif
647- if (ort != NULL ) {
648- if (if_route (RTM_DELETE , ort ) == -1 && errno != ESRCH )
650+ if (krt != NULL ) {
651+ if (if_route (RTM_DELETE , krt ) == -1 && errno != ESRCH )
649652 logerr ("if_route (DEL)" );
650- else
651- kroute = false;
652653 }
653654#ifdef ROUTE_PER_GATEWAY
654655 /* The OS allows many routes to the same dest with different gateways.
655656 * dhcpcd does not support this yet, so for the time being just keep on
656657 * deleting the route until there is an error. */
657- if (ort != NULL && errno == 0 ) {
658+ if (krt != NULL && errno == 0 ) {
658659 for (;;) {
659- if (if_route (RTM_DELETE , ort ) == -1 )
660+ if (if_route (RTM_DELETE , krt ) == -1 )
660661 break ;
661662 }
662663 }
@@ -675,9 +676,9 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort)
675676 logerr ("if_route (ADD)" );
676677
677678out :
678- if (kroute ) {
679- rb_tree_remove_node (kroutes , ort );
680- rt_free (ort );
679+ if (krt != NULL ) {
680+ rb_tree_remove_node (kroutes , krt );
681+ rt_free (krt );
681682 }
682683 return result ;
683684}
@@ -687,22 +688,24 @@ rt_delete(struct rt *rt)
687688{
688689 int retval ;
689690
690- rt_desc ("deleting" , rt );
691+ rt_desc (LOG_INFO , "deleting" , rt );
691692 retval = if_route (RTM_DELETE , rt ) == -1 ? false : true;
692693 if (!retval && errno != ENOENT && errno != ESRCH )
693694 logerr (__func__ );
694695 return retval ;
695696}
696697
697- static bool
698+ static int
698699rt_cmp (const struct rt * r1 , const struct rt * r2 )
699700{
700701
701- return (r1 -> rt_ifp == r2 -> rt_ifp &&
702+ if (r1 -> rt_ifp == r2 -> rt_ifp &&
702703#ifdef HAVE_ROUTE_METRIC
703704 r1 -> rt_metric == r2 -> rt_metric &&
704705#endif
705- sa_cmp (& r1 -> rt_gateway , & r2 -> rt_gateway ) == 0 );
706+ sa_cmp (& r1 -> rt_gateway , & r2 -> rt_gateway ) == 0 )
707+ return 0 ;
708+ return 1 ;
706709}
707710
708711static bool
@@ -718,10 +721,13 @@ rt_doroute(rb_tree_t *kroutes, struct rt *rt)
718721 if (rt -> rt_dflags & RTDF_FAKE )
719722 return true;
720723 if (or -> rt_dflags & RTDF_FAKE ||
721- ! rt_cmp (rt , or ) ||
724+ rt_cmp (rt , or ) != 0 ||
722725 (rt -> rt_ifa .sa_family != AF_UNSPEC &&
723726 sa_cmp (& or -> rt_ifa , & rt -> rt_ifa ) != 0 ) ||
724- !rt_cmp_misc (rt , or ))
727+ #ifdef HAVE_ROUTE_LIFETIME
728+ rt_cmp_lifetime (rt , or ) != 0 ||
729+ #endif
730+ rt_cmp_mtu (rt , or ) != 0 )
725731 {
726732 if (!rt_add (kroutes , rt , or ))
727733 return false;
@@ -733,7 +739,7 @@ rt_doroute(rb_tree_t *kroutes, struct rt *rt)
733739 or = rb_tree_find_node (kroutes , rt );
734740 if (or == NULL )
735741 return false;
736- if (! rt_cmp (rt , or ))
742+ if (rt_cmp (rt , or ) == 0 )
737743 return false;
738744 } else {
739745 if (!rt_add (kroutes , rt , NULL ))
0 commit comments