| 386 | } |
| 387 | |
| 388 | static void |
| 389 | pfsync_clone_destroy(struct ifnet *ifp) |
| 390 | { |
| 391 | struct pfsync_softc *sc = ifp->if_softc; |
| 392 | struct pfsync_bucket *b; |
| 393 | int c; |
| 394 | |
| 395 | for (c = 0; c < pfsync_buckets; c++) { |
| 396 | b = &sc->sc_buckets[c]; |
| 397 | /* |
| 398 | * At this stage, everything should have already been |
| 399 | * cleared by pfsync_uninit(), and we have only to |
| 400 | * drain callouts. |
| 401 | */ |
| 402 | while (b->b_deferred > 0) { |
| 403 | struct pfsync_deferral *pd = |
| 404 | TAILQ_FIRST(&b->b_deferrals); |
| 405 | |
| 406 | TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry); |
| 407 | b->b_deferred--; |
| 408 | if (callout_stop(&pd->pd_tmo) > 0) { |
| 409 | pf_release_state(pd->pd_st); |
| 410 | m_freem(pd->pd_m); |
| 411 | free(pd, M_PFSYNC); |
| 412 | } else { |
| 413 | pd->pd_refs++; |
| 414 | callout_drain(&pd->pd_tmo); |
| 415 | free(pd, M_PFSYNC); |
| 416 | } |
| 417 | } |
| 418 | |
| 419 | callout_drain(&b->b_tmo); |
| 420 | } |
| 421 | |
| 422 | callout_drain(&sc->sc_bulkfail_tmo); |
| 423 | callout_drain(&sc->sc_bulk_tmo); |
| 424 | |
| 425 | if (!(sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p) |
| 426 | (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy"); |
| 427 | bpfdetach(ifp); |
| 428 | if_detach(ifp); |
| 429 | |
| 430 | pfsync_drop(sc); |
| 431 | |
| 432 | if_free(ifp); |
| 433 | pfsync_multicast_cleanup(sc); |
| 434 | mtx_destroy(&sc->sc_mtx); |
| 435 | mtx_destroy(&sc->sc_bulk_mtx); |
| 436 | |
| 437 | free(sc->sc_buckets, M_PFSYNC); |
| 438 | free(sc, M_PFSYNC); |
| 439 | |
| 440 | V_pfsyncif = NULL; |
| 441 | } |
| 442 | |
| 443 | static int |
| 444 | pfsync_alloc_scrub_memory(struct pfsync_state_peer *s, |
nothing calls this directly
no test coverage detected