summaryrefslogtreecommitdiffstats
path: root/sys/netipsec
diff options
context:
space:
mode:
authorzec <zec@FreeBSD.org>2009-06-08 17:15:40 +0000
committerzec <zec@FreeBSD.org>2009-06-08 17:15:40 +0000
commit8b1f38241aaf07621c062901b7946145be2862b6 (patch)
tree7c00057a3f90cc6cfd121e2a6594d254fc72cba3 /sys/netipsec
parent76b38c556af92b00895865a09a6f444150b8a8d8 (diff)
downloadFreeBSD-src-8b1f38241aaf07621c062901b7946145be2862b6.zip
FreeBSD-src-8b1f38241aaf07621c062901b7946145be2862b6.tar.gz
Introduce an infrastructure for dismantling vnet instances.
Vnet modules and protocol domains may now register destructor functions to clean up and release per-module state. The destructor mechanisms can be triggered by invoking "vimage -d", or a future equivalent command which will be provided via the new jail framework. While this patch introduces numerous placeholder destructor functions, many of those are currently incomplete, thus leaking memory or (even worse) failing to stop all running timers. Many of such issues are already known and will be incrementaly fixed over the next weeks in smaller incremental commits. Apart from introducing new fields in structs ifnet, domain, protosw and vnet_net, which requires the kernel and modules to be rebuilt, this change should have no impact on nooptions VIMAGE builds, since vnet destructors can only be called in VIMAGE kernels. Moreover, destructor functions should be in general compiled in only in options VIMAGE builds, except for kernel modules which can be safely kldunloaded at run time. Bump __FreeBSD_version to 800097. Reviewed by: bz, julian Approved by: rwatson, kib (re), julian (mentor)
Diffstat (limited to 'sys/netipsec')
-rw-r--r--sys/netipsec/ipsec.c20
-rw-r--r--sys/netipsec/key.c68
-rw-r--r--sys/netipsec/key.h3
-rw-r--r--sys/netipsec/keysock.c3
4 files changed, 91 insertions, 3 deletions
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 6c42e32..4eef064 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -104,6 +104,9 @@ struct vnet_ipsec vnet_ipsec_0;
#endif
static int ipsec_iattach(const void *);
+#ifdef VIMAGE
+static int ipsec_idetach(const void *);
+#endif
#ifdef VIMAGE_GLOBALS
/* NB: name changed so netstat doesn't use it. */
@@ -256,7 +259,10 @@ static const vnet_modinfo_t vnet_ipsec_modinfo = {
.vmi_name = "ipsec",
.vmi_size = sizeof(struct vnet_ipsec),
.vmi_dependson = VNET_MOD_INET, /* XXX revisit - INET6 ? */
- .vmi_iattach = ipsec_iattach
+ .vmi_iattach = ipsec_iattach,
+#ifdef VIMAGE
+ .vmi_idetach = ipsec_idetach
+#endif
};
#endif /* !VIMAGE_GLOBALS */
@@ -1791,7 +1797,6 @@ ipsec_attach(void)
#else
ipsec_iattach(NULL);
#endif
-
}
static int
@@ -1804,6 +1809,17 @@ ipsec_iattach(const void *unused __unused)
return (0);
}
+
+#ifdef VIMAGE
+static int
+ipsec_idetach(const void *unused __unused)
+{
+
+ /* XXX revisit this! */
+
+ return (0);
+}
+#endif
SYSINIT(ipsec, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, ipsec_attach, NULL);
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index a38bb8d..e79179f 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -7223,9 +7223,75 @@ key_init(void)
keystat.getspi_count = 1;
printf("IPsec: Initialized Security Association Processing.\n");
+}
- return;
+#ifdef VIMAGE
+void
+key_destroy(void)
+{
+ INIT_VNET_IPSEC(curvnet);
+ struct secpolicy *sp, *nextsp;
+ struct secspacq *acq, *nextacq;
+ struct secashead *sah, *nextsah;
+ struct secreg *reg;
+ int i;
+
+ SPTREE_LOCK();
+ for (i = 0; i < IPSEC_DIR_MAX; i++) {
+ for (sp = LIST_FIRST(&V_sptree[i]);
+ sp != NULL; sp = nextsp) {
+ nextsp = LIST_NEXT(sp, chain);
+ if (__LIST_CHAINED(sp)) {
+ LIST_REMOVE(sp, chain);
+ free(sp, M_IPSEC_SP);
+ }
+ }
+ }
+ SPTREE_UNLOCK();
+
+ SAHTREE_LOCK();
+ for (sah = LIST_FIRST(&V_sahtree); sah != NULL; sah = nextsah) {
+ nextsah = LIST_NEXT(sah, chain);
+ if (__LIST_CHAINED(sah)) {
+ LIST_REMOVE(sah, chain);
+ free(sah, M_IPSEC_SAH);
+ }
+ }
+ SAHTREE_UNLOCK();
+
+ REGTREE_LOCK();
+ for (i = 0; i <= SADB_SATYPE_MAX; i++) {
+ LIST_FOREACH(reg, &V_regtree[i], chain) {
+ if (__LIST_CHAINED(reg)) {
+ LIST_REMOVE(reg, chain);
+ free(reg, M_IPSEC_SAR);
+ break;
+ }
+ }
+ }
+ REGTREE_UNLOCK();
+
+ ACQ_LOCK();
+ for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
+ nextacq = LIST_NEXT(acq, chain);
+ if (__LIST_CHAINED(acq)) {
+ LIST_REMOVE(acq, chain);
+ free(acq, M_IPSEC_SAQ);
+ }
+ }
+ ACQ_UNLOCK();
+
+ SPACQ_LOCK();
+ for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
+ nextacq = LIST_NEXT(acq, chain);
+ if (__LIST_CHAINED(acq)) {
+ LIST_REMOVE(acq, chain);
+ free(acq, M_IPSEC_SAQ);
+ }
+ }
+ SPACQ_UNLOCK();
}
+#endif
/*
* XXX: maybe This function is called after INBOUND IPsec processing.
diff --git a/sys/netipsec/key.h b/sys/netipsec/key.h
index 012b35c..fc38279 100644
--- a/sys/netipsec/key.h
+++ b/sys/netipsec/key.h
@@ -100,6 +100,9 @@ extern void key_randomfill __P((void *, size_t));
extern void key_freereg __P((struct socket *));
extern int key_parse __P((struct mbuf *, struct socket *));
extern void key_init __P((void));
+#ifdef VIMAGE
+extern void key_destroy(void);
+#endif
extern void key_sa_recordxfer __P((struct secasvar *, struct mbuf *));
extern void key_sa_routechange __P((struct sockaddr *));
extern void key_sa_stir_iv __P((struct secasvar *));
diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c
index 6117f65..ec0fcf9 100644
--- a/sys/netipsec/keysock.c
+++ b/sys/netipsec/keysock.c
@@ -579,6 +579,9 @@ struct domain keydomain = {
.dom_family = PF_KEY,
.dom_name = "key",
.dom_init = key_init0,
+#ifdef VIMAGE
+ .dom_destroy = key_destroy,
+#endif
.dom_protosw = keysw,
.dom_protoswNPROTOSW = &keysw[sizeof(keysw)/sizeof(keysw[0])]
};
OpenPOWER on IntegriCloud