Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net make workqueue sppp_{set, clear}_ip_addrs to be able ...
details: https://anonhg.NetBSD.org/src/rev/ca444d7e38ea
branches: trunk
changeset: 819272:ca444d7e38ea
user: knakahara <knakahara%NetBSD.org@localhost>
date: Fri Nov 25 05:03:12 2016 +0000
description:
make workqueue sppp_{set,clear}_ip_addrs to be able to call pserialize_perform.
diffstat:
sys/net/if_spppsubr.c | 108 +++++++++++++++++++++++++++++++++++++------------
sys/net/if_spppvar.h | 12 +++++-
2 files changed, 91 insertions(+), 29 deletions(-)
diffs (275 lines):
diff -r 1fdab9bf7d8f -r ca444d7e38ea sys/net/if_spppsubr.c
--- a/sys/net/if_spppsubr.c Fri Nov 25 05:00:29 2016 +0000
+++ b/sys/net/if_spppsubr.c Fri Nov 25 05:03:12 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppsubr.c,v 1.158 2016/11/25 05:00:29 knakahara Exp $ */
+/* $NetBSD: if_spppsubr.c,v 1.159 2016/11/25 05:03:12 knakahara Exp $ */
/*
* Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.158 2016/11/25 05:00:29 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.159 2016/11/25 05:03:12 knakahara Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -66,6 +66,8 @@
#include <sys/kauth.h>
#include <sys/cprng.h>
#include <sys/module.h>
+#include <sys/workqueue.h>
+#include <sys/atomic.h>
#include <net/if.h>
#include <net/netisr.h>
@@ -365,7 +367,9 @@
#ifdef INET
static void sppp_get_ip_addrs(struct sppp *sp, uint32_t *src, uint32_t *dst,
uint32_t *srcmask);
+static void sppp_set_ip_addrs_work(struct work *wk, void *arg);
static void sppp_set_ip_addrs(struct sppp *sp);
+static void sppp_clear_ip_addrs_work(struct work *wk, void *arg);
static void sppp_clear_ip_addrs(struct sppp *sp);
#endif
static void sppp_keepalive(void *dummy);
@@ -948,6 +952,9 @@
break;
}
+ workqueue_destroy(sp->ipcp.set_addrs_wq);
+ workqueue_destroy(sp->ipcp.clear_addrs_wq);
+
/* Stop keepalive handler. */
if (! spppq) {
callout_stop(&keepalive_ch);
@@ -2725,6 +2732,8 @@
static void
sppp_ipcp_init(struct sppp *sp)
{
+ int error;
+
sp->ipcp.opts = 0;
sp->ipcp.flags = 0;
sp->state[IDX_IPCP] = STATE_INITIAL;
@@ -2732,6 +2741,20 @@
sp->pp_seq[IDX_IPCP] = 0;
sp->pp_rseq[IDX_IPCP] = 0;
callout_init(&sp->ch[IDX_IPCP], 0);
+
+ error = workqueue_create(&sp->ipcp.set_addrs_wq, "ipcp_set_addrs",
+ sppp_set_ip_addrs_work, sp, PRI_SOFTNET, IPL_NET, 0);
+ if (error)
+ panic("%s: set_addrs workqueue_create failed (%d)\n",
+ __func__, error);
+ error = workqueue_create(&sp->ipcp.clear_addrs_wq, "ipcp_clear_addrs",
+ sppp_clear_ip_addrs_work, sp, PRI_SOFTNET, IPL_NET, 0);
+ if (error)
+ panic("%s: clear_addrs workqueue_create failed (%d)\n",
+ __func__, error);
+
+ sp->ipcp.set_addrs_enqueued = 0;
+ sp->ipcp.clear_addrs_enqueued = 0;
}
static void
@@ -2797,7 +2820,6 @@
static void
sppp_ipcp_close(struct sppp *sp)
{
- STDDCL;
sppp_close_event(&ipcp, sp);
#ifdef INET
@@ -2807,15 +2829,6 @@
*/
sppp_clear_ip_addrs(sp);
#endif
-
- if (sp->pp_saved_mtu > 0) {
- ifp->if_mtu = sp->pp_saved_mtu;
- sp->pp_saved_mtu = 0;
- if (debug)
- log(LOG_DEBUG,
- "%s: resetting MTU to %" PRIu64 " bytes\n",
- ifp->if_xname, ifp->if_mtu);
- }
}
static void
@@ -3163,21 +3176,7 @@
{
#ifdef INET
/* we are up. Set addresses and notify anyone interested */
- STDDCL;
-
sppp_set_ip_addrs(sp);
-
- if (ifp->if_mtu > sp->lcp.their_mru) {
- sp->pp_saved_mtu = ifp->if_mtu;
- ifp->if_mtu = sp->lcp.their_mru;
- if (debug)
- log(LOG_DEBUG,
- "%s: setting MTU to %" PRIu64 " bytes\n",
- ifp->if_xname, ifp->if_mtu);
- }
-
- if (sp->pp_con)
- sp->pp_con(sp);
#endif
}
@@ -4874,18 +4873,23 @@
* If an address is 0, leave it the way it is.
*/
static void
-sppp_set_ip_addrs(struct sppp *sp)
+sppp_set_ip_addrs_work(struct work *wk, void *arg)
{
+ struct sppp *sp = arg;
STDDCL;
struct ifaddr *ifa;
struct sockaddr_in *si, *dest;
uint32_t myaddr = 0, hisaddr = 0;
+ int s;
+
+ atomic_swap_uint(&sp->ipcp.set_addrs_enqueued, 0);
/*
* Pick the first AF_INET address from the list,
* aliases don't make any sense on a p2p link anyway.
*/
si = dest = NULL;
+ s = pserialize_read_enter();
IFADDR_READER_FOREACH(ifa, ifp) {
if (ifa->ifa_addr->sa_family == AF_INET) {
si = (struct sockaddr_in *)ifa->ifa_addr;
@@ -4893,6 +4897,7 @@
break;
}
}
+ pserialize_read_exit(s);
if ((sp->ipcp.flags & IPCP_MYADDR_DYN) && (sp->ipcp.flags & IPCP_MYADDR_SEEN))
myaddr = sp->ipcp.req_myaddr;
@@ -4941,23 +4946,50 @@
(struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR);
}
}
+
+ if (ifp->if_mtu > sp->lcp.their_mru) {
+ sp->pp_saved_mtu = ifp->if_mtu;
+ ifp->if_mtu = sp->lcp.their_mru;
+ if (debug)
+ log(LOG_DEBUG,
+ "%s: setting MTU to %" PRIu64 " bytes\n",
+ ifp->if_xname, ifp->if_mtu);
+ }
+
+ if (sp->pp_con)
+ sp->pp_con(sp);
+}
+
+static void
+sppp_set_ip_addrs(struct sppp *sp)
+{
+
+ if (atomic_swap_uint(&sp->ipcp.set_addrs_enqueued, 1) == 1)
+ return;
+
+ workqueue_enqueue(sp->ipcp.set_addrs_wq, &sp->ipcp.set_addrs_wk, NULL);
}
/*
* Clear IP addresses. Must be called at splnet.
*/
static void
-sppp_clear_ip_addrs(struct sppp *sp)
+sppp_clear_ip_addrs_work(struct work *wk, void *arg)
{
+ struct sppp *sp = arg;
STDDCL;
struct ifaddr *ifa;
struct sockaddr_in *si, *dest;
+ int s;
+
+ atomic_swap_uint(&sp->ipcp.clear_addrs_enqueued, 0);
/*
* Pick the first AF_INET address from the list,
* aliases don't make any sense on a p2p link anyway.
*/
si = dest = NULL;
+ s = pserialize_read_enter();
IFADDR_READER_FOREACH(ifa, ifp) {
if (ifa->ifa_addr->sa_family == AF_INET) {
si = (struct sockaddr_in *)ifa->ifa_addr;
@@ -4965,6 +4997,7 @@
break;
}
}
+ pserialize_read_exit(s);
if (si != NULL) {
struct sockaddr_in new_sin = *si;
@@ -5000,6 +5033,25 @@
(struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR);
}
}
+
+ if (sp->pp_saved_mtu > 0) {
+ ifp->if_mtu = sp->pp_saved_mtu;
+ sp->pp_saved_mtu = 0;
+ if (debug)
+ log(LOG_DEBUG,
+ "%s: resetting MTU to %" PRIu64 " bytes\n",
+ ifp->if_xname, ifp->if_mtu);
+ }
+}
+
+static void
+sppp_clear_ip_addrs(struct sppp *sp)
+{
+
+ if (atomic_swap_uint(&sp->ipcp.clear_addrs_enqueued, 1) == 1)
+ return;
+
+ workqueue_enqueue(sp->ipcp.clear_addrs_wq, &sp->ipcp.clear_addrs_wk, NULL);
}
#endif
diff -r 1fdab9bf7d8f -r ca444d7e38ea sys/net/if_spppvar.h
--- a/sys/net/if_spppvar.h Fri Nov 25 05:00:29 2016 +0000
+++ b/sys/net/if_spppvar.h Fri Nov 25 05:03:12 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppvar.h,v 1.17 2016/09/14 10:58:38 roy Exp $ */
+/* $NetBSD: if_spppvar.h,v 1.18 2016/11/25 05:03:12 knakahara Exp $ */
#ifndef _NET_IF_SPPPVAR_H_
#define _NET_IF_SPPPVAR_H_
@@ -26,6 +26,8 @@
* From: Id: if_sppp.h,v 1.7 1998/12/01 20:20:19 hm Exp
*/
+#include <sys/workqueue.h>
+
#include <net/if_media.h>
#define IDX_LCP 0 /* idx into state table */
@@ -61,6 +63,14 @@
uint32_t saved_hisaddr;/* if hisaddr (IPv4) is dynamic, save original one here, in network byte order */
uint32_t req_hisaddr; /* remote address requested */
uint32_t req_myaddr; /* local address requested */
+
+ struct workqueue *set_addrs_wq;
+ struct work set_addrs_wk;
+ u_int set_addrs_enqueued;
+
+ struct workqueue *clear_addrs_wq;
+ struct work clear_addrs_wk;
+ u_int clear_addrs_enqueued;
};
struct sauth {
Home |
Main Index |
Thread Index |
Old Index