Module Name:    src
Committed By:   ozaki-r
Date:           Tue Dec 20 03:35:13 UTC 2016

Modified Files:
        src/sbin/routed: table.c

Log Message:
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!


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sbin/routed/table.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/routed/table.c
diff -u src/sbin/routed/table.c:1.26 src/sbin/routed/table.c:1.27
--- src/sbin/routed/table.c:1.26	Fri Oct  7 22:32:50 2016
+++ src/sbin/routed/table.c	Tue Dec 20 03:35:12 2016
@@ -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 */

Reply via email to