Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys let gif(4) promise softint(9) contract (1/2) : gif(4) side
details: https://anonhg.NetBSD.org/src/rev/c605d19b3437
branches: trunk
changeset: 346257:c605d19b3437
user: knakahara <knakahara%NetBSD.org@localhost>
date: Mon Jul 04 04:14:47 2016 +0000
description:
let gif(4) promise softint(9) contract (1/2) : gif(4) side
To prevent calling softint_schedule() after called softint_disestablish(),
the following modifications are added
+ ioctl (writing configuration) side
- off IFF_RUNNING flag before changing configuration
- wait softint handler completion before changing configuration
+ packet processing (reading configuraiotn) side
- if IFF_RUNNING flag is on, do nothing
+ in whole
- add gif_list_lock_{enter,exit} to prevent the same configuration is
set to other gif(4) interfaces
diffstat:
sys/net/if_gif.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++---
sys/netinet/in_gif.c | 7 +++--
sys/netinet6/in6_gif.c | 7 +++--
3 files changed, 68 insertions(+), 10 deletions(-)
diffs (220 lines):
diff -r b1f0bc7cc5d8 -r c605d19b3437 sys/net/if_gif.c
--- a/sys/net/if_gif.c Mon Jul 04 03:04:25 2016 +0000
+++ b/sys/net/if_gif.c Mon Jul 04 04:14:47 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gif.c,v 1.113 2016/06/27 09:06:56 knakahara Exp $ */
+/* $NetBSD: if_gif.c,v 1.114 2016/07/04 04:14:47 knakahara Exp $ */
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.113 2016/06/27 09:06:56 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.114 2016/07/04 04:14:47 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -53,6 +53,7 @@
#include <sys/intr.h>
#include <sys/kmem.h>
#include <sys/sysctl.h>
+#include <sys/xcall.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -107,6 +108,10 @@
static int gif_encap_attach(struct gif_softc *);
static int gif_encap_detach(struct gif_softc *);
+static void gif_encap_pause(struct gif_softc *);
+
+static void gif_list_lock_enter(void);
+static void gif_list_lock_exit(void);
static struct if_clone gif_cloner =
IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
@@ -226,7 +231,8 @@
if (sc == NULL)
return 0;
- if ((sc->gif_if.if_flags & IFF_UP) == 0)
+ if ((sc->gif_if.if_flags & (IFF_UP|IFF_RUNNING))
+ != (IFF_UP|IFF_RUNNING))
return 0;
/* no physical address */
@@ -329,7 +335,7 @@
}
m->m_flags &= ~(M_BCAST|M_MCAST);
- if (!(ifp->if_flags & IFF_UP) ||
+ if (((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) ||
sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
m_freem(m);
error = ENETDOWN;
@@ -776,6 +782,25 @@
return error;
}
+static void
+gif_encap_pause(struct gif_softc *sc)
+{
+ struct ifnet *ifp = &sc->gif_if;
+ uint64_t where;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+ /* membar_sync() is done in xc_broadcast(). */
+
+ /*
+ * Wait for softint_execute()(ipintr() or ip6intr())
+ * completion done by other CPUs which already run over if_flags
+ * check in in_gif_input() or in6_gif_input().
+ * Furthermore, wait for gif_output() completion too.
+ */
+ where = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
+ xc_wait(where);
+}
+
static int
gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst)
{
@@ -787,6 +812,7 @@
int error;
s = splsoftnet();
+ gif_list_lock_enter();
LIST_FOREACH(sc2, &gif_softc_list, gif_list) {
if (sc2 == sc)
@@ -797,6 +823,7 @@
if (sockaddr_cmp(sc2->gif_pdst, dst) == 0 &&
sockaddr_cmp(sc2->gif_psrc, src) == 0) {
/* continue to use the old configureation. */
+ gif_list_lock_exit();
splx(s);
return EADDRNOTAVAIL;
}
@@ -805,15 +832,19 @@
}
if ((nsrc = sockaddr_dup(src, M_WAITOK)) == NULL) {
+ gif_list_lock_exit();
splx(s);
return ENOMEM;
}
if ((ndst = sockaddr_dup(dst, M_WAITOK)) == NULL) {
sockaddr_free(nsrc);
+ gif_list_lock_exit();
splx(s);
return ENOMEM;
}
+ gif_encap_pause(sc);
+
/* Firstly, clear old configurations. */
/* XXX we can detach from both, but be polite just in case */
if (sc->gif_psrc)
@@ -858,6 +889,7 @@
else
ifp->if_flags &= ~IFF_RUNNING;
+ gif_list_lock_exit();
splx(s);
return error;
}
@@ -869,7 +901,9 @@
int s;
s = splsoftnet();
+ gif_list_lock_enter();
+ gif_encap_pause(sc);
if (sc->gif_psrc) {
sockaddr_free(sc->gif_psrc);
sc->gif_psrc = NULL;
@@ -890,5 +924,27 @@
ifp->if_flags |= IFF_RUNNING;
else
ifp->if_flags &= ~IFF_RUNNING;
+
+ gif_list_lock_exit();
splx(s);
}
+
+static void
+gif_list_lock_enter(void)
+{
+
+ /* XXX future work
+ * should change interruptable lock.
+ */
+ KERNEL_LOCK(1, NULL);
+}
+
+static void
+gif_list_lock_exit(void)
+{
+
+ /* XXX future work
+ * should change interruptable lock.
+ */
+ KERNEL_UNLOCK_ONE(NULL);
+}
diff -r b1f0bc7cc5d8 -r c605d19b3437 sys/netinet/in_gif.c
--- a/sys/netinet/in_gif.c Mon Jul 04 03:04:25 2016 +0000
+++ b/sys/netinet/in_gif.c Mon Jul 04 04:14:47 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in_gif.c,v 1.76 2016/06/10 13:31:44 ozaki-r Exp $ */
+/* $NetBSD: in_gif.c,v 1.77 2016/07/04 04:14:47 knakahara Exp $ */
/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.76 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.77 2016/07/04 04:14:47 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -206,7 +206,8 @@
gifp = (struct ifnet *)encap_getarg(m);
- if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) {
+ if (gifp == NULL || (gifp->if_flags & (IFF_UP|IFF_RUNNING))
+ != (IFF_UP|IFF_RUNNING)) {
m_freem(m);
ip_statinc(IP_STAT_NOGIF);
return;
diff -r b1f0bc7cc5d8 -r c605d19b3437 sys/netinet6/in6_gif.c
--- a/sys/netinet6/in6_gif.c Mon Jul 04 03:04:25 2016 +0000
+++ b/sys/netinet6/in6_gif.c Mon Jul 04 04:14:47 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_gif.c,v 1.75 2016/06/28 02:02:56 ozaki-r Exp $ */
+/* $NetBSD: in6_gif.c,v 1.76 2016/07/04 04:14:47 knakahara Exp $ */
/* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.75 2016/06/28 02:02:56 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.76 2016/07/04 04:14:47 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -215,7 +215,8 @@
gifp = (struct ifnet *)encap_getarg(m);
- if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) {
+ if (gifp == NULL || (gifp->if_flags & (IFF_UP|IFF_RUNNING))
+ != (IFF_UP|IFF_RUNNING)) {
m_freem(m);
IP6_STATINC(IP6_STAT_NOGIF);
return IPPROTO_DONE;
Home |
Main Index |
Thread Index |
Old Index