PERFORCE change 163519 for review

Marko Zec zec at FreeBSD.org
Thu Jun 4 20:24:03 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163519

Change 163519 by zec at zec_amdx4 on 2009/06/04 20:23:23

	Merge vnet destructor framework from vimage branch.

Affected files ...

.. //depot/projects/vimage-commit2/src/sys/kern/kern_vimage.c#49 edit
.. //depot/projects/vimage-commit2/src/sys/kern/uipc_domain.c#5 edit
.. //depot/projects/vimage-commit2/src/sys/net/if.c#71 edit
.. //depot/projects/vimage-commit2/src/sys/net/if_gif.c#27 edit
.. //depot/projects/vimage-commit2/src/sys/net/if_loop.c#33 edit
.. //depot/projects/vimage-commit2/src/sys/net/if_var.h#29 edit
.. //depot/projects/vimage-commit2/src/sys/net/route.c#39 edit
.. //depot/projects/vimage-commit2/src/sys/netgraph/ng_base.c#29 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/igmp.c#40 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/in_proto.c#13 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/in_rmx.c#31 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/ip_var.h#16 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/raw_ip.c#29 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_hostcache.c#24 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_subr.c#52 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.c#36 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.h#7 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_timewait.c#27 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_var.h#14 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/udp_usrreq.c#40 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/udp_var.h#7 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/in6_proto.c#23 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/in6_rmx.c#33 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/ip6_input.c#34 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/ip6_var.h#9 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/ip6protosw.h#3 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/nd6.c#35 edit
.. //depot/projects/vimage-commit2/src/sys/netinet6/nd6.h#9 edit
.. //depot/projects/vimage-commit2/src/sys/netipsec/ipsec.c#32 edit
.. //depot/projects/vimage-commit2/src/sys/netipsec/key.c#30 edit
.. //depot/projects/vimage-commit2/src/sys/netipsec/key.h#3 edit
.. //depot/projects/vimage-commit2/src/sys/netipsec/keysock.c#21 edit
.. //depot/projects/vimage-commit2/src/sys/sys/domain.h#2 edit
.. //depot/projects/vimage-commit2/src/sys/sys/protosw.h#4 edit
.. //depot/projects/vimage-commit2/src/sys/sys/vimage.h#70 edit

Differences ...

==== //depot/projects/vimage-commit2/src/sys/kern/kern_vimage.c#49 (text+ko) ====

@@ -65,8 +65,8 @@
 static int vnet_mod_destructor(struct vnet_modlink *);
 
 #ifdef VIMAGE
-static struct vimage *vimage_by_name(struct vimage *, char *);
 static struct vimage *vi_alloc(struct vimage *, char *);
+static int vi_destroy(struct vimage *);
 static struct vimage *vimage_get_next(struct vimage *, struct vimage *, int);
 static void vimage_relative_name(struct vimage *, struct vimage *,
     char *, int);
@@ -216,11 +216,7 @@
 
 	case SIOCSPVIMAGE:
 		if (vi_req->vi_req_action == VI_DESTROY) {
-#ifdef NOTYET
 			error = vi_destroy(vip_r);
-#else
-			error = EOPNOTSUPP;
-#endif
 			break;
 		}
 
@@ -283,7 +279,7 @@
 	return (0);
 }
 
-static struct vimage *
+struct vimage *
 vimage_by_name(struct vimage *top, char *name)
 {
 	struct vimage *vip;
@@ -541,7 +537,6 @@
 	return (0);
 }
 
-
 static int
 vnet_mod_destructor(struct vnet_modlink *vml)
 {
@@ -663,6 +658,73 @@
 
 	return (vip);
 }
+
+/*
+ * Destroy a vnet - unlink all linked lists, free all the memory, stop all
+ * the timers... How can one ever be sure to have done *all* the necessary
+ * steps?
+ */
+static int
+vi_destroy(struct vimage *vip)
+{
+	struct vnet *vnet = vip->v_net;
+	struct vprocg *vprocg = vip->v_procg;
+	struct ifnet *ifp, *nifp;
+	struct vnet_modlink *vml;
+
+	/* XXX Beware of races -> more locking to be done... */
+	if (!LIST_EMPTY(&vip->vi_child_head))
+		return (EBUSY);
+
+	if (vprocg->nprocs != 0)
+		return (EBUSY);
+
+	if (vnet->sockcnt != 0)
+		return (EBUSY);
+
+	if (vip->vi_ucredrefc != 0)
+		printf("vi_destroy: %s ucredrefc %d\n",
+		    vip->vi_name, vip->vi_ucredrefc);
+
+	/* Point with no return - cleanup MUST succeed! */
+	/* XXX locking */
+	LIST_REMOVE(vip, vi_le);
+	LIST_REMOVE(vip, vi_sibling);
+
+	/* XXX locking */
+	LIST_REMOVE(vprocg, vprocg_le);
+
+	VNET_LIST_WLOCK();
+	LIST_REMOVE(vnet, vnet_le);
+	VNET_LIST_WUNLOCK();
+
+	CURVNET_SET_QUIET(vnet);
+	INIT_VNET_NET(vnet);
+
+	/*
+	 * Return all inherited interfaces to their parent vnets,
+	 * alternatively attempt to kill cloning ifnets.
+	 */
+	TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) {
+		if (ifp->if_home_vnet != ifp->if_vnet)
+			vi_if_move(NULL, ifp, vip);
+	}
+
+	/* Detach / free per-module state instances. */
+	TAILQ_FOREACH_REVERSE(vml, &vnet_modlink_head,
+			      vnet_modlink_head, vml_mod_le)
+		vnet_mod_destructor(vml);
+
+	CURVNET_RESTORE();
+
+	/* hopefully, we are finally OK to free the vnet container itself! */
+	vnet->vnet_magic_n = 0xdeadbeef;
+	free(vnet, M_VNET);
+	free(vprocg, M_VPROCG);
+	free(vip, M_VIMAGE);
+
+	return (0);
+}
 #endif /* VIMAGE */
 
 static void

==== //depot/projects/vimage-commit2/src/sys/kern/uipc_domain.c#5 (text+ko) ====

@@ -66,6 +66,9 @@
     NULL);
 
 static vnet_attach_fn net_init_domain;
+#ifdef VIMAGE
+static vnet_detach_fn net_detach_domain;
+#endif
 
 static struct callout pffast_callout;
 static struct callout pfslow_callout;
@@ -107,7 +110,10 @@
 vnet_modinfo_t vnet_domain_modinfo = {
 	.vmi_id		= VNET_MOD_DOMAIN,
 	.vmi_name	= "domain",
-	.vmi_iattach	= net_init_domain
+	.vmi_iattach	= net_init_domain,
+#ifdef VIMAGE
+	.vmi_idetach	= net_detach_domain,
+#endif
 };
 #endif
 
@@ -166,9 +172,7 @@
 }
 
 /*
- * Add a new protocol domain to the list of supported domains
- * Note: you cant unload it again because a socket may be using it.
- * XXX can't fail at this time.
+ * Initialize a domain instance.
  */
 static int
 net_init_domain(const void *arg)
@@ -190,6 +194,26 @@
 	return (0);
 }
 
+#ifdef VIMAGE
+/*
+ * Detach / free a domain instance.
+ */
+static int
+net_detach_domain(const void *arg)
+{
+	const struct domain *dp = arg;
+	struct protosw *pr;
+
+	if (dp->dom_destroy)
+		(*dp->dom_destroy)();
+	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+		if (pr->pr_destroy)
+			(*pr->pr_destroy)();
+
+	return 0;
+}
+#endif
+
 /*
  * Add a new protocol domain to the list of supported domains
  * Note: you cant unload it again because a socket may be using it.

==== //depot/projects/vimage-commit2/src/sys/net/if.c#71 (text+ko) ====

@@ -154,6 +154,9 @@
 #endif
 
 static int	vnet_net_iattach(const void *);
+#ifdef VIMAGE
+static int	vnet_net_idetach(const void *);
+#endif
 
 #ifdef VIMAGE_GLOBALS
 struct	ifnethead ifnet;	/* depend on static init XXX */
@@ -190,7 +193,10 @@
 	.vmi_name	= "net",
 	.vmi_size	= sizeof(struct vnet_net),
 	.vmi_symmap	= vnet_net_symmap,
-	.vmi_iattach	= vnet_net_iattach
+	.vmi_iattach	= vnet_net_iattach,
+#ifdef VIMAGE
+	.vmi_idetach	= vnet_net_idetach
+#endif
 };
 #endif /* !VIMAGE_GLOBALS */
 
@@ -447,6 +453,25 @@
 	return (0);
 }
 
+#ifdef VIMAGE
+static int
+vnet_net_idetach(unused)
+	const void *unused;
+{
+	INIT_VNET_NET(curvnet);
+
+	VNET_ASSERT(TAILQ_EMPTY(&V_ifnet));
+#ifdef NOTYET
+	VNET_ASSERT(TAILQ_EMPTY(&V_ifg_head));
+#endif
+	VNET_ASSERT(SLIST_EMPTY(&V_ifklist.kl_list));
+
+	free((caddr_t)V_ifindex_table, M_IFNET);
+
+	return (0);
+}
+#endif
+
 void
 if_grow(void)
 {
@@ -689,6 +714,8 @@
 
 #ifdef VIMAGE
 	ifp->if_vnet = curvnet;
+	if (ifp->if_home_vnet == NULL)
+		ifp->if_home_vnet = curvnet;
 #endif
 
 	if_addgroup(ifp, IFG_ALL);

==== //depot/projects/vimage-commit2/src/sys/net/if_gif.c#27 (text+ko) ====

@@ -302,12 +302,10 @@
 		break;
 	case MOD_UNLOAD:
 		if_clone_detach(&gif_cloner);
+#ifdef VIMAGE
+		vnet_mod_deregister(&vnet_gif_modinfo);
+#endif
 		mtx_destroy(&gif_mtx);
-#ifdef INET6
-#ifndef VIMAGE
-		V_ip6_gif_hlim = 0;	/* XXX -> vnet_gif_idetach() */
-#endif
-#endif
 		break;
 	default:
 		return EOPNOTSUPP;

==== //depot/projects/vimage-commit2/src/sys/net/if_loop.c#33 (text+ko) ====

@@ -106,6 +106,9 @@
 static int	lo_clone_create(struct if_clone *, int, caddr_t);
 static void	lo_clone_destroy(struct ifnet *);
 static int	vnet_loif_iattach(const void *);
+#ifdef VIMAGE
+static int	vnet_loif_idetach(const void *);
+#endif
 
 #ifdef VIMAGE_GLOBALS
 struct ifnet *loif;			/* Used externally */
@@ -120,7 +123,10 @@
 	.vmi_id		= VNET_MOD_LOIF,
 	.vmi_dependson	= VNET_MOD_IF_CLONE,
 	.vmi_name	= "loif",
-	.vmi_iattach	= vnet_loif_iattach
+	.vmi_iattach	= vnet_loif_iattach,
+#ifdef VIMAGE
+	.vmi_idetach	= vnet_loif_idetach
+#endif
 };
 #endif /* !VIMAGE_GLOBALS */
 
@@ -129,12 +135,11 @@
 static void
 lo_clone_destroy(struct ifnet *ifp)
 {
-#ifdef INVARIANTS
-	INIT_VNET_NET(ifp->if_vnet);
-#endif
 
+#ifndef VIMAGE
 	/* XXX: destroying lo0 will lead to panics. */
 	KASSERT(V_loif != ifp, ("%s: destroying lo0", __func__));
+#endif
 
 	bpfdetach(ifp);
 	if_detach(ifp);
@@ -184,6 +189,19 @@
 	return (0);
 }
 
+#ifdef VIMAGE
+static int vnet_loif_idetach(unused)
+	const void *unused;
+{
+	INIT_VNET_NET(curvnet);
+
+	if_clone_detach(V_lo_cloner);
+	V_loif = NULL;
+
+	return (0);
+}
+#endif
+
 static int
 loop_modevent(module_t mod, int type, void *data)
 {

==== //depot/projects/vimage-commit2/src/sys/net/if_var.h#29 (text+ko) ====

@@ -71,6 +71,7 @@
 struct	carp_if;
 struct  ifvlantrunk;
 struct	route;
+struct	vnet;
 #endif
 
 #include <sys/queue.h>		/* get TAILQ macros */
@@ -169,6 +170,9 @@
 		(struct ifnet *);
 	int	(*if_transmit)		/* initiate output routine */
 		(struct ifnet *, struct mbuf *);
+	void	(*if_reassign)		/* reassign to vnet routine */
+		(struct ifnet *, struct vnet *, char *);
+	struct	vnet *if_home_vnet;	/* where this ifnet originates from */
 	struct	ifaddr	*if_addr;	/* pointer to link-level address */
 	void	*if_llsoftc;		/* link layer softc */
 	int	if_drv_flags;		/* driver-managed status flags */

==== //depot/projects/vimage-commit2/src/sys/net/route.c#39 (text+ko) ====

@@ -99,12 +99,18 @@
 static void rt_maskedcopy(struct sockaddr *,
 	    struct sockaddr *, struct sockaddr *);
 static int vnet_route_iattach(const void *);
+#ifdef VIMAGE
+static int vnet_route_idetach(const void *);
+#endif
 
 #ifndef VIMAGE_GLOBALS
 static const vnet_modinfo_t vnet_rtable_modinfo = {
 	.vmi_id		= VNET_MOD_RTABLE,
 	.vmi_name	= "rtable",
-	.vmi_iattach	= vnet_route_iattach
+	.vmi_iattach	= vnet_route_iattach,
+#ifdef VIMAGE
+	.vmi_idetach	= vnet_route_idetach
+#endif
 };
 #endif /* !VIMAGE_GLOBALS */
 
@@ -194,7 +200,8 @@
 #endif
 }
 
-static int vnet_route_iattach(const void *unused __unused)
+static int
+vnet_route_iattach(const void *unused __unused)
 {
 	INIT_VNET_NET(curvnet);
 	struct domain *dom;
@@ -235,6 +242,36 @@
 	return (0);
 }
 
+#ifdef VIMAGE
+static int
+vnet_route_idetach(const void *unused)
+{
+	int table;
+	int fam;
+	struct domain *dom;
+	struct radix_node_head **rnh;
+
+	for (dom = domains; dom; dom = dom->dom_next) {
+		if (dom->dom_rtdetach)  {
+			for  (table = 0; table < rt_numfibs; table++) {
+				if ( (fam = dom->dom_family) == AF_INET ||
+				    table == 0) {
+ 					/* for now only AF_INET has > 1 table */
+					rnh = rt_tables_get_rnh_ptr(table, fam);
+					if (rnh == NULL)
+						panic("%s: rnh NULL", __func__);
+					dom->dom_rtdetach((void **)rnh,
+				    	    dom->dom_rtoffset);
+				} else {
+					break;
+				}
+			}
+		}
+	}
+	return (0);
+}
+#endif
+
 #ifndef _SYS_SYSPROTO_H_
 struct setfib_args {
 	int     fibnum;

==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_base.c#29 (text+ko) ====

@@ -85,6 +85,9 @@
 static struct mtx	ng_topo_mtx;
 
 static vnet_attach_fn vnet_netgraph_iattach;
+#ifdef VIMAGE
+static vnet_detach_fn vnet_netgraph_idetach;
+#endif
 
 #ifdef	NETGRAPH_DEBUG
 static struct mtx	ng_nodelist_mtx; /* protects global node/hook lists */
@@ -647,6 +650,9 @@
 		return (ENOMEM);
 	}
 	node->nd_type = type;
+#ifdef VIMAGE
+	node->nd_vnet = curvnet;
+#endif
 	NG_NODE_REF(node);				/* note reference */
 	type->refs++;
 
@@ -3074,22 +3080,49 @@
 static const vnet_modinfo_t vnet_netgraph_modinfo = {
 	.vmi_id		= VNET_MOD_NETGRAPH,
 	.vmi_name	= "netgraph",
+	.vmi_size	= sizeof(struct vnet_netgraph),
+	.vmi_dependson	= VNET_MOD_LOIF,
+	.vmi_iattach	= vnet_netgraph_iattach,
 #ifdef VIMAGE
-	.vmi_size	= sizeof(struct vnet_netgraph),
+	.vmi_idetach	= vnet_netgraph_idetach
 #endif
-	.vmi_iattach	= vnet_netgraph_iattach
 };
 #endif
 
-static int
-vnet_netgraph_iattach(const void *arg __unused)
+static int vnet_netgraph_iattach(const void *unused)
 {
 	INIT_VNET_NETGRAPH(curvnet);
 
 	V_nextID = 1;
 
-	return (0);
+	return 0;
+}
+
+#ifdef VIMAGE 
+static int vnet_netgraph_idetach(const void *unused)
+{
+	INIT_VNET_NETGRAPH(curvnet);
+	node_p node, last_killed = NULL;
+
+	while ((node = LIST_FIRST(&V_ng_nodelist)) != NULL) {
+		if (node == last_killed) {
+			/* This should never happen */
+			node->nd_flags |= NGF_REALLY_DIE;
+			printf("netgraph node %s needs NGF_REALLY_DIE\n",
+			    node->nd_name);
+			ng_rmnode(node, NULL, NULL, 0);
+			/* This must never happen */
+			if (node == LIST_FIRST(&V_ng_nodelist))
+				panic("netgraph node %s won't die",
+				    node->nd_name);
+		}
+		ng_rmnode(node, NULL, NULL, 0);
+		last_killed = node;
+	}
+
+	return 0;
 }
+#endif /* VIMAGE */
 
 /*
  * Handle loading and unloading for this code.
@@ -3313,6 +3346,7 @@
 			NG_WORKLIST_SLEEP();
 		STAILQ_REMOVE_HEAD(&ng_worklist, nd_input_queue.q_work);
 		NG_WORKLIST_UNLOCK();
+		CURVNET_SET(node->nd_vnet);
 		CTR3(KTR_NET, "%20s: node [%x] (%p) taken off worklist",
 		    __func__, node->nd_ID, node);
 		/*
@@ -3342,6 +3376,7 @@
 			}
 		}
 		NG_NODE_UNREF(node);
+		CURVNET_RESTORE();
 	}
 }
 
@@ -3675,7 +3710,9 @@
 {
 	item_p item = arg;
 
+	CURVNET_SET(NGI_NODE(item)->nd_vnet);
 	ng_snd_item(item, 0);
+	CURVNET_RESTORE();
 }
 
 

==== //depot/projects/vimage-commit2/src/sys/netinet/igmp.c#40 (text+ko) ====

@@ -1993,7 +1993,6 @@
 static void
 igmp_v3_cancel_link_timers(struct igmp_ifinfo *igi)
 {
-	INIT_VNET_INET(curvnet);
 	struct ifmultiaddr	*ifma;
 	struct ifnet		*ifp;
 	struct in_multi		*inm;

==== //depot/projects/vimage-commit2/src/sys/netinet/in_proto.c#13 (text+ko) ====

@@ -127,6 +127,9 @@
 	.pr_ctlinput =		udp_ctlinput,
 	.pr_ctloutput =		ip_ctloutput,
 	.pr_init =		udp_init,
+#ifdef VIMAGE
+	.pr_destroy =		udp_destroy,
+#endif
 	.pr_usrreqs =		&udp_usrreqs
 },
 {
@@ -138,6 +141,9 @@
 	.pr_ctlinput =		tcp_ctlinput,
 	.pr_ctloutput =		tcp_ctloutput,
 	.pr_init =		tcp_init,
+#ifdef VIMAGE
+	.pr_destroy =		tcp_destroy,
+#endif
 	.pr_slowtimo =		tcp_slowtimo,
 	.pr_drain =		tcp_drain,
 	.pr_usrreqs =		&tcp_usrreqs
@@ -348,11 +354,15 @@
 	.pr_input =		rip_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_init =		rip_init,
+#ifdef VIMAGE
+	.pr_destroy =		rip_destroy,
+#endif
 	.pr_usrreqs =		&rip_usrreqs
 },
 };
 
 extern int in_inithead(void **, int);
+extern int in_detachhead(void **, int);
 
 struct domain inetdomain = {
 	.dom_family =		AF_INET,
@@ -364,6 +374,9 @@
 #else
 	.dom_rtattach =		in_inithead,
 #endif
+#ifdef VIMAGE
+	.dom_rtdetach =		in_detachhead,
+#endif
 	.dom_rtoffset =		32,
 	.dom_maxrtkey =		sizeof(struct sockaddr_in),
 	.dom_ifattach =		in_domifattach,

==== //depot/projects/vimage-commit2/src/sys/netinet/in_rmx.c#31 (text+ko) ====

@@ -65,6 +65,9 @@
 #include <netinet/vinet.h>
 
 extern int	in_inithead(void **head, int off);
+#ifdef VIMAGE
+extern int	in_detachhead(void **head, int off);
+#endif
 
 #define RTPRF_OURS		RTF_PROTO3	/* set on routes we manage */
 
@@ -382,6 +385,17 @@
 	return 1;
 }
 
+#ifdef VIMAGE
+int
+in_detachhead(void **head, int off)
+{
+	INIT_VNET_INET(curvnet);
+
+	callout_drain(&V_rtq_timer);
+	return 1;
+}
+#endif
+
 /*
  * This zaps old routes when the interface goes down or interface
  * address is deleted.  In the latter case, it deletes static routes

==== //depot/projects/vimage-commit2/src/sys/netinet/ip_var.h#16 (text+ko) ====

@@ -209,6 +209,9 @@
 int	rip_ctloutput(struct socket *, struct sockopt *);
 void	rip_ctlinput(int, struct sockaddr *, void *);
 void	rip_init(void);
+#ifdef VIMAGE
+void	rip_destroy(void);
+#endif
 void	rip_input(struct mbuf *, int);
 int	rip_output(struct mbuf *, struct socket *, u_long);
 void	ipip_input(struct mbuf *, int);

==== //depot/projects/vimage-commit2/src/sys/netinet/raw_ip.c#29 (text+ko) ====

@@ -202,6 +202,19 @@
 	    EVENTHANDLER_PRI_ANY);
 }
 
+#ifdef VIMAGE
+void
+rip_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+
+	hashdestroy(V_ripcbinfo.ipi_hashbase, M_PCB,
+	    V_ripcbinfo.ipi_hashmask);
+	hashdestroy(V_ripcbinfo.ipi_porthashbase, M_PCB,
+	    V_ripcbinfo.ipi_porthashmask);
+}
+#endif
+
 static int
 rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
     struct sockaddr_in *ripsrc)

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_hostcache.c#24 (text+ko) ====

@@ -230,6 +230,16 @@
 	    tcp_hc_purge, curvnet);
 }
 
+void
+tcp_hc_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+
+	/* XXX TODO walk the hashtable and free all entries  */
+
+	callout_drain(&V_tcp_hc_callout);
+}
+
 /*
  * Internal function: look up an entry in the hostcache or return NULL.
  *
@@ -663,5 +673,6 @@
 
 	callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
 	    tcp_hc_purge, arg);
+
 	CURVNET_RESTORE();
 }

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_subr.c#52 (text+ko) ====

@@ -427,6 +427,25 @@
 		EVENTHANDLER_PRI_ANY);
 }
 
+#ifdef VIMAGE
+void
+tcp_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+
+	tcp_tw_destroy();
+	tcp_hc_destroy();
+	syncache_destroy();
+
+	/* XXX check that hashes are empty! */
+	hashdestroy(V_tcbinfo.ipi_hashbase, M_PCB,
+	    V_tcbinfo.ipi_hashmask);
+	hashdestroy(V_tcbinfo.ipi_porthashbase, M_PCB,
+	    V_tcbinfo.ipi_porthashmask);
+	INP_INFO_LOCK_DESTROY(&V_tcbinfo);
+}
+#endif
+
 void
 tcp_fini(void *xtp)
 {

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.c#36 (text+ko) ====

@@ -276,6 +276,19 @@
 	uma_zone_set_max(V_tcp_syncache.zone, V_tcp_syncache.cache_limit);
 }
 
+#ifdef VIMAGE
+void
+syncache_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+
+	/* XXX walk the cache, free remaining objects, stop timers */
+
+	uma_zdestroy(V_tcp_syncache.zone);
+	FREE(V_tcp_syncache.hashbase, M_SYNCACHE);
+}
+#endif
+
 /*
  * Inserts a syncache entry into the specified bucket row.
  * Locks and unlocks the syncache_head autonomously.

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.h#7 (text+ko) ====

@@ -35,6 +35,9 @@
 #ifdef _KERNEL
 
 void	 syncache_init(void);
+#ifdef VIMAGE
+void	syncache_destroy(void);
+#endif
 void	 syncache_unreach(struct in_conninfo *, struct tcphdr *);
 int	 syncache_expand(struct in_conninfo *, struct tcpopt *,
 	     struct tcphdr *, struct socket **, struct mbuf *);

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_timewait.c#27 (text+ko) ====

@@ -180,6 +180,20 @@
 	TAILQ_INIT(&V_twq_2msl);
 }
 
+#ifdef VIMAGE
+void
+tcp_tw_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+	struct tcptw *tw;
+
+	INP_INFO_WLOCK(&V_tcbinfo);
+	while((tw = TAILQ_FIRST(&V_twq_2msl)) != NULL)
+		tcp_twclose(tw, 0);
+	INP_INFO_WUNLOCK(&V_tcbinfo);
+}
+#endif
+
 /*
  * Move a TCP connection into TIME_WAIT state.
  *    tcbinfo is locked.

==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_var.h#14 (text+ko) ====

@@ -584,6 +584,7 @@
 void	 tcp_drain(void);
 void	 tcp_fasttimo(void);
 void	 tcp_init(void);
+void	 tcp_destroy(void);
 void	 tcp_fini(void *);
 char 	*tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *,
 	    const void *);
@@ -605,6 +606,9 @@
 void	 tcp_respond(struct tcpcb *, void *,
 	    struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
 void	 tcp_tw_init(void);
+#ifdef VIMAGE
+void	 tcp_tw_destroy(void);
+#endif
 void	 tcp_tw_zone_change(void);
 int	 tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
 	    struct mbuf *, int);
@@ -625,6 +629,7 @@
  * All tcp_hc_* functions are IPv4 and IPv6 (via in_conninfo)
  */
 void	 tcp_hc_init(void);
+void	 tcp_hc_destroy(void);
 void	 tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
 u_long	 tcp_hc_getmtu(struct in_conninfo *);
 void	 tcp_hc_updatemtu(struct in_conninfo *, u_long);

==== //depot/projects/vimage-commit2/src/sys/netinet/udp_usrreq.c#40 (text+ko) ====

@@ -222,6 +222,20 @@
 	uma_zfree(V_udpcb_zone, up);
 }
 
+#ifdef VIMAGE
+void
+udp_destroy(void)
+{
+	INIT_VNET_INET(curvnet);
+
+	hashdestroy(V_udbinfo.ipi_hashbase, M_PCB,
+	    V_udbinfo.ipi_hashmask);
+	hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB,
+	    V_udbinfo.ipi_porthashmask);
+	INP_INFO_LOCK_DESTROY(&V_udbinfo);
+}
+#endif
+
 /*
  * Subroutine of udp_input(), which appends the provided mbuf chain to the
  * passed pcb/socket.  The caller must provide a sockaddr_in via udp_in that

==== //depot/projects/vimage-commit2/src/sys/netinet/udp_var.h#7 (text+ko) ====

@@ -128,6 +128,9 @@
 
 void		 udp_ctlinput(int, struct sockaddr *, void *);
 void		 udp_init(void);
+#ifdef VIMAGE
+void		 udp_destroy(void);
+#endif
 void		 udp_input(struct mbuf *, int);
 struct inpcb	*udp_notify(struct inpcb *inp, int errno);
 int		 udp_shutdown(struct socket *so);

==== //depot/projects/vimage-commit2/src/sys/netinet6/in6_proto.c#23 (text+ko) ====

@@ -148,6 +148,9 @@
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_IPV6,
 	.pr_init =		ip6_init,
+#ifdef VIMAGE
+	.pr_destroy =		ip6_destroy,
+#endif
 	.pr_slowtimo =		frag6_slowtimo,
 	.pr_drain =		frag6_drain,
 	.pr_usrreqs =		&nousrreqs,
@@ -349,6 +352,9 @@
 };
 
 extern int in6_inithead(void **, int);
+#ifdef VIMAGE
+extern int in6_detachhead(void **, int);
+#endif
 
 struct domain inet6domain = {
 	.dom_family =		AF_INET6,
@@ -361,6 +367,9 @@
 #else
 	.dom_rtattach =		in6_inithead,
 #endif
+#ifdef VIMAGE
+	.dom_rtdetach =		in6_detachhead,
+#endif
 	.dom_rtoffset =		offsetof(struct sockaddr_in6, sin6_addr) << 3,
 	.dom_maxrtkey =		sizeof(struct sockaddr_in6),
 	.dom_ifattach =		in6_domifattach,

==== //depot/projects/vimage-commit2/src/sys/netinet6/in6_rmx.c#33 (text+ko) ====

@@ -112,6 +112,9 @@
 #include <netinet/tcp_var.h>
 
 extern int	in6_inithead(void **head, int off);
+#ifdef VIMAGE
+extern int	in6_detachhead(void **head, int off);
+#endif
 
 #define RTPRF_OURS		RTF_PROTO3	/* set on routes we manage */
 
@@ -464,3 +467,15 @@
 	in6_mtutimo(curvnet);	/* kick off timeout first time */
 	return 1;
 }
+
+#ifdef VIMAGE
+int
+in6_detachhead(void **head, int off)
+{
+	INIT_VNET_INET6(curvnet);
+
+	callout_drain(&V_rtq_timer6);
+	callout_drain(&V_rtq_mtutimer);
+	return (1);
+}
+#endif

==== //depot/projects/vimage-commit2/src/sys/netinet6/ip6_input.c#34 (text+ko) ====

@@ -303,6 +303,17 @@
 	netisr_register(&ip6_nh);
 }
 
+#ifdef VIMAGE
+void
+ip6_destroy()
+{
+	INIT_VNET_INET6(curvnet);
+
+	nd6_destroy();
+	callout_drain(&V_in6_tmpaddrtimer_ch);
+}
+#endif
+
 static int
 ip6_init2_vnet(const void *unused __unused)
 {

==== //depot/projects/vimage-commit2/src/sys/netinet6/ip6_var.h#9 (text+ko) ====

@@ -339,6 +339,9 @@
 
 struct in6_ifaddr;
 void	ip6_init __P((void));
+#ifdef VIMAGE
+void	ip6_destroy __P((void));
+#endif
 void	ip6_input __P((struct mbuf *));
 struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
 void	ip6_freepcbopts __P((struct ip6_pktopts *));

==== //depot/projects/vimage-commit2/src/sys/netinet6/ip6protosw.h#3 (text+ko) ====

@@ -129,6 +129,8 @@
 /* utility hooks */
 	void	(*pr_init)		/* initialization hook */
 			__P((void));
+	void	(*pr_destroy)		/* cleanup hook */
+			__P((void));
 
 	void	(*pr_fasttimo)		/* fast timeout (200ms) */
 			__P((void));

==== //depot/projects/vimage-commit2/src/sys/netinet6/nd6.c#35 (text+ko) ====

@@ -135,14 +135,8 @@
 nd6_init(void)
 {
 	INIT_VNET_INET6(curvnet);
-	static int nd6_init_done = 0;
 	int i;
 
-	if (nd6_init_done) {
-		log(LOG_NOTICE, "nd6_init called more than once(ignored)\n");
-		return;
-	}
-
 	V_nd6_prune	= 1;	/* walk list every 1 seconds */
 	V_nd6_delay	= 5;	/* delay first probe time 5 second */
 	V_nd6_umaxtries	= 3;	/* maximum unicast query */
@@ -181,6 +175,8 @@
 	V_ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME;
 	V_ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE;
 
+	V_ip6_desync_factor = 0;
+
 	all1_sa.sin6_family = AF_INET6;
 	all1_sa.sin6_len = sizeof(struct sockaddr_in6);
 	for (i = 0; i < sizeof(all1_sa.sin6_addr); i++)

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list