Module Name:    src
Committed By:   ozaki-r
Date:           Fri May 19 08:53:51 UTC 2017

Modified Files:
        src/sys/net: if.c if.h
        src/sys/netinet: ip_carp.c

Log Message:
Allow CARP to call the link_state_change handler immediately

If the handler is delayed because of the indirection call via softint,
some operations are executed in reverse and may cause unexpected
behaviors. For example, due to the issue a GARP packet wasn't sent on
a transition from the BACKUP state to the MASTER state; this happened
because IN_IFF_DETACHED flag wasn't cleared on arpannounce, which
had been cleared in the link_state_change handler.

This fixes an issue reported by sborrill@ on tech-net:
  http://mail-index.netbsd.org/tech-net/2017/03/14/msg006283.html


To generate a diff of this commit:
cvs rdiff -u -r1.392 -r1.393 src/sys/net/if.c
cvs rdiff -u -r1.238 -r1.239 src/sys/net/if.h
cvs rdiff -u -r1.89 -r1.90 src/sys/netinet/ip_carp.c

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

Modified files:

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.392 src/sys/net/if.c:1.393
--- src/sys/net/if.c:1.392	Thu Apr  6 09:20:07 2017
+++ src/sys/net/if.c	Fri May 19 08:53:51 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.392 2017/04/06 09:20:07 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.393 2017/05/19 08:53:51 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.392 2017/04/06 09:20:07 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.393 2017/05/19 08:53:51 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -2247,16 +2247,20 @@ out:
 
 /*
  * Handle interface link state change notifications.
- * Must be called at splnet().
  */
-static void
-if_link_state_change0(struct ifnet *ifp, int link_state)
+void
+if_link_state_change_softint(struct ifnet *ifp, int link_state)
 {
 	struct domain *dp;
+	int s = splnet();
+
+	KASSERT(!cpu_intr_p());
 
 	/* Ensure the change is still valid. */
-	if (ifp->if_link_state == link_state)
+	if (ifp->if_link_state == link_state) {
+		splx(s);
 		return;
+	}
 
 #ifdef DEBUG
 	log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname,
@@ -2301,6 +2305,7 @@ if_link_state_change0(struct ifnet *ifp,
 		if (dp->dom_if_link_state_change != NULL)
 			dp->dom_if_link_state_change(ifp, link_state);
 	}
+	splx(s);
 }
 
 /*
@@ -2321,7 +2326,7 @@ if_link_state_change_si(void *arg)
 
 	/* Pop a link state change from the queue and process it. */
 	LQ_POP(ifp->if_link_queue, state);
-	if_link_state_change0(ifp, state);
+	if_link_state_change_softint(ifp, state);
 
 	/* If there is a link state change to come, schedule it. */
 	if (LQ_ITEM(ifp->if_link_queue, 0) != LINK_STATE_UNSET)

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.238 src/sys/net/if.h:1.239
--- src/sys/net/if.h:1.238	Thu Apr  6 03:54:59 2017
+++ src/sys/net/if.h	Fri May 19 08:53:51 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.238 2017/04/06 03:54:59 ozaki-r Exp $	*/
+/*	$NetBSD: if.h,v 1.239 2017/05/19 08:53:51 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -956,6 +956,7 @@ void	if_purgeaddrs(struct ifnet *, int, 
 void	if_detach(struct ifnet *);
 void	if_down(struct ifnet *);
 void	if_link_state_change(struct ifnet *, int);
+void	if_link_state_change_softint(struct ifnet *, int);
 void	if_up(struct ifnet *);
 void	ifinit(void);
 void	ifinit1(void);

Index: src/sys/netinet/ip_carp.c
diff -u src/sys/netinet/ip_carp.c:1.89 src/sys/netinet/ip_carp.c:1.90
--- src/sys/netinet/ip_carp.c:1.89	Fri May 12 17:53:54 2017
+++ src/sys/netinet/ip_carp.c	Fri May 19 08:53:51 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_carp.c,v 1.89 2017/05/12 17:53:54 ryo Exp $	*/
+/*	$NetBSD: ip_carp.c,v 1.90 2017/05/19 08:53:51 ozaki-r Exp $	*/
 /*	$OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.89 2017/05/12 17:53:54 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.90 2017/05/19 08:53:51 ozaki-r Exp $");
 
 /*
  * TODO:
@@ -2191,7 +2191,7 @@ carp_set_state(struct carp_softc *sc, in
 		link_state = LINK_STATE_UNKNOWN;
 		break;
 	}
-	if_link_state_change(&sc->sc_if, link_state);
+	if_link_state_change_softint(&sc->sc_if, link_state);
 }
 
 void

Reply via email to