From e3db1a05a1b2399b8d728a51225622a103c692e5 Mon Sep 17 00:00:00 2001 From: ozaki-r Date: Tue, 20 Dec 2016 03:35:12 +0000 Subject: [PATCH] Fix that routed deletes local routes routed previousely ignored local routes, which have RTF_LOCAL flag, because such routes have RTF_LLINFO and routed ignored routes having the flag. When we obsoleted RTF_LLINFO, we removed the ignoring logic from routed, then routed started removing local routes unexpectedly. Fix this behavior by teaching local routes to routed to ignore them. kardel@ reported the issue and helped testing, thanks! --- sbin/routed/table.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sbin/routed/table.c b/sbin/routed/table.c index d05f2136fed8..7768924d6e3d 100644 --- a/sbin/routed/table.c +++ b/sbin/routed/table.c @@ -1,4 +1,4 @@ -/* $NetBSD: table.c,v 1.26 2016/10/07 22:32:50 joerg Exp $ */ +/* $NetBSD: table.c,v 1.27 2016/12/20 03:35:12 ozaki-r Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -36,7 +36,7 @@ #include "defs.h" #ifdef __NetBSD__ -__RCSID("$NetBSD: table.c,v 1.26 2016/10/07 22:32:50 joerg Exp $"); +__RCSID("$NetBSD: table.c,v 1.27 2016/12/20 03:35:12 ozaki-r Exp $"); #elif defined(__FreeBSD__) __RCSID("$FreeBSD$"); #else @@ -778,6 +778,7 @@ static struct khash { #define KS_DYNAMIC 0x080 /* result of redirect */ #define KS_DELETED 0x100 /* already deleted from kernel */ #define KS_CHECK 0x200 +#define KS_LOCAL 0x400 time_t k_keep; #define K_KEEP_LIM 30 time_t k_redirect_time; /* when redirected route 1st seen */ @@ -924,11 +925,13 @@ rtm_add(struct rt_msghdr *rtm, } k->k_state &= ~(KS_DELETE | KS_ADD | KS_CHANGE | KS_DEL_ADD | KS_DELETED | KS_GATEWAY | KS_STATIC - | KS_NEW | KS_CHECK); + | KS_NEW | KS_CHECK | KS_LOCAL); if (rtm->rtm_flags & RTF_GATEWAY) k->k_state |= KS_GATEWAY; if (rtm->rtm_flags & RTF_STATIC) k->k_state |= KS_STATIC; + if (rtm->rtm_flags & RTF_LOCAL) + k->k_state |= KS_LOCAL; if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) { if (INFO_AUTHOR(info) != 0 @@ -964,7 +967,7 @@ rtm_add(struct rt_msghdr *rtm, /* If it is not a static route, quit until the next comparison * between the kernel and daemon tables, when it will be deleted. */ - if (!(k->k_state & KS_STATIC)) { + if (!(k->k_state & KS_STATIC) && !(k->k_state & KS_LOCAL)) { k->k_state |= KS_DELETE; LIM_SEC(need_kern, k->k_keep); return; @@ -1363,7 +1366,7 @@ kern_out(struct ag_info *ag) return; } - if (k->k_state & KS_STATIC) + if ((k->k_state & KS_STATIC) || (k->k_state & KS_LOCAL)) return; /* modify existing kernel entry if necessary */ @@ -1512,6 +1515,12 @@ fix_kern(void) continue; } + /* Do not touch local routes */ + if (k->k_state & KS_LOCAL) { + pk = &k->k_next; + continue; + } + /* check hold on routes deleted by the operator */ if (k->k_keep > now.tv_sec) { /* ensure we check when the hold is over */