! ! Manually stripped down patch from the work to bring forward VNET ! teardown changes to FreeBSD HEAD. This is part 1. ! ! Various partial changes or ad-hoc breakage fixes, as well as SCTP ! bits were merged already. ! ! Also includes some extra kernel debugging changes, which were helpful ! while debugging panics. ! ! Obtained from: projects/vnet ! Sponsored by: The FreeBSD Foundation ! Index: sys/netipsec/ipsec.c =================================================================== --- sys/netipsec/ipsec.c (.../head) (revision 295854) +++ sys/netipsec/ipsec.c (.../projects/vnet) (working copy) @@ -1709,7 +1709,7 @@ def_policy_init(const void *unused __unused) V_def_policy.policy = IPSEC_POLICY_NONE; V_def_policy.refcnt = 1; } -VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, +VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, def_policy_init, NULL); Index: sys/netipsec/xform_tcp.c =================================================================== --- sys/netipsec/xform_tcp.c (.../head) (revision 295854) +++ sys/netipsec/xform_tcp.c (.../projects/vnet) (working copy) @@ -166,5 +166,5 @@ tcpsignature_attach(void) xform_register(&tcpsignature_xformsw); } -SYSINIT(tcpsignature_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, +SYSINIT(tcpsignature_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, tcpsignature_attach, NULL); Index: sys/sys/kernel.h =================================================================== --- sys/sys/kernel.h (.../head) (revision 295854) +++ sys/sys/kernel.h (.../projects/vnet) (working copy) @@ -136,10 +136,13 @@ enum sysinit_sub_id { SI_SUB_PSEUDO = 0x7000000, /* pseudo devices*/ SI_SUB_EXEC = 0x7400000, /* execve() handlers */ SI_SUB_PROTO_BEGIN = 0x8000000, /* VNET initialization */ + SI_SUB_PROTO_PFIL = 0x8100000, /* Intialize pfil before FWs */ SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/ SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */ + SI_SUB_PROTO_MC = 0x8700000, /* Multicast */ SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/ - SI_SUB_PROTO_IFATTACHDOMAIN = 0x8800001, /* domain dependent data init*/ + SI_SUB_FW = 0x8806000, /* Firewalls */ + SI_SUB_PROTO_IFATTACHDOMAIN = 0x8808000,/* domain dependent data init */ SI_SUB_PROTO_END = 0x8ffffff, /* VNET helper functions */ SI_SUB_KPROF = 0x9000000, /* kernel profiling*/ SI_SUB_KICK_SCHEDULER = 0xa000000, /* start the timeout events*/ Index: sys/kern/kern_shutdown.c =================================================================== --- sys/kern/kern_shutdown.c (.../head) (revision 295854) +++ sys/kern/kern_shutdown.c (.../projects/vnet) (working copy) @@ -899,3 +899,14 @@ mkdumpheader(struct kerneldumpheader *kdh, char *m strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); kdh->parity = kerneldump_parity(kdh); } + +#ifdef DDB +DB_SHOW_COMMAND(panic, db_show_panic) +{ + + if (panicstr == NULL) + db_printf("Not paniced\n"); + else + db_printf("panic: %s\n", panicstr); +} +#endif Index: sys/kern/kern_timeout.c =================================================================== --- sys/kern/kern_timeout.c (.../head) (revision 295854) +++ sys/kern/kern_timeout.c (.../projects/vnet) (working copy) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "opt_callout_profiling.h" +#include "opt_ddb.h" #if defined(__arm__) #include "opt_timer.h" #endif @@ -60,6 +61,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef DDB +#include +#include +#endif + #ifdef SMP #include #endif @@ -1615,3 +1621,35 @@ SYSCTL_PROC(_kern, OID_AUTO, callout_stat, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_callout_stat, "I", "Dump immediate statistic snapshot of the scheduled callouts"); + +#ifdef DDB + +static void +_show_callout(struct callout *c) +{ + + db_printf("callout %p\n", c); +#define C_DB_PRINTF(f, e) db_printf(" %s = " f "\n", #e, c->e); + db_printf(" &c_links = %p\n", &(c->c_links)); + C_DB_PRINTF("%" PRId64, c_time); + C_DB_PRINTF("%" PRId64, c_precision); + C_DB_PRINTF("%p", c_arg); + C_DB_PRINTF("%p", c_func); + C_DB_PRINTF("%p", c_lock); + C_DB_PRINTF("%#x", c_flags); + C_DB_PRINTF("%#x", c_iflags); + C_DB_PRINTF("%d", c_cpu); +#undef C_DB_PRINTF +} + +DB_SHOW_COMMAND(callout, db_show_callout) +{ + + if (!have_addr) { + db_printf("usage: show callout \n"); + return; + } + + _show_callout((struct callout *)addr); +} +#endif /* DDB */ Index: sys/kern/uipc_domain.c =================================================================== --- sys/kern/uipc_domain.c (.../head) (revision 295854) +++ sys/kern/uipc_domain.c (.../projects/vnet) (working copy) @@ -198,8 +198,12 @@ vnet_domain_uninit(void *arg) struct protosw *pr; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) - if (pr->pr_destroy) + if (pr->pr_destroy) { +#ifdef INVARIANTS + printf("%s: pr %p called pr_destroy\n", __func__, pr); +#endif (*pr->pr_destroy)(); + } if (dp->dom_destroy) (*dp->dom_destroy)(); } Index: sys/netinet/igmp.c =================================================================== --- sys/netinet/igmp.c (.../head) (revision 295854) +++ sys/netinet/igmp.c (.../projects/vnet) (working copy) @@ -50,6 +50,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_ddb.h" + #include #include #include @@ -64,6 +66,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef DDB +#include +#endif + #include #include #include @@ -221,7 +227,8 @@ static VNET_DEFINE(int, current_state_timers_runni #define V_state_change_timers_running VNET(state_change_timers_running) #define V_current_state_timers_running VNET(current_state_timers_running) -static VNET_DEFINE(LIST_HEAD(, igmp_ifsoftc), igi_head); +static VNET_DEFINE(LIST_HEAD(, igmp_ifsoftc), igi_head) = + LIST_HEAD_INITIALIZER(igi_head); static VNET_DEFINE(struct igmpstat, igmpstat) = { .igps_version = IGPS_VERSION_3, .igps_len = sizeof(struct igmpstat), @@ -3589,70 +3596,74 @@ igmp_rec_type_to_str(const int type) } #endif +#ifdef VIMAGE static void -igmp_init(void *unused __unused) +vnet_igmp_uninit(const void *unused __unused) { - CTR1(KTR_IGMPV3, "%s: initializing", __func__); - - IGMP_LOCK_INIT(); - - m_raopt = igmp_ra_alloc(); - - netisr_register(&igmp_nh); -} -SYSINIT(igmp_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_init, NULL); - -static void -igmp_uninit(void *unused __unused) -{ - CTR1(KTR_IGMPV3, "%s: tearing down", __func__); - netisr_unregister(&igmp_nh); - - m_free(m_raopt); - m_raopt = NULL; - - IGMP_LOCK_DESTROY(); + VNET_ASSERT(LIST_EMPTY(&V_igi_head), + ("%s: igi list %p not empty; ifnets not detached?", __func__, + &V_igi_head)); } -SYSUNINIT(igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_uninit, NULL); +VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY, + vnet_igmp_uninit, NULL); +#endif -static void -vnet_igmp_init(const void *unused __unused) +#ifdef DDB +DB_SHOW_COMMAND(igi_list, db_show_igi_list) { + struct igmp_ifsoftc *igi, *tigi; + LIST_HEAD(_igi_list, igmp_ifsoftc) *igi_head; - CTR1(KTR_IGMPV3, "%s: initializing", __func__); + if (!have_addr) { + db_printf("usage: show igi_list \n"); + return; + } + igi_head = (struct _igi_list *)addr; - LIST_INIT(&V_igi_head); + LIST_FOREACH_SAFE(igi, igi_head, igi_link, tigi) { + db_printf("igmp_ifsoftc %p:\n", igi); + db_printf(" ifp %p\n", igi->igi_ifp); + db_printf(" version %u\n", igi->igi_version); + db_printf(" v1_timer %u\n", igi->igi_v1_timer); + db_printf(" v2_timer %u\n", igi->igi_v2_timer); + db_printf(" v3_timer %u\n", igi->igi_v3_timer); + db_printf(" flags %#x\n", igi->igi_flags); + db_printf(" rv %u\n", igi->igi_rv); + db_printf(" qi %u\n", igi->igi_qi); + db_printf(" qri %u\n", igi->igi_qri); + db_printf(" uri %u\n", igi->igi_uri); + /* SLIST_HEAD(,in_multi) igi_relinmhead */ + /* struct mbufq igi_gq; */ + db_printf("\n"); + } } -VNET_SYSINIT(vnet_igmp_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_igmp_init, - NULL); +#endif -static void -vnet_igmp_uninit(const void *unused __unused) -{ - - CTR1(KTR_IGMPV3, "%s: tearing down", __func__); - - KASSERT(LIST_EMPTY(&V_igi_head), - ("%s: igi list not empty; ifnets not detached?", __func__)); -} -VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, - vnet_igmp_uninit, NULL); - static int igmp_modevent(module_t mod, int type, void *unused __unused) { - switch (type) { - case MOD_LOAD: - case MOD_UNLOAD: - break; - default: - return (EOPNOTSUPP); - } - return (0); + switch (type) { + case MOD_LOAD: + CTR1(KTR_IGMPV3, "%s: initializing", __func__); + IGMP_LOCK_INIT(); + m_raopt = igmp_ra_alloc(); + netisr_register(&igmp_nh); + break; + case MOD_UNLOAD: + CTR1(KTR_IGMPV3, "%s: tearing down", __func__); + netisr_unregister(&igmp_nh); + m_free(m_raopt); + m_raopt = NULL; + IGMP_LOCK_DESTROY(); + break; + default: + return (EOPNOTSUPP); + } + return (0); } static moduledata_t igmp_mod = { @@ -3660,4 +3671,4 @@ static moduledata_t igmp_mod = { igmp_modevent, 0 }; -DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PROTO_MC, SI_ORDER_ANY); Index: sys/netinet/in_proto.c =================================================================== --- sys/netinet/in_proto.c (.../head) (revision 295854) +++ sys/netinet/in_proto.c (.../projects/vnet) (working copy) @@ -119,9 +119,6 @@ struct protosw inetsw[] = { .pr_domain = &inetdomain, .pr_protocol = IPPROTO_IP, .pr_init = ip_init, -#ifdef VIMAGE - .pr_destroy = ip_destroy, -#endif .pr_slowtimo = ip_slowtimo, .pr_drain = ip_drain, .pr_usrreqs = &nousrreqs @@ -135,9 +132,6 @@ struct protosw inetsw[] = { .pr_ctlinput = udp_ctlinput, .pr_ctloutput = udp_ctloutput, .pr_init = udp_init, -#ifdef VIMAGE - .pr_destroy = udp_destroy, -#endif .pr_usrreqs = &udp_usrreqs }, { @@ -149,9 +143,6 @@ struct protosw inetsw[] = { .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 @@ -166,9 +157,6 @@ struct protosw inetsw[] = { .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, .pr_init = sctp_init, -#ifdef VIMAGE - .pr_destroy = sctp_finish, -#endif .pr_drain = sctp_drain, .pr_usrreqs = &sctp_usrreqs }, @@ -193,9 +181,6 @@ struct protosw inetsw[] = { .pr_ctlinput = udplite_ctlinput, .pr_ctloutput = udp_ctloutput, .pr_init = udplite_init, -#ifdef VIMAGE - .pr_destroy = udplite_destroy, -#endif .pr_usrreqs = &udp_usrreqs }, { @@ -343,9 +328,6 @@ IPPROTOSPACER, .pr_input = rip_input, .pr_ctloutput = rip_ctloutput, .pr_init = rip_init, -#ifdef VIMAGE - .pr_destroy = rip_destroy, -#endif .pr_usrreqs = &rip_usrreqs }, }; Index: sys/netinet/ip_divert.c =================================================================== --- sys/netinet/ip_divert.c (.../head) (revision 295854) +++ sys/netinet/ip_divert.c (.../projects/vnet) (working copy) @@ -163,11 +163,13 @@ div_init(void) } static void -div_destroy(void) +div_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_divcbinfo); } +VNET_SYSUNINIT(divert, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, + div_destroy, NULL); /* * IPPROTO_DIVERT is not in the real IP protocol number space; this @@ -756,9 +758,6 @@ struct protosw div_protosw = { .pr_ctlinput = div_ctlinput, .pr_ctloutput = ip_ctloutput, .pr_init = div_init, -#ifdef VIMAGE - .pr_destroy = div_destroy, -#endif .pr_usrreqs = &div_usrreqs }; @@ -766,9 +765,7 @@ static int div_modevent(module_t mod, int type, void *unused) { int err = 0; -#ifndef VIMAGE int n; -#endif switch (type) { case MOD_LOAD: @@ -793,10 +790,6 @@ div_modevent(module_t mod, int type, void *unused) err = EPERM; break; case MOD_UNLOAD: -#ifdef VIMAGE - err = EPERM; - break; -#else /* * Forced unload. * @@ -818,10 +811,11 @@ div_modevent(module_t mod, int type, void *unused) ip_divert_ptr = NULL; err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW); INP_INFO_WUNLOCK(&V_divcbinfo); - div_destroy(); +#ifndef VIMAGE + div_destroy(NULL); +#endif EVENTHANDLER_DEREGISTER(maxsockets_change, ip_divert_event_tag); break; -#endif /* !VIMAGE */ default: err = EOPNOTSUPP; break; @@ -835,6 +829,6 @@ static moduledata_t ipdivertmod = { 0 }; -DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_FW, SI_ORDER_ANY); MODULE_DEPEND(ipdivert, ipfw, 3, 3, 3); MODULE_VERSION(ipdivert, 1); Index: sys/netinet/ip_input.c =================================================================== --- sys/netinet/ip_input.c (.../head) (revision 295854) +++ sys/netinet/ip_input.c (.../projects/vnet) (working copy) @@ -361,8 +361,8 @@ ip_init(void) } #ifdef VIMAGE -void -ip_destroy(void) +static void +ip_destroy(void *unused __unused) { int error; @@ -388,6 +388,8 @@ ip_init(void) /* Destroy IP reassembly queue. */ ipreass_destroy(); } + +VNET_SYSUNINIT(ip, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip_destroy, NULL); #endif #ifdef RSS Index: sys/netinet/ip_mroute.c =================================================================== --- sys/netinet/ip_mroute.c (.../head) (revision 295854) +++ sys/netinet/ip_mroute.c (.../projects/vnet) (working copy) @@ -2822,7 +2822,7 @@ vnet_mroute_init(const void *unused __unused) callout_init(&V_bw_meter_ch, 1); } -VNET_SYSINIT(vnet_mroute_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mroute_init, +VNET_SYSINIT(vnet_mroute_init, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mroute_init, NULL); static void @@ -2833,7 +2833,7 @@ vnet_mroute_uninit(const void *unused __unused) V_nexpire = NULL; } -VNET_SYSUNINIT(vnet_mroute_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, +VNET_SYSUNINIT(vnet_mroute_uninit, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, vnet_mroute_uninit, NULL); static int @@ -2946,4 +2946,4 @@ static moduledata_t ip_mroutemod = { 0 }; -DECLARE_MODULE(ip_mroute, ip_mroutemod, SI_SUB_PSEUDO, SI_ORDER_MIDDLE); +DECLARE_MODULE(ip_mroute, ip_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE); Index: sys/netinet/ip_var.h =================================================================== --- sys/netinet/ip_var.h (.../head) (revision 295854) +++ sys/netinet/ip_var.h (.../projects/vnet) (working copy) @@ -209,9 +209,6 @@ int ip_fragment(struct ip *ip, struct mbuf **m_fra u_long if_hwassist_flags); void ip_forward(struct mbuf *m, int srcrt); void ip_init(void); -#ifdef VIMAGE -void ip_destroy(void); -#endif extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, struct ip_moptions *); @@ -229,9 +226,6 @@ void ip_fillid(struct ip *); 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 int rip_input(struct mbuf **, int *, int); int rip_output(struct mbuf *, struct socket *, ...); int ipip_input(struct mbuf **, int *, int); Index: sys/netinet/raw_ip.c =================================================================== --- sys/netinet/raw_ip.c (.../head) (revision 295854) +++ sys/netinet/raw_ip.c (.../projects/vnet) (working copy) @@ -216,12 +216,13 @@ rip_init(void) } #ifdef VIMAGE -void -rip_destroy(void) +static void +rip_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_ripcbinfo); } +VNET_SYSUNINIT(raw_ip, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, rip_destroy, NULL); #endif #ifdef INET Index: sys/netinet/sctp_usrreq.c =================================================================== --- sys/netinet/sctp_usrreq.c (.../head) (revision 295854) +++ sys/netinet/sctp_usrreq.c (.../projects/vnet) (working copy) @@ -89,14 +89,15 @@ sctp_init(void) #endif } -void -sctp_finish(void) +#ifdef VIMAGE +static void +sctp_finish(void *unused __unused) { sctp_pcb_finish(); } +VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL); +#endif - - void sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz) { Index: sys/netinet/sctp_var.h =================================================================== --- sys/netinet/sctp_var.h (.../head) (revision 295854) +++ sys/netinet/sctp_var.h (.../projects/vnet) (working copy) @@ -333,7 +333,6 @@ int sctp_input(struct mbuf **, int *, int); void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); void sctp_drain(void); void sctp_init(void); -void sctp_finish(void); int sctp_flush(struct socket *, int); int sctp_shutdown(struct socket *); void Index: sys/netinet/tcp_subr.c =================================================================== --- sys/netinet/tcp_subr.c (.../head) (revision 295854) +++ sys/netinet/tcp_subr.c (.../projects/vnet) (working copy) @@ -720,8 +719,8 @@ tcp_init(void) } #ifdef VIMAGE -void -tcp_destroy(void) +static void +tcp_destroy(void *unused __unused) { int error; @@ -748,6 +747,7 @@ tcp_init(void) HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, error); } } +VNET_SYSUNINIT(tcp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_destroy, NULL); #endif void Index: sys/netinet/tcp_var.h =================================================================== --- sys/netinet/tcp_var.h (.../head) (revision 295854) +++ sys/netinet/tcp_var.h (.../projects/vnet) (working copy) @@ -741,9 +741,6 @@ struct tcpcb * tcp_drop(struct tcpcb *, int); void tcp_drain(void); void tcp_init(void); -#ifdef VIMAGE -void tcp_destroy(void); -#endif void tcp_fini(void *); char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *, const void *); Index: sys/netinet/udp_usrreq.c =================================================================== --- sys/netinet/udp_usrreq.c (.../head) (revision 295854) +++ sys/netinet/udp_usrreq.c (.../projects/vnet) (working copy) @@ -269,20 +269,23 @@ udp_discardcb(struct udpcb *up) } #ifdef VIMAGE -void -udp_destroy(void) +static void +udp_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_udbinfo); uma_zdestroy(V_udpcb_zone); } +VNET_SYSUNINIT(udp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udp_destroy, NULL); -void -udplite_destroy(void) +static void +udplite_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_ulitecbinfo); } +VNET_SYSUNINIT(udplite, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udplite_destroy, + NULL); #endif #ifdef INET Index: sys/netinet/udp_var.h =================================================================== --- sys/netinet/udp_var.h (.../head) (revision 295854) +++ sys/netinet/udp_var.h (.../projects/vnet) (working copy) @@ -169,10 +169,6 @@ void udplite_ctlinput(int, struct sockaddr *, voi int udp_ctloutput(struct socket *, struct sockopt *); void udp_init(void); void udplite_init(void); -#ifdef VIMAGE -void udp_destroy(void); -void udplite_destroy(void); -#endif int udp_input(struct mbuf **, int *, int); void udplite_input(struct mbuf *, int); struct inpcb *udp_notify(struct inpcb *inp, int errno); Index: sys/dev/usb/net/usb_ethernet.c =================================================================== --- sys/dev/usb/net/usb_ethernet.c (.../head) (revision 295854) +++ sys/dev/usb/net/usb_ethernet.c (.../projects/vnet) (working copy) @@ -641,5 +641,9 @@ uether_rxflush(struct usb_ether *ue) } } -DECLARE_MODULE(uether, uether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +/* + * USB net drivers are run by DRIVER_MODULE() thus SI_SUB_DRIVERS, + * SI_ORDER_MIDDLE. Run uether after that. + */ +DECLARE_MODULE(uether, uether_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); MODULE_VERSION(uether, 1); Index: sys/net/if.c =================================================================== --- sys/net/if.c (.../head) (revision 295854) +++ sys/net/if.c (.../projects/vnet) (working copy) @@ -385,6 +385,26 @@ vnet_if_uninit(const void *unused __unused) } VNET_SYSUNINIT(vnet_if_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST, vnet_if_uninit, NULL); + +/* + * XXX-BZ VNET; probably along with dom stuff. + * This is very wrong but MC currently implies that interfaces are + * gone before we can free it. This needs to be fixed differently + * and this needs to be moved back to SI_SUB_INIT_IF. + */ +static void +vnet_if_return(const void *unused __unused) +{ + struct ifnet *ifp, *nifp; + + /* Return all inherited interfaces to their parent vnets. */ + TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { + if (ifp->if_home_vnet != ifp->if_vnet) + if_vmove(ifp, ifp->if_home_vnet); + } +} +VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, + vnet_if_return, NULL); #endif static void @@ -825,6 +845,7 @@ if_purgeaddrs(struct ifnet *ifp) { struct ifaddr *ifa, *next; + /* XXX IF_ADDR_R/WLOCK */ TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) { if (ifa->ifa_addr->sa_family == AF_LINK) continue; @@ -849,7 +870,9 @@ if_purgeaddrs(struct ifnet *ifp) continue; } #endif /* INET6 */ + IF_ADDR_WLOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); + IF_ADDR_WUNLOCK(ifp); ifa_free(ifa); } } @@ -983,7 +1006,9 @@ if_detach_internal(struct ifnet *ifp, int vmove, s /* We can now free link ifaddr. */ if (!TAILQ_EMPTY(&ifp->if_addrhead)) { ifa = TAILQ_FIRST(&ifp->if_addrhead); + IF_ADDR_WLOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); + IF_ADDR_WUNLOCK(ifp); ifa_free(ifa); } } Index: sys/net/if_disc.c =================================================================== --- sys/net/if_disc.c (.../head) (revision 295854) +++ sys/net/if_disc.c (.../projects/vnet) (working copy) @@ -137,7 +137,7 @@ vnet_disc_init(const void *unused __unused) V_disc_cloner = if_clone_simple(discname, disc_clone_create, disc_clone_destroy, 0); } -VNET_SYSINIT(vnet_disc_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSINIT(vnet_disc_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_disc_init, NULL); static void @@ -146,7 +146,7 @@ vnet_disc_uninit(const void *unused __unused) if_clone_detach(V_disc_cloner); } -VNET_SYSUNINIT(vnet_disc_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_disc_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_disc_uninit, NULL); static int Index: sys/net/if_enc.c =================================================================== --- sys/net/if_enc.c (.../head) (revision 295854) +++ sys/net/if_enc.c (.../projects/vnet) (working copy) @@ -369,7 +369,7 @@ vnet_enc_init(const void *unused __unused) V_enc_cloner = if_clone_simple(encname, enc_clone_create, enc_clone_destroy, 1); } -VNET_SYSINIT(vnet_enc_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSINIT(vnet_enc_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_enc_init, NULL); static void @@ -378,7 +378,7 @@ vnet_enc_uninit(const void *unused __unused) if_clone_detach(V_enc_cloner); } -VNET_SYSUNINIT(vnet_enc_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_enc_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_enc_uninit, NULL); static int @@ -401,4 +401,4 @@ static moduledata_t enc_mod = { 0 }; -DECLARE_MODULE(if_enc, enc_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(if_enc, enc_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); Index: sys/net/pfil.c =================================================================== --- sys/net/pfil.c (.../head) (revision 295854) +++ sys/net/pfil.c (.../projects/vnet) (working copy) @@ -363,39 +363,34 @@ pfil_chain_remove(pfil_chain_t *chain, pfil_func_t * Stuff that must be initialized for every instance (including the first of * course). */ -static int +static void vnet_pfil_init(const void *unused) { LIST_INIT(&V_pfil_head_list); PFIL_LOCK_INIT_REAL(&V_pfil_lock, "shared"); - return (0); } /* * Called for the removal of each instance. */ -static int +static void vnet_pfil_uninit(const void *unused) { - KASSERT(LIST_EMPTY(&V_pfil_head_list), + VNET_ASSERT(LIST_EMPTY(&V_pfil_head_list), ("%s: pfil_head_list %p not empty", __func__, &V_pfil_head_list)); PFIL_LOCK_DESTROY_REAL(&V_pfil_lock); - return (0); } -/* Define startup order. */ -#define PFIL_SYSINIT_ORDER SI_SUB_PROTO_BEGIN -#define PFIL_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */ -#define PFIL_VNET_ORDER (PFIL_MODEVENT_ORDER + 2) /* Later still. */ - /* * Starting up. * * VNET_SYSINIT is called for each existing vnet and each new vnet. + * Make sure the pfil bits are first before any possible subsystem which + * might piggyback on the SI_SUB_PROTO_PFIL. */ -VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, +VNET_SYSINIT(vnet_pfil_init, SI_SUB_PROTO_PFIL, SI_ORDER_FIRST, vnet_pfil_init, NULL); /* @@ -403,5 +398,5 @@ vnet_pfil_uninit(const void *unused) * * VNET_SYSUNINIT is called for each exiting vnet as it exits. */ -VNET_SYSUNINIT(vnet_pfil_uninit, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, +VNET_SYSUNINIT(vnet_pfil_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_FIRST, vnet_pfil_uninit, NULL); Index: sys/net/vnet.c =================================================================== --- sys/net/vnet.c (.../head) (revision 295854) +++ sys/net/vnet.c (.../projects/vnet) (working copy) @@ -268,7 +268,6 @@ vnet_alloc(void) void vnet_destroy(struct vnet *vnet) { - struct ifnet *ifp, *nifp; SDT_PROBE2(vnet, functions, vnet_destroy, entry, __LINE__, vnet); KASSERT(vnet->vnet_sockcnt == 0, @@ -279,13 +278,6 @@ vnet_destroy(struct vnet *vnet) VNET_LIST_WUNLOCK(); CURVNET_SET_QUIET(vnet); - - /* Return all inherited interfaces to their parent vnets. */ - TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { - if (ifp->if_home_vnet != ifp->if_vnet) - if_vmove(ifp, ifp->if_home_vnet); - } - vnet_sysuninit(); CURVNET_RESTORE(); Index: sys/netinet6/nd6.c =================================================================== --- sys/netinet6/nd6.c (.../head) (revision 295854) +++ sys/netinet6/nd6.c (.../projects/vnet) (working copy) @@ -141,6 +141,7 @@ static VNET_DEFINE(struct callout, nd6_slowtimo_ch #define V_nd6_slowtimo_ch VNET(nd6_slowtimo_ch) VNET_DEFINE(struct callout, nd6_timer_ch); +#define V_nd6_timer_ch VNET(nd6_timer_ch) static void nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) @@ -210,11 +211,14 @@ nd6_init(void) /* initialization of the default router list */ TAILQ_INIT(&V_nd_defrouter); - /* start timer */ + /* Start timers. */ callout_init(&V_nd6_slowtimo_ch, 0); callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, nd6_slowtimo, curvnet); + callout_init(&V_nd6_timer_ch, 0); + callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet); + nd6_dad_init(); if (IS_DEFAULT_VNET(curvnet)) { lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event, Index: sys/netinet6/nd6.h =================================================================== --- sys/netinet6/nd6.h (.../head) (revision 295854) +++ sys/netinet6/nd6.h (.../projects/vnet) (working copy) @@ -341,9 +341,6 @@ VNET_DECLARE(int, nd6_onlink_ns_rfc4861); #define nd6log(x) do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0) -VNET_DECLARE(struct callout, nd6_timer_ch); -#define V_nd6_timer_ch VNET(nd6_timer_ch) - /* nd6_rtr.c */ VNET_DECLARE(int, nd6_defifindex); VNET_DECLARE(int, ip6_desync_factor); /* seconds */ Index: sys/netinet6/in6_ifattach.c =================================================================== --- sys/netinet6/in6_ifattach.c (.../head) (revision 295854) +++ sys/netinet6/in6_ifattach.c (.../projects/vnet) (working copy) @@ -890,3 +890,29 @@ in6_purgemaddrs(struct ifnet *ifp) IN6_MULTI_UNLOCK(); } + +void +in6_ifattach_destroy(void) +{ + + callout_drain(&V_in6_tmpaddrtimer_ch); +} + +static void +in6_ifattach_init(void *dummy) +{ + + /* Timer for regeneranation of temporary addresses randomize ID. */ + callout_init(&V_in6_tmpaddrtimer_ch, 0); + callout_reset(&V_in6_tmpaddrtimer_ch, + (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor - + V_ip6_temp_regen_advance) * hz, + in6_tmpaddrtimer, curvnet); +} + +/* + * Cheat. + * This must be after route_init(), which is now SI_ORDER_THIRD. + */ +SYSINIT(in6_ifattach_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, + in6_ifattach_init, NULL); Index: sys/netinet6/in6_ifattach.h =================================================================== --- sys/netinet6/in6_ifattach.h (.../head) (revision 295854) +++ sys/netinet6/in6_ifattach.h (.../projects/vnet) (working copy) @@ -35,6 +35,7 @@ #ifdef _KERNEL void in6_ifattach(struct ifnet *, struct ifnet *); +void in6_ifattach_destroy(void); void in6_ifdetach(struct ifnet *); int in6_get_tmpifid(struct ifnet *, u_int8_t *, const u_int8_t *, int); void in6_tmpaddrtimer(void *); Index: sys/netinet6/in6_proto.c =================================================================== --- sys/netinet6/in6_proto.c (.../head) (revision 295854) +++ sys/netinet6/in6_proto.c (.../projects/vnet) (working copy) @@ -153,9 +153,6 @@ struct protosw inet6sw[] = { .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, Index: sys/netinet6/ip6_input.c =================================================================== --- sys/netinet6/ip6_input.c (.../head) (revision 295854) +++ sys/netinet6/ip6_input.c (.../projects/vnet) (working copy) @@ -156,9 +156,6 @@ static struct netisr_handler ip6_direct_nh = { }; #endif -VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch); -#define V_in6_tmpaddrtimer_ch VNET(in6_tmpaddrtimer_ch) - VNET_DEFINE(struct pfil_head, inet6_pfil_hook); VNET_PCPUSTAT_DEFINE(struct ip6stat, ip6stat); @@ -170,7 +167,6 @@ VNET_PCPUSTAT_SYSUNINIT(ip6stat); struct rmlock in6_ifaddr_lock; RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); -static void ip6_init2(void *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); #ifdef PULLDOWN_TEST static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); @@ -309,8 +305,8 @@ ip6proto_unregister(short ip6proto) } #ifdef VIMAGE -void -ip6_destroy() +static void +ip6_destroy(void *unused __unused) { int error; @@ -331,40 +327,13 @@ ip6proto_unregister(short ip6proto) } hashdestroy(V_in6_ifaddrhashtbl, M_IFADDR, V_in6_ifaddrhmask); nd6_destroy(); - callout_drain(&V_in6_tmpaddrtimer_ch); + in6_ifattach_destroy(); } + +VNET_SYSUNINIT(inet6, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_destroy, NULL); #endif static int -ip6_init2_vnet(const void *unused __unused) -{ - - /* nd6_timer_init */ - callout_init(&V_nd6_timer_ch, 0); - callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet); - - /* timer for regeneranation of temporary addresses randomize ID */ - callout_init(&V_in6_tmpaddrtimer_ch, 0); - callout_reset(&V_in6_tmpaddrtimer_ch, - (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor - - V_ip6_temp_regen_advance) * hz, - in6_tmpaddrtimer, curvnet); - - return (0); -} - -static void -ip6_init2(void *dummy) -{ - - ip6_init2_vnet(NULL); -} - -/* cheat */ -/* This must be after route_init(), which is now SI_ORDER_THIRD */ -SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL); - -static int ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off, int *nxt, int *ours) { Index: sys/netinet6/ip6_mroute.c =================================================================== --- sys/netinet6/ip6_mroute.c (.../head) (revision 295854) +++ sys/netinet6/ip6_mroute.c (.../projects/vnet) (working copy) @@ -1966,4 +1966,4 @@ static moduledata_t ip6_mroutemod = { 0 }; -DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_ANY); Index: sys/netinet6/ip6_var.h =================================================================== --- sys/netinet6/ip6_var.h (.../head) (revision 295854) +++ sys/netinet6/ip6_var.h (.../projects/vnet) (working copy) @@ -354,9 +354,6 @@ int icmp6_ctloutput(struct socket *, struct sockop struct in6_ifaddr; void ip6_init(void); -#ifdef VIMAGE -void ip6_destroy(void); -#endif int ip6proto_register(short); int ip6proto_unregister(short); Index: sys/netinet6/mld6.c =================================================================== --- sys/netinet6/mld6.c (.../head) (revision 295854) +++ sys/netinet6/mld6.c (.../projects/vnet) (working copy) @@ -3264,7 +3264,7 @@ mld_init(void *unused __unused) mld_po.ip6po_prefer_tempaddr = IP6PO_TEMPADDR_NOTPREFER; mld_po.ip6po_flags = IP6PO_DONTFRAG; } -SYSINIT(mld_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_init, NULL); +SYSINIT(mld_init, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_init, NULL); static void mld_uninit(void *unused __unused) @@ -3273,7 +3273,7 @@ mld_uninit(void *unused __unused) CTR1(KTR_MLD, "%s: tearing down", __func__); MLD_LOCK_DESTROY(); } -SYSUNINIT(mld_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_uninit, NULL); +SYSUNINIT(mld_uninit, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_uninit, NULL); static void vnet_mld_init(const void *unused __unused) @@ -3283,7 +3283,7 @@ vnet_mld_init(const void *unused __unused) LIST_INIT(&V_mli_head); } -VNET_SYSINIT(vnet_mld_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_init, +VNET_SYSINIT(vnet_mld_init, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mld_init, NULL); static void @@ -3295,7 +3295,7 @@ vnet_mld_uninit(const void *unused __unused) KASSERT(LIST_EMPTY(&V_mli_head), ("%s: mli list not empty; ifnets not detached?", __func__)); } -VNET_SYSUNINIT(vnet_mld_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_uninit, +VNET_SYSUNINIT(vnet_mld_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mld_uninit, NULL); static int @@ -3317,4 +3317,4 @@ static moduledata_t mld_mod = { mld_modevent, 0 }; -DECLARE_MODULE(mld, mld_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(mld, mld_mod, SI_SUB_PROTO_MC, SI_ORDER_ANY); Index: sys/contrib/ipfilter/netinet/mlfk_ipl.c =================================================================== --- sys/contrib/ipfilter/netinet/mlfk_ipl.c (.../head) (revision 295854) +++ sys/contrib/ipfilter/netinet/mlfk_ipl.c (.../projects/vnet) (working copy) @@ -287,7 +287,7 @@ static moduledata_t ipfiltermod = { }; -DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_FW, SI_ORDER_ANY); #ifdef MODULE_VERSION MODULE_VERSION(ipfilter, 1); #endif Index: sys/netpfil/ipfw/dn_sched.h =================================================================== --- sys/netpfil/ipfw/dn_sched.h (.../head) (revision 295854) +++ sys/netpfil/ipfw/dn_sched.h (.../projects/vnet) (working copy) @@ -187,6 +187,6 @@ int dn_sched_modevent(module_t mod, int cmd, void #name, dn_sched_modevent, dnsched \ }; \ DECLARE_MODULE(name, name##_mod, \ - SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \ + SI_SUB_FW, SI_ORDER_ANY); \ MODULE_DEPEND(name, dummynet, 3, 3, 3) #endif /* _DN_SCHED_H */ Index: sys/netpfil/ipfw/ip_dummynet.c =================================================================== --- sys/netpfil/ipfw/ip_dummynet.c (.../head) (revision 295854) +++ sys/netpfil/ipfw/ip_dummynet.c (.../projects/vnet) (working copy) @@ -2298,7 +2298,7 @@ static moduledata_t dummynet_mod = { "dummynet", dummynet_modevent, NULL }; -#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN +#define DN_SI_SUB SI_SUB_FW #define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */ DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD); MODULE_DEPEND(dummynet, ipfw, 3, 3, 3); Index: sys/netpfil/ipfw/ip_fw2.c =================================================================== --- sys/netpfil/ipfw/ip_fw2.c (.../head) (revision 295854) +++ sys/netpfil/ipfw/ip_fw2.c (.../projects/vnet) (working copy) @@ -2883,7 +2883,7 @@ static moduledata_t ipfwmod = { }; /* Define startup order. */ -#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_SI_SUB_FIREWALL SI_SUB_FW #define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */ #define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */ #define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */ Index: sys/netpfil/ipfw/ip_fw_nat.c =================================================================== --- sys/netpfil/ipfw/ip_fw_nat.c (.../head) (revision 295854) +++ sys/netpfil/ipfw/ip_fw_nat.c (.../projects/vnet) (working copy) @@ -1213,7 +1213,7 @@ static moduledata_t ipfw_nat_mod = { }; /* Define startup order. */ -#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_FW #define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) /* after ipfw */ #define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) #define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) Index: sys/netpfil/pf/if_pfsync.c =================================================================== --- sys/netpfil/pf/if_pfsync.c (.../head) (revision 295854) +++ sys/netpfil/pf/if_pfsync.c (.../projects/vnet) (working copy) @@ -2416,6 +2416,7 @@ static moduledata_t pfsync_mod = { #define PFSYNC_MODVER 1 +/* XXX-BZ recheck the r229853 comment once the shuffling is done. */ DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); MODULE_VERSION(pfsync, PFSYNC_MODVER); MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER); Index: sys/netpfil/pf/pf_ioctl.c =================================================================== --- sys/netpfil/pf/pf_ioctl.c (.../head) (revision 295854) +++ sys/netpfil/pf/pf_ioctl.c (.../projects/vnet) (working copy) @@ -3789,5 +3789,5 @@ static moduledata_t pf_mod = { 0 }; -DECLARE_MODULE(pf, pf_mod, SI_SUB_PSEUDO, SI_ORDER_FIRST); +DECLARE_MODULE(pf, pf_mod, SI_SUB_FW, SI_ORDER_FIRST); MODULE_VERSION(pf, PF_MODVER);