/* * npf_pfil_register: register pfil(9) hooks. */ int npf_pfil_register(bool init) { npf_t *npf = npf_getkernctx(); int error = 0; mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); /* Init: interface re-config and attach/detach hook. */ if (!npf_ph_if) { npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0); if (!npf_ph_if) { error = ENOENT; goto out; } error = pfil_add_hook(npf_ifhook, NULL, PFIL_IFADDR | PFIL_IFNET, npf_ph_if); KASSERT(error == 0); } if (init) { goto out; } /* Check if pfil hooks are not already registered. */ if (pfil_registered) { error = EEXIST; goto out; } /* Capture points of the activity in the IP layer. */ npf_ph_inet = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET); npf_ph_inet6 = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET6); if (!npf_ph_inet && !npf_ph_inet6) { error = ENOENT; goto out; } /* Packet IN/OUT handlers for IP layer. */ if (npf_ph_inet) { error = pfil_add_hook(npf_packet_handler, npf, PFIL_ALL, npf_ph_inet); KASSERT(error == 0); } if (npf_ph_inet6) { error = pfil_add_hook(npf_packet_handler, npf, PFIL_ALL, npf_ph_inet6); KASSERT(error == 0); } pfil_registered = true; out: KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); return error; }
/* * npf_pfil_register: register pfil(9) hooks. */ int npf_pfil_register(void) { int error; mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); /* Check if pfil hooks are not already registered. */ if (npf_ph_if) { error = EEXIST; goto fail; } /* Capture point of any activity in interfaces and IP layer. */ npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0); npf_ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); npf_ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); if (!npf_ph_if || (!npf_ph_inet && !npf_ph_inet6)) { npf_ph_if = NULL; error = ENOENT; goto fail; } /* Interface re-config or attach/detach hook. */ error = pfil_add_hook(npf_ifhook, NULL, PFIL_WAITOK | PFIL_IFADDR | PFIL_IFNET, npf_ph_if); KASSERT(error == 0); /* Packet IN/OUT handler on all interfaces and IP layer. */ if (npf_ph_inet) { error = pfil_add_hook(npf_packet_handler, NULL, PFIL_WAITOK | PFIL_ALL, npf_ph_inet); KASSERT(error == 0); } if (npf_ph_inet6) { error = pfil_add_hook(npf_packet_handler, NULL, PFIL_WAITOK | PFIL_ALL, npf_ph_inet6); KASSERT(error == 0); } fail: KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); return error; }
void pfi_initialize(void) { int s; int bound; if (pfi_all != NULL) /* already initialized */ return; #ifdef __NetBSD__ pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl", &pool_allocator_nointr, IPL_NONE); #else pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl", &pool_allocator_nointr); #endif /* !__NetBSD__ */ pfi_buffer_max = 64; pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer), PFI_MTYPE, M_WAITOK); if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL) panic("pfi_kif_get for pfi_all failed"); #ifdef __NetBSD__ ifnet_t *ifp; bound = curlwp_bind(); s = pserialize_read_enter(); IFNET_READER_FOREACH(ifp) { struct psref psref; psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class); pserialize_read_exit(s); pfi_init_groups(ifp); pfi_attach_ifnet(ifp); s = pserialize_read_enter(); psref_release(&psref, &ifp->if_psref, ifnet_psref_class); } pserialize_read_exit(s); curlwp_bindx(bound); pfil_add_hook(pfil_ifnet_wrapper, NULL, PFIL_IFNET, if_pfil); pfil_add_hook(pfil_ifaddr_wrapper, NULL, PFIL_IFADDR, if_pfil); #endif /* __NetBSD__ */ }