/** * Stop the kernel module. */ static kern_return_t VBoxNetFltDarwinStop(struct kmod_info *pKModInfo, void *pvData) { Log(("VBoxNetFltDarwinStop\n")); /* * Refuse to unload if anyone is currently using the filter driver. * This is important as I/O kit / xnu will to be able to do usage * tracking for us! */ int rc = vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltGlobals); if (RT_FAILURE(rc)) { Log(("VBoxNetFltDarwinStop - failed, busy.\n")); return KMOD_RETURN_FAILURE; } /* * Undo the work done during start (in reverse order). */ memset(&g_VBoxNetFltGlobals, 0, sizeof(g_VBoxNetFltGlobals)); RTR0Term(); return KMOD_RETURN_SUCCESS; }
/** * Module event handler, called from netgraph subsystem. */ static int vboxnetflt_modevent(struct module *pMod, int enmEventType, void *pvArg) { int rc; Log(("VBoxNetFltFreeBSDModuleEvent\n")); switch (enmEventType) { case MOD_LOAD: rc = RTR0Init(0); if (RT_FAILURE(rc)) { printf("RTR0Init failed %d\n", rc); return RTErrConvertToErrno(rc); } memset(&g_VBoxNetFltGlobals, 0, sizeof(VBOXNETFLTGLOBALS)); rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltGlobals); if (RT_FAILURE(rc)) { printf("vboxNetFltInitGlobalsAndIdc failed %d\n", rc); return RTErrConvertToErrno(rc); } /* No MODULE_VERSION in ng_ether so we can't MODULE_DEPEND it */ kern_kldload(curthread, "ng_ether", NULL); break; case MOD_UNLOAD: rc = vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltGlobals); memset(&g_VBoxNetFltGlobals, 0, sizeof(VBOXNETFLTGLOBALS)); RTR0Term(); break; case MOD_SHUTDOWN: case MOD_QUIESCE: default: return EOPNOTSUPP; } if (RT_SUCCESS(rc)) return 0; return RTErrConvertToErrno(rc); }