Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add support for pfs(8)



details:   https://anonhg.NetBSD.org/src/rev/012b24d1f663
branches:  trunk
changeset: 754653:012b24d1f663
user:      degroote <degroote%NetBSD.org@localhost>
date:      Fri May 07 17:41:57 2010 +0000

description:
Add support for pfs(8)

pfs(8) is a tool similar to ipfs(8) but for pf(4). It allows the admin to
dump internal configuration of pf, and restore at a latter point, after a
maintenance reboot for example, in a transparent way for user.

This work has been done mostly during my GSoC 2009

No objections on tech-net@

diffstat:

 distrib/sets/lists/base/mi |    3 +-
 distrib/sets/lists/man/mi  |    5 +-
 sys/dist/pf/net/pf.c       |   20 +-
 sys/dist/pf/net/pf_ioctl.c |  123 ++++++--
 sys/dist/pf/net/pfvar.h    |   12 +-
 usr.sbin/pf/Makefile       |    3 +-
 usr.sbin/pf/pfs/Makefile   |   18 +
 usr.sbin/pf/pfs/parse.y    |  504 +++++++++++++++++++++++++++++++++++++++
 usr.sbin/pf/pfs/parser.h   |   42 +++
 usr.sbin/pf/pfs/pfs.8      |   75 +++++
 usr.sbin/pf/pfs/pfs.c      |  575 +++++++++++++++++++++++++++++++++++++++++++++
 usr.sbin/pf/pfs/token.l    |  130 ++++++++++
 12 files changed, 1463 insertions(+), 47 deletions(-)

diffs (truncated from 1754 to 300 lines):

diff -r a1486b1f80a9 -r 012b24d1f663 distrib/sets/lists/base/mi
--- a/distrib/sets/lists/base/mi        Fri May 07 17:35:31 2010 +0000
+++ b/distrib/sets/lists/base/mi        Fri May 07 17:41:57 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.863 2010/04/27 02:51:04 lukem Exp $
+# $NetBSD: mi,v 1.864 2010/05/07 17:41:57 degroote Exp $
 #
 # Note:        Don't delete entries from here - mark them as "obsolete" instead,
 #      unless otherwise stated below.
@@ -279,6 +279,7 @@
 ./sbin/nologin                                 base-sysutil-root
 ./sbin/pfctl                                   base-pf-root            pf
 ./sbin/pflogd                                  base-pf-root            pf
+./sbin/pfs                                             base-pf-root            pf
 ./sbin/ping                                    base-netutil-root
 ./sbin/ping6                                   base-netutil-root       use_inet6
 ./sbin/poweroff                                        base-sysutil-root
diff -r a1486b1f80a9 -r 012b24d1f663 distrib/sets/lists/man/mi
--- a/distrib/sets/lists/man/mi Fri May 07 17:35:31 2010 +0000
+++ b/distrib/sets/lists/man/mi Fri May 07 17:41:57 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1205 2010/04/25 00:54:45 joerg Exp $
+# $NetBSD: mi,v 1.1206 2010/05/07 17:41:57 degroote Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -2448,6 +2448,7 @@
 ./usr/share/man/cat8/peace.0                   man-sys-catman          .cat
 ./usr/share/man/cat8/pfctl.0                   man-pf-catman           pf,.cat
 ./usr/share/man/cat8/pflogd.0                  man-pf-catman           pf,.cat
+./usr/share/man/cat8/pfs.0                             man-pf-catman           pf,.cat
 ./usr/share/man/cat8/pfspamd-setup.0           man-obsolete            obsolete
 ./usr/share/man/cat8/pfspamd.0                 man-obsolete            obsolete
 ./usr/share/man/cat8/pfspamdb.0                        man-obsolete            obsolete
@@ -4877,6 +4878,7 @@
 ./usr/share/man/html8/peace.html               man-sys-htmlman         html
 ./usr/share/man/html8/pfctl.html               man-pf-htmlman          pf,html
 ./usr/share/man/html8/pflogd.html              man-pf-htmlman          pf,html
+./usr/share/man/html8/pfs.html                 man-pf-htmlman          pf,html
 ./usr/share/man/html8/pickup.html              man-postfix-htmlman     postfix,html
 ./usr/share/man/html8/ping.html                        man-netutil-htmlman     html
 ./usr/share/man/html8/ping6.html               man-netutil-htmlman     use_inet6,html
@@ -7540,6 +7542,7 @@
 ./usr/share/man/man8/peace.8                   man-sys-man             .man
 ./usr/share/man/man8/pfctl.8                   man-pf-man              pf,.man
 ./usr/share/man/man8/pflogd.8                  man-pf-man              pf,.man
+./usr/share/man/man8/pfs.8                             man-pf-man              pf,.man
 ./usr/share/man/man8/pfspamd-setup.8           man-obsolete            obsolete
 ./usr/share/man/man8/pfspamd.8                 man-obsolete            obsolete
 ./usr/share/man/man8/pfspamdb.8                        man-obsolete            obsolete
diff -r a1486b1f80a9 -r 012b24d1f663 sys/dist/pf/net/pf.c
--- a/sys/dist/pf/net/pf.c      Fri May 07 17:35:31 2010 +0000
+++ b/sys/dist/pf/net/pf.c      Fri May 07 17:41:57 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pf.c,v 1.63 2010/04/12 13:57:38 ahoka Exp $    */
+/*     $NetBSD: pf.c,v 1.64 2010/05/07 17:41:57 degroote Exp $ */
 /*     $OpenBSD: pf.c,v 1.552.2.1 2007/11/27 16:37:57 henning Exp $ */
 
 /*
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.63 2010/04/12 13:57:38 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.64 2010/05/07 17:41:57 degroote Exp $");
 
 #include "pflog.h"
 
@@ -257,6 +257,8 @@
 extern struct pool pfr_ktable_pl;
 extern struct pool pfr_kentry_pl;
 
+extern int pf_state_lock;
+
 struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
        { &pf_state_pl, PFSTATE_HIWAT },
        { &pf_src_tree_pl, PFSNODE_HIWAT },
@@ -267,6 +269,10 @@
 
 #define STATE_LOOKUP()                                                 \
        do {                                                            \
+               if (pf_state_lock) {                \
+                       *state = NULL;                          \
+                       return (PF_DROP);                       \
+               }                                                               \
                if (direction == PF_IN)                                 \
                        *state = pf_find_state(kif, &key, PF_EXT_GWY);  \
                else                                                    \
@@ -940,8 +946,9 @@
                s = splsoftnet();
 
                /* process a fraction of the state table every second */
-               pf_purge_expired_states(1 + (pf_status.states
-                   / pf_default_rule.timeout[PFTM_INTERVAL]));
+               if (! pf_state_lock)
+                       pf_purge_expired_states(1 + (pf_status.states
+                                               / pf_default_rule.timeout[PFTM_INTERVAL]));
 
                /* purge other expired types every PFTM_INTERVAL seconds */
                if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
@@ -3341,6 +3348,11 @@
                    a, ruleset, pd);
        }
 
+       if (r->keep_state && pf_state_lock) {
+               REASON_SET(&reason, PFRES_STATELOCKED);
+               return PF_DROP;
+       }
+
        if ((r->action == PF_DROP) &&
            ((r->rule_flag & PFRULE_RETURNRST) ||
            (r->rule_flag & PFRULE_RETURNICMP) ||
diff -r a1486b1f80a9 -r 012b24d1f663 sys/dist/pf/net/pf_ioctl.c
--- a/sys/dist/pf/net/pf_ioctl.c        Fri May 07 17:35:31 2010 +0000
+++ b/sys/dist/pf/net/pf_ioctl.c        Fri May 07 17:41:57 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pf_ioctl.c,v 1.41 2010/04/13 13:08:16 ahoka Exp $      */
+/*     $NetBSD: pf_ioctl.c,v 1.42 2010/05/07 17:41:57 degroote Exp $   */
 /*     $OpenBSD: pf_ioctl.c,v 1.182 2007/06/24 11:17:13 mcbride Exp $ */
 
 /*
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf_ioctl.c,v 1.41 2010/04/13 13:08:16 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf_ioctl.c,v 1.42 2010/05/07 17:41:57 degroote Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -137,6 +137,8 @@
 void                    pf_state_import(struct pfsync_state *,
                            struct pf_state_key *, struct pf_state *);
 
+static int             pf_state_add(struct pfsync_state*);
+
 struct pf_rule          pf_default_rule;
 #ifdef __NetBSD__
 krwlock_t               pf_consistency_lock;
@@ -147,6 +149,8 @@
 static int              pf_altq_running;
 #endif
 
+int            pf_state_lock = 0;
+
 #define        TAGID_MAX        50000
 TAILQ_HEAD(pf_tags, pf_tagname)        pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
                                pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
@@ -1112,21 +1116,62 @@
        /* copy to state */
        memcpy(&s->id, &sp->id, sizeof(sp->id));
        s->creatorid = sp->creatorid;
-       strlcpy(sp->ifname, s->kif->pfik_name, sizeof(sp->ifname));
        pf_state_peer_from_pfsync(&sp->src, &s->src);
        pf_state_peer_from_pfsync(&sp->dst, &s->dst);
 
        s->rule.ptr = &pf_default_rule;
+       s->rule.ptr->states++;
        s->nat_rule.ptr = NULL;
        s->anchor.ptr = NULL;
        s->rt_kif = NULL;
        s->creation = time_second;
+       s->expire = time_second;
+       s->timeout = sp->timeout;
+       if (sp->expire > 0)
+               s->expire -= pf_default_rule.timeout[sp->timeout] - sp->expire;
        s->pfsync_time = 0;
        s->packets[0] = s->packets[1] = 0;
        s->bytes[0] = s->bytes[1] = 0;
 }
 
 int
+pf_state_add(struct pfsync_state* sp)
+{
+       struct pf_state         *s;
+       struct pf_state_key     *sk;
+       struct pfi_kif          *kif;
+
+       if (sp->timeout >= PFTM_MAX &&
+                       sp->timeout != PFTM_UNTIL_PACKET) {
+               return EINVAL;
+       }
+       s = pool_get(&pf_state_pl, PR_NOWAIT);
+       if (s == NULL) {
+               return ENOMEM;
+       }
+       bzero(s, sizeof(struct pf_state));
+       if ((sk = pf_alloc_state_key(s)) == NULL) {
+               pool_put(&pf_state_pl, s);
+               return ENOMEM;
+       }
+       pf_state_import(sp, sk, s);
+       kif = pfi_kif_get(sp->ifname);
+       if (kif == NULL) {
+               pool_put(&pf_state_pl, s);
+               pool_put(&pf_state_key_pl, sk);
+               return ENOENT;
+       }
+       if (pf_insert_state(kif, s)) {
+               pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+               pool_put(&pf_state_pl, s);
+               return ENOMEM;
+       }
+
+       return 0;
+}
+
+
+int
 pf_setup_pfsync_matching(struct pf_ruleset *rs)
 {
        MD5_CTX                  ctx;
@@ -1214,6 +1259,8 @@
                case DIOCIGETIFACES:
                case DIOCSETIFFLAG:
                case DIOCCLRIFFLAG:
+               case DIOCSETLCK:
+               case DIOCADDSTATES:
                        break;
                case DIOCRCLRTABLES:
                case DIOCRADDTABLES:
@@ -1251,6 +1298,7 @@
                case DIOCOSFPGET:
                case DIOCGETSRCNODES:
                case DIOCIGETIFACES:
+               case DIOCSETLCK:
                        break;
                case DIOCRCLRTABLES:
                case DIOCRADDTABLES:
@@ -1261,6 +1309,7 @@
                case DIOCRDELADDRS:
                case DIOCRSETADDRS:
                case DIOCRSETTFLAGS:
+               case DIOCADDSTATES:
                        if (((struct pfioc_table *)addr)->pfrio_flags &
                            PFR_FLAG_DUMMY) {
                                flags |= FWRITE; /* need write lock for dummy */
@@ -1859,42 +1908,39 @@
        case DIOCADDSTATE: {
                struct pfioc_state      *ps = (struct pfioc_state *)addr;
                struct pfsync_state     *sp = (struct pfsync_state *)ps->state;
-               struct pf_state         *s;
-               struct pf_state_key     *sk;
-               struct pfi_kif          *kif;
-
-               if (sp->timeout >= PFTM_MAX &&
-                   sp->timeout != PFTM_UNTIL_PACKET) {
-                       error = EINVAL;
-                       break;
-               }
-               s = pool_get(&pf_state_pl, PR_NOWAIT);
-               if (s == NULL) {
-                       error = ENOMEM;
-                       break;
-               }
-               bzero(s, sizeof(struct pf_state));
-               if ((sk = pf_alloc_state_key(s)) == NULL) {
-                       error = ENOMEM;
-                       break;
-               }
-               pf_state_import(sp, sk, s);
-               kif = pfi_kif_get(sp->ifname);
-               if (kif == NULL) {
-                       pool_put(&pf_state_pl, s);
-                       pool_put(&pf_state_key_pl, sk);
-                       error = ENOENT;
-                       break;
-               }
-               if (pf_insert_state(kif, s)) {
-                       pfi_kif_unref(kif, PFI_KIF_REF_NONE);
-                       pool_put(&pf_state_pl, s);
-                       pool_put(&pf_state_key_pl, sk);
-                       error = ENOMEM;
-               }
+
+               error = pf_state_add(sp);
                break;
        }
 
+       case DIOCADDSTATES: {
+               struct pfioc_states     *ps = (struct pfioc_states *)addr;
+               struct pfsync_state     *p = (struct pfsync_state *) ps->ps_states;
+               struct pfsync_state *pk;
+               int size = ps->ps_len;
+               int i = 0;
+               error = 0;
+
+               pk = malloc(sizeof(*pk), M_TEMP,M_WAITOK);
+
+               while (error == 0 && i < size) 
+               {
+                       if (copyin(p, pk, sizeof(struct pfsync_state))) 
+                       {
+                               error = EFAULT;
+                               free(pk, M_TEMP);
+                       } else {
+                               error = pf_state_add(pk);
+                               i += sizeof(*p);
+                               p++;
+                       }



Home | Main Index | Thread Index | Old Index