| 1747 | } |
| 1748 | |
| 1749 | static int |
| 1750 | pfsync_defer(struct pf_state *st, struct mbuf *m) |
| 1751 | { |
| 1752 | struct pfsync_softc *sc = V_pfsyncif; |
| 1753 | struct pfsync_deferral *pd; |
| 1754 | struct pfsync_bucket *b = pfsync_get_bucket(sc, st); |
| 1755 | |
| 1756 | if (m->m_flags & (M_BCAST|M_MCAST)) |
| 1757 | return (0); |
| 1758 | |
| 1759 | PFSYNC_LOCK(sc); |
| 1760 | |
| 1761 | if (sc == NULL || !(sc->sc_ifp->if_flags & IFF_DRV_RUNNING) || |
| 1762 | !(sc->sc_flags & PFSYNCF_DEFER)) { |
| 1763 | PFSYNC_UNLOCK(sc); |
| 1764 | return (0); |
| 1765 | } |
| 1766 | |
| 1767 | if (b->b_deferred >= 128) |
| 1768 | pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0); |
| 1769 | |
| 1770 | pd = malloc(sizeof(*pd), M_PFSYNC, M_NOWAIT); |
| 1771 | if (pd == NULL) |
| 1772 | return (0); |
| 1773 | b->b_deferred++; |
| 1774 | |
| 1775 | m->m_flags |= M_SKIP_FIREWALL; |
| 1776 | st->state_flags |= PFSTATE_ACK; |
| 1777 | |
| 1778 | pd->pd_sc = sc; |
| 1779 | pd->pd_refs = 0; |
| 1780 | pd->pd_st = st; |
| 1781 | pf_ref_state(st); |
| 1782 | pd->pd_m = m; |
| 1783 | |
| 1784 | TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry); |
| 1785 | callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED); |
| 1786 | callout_reset(&pd->pd_tmo, 10, pfsync_defer_tmo, pd); |
| 1787 | |
| 1788 | pfsync_push(b); |
| 1789 | |
| 1790 | return (1); |
| 1791 | } |
| 1792 | |
| 1793 | static void |
| 1794 | pfsync_undefer(struct pfsync_deferral *pd, int drop) |
nothing calls this directly
no test coverage detected