Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Allow CARP to call the link_state_change handler immedia...



details:   https://anonhg.NetBSD.org/src/rev/231e6b5ed6a2
branches:  trunk
changeset: 824025:231e6b5ed6a2
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Fri May 19 08:53:51 2017 +0000

description:
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

diffstat:

 sys/net/if.c          |  19 ++++++++++++-------
 sys/net/if.h          |   3 ++-
 sys/netinet/ip_carp.c |   6 +++---
 3 files changed, 17 insertions(+), 11 deletions(-)

diffs (104 lines):

diff -r 0a65b0d2fded -r 231e6b5ed6a2 sys/net/if.c
--- a/sys/net/if.c      Fri May 19 07:40:58 2017 +0000
+++ b/sys/net/if.c      Fri May 19 08:53:51 2017 +0000
@@ -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 @@
 
 /*
  * 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 (dp->dom_if_link_state_change != NULL)
                        dp->dom_if_link_state_change(ifp, link_state);
        }
+       splx(s);
 }
 
 /*
@@ -2321,7 +2326,7 @@
 
        /* 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)
diff -r 0a65b0d2fded -r 231e6b5ed6a2 sys/net/if.h
--- a/sys/net/if.h      Fri May 19 07:40:58 2017 +0000
+++ b/sys/net/if.h      Fri May 19 08:53:51 2017 +0000
@@ -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_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);
diff -r 0a65b0d2fded -r 231e6b5ed6a2 sys/netinet/ip_carp.c
--- a/sys/netinet/ip_carp.c     Fri May 19 07:40:58 2017 +0000
+++ b/sys/netinet/ip_carp.c     Fri May 19 08:53:51 2017 +0000
@@ -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 @@
                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



Home | Main Index | Thread Index | Old Index