From owner-dev-commits-src-all@freebsd.org Sat Apr 10 09:16:24 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DA1395E0152; Sat, 10 Apr 2021 09:16:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FHTrl6jvsz4nXl; Sat, 10 Apr 2021 09:16:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9B89368C2; Sat, 10 Apr 2021 09:16:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13A9GNmc069041; Sat, 10 Apr 2021 09:16:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13A9GNGO069040; Sat, 10 Apr 2021 09:16:23 GMT (envelope-from git) Date: Sat, 10 Apr 2021 09:16:23 GMT Message-Id: <202104100916.13A9GNGO069040@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 0d71f9f36e6c - main - pfctl: Move ioctl abstraction functions into libpfctl MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0d71f9f36e6c1849fdaf6c1edc1178be07357034 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Apr 2021 09:16:25 -0000 The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=0d71f9f36e6c1849fdaf6c1edc1178be07357034 commit 0d71f9f36e6c1849fdaf6c1edc1178be07357034 Author: Kristof Provost AuthorDate: 2021-03-26 10:38:58 +0000 Commit: Kristof Provost CommitDate: 2021-04-10 09:16:02 +0000 pfctl: Move ioctl abstraction functions into libpfctl Introduce a library to wrap the pf ioctl interface. MFC after: 4 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D29562 --- lib/Makefile | 1 + lib/libpfctl/Makefile | 12 ++ .../pfctl/pfctl_ioctl.c => lib/libpfctl/libpfctl.c | 199 ++++++++++++++++++- lib/libpfctl/libpfctl.h | 45 +++++ sbin/pfctl/Makefile | 5 +- sbin/pfctl/parse.y | 6 +- sbin/pfctl/pfctl.c | 212 +-------------------- sbin/pfctl/pfctl_ioctl.h | 43 ----- sbin/pfctl/pfctl_optimize.c | 2 +- sbin/pfctl/pfctl_parser.h | 2 +- share/mk/src.libnames.mk | 5 + 11 files changed, 276 insertions(+), 256 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 80b77f1fd704..26b867ec00e1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -210,6 +210,7 @@ SUBDIR.${MK_BHYVE}+= libvmmapi SUBDIR.${MK_OPENMP}+= libomp .endif SUBDIR.${MK_OPENSSL}+= libmp +SUBDIR.${MK_PF}+= libpfctl SUBDIR.${MK_PMC}+= libpmc libpmcstat SUBDIR.${MK_RADIUS_SUPPORT}+= libradius SUBDIR.${MK_SENDMAIL}+= libmilter libsm libsmdb libsmutil diff --git a/lib/libpfctl/Makefile b/lib/libpfctl/Makefile new file mode 100644 index 000000000000..d7a00a94b349 --- /dev/null +++ b/lib/libpfctl/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +PACKAGE= lib${LIB} +LIB= pfctl +INTERNALLIB= true + +SRCS= libpfctl.c +INCS= libpfctl.h + +CFLAGS+= -fPIC + +.include diff --git a/sbin/pfctl/pfctl_ioctl.c b/lib/libpfctl/libpfctl.c similarity index 62% rename from sbin/pfctl/pfctl_ioctl.c rename to lib/libpfctl/libpfctl.c index 878a57de0fe4..e0d429112f5b 100644 --- a/sbin/pfctl/pfctl_ioctl.c +++ b/lib/libpfctl/libpfctl.c @@ -48,7 +48,7 @@ #include #include -#include "pfctl_ioctl.h" +#include "libpfctl.h" static void pf_nvuint_8_array(const nvlist_t *nvl, const char *name, size_t maxelems, @@ -118,6 +118,17 @@ pf_nvuint_64_array(const nvlist_t *nvl, const char *name, size_t maxelems, *nelems = elems; } +static void +pfctl_nv_add_addr(nvlist_t *nvparent, const char *name, + const struct pf_addr *addr) +{ + nvlist_t *nvl = nvlist_create(0); + + nvlist_add_binary(nvl, "addr", addr, sizeof(*addr)); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvaddr_to_addr(const nvlist_t *nvl, struct pf_addr *addr) { @@ -129,6 +140,22 @@ pf_nvaddr_to_addr(const nvlist_t *nvl, struct pf_addr *addr) memcpy(addr, data, len); } +static void +pfctl_nv_add_addr_wrap(nvlist_t *nvparent, const char *name, + const struct pf_addr_wrap *addr) +{ + nvlist_t *nvl = nvlist_create(0); + + nvlist_add_number(nvl, "type", addr->type); + nvlist_add_number(nvl, "iflags", addr->iflags); + nvlist_add_string(nvl, "ifname", addr->v.ifname); + nvlist_add_string(nvl, "tblname", addr->v.tblname); + pfctl_nv_add_addr(nvl, "addr", &addr->v.a.addr); + pfctl_nv_add_addr(nvl, "mask", &addr->v.a.mask); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr) { @@ -142,6 +169,23 @@ pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr) pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "mask"), &addr->v.a.mask); } +static void +pfctl_nv_add_rule_addr(nvlist_t *nvparent, const char *name, + const struct pf_rule_addr *addr) +{ + u_int64_t ports[2]; + nvlist_t *nvl = nvlist_create(0); + + pfctl_nv_add_addr_wrap(nvl, "addr", &addr->addr); + ports[0] = addr->port[0]; + ports[1] = addr->port[1]; + nvlist_add_number_array(nvl, "port", ports, 2); + nvlist_add_number(nvl, "neg", addr->neg); + nvlist_add_number(nvl, "port_op", addr->port_op); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvrule_addr_to_rule_addr(const nvlist_t *nvl, struct pf_rule_addr *addr) { @@ -152,6 +196,25 @@ pf_nvrule_addr_to_rule_addr(const nvlist_t *nvl, struct pf_rule_addr *addr) addr->port_op = nvlist_get_number(nvl, "port_op"); } +static void +pfctl_nv_add_pool(nvlist_t *nvparent, const char *name, + const struct pf_pool *pool) +{ + u_int64_t ports[2]; + nvlist_t *nvl = nvlist_create(0); + + nvlist_add_binary(nvl, "key", &pool->key, sizeof(pool->key)); + pfctl_nv_add_addr(nvl, "counter", &pool->counter); + nvlist_add_number(nvl, "tblidx", pool->tblidx); + + ports[0] = pool->proxy_port[0]; + ports[1] = pool->proxy_port[1]; + nvlist_add_number_array(nvl, "proxy_port", ports, 2); + nvlist_add_number(nvl, "opts", pool->opts); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvpool_to_pool(const nvlist_t *nvl, struct pf_pool *pool) { @@ -169,6 +232,21 @@ pf_nvpool_to_pool(const nvlist_t *nvl, struct pf_pool *pool) pool->opts = nvlist_get_number(nvl, "opts"); } +static void +pfctl_nv_add_uid(nvlist_t *nvparent, const char *name, + const struct pf_rule_uid *uid) +{ + u_int64_t uids[2]; + nvlist_t *nvl = nvlist_create(0); + + uids[0] = uid->uid[0]; + uids[1] = uid->uid[1]; + nvlist_add_number_array(nvl, "uid", uids, 2); + nvlist_add_number(nvl, "op", uid->op); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvrule_uid_to_rule_uid(const nvlist_t *nvl, struct pf_rule_uid *uid) { @@ -176,6 +254,18 @@ pf_nvrule_uid_to_rule_uid(const nvlist_t *nvl, struct pf_rule_uid *uid) uid->op = nvlist_get_number(nvl, "op"); } +static void +pfctl_nv_add_divert(nvlist_t *nvparent, const char *name, + const struct pf_rule *r) +{ + nvlist_t *nvl = nvlist_create(0); + + pfctl_nv_add_addr(nvl, "addr", &r->divert.addr); + nvlist_add_number(nvl, "port", r->divert.port); + + nvlist_add_nvlist(nvparent, name, nvl); +} + static void pf_nvdivert_to_divert(const nvlist_t *nvl, struct pf_rule *rule) { @@ -282,6 +372,113 @@ pf_nvrule_to_rule(const nvlist_t *nvl, struct pf_rule *rule) rule->u_src_nodes = nvlist_get_number(nvl, "src_nodes"); } +int +pfctl_add_rule(int dev, const struct pf_rule *r, const char *anchor, + const char *anchor_call, u_int32_t ticket, u_int32_t pool_ticket) +{ + struct pfioc_nv nv; + u_int64_t timeouts[PFTM_MAX]; + u_int64_t set_prio[2]; + nvlist_t *nvl, *nvlr; + int ret; + + nvl = nvlist_create(0); + nvlr = nvlist_create(0); + + nvlist_add_number(nvl, "ticket", ticket); + nvlist_add_number(nvl, "pool_ticket", pool_ticket); + nvlist_add_string(nvl, "anchor", anchor); + nvlist_add_string(nvl, "anchor_call", anchor_call); + + nvlist_add_number(nvlr, "nr", r->nr); + pfctl_nv_add_rule_addr(nvlr, "src", &r->src); + pfctl_nv_add_rule_addr(nvlr, "dst", &r->dst); + + nvlist_add_string(nvlr, "label", r->label); + nvlist_add_string(nvlr, "ifname", r->ifname); + nvlist_add_string(nvlr, "qname", r->qname); + nvlist_add_string(nvlr, "pqname", r->pqname); + nvlist_add_string(nvlr, "tagname", r->tagname); + nvlist_add_string(nvlr, "match_tagname", r->match_tagname); + nvlist_add_string(nvlr, "overload_tblname", r->overload_tblname); + + pfctl_nv_add_pool(nvlr, "rpool", &r->rpool); + + nvlist_add_number(nvlr, "os_fingerprint", r->os_fingerprint); + + nvlist_add_number(nvlr, "rtableid", r->rtableid); + for (int i = 0; i < PFTM_MAX; i++) + timeouts[i] = r->timeout[i]; + nvlist_add_number_array(nvlr, "timeout", timeouts, PFTM_MAX); + nvlist_add_number(nvlr, "max_states", r->max_states); + nvlist_add_number(nvlr, "max_src_nodes", r->max_src_nodes); + nvlist_add_number(nvlr, "max_src_states", r->max_src_states); + nvlist_add_number(nvlr, "max_src_conn", r->max_src_conn); + nvlist_add_number(nvlr, "max_src_conn_rate.limit", + r->max_src_conn_rate.limit); + nvlist_add_number(nvlr, "max_src_conn_rate.seconds", + r->max_src_conn_rate.seconds); + nvlist_add_number(nvlr, "prob", r->prob); + nvlist_add_number(nvlr, "cuid", r->cuid); + nvlist_add_number(nvlr, "cpid", r->cpid); + + nvlist_add_number(nvlr, "return_icmp", r->return_icmp); + nvlist_add_number(nvlr, "return_icmp6", r->return_icmp6); + + nvlist_add_number(nvlr, "max_mss", r->max_mss); + nvlist_add_number(nvlr, "scrub_flags", r->scrub_flags); + + pfctl_nv_add_uid(nvlr, "uid", &r->uid); + pfctl_nv_add_uid(nvlr, "gid", (const struct pf_rule_uid *)&r->gid); + + nvlist_add_number(nvlr, "rule_flag", r->rule_flag); + nvlist_add_number(nvlr, "action", r->action); + nvlist_add_number(nvlr, "direction", r->direction); + nvlist_add_number(nvlr, "log", r->log); + nvlist_add_number(nvlr, "logif", r->logif); + nvlist_add_number(nvlr, "quick", r->quick); + nvlist_add_number(nvlr, "ifnot", r->ifnot); + nvlist_add_number(nvlr, "match_tag_not", r->match_tag_not); + nvlist_add_number(nvlr, "natpass", r->natpass); + + nvlist_add_number(nvlr, "keep_state", r->keep_state); + nvlist_add_number(nvlr, "af", r->af); + nvlist_add_number(nvlr, "proto", r->proto); + nvlist_add_number(nvlr, "type", r->type); + nvlist_add_number(nvlr, "code", r->code); + nvlist_add_number(nvlr, "flags", r->flags); + nvlist_add_number(nvlr, "flagset", r->flagset); + nvlist_add_number(nvlr, "min_ttl", r->min_ttl); + nvlist_add_number(nvlr, "allow_opts", r->allow_opts); + nvlist_add_number(nvlr, "rt", r->rt); + nvlist_add_number(nvlr, "return_ttl", r->return_ttl); + nvlist_add_number(nvlr, "tos", r->tos); + nvlist_add_number(nvlr, "set_tos", r->set_tos); + nvlist_add_number(nvlr, "anchor_relative", r->anchor_relative); + nvlist_add_number(nvlr, "anchor_wildcard", r->anchor_wildcard); + + nvlist_add_number(nvlr, "flush", r->flush); + + nvlist_add_number(nvlr, "prio", r->prio); + set_prio[0] = r->set_prio[0]; + set_prio[1] = r->set_prio[1]; + nvlist_add_number_array(nvlr, "set_prio", set_prio, 2); + + pfctl_nv_add_divert(nvlr, "divert", r); + + nvlist_add_nvlist(nvl, "rule", nvlr); + + /* Now do the call. */ + nv.data = nvlist_pack(nvl, &nv.len); + nv.size = nv.len; + + ret = ioctl(dev, DIOCADDRULENV, &nv); + + free(nv.data); + nvlist_destroy(nvl); + + return (ret); +} int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket, const char *anchor, diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h new file mode 100644 index 000000000000..65ff2179f23d --- /dev/null +++ b/lib/libpfctl/libpfctl.h @@ -0,0 +1,45 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Rubicon Communications, LLC (Netgate) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _PFCTL_IOCTL_H_ +#define _PFCTL_IOCTL_H_ + +#include + +int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket, + const char *anchor, u_int32_t ruleset, struct pf_rule *rule, + char *anchor_call); +int pfctl_add_rule(int dev, const struct pf_rule *r, const char *anchor, + const char *anchor_call, u_int32_t ticket, u_int32_t pool_ticket); + +#endif diff --git a/sbin/pfctl/Makefile b/sbin/pfctl/Makefile index c84d558c989d..49bdfb9e3733 100644 --- a/sbin/pfctl/Makefile +++ b/sbin/pfctl/Makefile @@ -9,13 +9,14 @@ MAN= pfctl.8 SRCS = pfctl.c parse.y pfctl_parser.c pf_print_state.c pfctl_altq.c SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c pfctl_qstats.c -SRCS+= pfctl_optimize.c pfctl_ioctl.c +SRCS+= pfctl_optimize.c SRCS+= pf_ruleset.c WARNS?= 2 CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized CFLAGS+= -Wstrict-prototypes CFLAGS+= -DENABLE_ALTQ -I${.CURDIR} +CFLAGS+= -I${SRCTOP}/lib/libpfctl -I${OBJTOP}/lib/libpfctl # Need to use "WITH_" prefix to not conflict with the l/y INET/INET6 keywords .if ${MK_INET6_SUPPORT} != "no" @@ -27,7 +28,7 @@ CFLAGS+= -DWITH_INET YFLAGS= -LIBADD= m md nv +LIBADD= m md pfctl HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 9db85538feaf..89e421e6b5ad 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1040,7 +1040,7 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto decide_address_family($6.src.host, &r.af); decide_address_family($6.dst.host, &r.af); - pfctl_add_rule(pf, &r, $2); + pfctl_append_rule(pf, &r, $2); free($2); } ; @@ -4390,7 +4390,7 @@ binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag free($13); } - pfctl_add_rule(pf, &binat, ""); + pfctl_append_rule(pf, &binat, ""); } ; @@ -5407,7 +5407,7 @@ expand_rule(struct pf_rule *r, yyerror("skipping rule due to errors"); else { r->nr = pf->astack[pf->asd]->match++; - pfctl_add_rule(pf, r, anchor_call); + pfctl_append_rule(pf, r, anchor_call); added++; } diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 1aa17065597b..fde9d61260ef 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -63,7 +64,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include "pfctl_ioctl.h" #include "pfctl_parser.h" #include "pfctl.h" @@ -1291,7 +1291,7 @@ pfctl_add_pool(struct pfctl *pf, struct pf_pool *p, sa_family_t af) } int -pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call) +pfctl_append_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call) { u_int8_t rs_num; struct pf_rule *rule; @@ -1309,22 +1309,22 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call) * Don't make non-brace anchors part of the main anchor pool. */ if ((r->anchor = calloc(1, sizeof(*r->anchor))) == NULL) - err(1, "pfctl_add_rule: calloc"); + err(1, "pfctl_append_rule: calloc"); pf_init_ruleset(&r->anchor->ruleset); r->anchor->ruleset.anchor = r->anchor; if (strlcpy(r->anchor->path, anchor_call, sizeof(rule->anchor->path)) >= sizeof(rule->anchor->path)) - errx(1, "pfctl_add_rule: strlcpy"); + errx(1, "pfctl_append_rule: strlcpy"); if ((p = strrchr(anchor_call, '/')) != NULL) { if (!strlen(p)) - err(1, "pfctl_add_rule: bad anchor name %s", + err(1, "pfctl_append_rule: bad anchor name %s", anchor_call); } else p = (char *)anchor_call; if (strlcpy(r->anchor->name, p, sizeof(rule->anchor->name)) >= sizeof(rule->anchor->name)) - errx(1, "pfctl_add_rule: strlcpy"); + errx(1, "pfctl_append_rule: strlcpy"); } if ((rule = calloc(1, sizeof(*rule))) == NULL) @@ -1427,204 +1427,6 @@ pfctl_load_ruleset(struct pfctl *pf, char *path, struct pf_ruleset *rs, } -static void -pfctl_nv_add_addr(nvlist_t *nvparent, const char *name, - const struct pf_addr *addr) -{ - nvlist_t *nvl = nvlist_create(0); - - nvlist_add_binary(nvl, "addr", addr, sizeof(*addr)); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static void -pfctl_nv_add_addr_wrap(nvlist_t *nvparent, const char *name, - const struct pf_addr_wrap *addr) -{ - nvlist_t *nvl = nvlist_create(0); - - nvlist_add_number(nvl, "type", addr->type); - nvlist_add_number(nvl, "iflags", addr->iflags); - nvlist_add_string(nvl, "ifname", addr->v.ifname); - nvlist_add_string(nvl, "tblname", addr->v.tblname); - pfctl_nv_add_addr(nvl, "addr", &addr->v.a.addr); - pfctl_nv_add_addr(nvl, "mask", &addr->v.a.mask); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static void -pfctl_nv_add_rule_addr(nvlist_t *nvparent, const char *name, - const struct pf_rule_addr *addr) -{ - u_int64_t ports[2]; - nvlist_t *nvl = nvlist_create(0); - - pfctl_nv_add_addr_wrap(nvl, "addr", &addr->addr); - ports[0] = addr->port[0]; - ports[1] = addr->port[1]; - nvlist_add_number_array(nvl, "port", ports, 2); - nvlist_add_number(nvl, "neg", addr->neg); - nvlist_add_number(nvl, "port_op", addr->port_op); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static void -pfctl_nv_add_pool(nvlist_t *nvparent, const char *name, - const struct pf_pool *pool) -{ - u_int64_t ports[2]; - nvlist_t *nvl = nvlist_create(0); - - nvlist_add_binary(nvl, "key", &pool->key, sizeof(pool->key)); - pfctl_nv_add_addr(nvl, "counter", &pool->counter); - nvlist_add_number(nvl, "tblidx", pool->tblidx); - - ports[0] = pool->proxy_port[0]; - ports[1] = pool->proxy_port[1]; - nvlist_add_number_array(nvl, "proxy_port", ports, 2); - nvlist_add_number(nvl, "opts", pool->opts); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static void -pfctl_nv_add_uid(nvlist_t *nvparent, const char *name, - const struct pf_rule_uid *uid) -{ - u_int64_t uids[2]; - nvlist_t *nvl = nvlist_create(0); - - uids[0] = uid->uid[0]; - uids[1] = uid->uid[1]; - nvlist_add_number_array(nvl, "uid", uids, 2); - nvlist_add_number(nvl, "op", uid->op); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static void -pfctl_nv_add_divert(nvlist_t *nvparent, const char *name, - const struct pf_rule *r) -{ - nvlist_t *nvl = nvlist_create(0); - - pfctl_nv_add_addr(nvl, "addr", &r->divert.addr); - nvlist_add_number(nvl, "port", r->divert.port); - - nvlist_add_nvlist(nvparent, name, nvl); -} - -static int -pfctl_addrule(struct pfctl *pf, const struct pf_rule *r, const char *anchor, - const char *anchor_call, u_int32_t ticket, u_int32_t pool_ticket) -{ - struct pfioc_nv nv; - u_int64_t timeouts[PFTM_MAX]; - u_int64_t set_prio[2]; - nvlist_t *nvl, *nvlr; - int ret; - - nvl = nvlist_create(0); - nvlr = nvlist_create(0); - - nvlist_add_number(nvl, "ticket", ticket); - nvlist_add_number(nvl, "pool_ticket", pool_ticket); - nvlist_add_string(nvl, "anchor", anchor); - nvlist_add_string(nvl, "anchor_call", anchor_call); - - nvlist_add_number(nvlr, "nr", r->nr); - pfctl_nv_add_rule_addr(nvlr, "src", &r->src); - pfctl_nv_add_rule_addr(nvlr, "dst", &r->dst); - - nvlist_add_string(nvlr, "label", r->label); - nvlist_add_string(nvlr, "ifname", r->ifname); - nvlist_add_string(nvlr, "qname", r->qname); - nvlist_add_string(nvlr, "pqname", r->pqname); - nvlist_add_string(nvlr, "tagname", r->tagname); - nvlist_add_string(nvlr, "match_tagname", r->match_tagname); - nvlist_add_string(nvlr, "overload_tblname", r->overload_tblname); - - pfctl_nv_add_pool(nvlr, "rpool", &r->rpool); - - nvlist_add_number(nvlr, "os_fingerprint", r->os_fingerprint); - - nvlist_add_number(nvlr, "rtableid", r->rtableid); - for (int i = 0; i < PFTM_MAX; i++) - timeouts[i] = r->timeout[i]; - nvlist_add_number_array(nvlr, "timeout", timeouts, PFTM_MAX); - nvlist_add_number(nvlr, "max_states", r->max_states); - nvlist_add_number(nvlr, "max_src_nodes", r->max_src_nodes); - nvlist_add_number(nvlr, "max_src_states", r->max_src_states); - nvlist_add_number(nvlr, "max_src_conn", r->max_src_conn); - nvlist_add_number(nvlr, "max_src_conn_rate.limit", - r->max_src_conn_rate.limit); - nvlist_add_number(nvlr, "max_src_conn_rate.seconds", - r->max_src_conn_rate.seconds); - nvlist_add_number(nvlr, "prob", r->prob); - nvlist_add_number(nvlr, "cuid", r->cuid); - nvlist_add_number(nvlr, "cpid", r->cpid); - - nvlist_add_number(nvlr, "return_icmp", r->return_icmp); - nvlist_add_number(nvlr, "return_icmp6", r->return_icmp6); - - nvlist_add_number(nvlr, "max_mss", r->max_mss); - nvlist_add_number(nvlr, "scrub_flags", r->scrub_flags); - - pfctl_nv_add_uid(nvlr, "uid", &r->uid); - pfctl_nv_add_uid(nvlr, "gid", (struct pf_rule_uid *)&r->gid); - - nvlist_add_number(nvlr, "rule_flag", r->rule_flag); - nvlist_add_number(nvlr, "action", r->action); - nvlist_add_number(nvlr, "direction", r->direction); - nvlist_add_number(nvlr, "log", r->log); - nvlist_add_number(nvlr, "logif", r->logif); - nvlist_add_number(nvlr, "quick", r->quick); - nvlist_add_number(nvlr, "ifnot", r->ifnot); - nvlist_add_number(nvlr, "match_tag_not", r->match_tag_not); - nvlist_add_number(nvlr, "natpass", r->natpass); - - nvlist_add_number(nvlr, "keep_state", r->keep_state); - nvlist_add_number(nvlr, "af", r->af); - nvlist_add_number(nvlr, "proto", r->proto); - nvlist_add_number(nvlr, "type", r->type); - nvlist_add_number(nvlr, "code", r->code); - nvlist_add_number(nvlr, "flags", r->flags); - nvlist_add_number(nvlr, "flagset", r->flagset); - nvlist_add_number(nvlr, "min_ttl", r->min_ttl); - nvlist_add_number(nvlr, "allow_opts", r->allow_opts); - nvlist_add_number(nvlr, "rt", r->rt); - nvlist_add_number(nvlr, "return_ttl", r->return_ttl); - nvlist_add_number(nvlr, "tos", r->tos); - nvlist_add_number(nvlr, "set_tos", r->set_tos); - nvlist_add_number(nvlr, "anchor_relative", r->anchor_relative); - nvlist_add_number(nvlr, "anchor_wildcard", r->anchor_wildcard); - - nvlist_add_number(nvlr, "flush", r->flush); - - nvlist_add_number(nvlr, "prio", r->prio); - set_prio[0] = r->set_prio[0]; - set_prio[1] = r->set_prio[1]; - nvlist_add_number_array(nvlr, "set_prio", set_prio, 2); - - pfctl_nv_add_divert(nvlr, "divert", r); - - nvlist_add_nvlist(nvl, "rule", nvlr); - - /* Now do the call. */ - nv.data = nvlist_pack(nvl, &nv.len); - nv.size = nv.len; - - ret = ioctl(pf->dev, DIOCADDRULENV, &nv); - - free(nv.data); - nvlist_destroy(nvl); - - return (ret); -} - int pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth) { @@ -1657,7 +1459,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth) if ((pf->opts & PF_OPT_NOACTION) == 0) { if (pfctl_add_pool(pf, &r->rpool, r->af)) return (1); - if (pfctl_addrule(pf, r, anchor, name, ticket, + if (pfctl_add_rule(pf->dev, r, anchor, name, ticket, pf->paddr.ticket)) err(1, "DIOCADDRULENV"); } diff --git a/sbin/pfctl/pfctl_ioctl.h b/sbin/pfctl/pfctl_ioctl.h index 41dd0776854a..e69de29bb2d1 100644 --- a/sbin/pfctl/pfctl_ioctl.h +++ b/sbin/pfctl/pfctl_ioctl.h @@ -1,43 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2021 Rubicon Communications, LLC (Netgate) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _PFCTL_IOCTL_H_ -#define _PFCTL_IOCTL_H_ - -#include - -int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket, - const char *anchor, u_int32_t ruleset, struct pf_rule *rule, - char *anchor_call); - -#endif diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c index d3f0aa1bf3a4..821a528932f3 100644 --- a/sbin/pfctl/pfctl_optimize.c +++ b/sbin/pfctl/pfctl_optimize.c @@ -33,12 +33,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include -#include "pfctl_ioctl.h" #include "pfctl_parser.h" #include "pfctl.h" diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index aa6d98d7cf91..2547caa1a8ce 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -252,7 +252,7 @@ TAILQ_HEAD(pf_opt_queue, pf_opt_rule); int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *); int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *); -int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *); +int pfctl_append_rule(struct pfctl *, struct pf_rule *, const char *); int pfctl_add_altq(struct pfctl *, struct pf_altq *); int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t); void pfctl_move_pool(struct pf_pool *, struct pf_pool *); diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 1d3195f53eb1..259a65a7afd4 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -57,6 +57,7 @@ _INTERNALLIBS= \ opts \ parse \ pe \ + pfctl \ pmcstat \ sl \ sm \ @@ -387,6 +388,7 @@ _DP_zutil= avl tpool _DP_be= zfs spl nvpair zfsbootenv _DP_netmap= _DP_ifconfig= m +_DP_pfctl= nv # OFED support .if ${MK_OFED} != "no" @@ -564,6 +566,9 @@ LIBOPTS?= ${LIBOPTSDIR}/libopts${PIE_SUFFIX}.a LIBPARSEDIR= ${_LIB_OBJTOP}/usr.sbin/ntp/libparse LIBPARSE?= ${LIBPARSEDIR}/libparse${PIE_SUFFIX}.a +LIBPFCTL= ${_LIB_OBJTOP}/lib/libpfctl +LIBPFCTL?= ${LIBPFCTLDIR}/libpfctl${PIE_SUFFIX}.a + LIBLPRDIR= ${_LIB_OBJTOP}/usr.sbin/lpr/common_source LIBLPR?= ${LIBLPRDIR}/liblpr${PIE_SUFFIX}.a