Deleted Added
sdiff udiff text old ( 284577 ) new ( 285940 )
full compact
1/*-
2 * Copyright (c) 2001 Daniel Hartmeier
3 * Copyright (c) 2002 - 2008 Henning Brauer
4 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 22 unchanged lines hidden (view full) ---

31 * Effort sponsored in part by the Defense Advanced Research Projects
32 * Agency (DARPA) and Air Force Research Laboratory, Air Force
33 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
34 *
35 * $OpenBSD: pf.c,v 1.634 2009/02/27 12:37:45 henning Exp $
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: stable/10/sys/netpfil/pf/pf.c 284577 2015-06-18 20:59:48Z kp $");
40
41#include "opt_inet.h"
42#include "opt_inet6.h"
43#include "opt_bpf.h"
44#include "opt_pf.h"
45
46#include <sys/param.h>
47#include <sys/bus.h>

--- 602 unchanged lines hidden (view full) ---

650
651 sh = &V_pf_srchash[pf_hashsrc(src, af)];
652 PF_HASHROW_LOCK(sh);
653 LIST_FOREACH(n, &sh->nodes, entry)
654 if (n->rule.ptr == rule && n->af == af &&
655 ((af == AF_INET && n->addr.v4.s_addr == src->v4.s_addr) ||
656 (af == AF_INET6 && bcmp(&n->addr, src, sizeof(*src)) == 0)))
657 break;
658 if (n != NULL || returnlocked == 0)
659 PF_HASHROW_UNLOCK(sh);
660
661 return (n);
662}
663
664static int
665pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
666 struct pf_addr *src, sa_family_t af)
667{

--- 26 unchanged lines hidden (view full) ---

694 rule->max_src_conn_rate.seconds);
695
696 (*sn)->af = af;
697 (*sn)->rule.ptr = rule;
698 PF_ACPY(&(*sn)->addr, src, af);
699 LIST_INSERT_HEAD(&sh->nodes, *sn, entry);
700 (*sn)->creation = time_uptime;
701 (*sn)->ruletype = rule->action;
702 if ((*sn)->rule.ptr != NULL)
703 counter_u64_add((*sn)->rule.ptr->src_nodes, 1);
704 PF_HASHROW_UNLOCK(sh);
705 counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_INSERT], 1);
706 } else {
707 if (rule->max_src_states &&
708 (*sn)->states >= rule->max_src_states) {
709 counter_u64_add(V_pf_status.lcounters[LCNT_SRCSTATES],
710 1);
711 return (-1);
712 }
713 }
714 return (0);
715}
716
717void
718pf_unlink_src_node_locked(struct pf_src_node *src)
719{
720#ifdef INVARIANTS
721 struct pf_srchash *sh;
722
723 sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)];
724 PF_HASHROW_ASSERT(sh);
725#endif
726 LIST_REMOVE(src, entry);
727 if (src->rule.ptr)
728 counter_u64_add(src->rule.ptr->src_nodes, -1);
729 counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1);
730}
731
732void
733pf_unlink_src_node(struct pf_src_node *src)
734{
735 struct pf_srchash *sh;
736
737 sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)];
738 PF_HASHROW_LOCK(sh);
739 pf_unlink_src_node_locked(src);
740 PF_HASHROW_UNLOCK(sh);
741}
742
743static void
744pf_free_src_node(struct pf_src_node *sn)
745{
746
747 KASSERT(sn->states == 0, ("%s: %p has refs", __func__, sn));
748 uma_zfree(V_pf_sources_z, sn);
749}
750
751u_int
752pf_free_src_nodes(struct pf_src_node_list *head)
753{
754 struct pf_src_node *sn, *tmp;
755 u_int count = 0;
756
757 LIST_FOREACH_SAFE(sn, head, entry, tmp) {
758 pf_free_src_node(sn);
759 count++;
760 }
761
762 return (count);
763}
764
765void
766pf_mtag_initialize()
767{
768
769 pf_mtag_z = uma_zcreate("pf mtags", sizeof(struct m_tag) +

--- 775 unchanged lines hidden (view full) ---

1545 struct pf_src_node *cur, *next;
1546 int i;
1547
1548 LIST_INIT(&freelist);
1549 for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask; i++, sh++) {
1550 PF_HASHROW_LOCK(sh);
1551 LIST_FOREACH_SAFE(cur, &sh->nodes, entry, next)
1552 if (cur->states == 0 && cur->expire <= time_uptime) {
1553 pf_unlink_src_node_locked(cur);
1554 LIST_INSERT_HEAD(&freelist, cur, entry);
1555 } else if (cur->rule.ptr != NULL)
1556 cur->rule.ptr->rule_flag |= PFRULE_REFS;
1557 PF_HASHROW_UNLOCK(sh);
1558 }
1559
1560 pf_free_src_nodes(&freelist);
1561
1562 V_pf_status.src_nodes = uma_zone_get_cur(V_pf_sources_z);
1563}
1564
1565static void
1566pf_src_tree_remove_state(struct pf_state *s)
1567{
1568 u_int32_t timeout;
1569
1570 if (s->src_node != NULL) {
1571 if (s->src.tcp_est)
1572 --s->src_node->conn;
1573 if (--s->src_node->states == 0) {
1574 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1575 if (!timeout)
1576 timeout =
1577 V_pf_default_rule.timeout[PFTM_SRC_NODE];
1578 s->src_node->expire = time_uptime + timeout;
1579 }
1580 }
1581 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1582 if (--s->nat_src_node->states == 0) {
1583 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1584 if (!timeout)
1585 timeout =
1586 V_pf_default_rule.timeout[PFTM_SRC_NODE];
1587 s->nat_src_node->expire = time_uptime + timeout;
1588 }
1589 }
1590 s->src_node = s->nat_src_node = NULL;
1591}
1592
1593/*
1594 * Unlink and potentilly free a state. Function may be
1595 * called with ID hash row locked, but always returns
1596 * unlocked, since it needs to go through key hash locking.

--- 1969 unchanged lines hidden (view full) ---

3566 goto csfailed;
3567 }
3568 s->rt_kif = r->rpool.cur->kif;
3569 }
3570
3571 s->creation = time_uptime;
3572 s->expire = time_uptime;
3573
3574 if (sn != NULL) {
3575 s->src_node = sn;
3576 s->src_node->states++;
3577 }
3578 if (nsn != NULL) {
3579 /* XXX We only modify one side for now. */
3580 PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
3581 s->nat_src_node = nsn;
3582 s->nat_src_node->states++;
3583 }
3584 if (pd->proto == IPPROTO_TCP) {
3585 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
3586 off, pd, th, &s->src, &s->dst)) {
3587 REASON_SET(&reason, PFRES_MEMORY);
3588 pf_src_tree_remove_state(s);
3589 STATE_DEC_COUNTERS(s);
3590 uma_zfree(V_pf_state_z, s);

--- 81 unchanged lines hidden (view full) ---

3672 return (PF_PASS);
3673
3674csfailed:
3675 if (sk != NULL)
3676 uma_zfree(V_pf_state_key_z, sk);
3677 if (nk != NULL)
3678 uma_zfree(V_pf_state_key_z, nk);
3679
3680 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3681 pf_unlink_src_node(sn);
3682 pf_free_src_node(sn);
3683 }
3684
3685 if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) {
3686 pf_unlink_src_node(nsn);
3687 pf_free_src_node(nsn);
3688 }
3689
3690 return (PF_DROP);
3691}
3692
3693static int
3694pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
3695 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,

--- 2757 unchanged lines hidden ---