| 1804 | } |
| 1805 | |
| 1806 | static void |
| 1807 | pf_purge_unlinked_rules() |
| 1808 | { |
| 1809 | struct pf_krulequeue tmpq; |
| 1810 | struct pf_krule *r, *r1; |
| 1811 | |
| 1812 | /* |
| 1813 | * If we have overloading task pending, then we'd |
| 1814 | * better skip purging this time. There is a tiny |
| 1815 | * probability that overloading task references |
| 1816 | * an already unlinked rule. |
| 1817 | */ |
| 1818 | PF_OVERLOADQ_LOCK(); |
| 1819 | if (!SLIST_EMPTY(&V_pf_overloadqueue)) { |
| 1820 | PF_OVERLOADQ_UNLOCK(); |
| 1821 | return; |
| 1822 | } |
| 1823 | PF_OVERLOADQ_UNLOCK(); |
| 1824 | |
| 1825 | /* |
| 1826 | * Do naive mark-and-sweep garbage collecting of old rules. |
| 1827 | * Reference flag is raised by pf_purge_expired_states() |
| 1828 | * and pf_purge_expired_src_nodes(). |
| 1829 | * |
| 1830 | * To avoid LOR between PF_UNLNKDRULES_LOCK/PF_RULES_WLOCK, |
| 1831 | * use a temporary queue. |
| 1832 | */ |
| 1833 | TAILQ_INIT(&tmpq); |
| 1834 | PF_UNLNKDRULES_LOCK(); |
| 1835 | TAILQ_FOREACH_SAFE(r, &V_pf_unlinked_rules, entries, r1) { |
| 1836 | if (!(r->rule_flag & PFRULE_REFS)) { |
| 1837 | TAILQ_REMOVE(&V_pf_unlinked_rules, r, entries); |
| 1838 | TAILQ_INSERT_TAIL(&tmpq, r, entries); |
| 1839 | } else |
| 1840 | r->rule_flag &= ~PFRULE_REFS; |
| 1841 | } |
| 1842 | PF_UNLNKDRULES_UNLOCK(); |
| 1843 | |
| 1844 | if (!TAILQ_EMPTY(&tmpq)) { |
| 1845 | PF_RULES_WLOCK(); |
| 1846 | TAILQ_FOREACH_SAFE(r, &tmpq, entries, r1) { |
| 1847 | TAILQ_REMOVE(&tmpq, r, entries); |
| 1848 | pf_free_rule(r); |
| 1849 | } |
| 1850 | PF_RULES_WUNLOCK(); |
| 1851 | } |
| 1852 | } |
| 1853 | |
| 1854 | void |
| 1855 | pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) |
no test coverage detected