From owner-dev-commits-src-all@freebsd.org Tue Jun 1 14:55:12 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 37983655F80; Tue, 1 Jun 2021 14:55:12 +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 4FvZvh13Cxz3NTf; Tue, 1 Jun 2021 14:55:12 +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 0C1A425734; Tue, 1 Jun 2021 14:55:12 +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 151EtCQd003958; Tue, 1 Jun 2021 14:55:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 151EtCNC003955; Tue, 1 Jun 2021 14:55:12 GMT (envelope-from git) Date: Tue, 1 Jun 2021 14:55:12 GMT Message-Id: <202106011455.151EtCNC003955@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: ae23d302479c - stable/13 - pf: Move nvlist conversion functions to pf_nv 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/stable/13 X-Git-Reftype: branch X-Git-Commit: ae23d302479c5276e4e0a36e6ba1e882dc6e9899 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: Tue, 01 Jun 2021 14:55:12 -0000 The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=ae23d302479c5276e4e0a36e6ba1e882dc6e9899 commit ae23d302479c5276e4e0a36e6ba1e882dc6e9899 Author: Kristof Provost AuthorDate: 2021-05-18 07:24:50 +0000 Commit: Kristof Provost CommitDate: 2021-06-01 14:29:50 +0000 pf: Move nvlist conversion functions to pf_nv Separate the conversion functions (between kernel structs and nvlists) to pf_nv. This reduces the size of pf_ioctl.c, which is already quite large and complex, a good bit. It also keeps all the fairly straightforward conversion code together. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D30359 (cherry picked from commit 3032c353882aa70a461ef251b8aa6c59a0829ec5) --- sys/netpfil/pf/pf_ioctl.c | 866 +--------------------------------------------- sys/netpfil/pf/pf_nv.c | 851 +++++++++++++++++++++++++++++++++++++++++++++ sys/netpfil/pf/pf_nv.h | 42 ++- 3 files changed, 888 insertions(+), 871 deletions(-) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index ea4924e2dd41..af89ddf80daf 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -276,14 +276,6 @@ pflog_packet_t *pflog_packet_ptr = NULL; extern u_long pf_ioctl_maxcount; -#define ERROUT_FUNCTION(target, x) \ - do { \ - error = (x); \ - SDT_PROBE3(pf, ioctl, function, error, __func__, error, \ - __LINE__); \ - goto target; \ - } while (0) - static void pfattach_vnet(void) { @@ -1666,648 +1658,6 @@ pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule) rule->u_src_nodes = counter_u64_fetch(krule->src_nodes); } -static int -pf_check_rule_addr(const struct pf_rule_addr *addr) -{ - - switch (addr->addr.type) { - case PF_ADDR_ADDRMASK: - case PF_ADDR_NOROUTE: - case PF_ADDR_DYNIFTL: - case PF_ADDR_TABLE: - case PF_ADDR_URPFFAILED: - case PF_ADDR_RANGE: - break; - default: - return (EINVAL); - } - - if (addr->addr.p.dyn != NULL) { - return (EINVAL); - } - - return (0); -} - -static int -pf_nvaddr_to_addr(const nvlist_t *nvl, struct pf_addr *paddr) -{ - return (pf_nvbinary(nvl, "addr", paddr, sizeof(*paddr))); -} - -static nvlist_t * -pf_addr_to_nvaddr(const struct pf_addr *paddr) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_binary(nvl, "addr", paddr, sizeof(*paddr)); - - return (nvl); -} - -static int -pf_nvmape_to_mape(const nvlist_t *nvl, struct pf_mape_portset *mape) -{ - int error = 0; - - bzero(mape, sizeof(*mape)); - PFNV_CHK(pf_nvuint8(nvl, "offset", &mape->offset)); - PFNV_CHK(pf_nvuint8(nvl, "psidlen", &mape->psidlen)); - PFNV_CHK(pf_nvuint16(nvl, "psid", &mape->psid)); - -errout: - return (error); -} - -static nvlist_t * -pf_mape_to_nvmape(const struct pf_mape_portset *mape) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_number(nvl, "offset", mape->offset); - nvlist_add_number(nvl, "psidlen", mape->psidlen); - nvlist_add_number(nvl, "psid", mape->psid); - - return (nvl); -} - -static int -pf_nvpool_to_pool(const nvlist_t *nvl, struct pf_kpool *kpool) -{ - int error = 0; - - bzero(kpool, sizeof(*kpool)); - - PFNV_CHK(pf_nvbinary(nvl, "key", &kpool->key, sizeof(kpool->key))); - - if (nvlist_exists_nvlist(nvl, "counter")) { - PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "counter"), - &kpool->counter)); - } - - PFNV_CHK(pf_nvint(nvl, "tblidx", &kpool->tblidx)); - PFNV_CHK(pf_nvuint16_array(nvl, "proxy_port", kpool->proxy_port, 2, - NULL)); - PFNV_CHK(pf_nvuint8(nvl, "opts", &kpool->opts)); - - if (nvlist_exists_nvlist(nvl, "mape")) { - PFNV_CHK(pf_nvmape_to_mape(nvlist_get_nvlist(nvl, "mape"), - &kpool->mape)); - } - -errout: - return (error); -} - -static nvlist_t * -pf_pool_to_nvpool(const struct pf_kpool *pool) -{ - nvlist_t *nvl; - nvlist_t *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_binary(nvl, "key", &pool->key, sizeof(pool->key)); - tmp = pf_addr_to_nvaddr(&pool->counter); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "counter", tmp); - nvlist_destroy(tmp); - - nvlist_add_number(nvl, "tblidx", pool->tblidx); - pf_uint16_array_nv(nvl, "proxy_port", pool->proxy_port, 2); - nvlist_add_number(nvl, "opts", pool->opts); - - tmp = pf_mape_to_nvmape(&pool->mape); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "mape", tmp); - nvlist_destroy(tmp); - - return (nvl); - -error: - nvlist_destroy(nvl); - return (NULL); -} - -static int -pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr) -{ - int error = 0; - - bzero(addr, sizeof(*addr)); - - PFNV_CHK(pf_nvuint8(nvl, "type", &addr->type)); - PFNV_CHK(pf_nvuint8(nvl, "iflags", &addr->iflags)); - if (addr->type == PF_ADDR_DYNIFTL) - PFNV_CHK(pf_nvstring(nvl, "ifname", addr->v.ifname, - sizeof(addr->v.ifname))); - if (addr->type == PF_ADDR_TABLE) - PFNV_CHK(pf_nvstring(nvl, "tblname", addr->v.tblname, - sizeof(addr->v.tblname))); - - if (! nvlist_exists_nvlist(nvl, "addr")) - return (EINVAL); - PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "addr"), - &addr->v.a.addr)); - - if (! nvlist_exists_nvlist(nvl, "mask")) - return (EINVAL); - PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "mask"), - &addr->v.a.mask)); - - switch (addr->type) { - case PF_ADDR_DYNIFTL: - case PF_ADDR_TABLE: - case PF_ADDR_RANGE: - case PF_ADDR_ADDRMASK: - case PF_ADDR_NOROUTE: - case PF_ADDR_URPFFAILED: - break; - default: - return (EINVAL); - } - -errout: - return (error); -} - -static nvlist_t * -pf_addr_wrap_to_nvaddr_wrap(const struct pf_addr_wrap *addr) -{ - nvlist_t *nvl; - nvlist_t *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_number(nvl, "type", addr->type); - nvlist_add_number(nvl, "iflags", addr->iflags); - if (addr->type == PF_ADDR_DYNIFTL) - nvlist_add_string(nvl, "ifname", addr->v.ifname); - if (addr->type == PF_ADDR_TABLE) - nvlist_add_string(nvl, "tblname", addr->v.tblname); - - tmp = pf_addr_to_nvaddr(&addr->v.a.addr); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "addr", tmp); - nvlist_destroy(tmp); - tmp = pf_addr_to_nvaddr(&addr->v.a.mask); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "mask", tmp); - nvlist_destroy(tmp); - - return (nvl); - -error: - nvlist_destroy(nvl); - return (NULL); -} - -static int -pf_validate_op(uint8_t op) -{ - switch (op) { - case PF_OP_NONE: - case PF_OP_IRG: - case PF_OP_EQ: - case PF_OP_NE: - case PF_OP_LT: - case PF_OP_LE: - case PF_OP_GT: - case PF_OP_GE: - case PF_OP_XRG: - case PF_OP_RRG: - break; - default: - return (EINVAL); - } - - return (0); -} - -static int -pf_nvrule_addr_to_rule_addr(const nvlist_t *nvl, struct pf_rule_addr *addr) -{ - int error = 0; - - if (! nvlist_exists_nvlist(nvl, "addr")) - return (EINVAL); - - PFNV_CHK(pf_nvaddr_wrap_to_addr_wrap(nvlist_get_nvlist(nvl, "addr"), - &addr->addr)); - PFNV_CHK(pf_nvuint16_array(nvl, "port", addr->port, 2, NULL)); - PFNV_CHK(pf_nvuint8(nvl, "neg", &addr->neg)); - PFNV_CHK(pf_nvuint8(nvl, "port_op", &addr->port_op)); - - PFNV_CHK(pf_validate_op(addr->port_op)); - -errout: - return (error); -} - -static nvlist_t * -pf_rule_addr_to_nvrule_addr(const struct pf_rule_addr *addr) -{ - nvlist_t *nvl; - nvlist_t *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - tmp = pf_addr_wrap_to_nvaddr_wrap(&addr->addr); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "addr", tmp); - nvlist_destroy(tmp); - pf_uint16_array_nv(nvl, "port", addr->port, 2); - nvlist_add_number(nvl, "neg", addr->neg); - nvlist_add_number(nvl, "port_op", addr->port_op); - - return (nvl); - -error: - nvlist_destroy(nvl); - return (NULL); -} - -static int -pf_nvrule_uid_to_rule_uid(const nvlist_t *nvl, struct pf_rule_uid *uid) -{ - int error = 0; - - bzero(uid, sizeof(*uid)); - - PFNV_CHK(pf_nvuint32_array(nvl, "uid", uid->uid, 2, NULL)); - PFNV_CHK(pf_nvuint8(nvl, "op", &uid->op)); - - PFNV_CHK(pf_validate_op(uid->op)); - -errout: - return (error); -} - -static nvlist_t * -pf_rule_uid_to_nvrule_uid(const struct pf_rule_uid *uid) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - pf_uint32_array_nv(nvl, "uid", uid->uid, 2); - nvlist_add_number(nvl, "op", uid->op); - - return (nvl); -} - -static int -pf_nvrule_gid_to_rule_gid(const nvlist_t *nvl, struct pf_rule_gid *gid) -{ - /* Cheat a little. These stucts are the same, other than the name of - * the first field. */ - return (pf_nvrule_uid_to_rule_uid(nvl, (struct pf_rule_uid *)gid)); -} - -static int -pf_nvrule_to_krule(const nvlist_t *nvl, struct pf_krule **prule) -{ - struct pf_krule *rule; - int error = 0; - -#define ERROUT(x) ERROUT_FUNCTION(errout, x) - - rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK | M_ZERO); - - PFNV_CHK(pf_nvuint32(nvl, "nr", &rule->nr)); - - if (! nvlist_exists_nvlist(nvl, "src")) - ERROUT(EINVAL); - - error = pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "src"), - &rule->src); - if (error != 0) - ERROUT(error); - - if (! nvlist_exists_nvlist(nvl, "dst")) - ERROUT(EINVAL); - - PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"), - &rule->dst)); - - if (nvlist_exists_string(nvl, "label")) { - PFNV_CHK(pf_nvstring(nvl, "label", rule->label[0], - sizeof(rule->label[0]))); - } else if (nvlist_exists_string_array(nvl, "labels")) { - const char *const *strs; - size_t items; - int ret; - - strs = nvlist_get_string_array(nvl, "labels", &items); - if (items > PF_RULE_MAX_LABEL_COUNT) - ERROUT(E2BIG); - - for (size_t i = 0; i < items; i++) { - ret = strlcpy(rule->label[i], strs[i], - sizeof(rule->label[0])); - if (ret >= sizeof(rule->label[0])) - ERROUT(E2BIG); - } - } - - PFNV_CHK(pf_nvstring(nvl, "ifname", rule->ifname, - sizeof(rule->ifname))); - PFNV_CHK(pf_nvstring(nvl, "qname", rule->qname, sizeof(rule->qname))); - PFNV_CHK(pf_nvstring(nvl, "pqname", rule->pqname, - sizeof(rule->pqname))); - PFNV_CHK(pf_nvstring(nvl, "tagname", rule->tagname, - sizeof(rule->tagname))); - PFNV_CHK(pf_nvstring(nvl, "match_tagname", rule->match_tagname, - sizeof(rule->match_tagname))); - PFNV_CHK(pf_nvstring(nvl, "overload_tblname", rule->overload_tblname, - sizeof(rule->overload_tblname))); - - if (! nvlist_exists_nvlist(nvl, "rpool")) - ERROUT(EINVAL); - PFNV_CHK(pf_nvpool_to_pool(nvlist_get_nvlist(nvl, "rpool"), - &rule->rpool)); - - PFNV_CHK(pf_nvuint32(nvl, "os_fingerprint", &rule->os_fingerprint)); - - PFNV_CHK(pf_nvint(nvl, "rtableid", &rule->rtableid)); - PFNV_CHK(pf_nvuint32_array(nvl, "timeout", rule->timeout, PFTM_MAX, NULL)); - PFNV_CHK(pf_nvuint32(nvl, "max_states", &rule->max_states)); - PFNV_CHK(pf_nvuint32(nvl, "max_src_nodes", &rule->max_src_nodes)); - PFNV_CHK(pf_nvuint32(nvl, "max_src_states", &rule->max_src_states)); - PFNV_CHK(pf_nvuint32(nvl, "max_src_conn", &rule->max_src_conn)); - PFNV_CHK(pf_nvuint32(nvl, "max_src_conn_rate.limit", - &rule->max_src_conn_rate.limit)); - PFNV_CHK(pf_nvuint32(nvl, "max_src_conn_rate.seconds", - &rule->max_src_conn_rate.seconds)); - PFNV_CHK(pf_nvuint32(nvl, "prob", &rule->prob)); - PFNV_CHK(pf_nvuint32(nvl, "cuid", &rule->cuid)); - PFNV_CHK(pf_nvuint32(nvl, "cpid", &rule->cpid)); - - PFNV_CHK(pf_nvuint16(nvl, "return_icmp", &rule->return_icmp)); - PFNV_CHK(pf_nvuint16(nvl, "return_icmp6", &rule->return_icmp6)); - - PFNV_CHK(pf_nvuint16(nvl, "max_mss", &rule->max_mss)); - PFNV_CHK(pf_nvuint16(nvl, "scrub_flags", &rule->scrub_flags)); - - if (! nvlist_exists_nvlist(nvl, "uid")) - ERROUT(EINVAL); - PFNV_CHK(pf_nvrule_uid_to_rule_uid(nvlist_get_nvlist(nvl, "uid"), - &rule->uid)); - - if (! nvlist_exists_nvlist(nvl, "gid")) - ERROUT(EINVAL); - PFNV_CHK(pf_nvrule_gid_to_rule_gid(nvlist_get_nvlist(nvl, "gid"), - &rule->gid)); - - PFNV_CHK(pf_nvuint32(nvl, "rule_flag", &rule->rule_flag)); - PFNV_CHK(pf_nvuint8(nvl, "action", &rule->action)); - PFNV_CHK(pf_nvuint8(nvl, "direction", &rule->direction)); - PFNV_CHK(pf_nvuint8(nvl, "log", &rule->log)); - PFNV_CHK(pf_nvuint8(nvl, "logif", &rule->logif)); - PFNV_CHK(pf_nvuint8(nvl, "quick", &rule->quick)); - PFNV_CHK(pf_nvuint8(nvl, "ifnot", &rule->ifnot)); - PFNV_CHK(pf_nvuint8(nvl, "match_tag_not", &rule->match_tag_not)); - PFNV_CHK(pf_nvuint8(nvl, "natpass", &rule->natpass)); - - PFNV_CHK(pf_nvuint8(nvl, "keep_state", &rule->keep_state)); - PFNV_CHK(pf_nvuint8(nvl, "af", &rule->af)); - PFNV_CHK(pf_nvuint8(nvl, "proto", &rule->proto)); - PFNV_CHK(pf_nvuint8(nvl, "type", &rule->type)); - PFNV_CHK(pf_nvuint8(nvl, "code", &rule->code)); - PFNV_CHK(pf_nvuint8(nvl, "flags", &rule->flags)); - PFNV_CHK(pf_nvuint8(nvl, "flagset", &rule->flagset)); - PFNV_CHK(pf_nvuint8(nvl, "min_ttl", &rule->min_ttl)); - PFNV_CHK(pf_nvuint8(nvl, "allow_opts", &rule->allow_opts)); - PFNV_CHK(pf_nvuint8(nvl, "rt", &rule->rt)); - PFNV_CHK(pf_nvuint8(nvl, "return_ttl", &rule->return_ttl)); - PFNV_CHK(pf_nvuint8(nvl, "tos", &rule->tos)); - PFNV_CHK(pf_nvuint8(nvl, "set_tos", &rule->set_tos)); - PFNV_CHK(pf_nvuint8(nvl, "anchor_relative", &rule->anchor_relative)); - PFNV_CHK(pf_nvuint8(nvl, "anchor_wildcard", &rule->anchor_wildcard)); - - PFNV_CHK(pf_nvuint8(nvl, "flush", &rule->flush)); - PFNV_CHK(pf_nvuint8(nvl, "prio", &rule->prio)); - - PFNV_CHK(pf_nvuint8_array(nvl, "set_prio", &rule->prio, 2, NULL)); - - if (nvlist_exists_nvlist(nvl, "divert")) { - const nvlist_t *nvldivert = nvlist_get_nvlist(nvl, "divert"); - - if (! nvlist_exists_nvlist(nvldivert, "addr")) - ERROUT(EINVAL); - PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvldivert, "addr"), - &rule->divert.addr)); - PFNV_CHK(pf_nvuint16(nvldivert, "port", &rule->divert.port)); - } - - /* Validation */ -#ifndef INET - if (rule->af == AF_INET) - ERROUT(EAFNOSUPPORT); -#endif /* INET */ -#ifndef INET6 - if (rule->af == AF_INET6) - ERROUT(EAFNOSUPPORT); -#endif /* INET6 */ - - PFNV_CHK(pf_check_rule_addr(&rule->src)); - PFNV_CHK(pf_check_rule_addr(&rule->dst)); - - *prule = rule; - - return (0); - -#undef ERROUT -errout: - pf_krule_free(rule); - *prule = NULL; - - return (error); -} - -static nvlist_t * -pf_divert_to_nvdivert(const struct pf_krule *rule) -{ - nvlist_t *nvl; - nvlist_t *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - tmp = pf_addr_to_nvaddr(&rule->divert.addr); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "addr", tmp); - nvlist_destroy(tmp); - nvlist_add_number(nvl, "port", rule->divert.port); - - return (nvl); - -error: - nvlist_destroy(nvl); - return (NULL); -} - -static nvlist_t * -pf_krule_to_nvrule(const struct pf_krule *rule) -{ - nvlist_t *nvl, *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (nvl); - - nvlist_add_number(nvl, "nr", rule->nr); - tmp = pf_rule_addr_to_nvrule_addr(&rule->src); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "src", tmp); - nvlist_destroy(tmp); - tmp = pf_rule_addr_to_nvrule_addr(&rule->dst); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "dst", tmp); - nvlist_destroy(tmp); - - for (int i = 0; i < PF_SKIP_COUNT; i++) { - nvlist_append_number_array(nvl, "skip", - rule->skip[i].ptr ? rule->skip[i].ptr->nr : -1); - } - - for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) { - nvlist_append_string_array(nvl, "labels", rule->label[i]); - } - nvlist_add_string(nvl, "label", rule->label[0]); - nvlist_add_string(nvl, "ifname", rule->ifname); - nvlist_add_string(nvl, "qname", rule->qname); - nvlist_add_string(nvl, "pqname", rule->pqname); - nvlist_add_string(nvl, "tagname", rule->tagname); - nvlist_add_string(nvl, "match_tagname", rule->match_tagname); - nvlist_add_string(nvl, "overload_tblname", rule->overload_tblname); - - tmp = pf_pool_to_nvpool(&rule->rpool); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "rpool", tmp); - nvlist_destroy(tmp); - - nvlist_add_number(nvl, "evaluations", - counter_u64_fetch(rule->evaluations)); - for (int i = 0; i < 2; i++) { - nvlist_append_number_array(nvl, "packets", - counter_u64_fetch(rule->packets[i])); - nvlist_append_number_array(nvl, "bytes", - counter_u64_fetch(rule->bytes[i])); - } - - nvlist_add_number(nvl, "os_fingerprint", rule->os_fingerprint); - - nvlist_add_number(nvl, "rtableid", rule->rtableid); - pf_uint32_array_nv(nvl, "timeout", rule->timeout, PFTM_MAX); - nvlist_add_number(nvl, "max_states", rule->max_states); - nvlist_add_number(nvl, "max_src_nodes", rule->max_src_nodes); - nvlist_add_number(nvl, "max_src_states", rule->max_src_states); - nvlist_add_number(nvl, "max_src_conn", rule->max_src_conn); - nvlist_add_number(nvl, "max_src_conn_rate.limit", - rule->max_src_conn_rate.limit); - nvlist_add_number(nvl, "max_src_conn_rate.seconds", - rule->max_src_conn_rate.seconds); - nvlist_add_number(nvl, "qid", rule->qid); - nvlist_add_number(nvl, "pqid", rule->pqid); - nvlist_add_number(nvl, "prob", rule->prob); - nvlist_add_number(nvl, "cuid", rule->cuid); - nvlist_add_number(nvl, "cpid", rule->cpid); - - nvlist_add_number(nvl, "states_cur", - counter_u64_fetch(rule->states_cur)); - nvlist_add_number(nvl, "states_tot", - counter_u64_fetch(rule->states_tot)); - nvlist_add_number(nvl, "src_nodes", - counter_u64_fetch(rule->src_nodes)); - - nvlist_add_number(nvl, "return_icmp", rule->return_icmp); - nvlist_add_number(nvl, "return_icmp6", rule->return_icmp6); - - nvlist_add_number(nvl, "max_mss", rule->max_mss); - nvlist_add_number(nvl, "scrub_flags", rule->scrub_flags); - - tmp = pf_rule_uid_to_nvrule_uid(&rule->uid); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "uid", tmp); - nvlist_destroy(tmp); - tmp = pf_rule_uid_to_nvrule_uid((const struct pf_rule_uid *)&rule->gid); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "gid", tmp); - nvlist_destroy(tmp); - - nvlist_add_number(nvl, "rule_flag", rule->rule_flag); - nvlist_add_number(nvl, "action", rule->action); - nvlist_add_number(nvl, "direction", rule->direction); - nvlist_add_number(nvl, "log", rule->log); - nvlist_add_number(nvl, "logif", rule->logif); - nvlist_add_number(nvl, "quick", rule->quick); - nvlist_add_number(nvl, "ifnot", rule->ifnot); - nvlist_add_number(nvl, "match_tag_not", rule->match_tag_not); - nvlist_add_number(nvl, "natpass", rule->natpass); - - nvlist_add_number(nvl, "keep_state", rule->keep_state); - nvlist_add_number(nvl, "af", rule->af); - nvlist_add_number(nvl, "proto", rule->proto); - nvlist_add_number(nvl, "type", rule->type); - nvlist_add_number(nvl, "code", rule->code); - nvlist_add_number(nvl, "flags", rule->flags); - nvlist_add_number(nvl, "flagset", rule->flagset); - nvlist_add_number(nvl, "min_ttl", rule->min_ttl); - nvlist_add_number(nvl, "allow_opts", rule->allow_opts); - nvlist_add_number(nvl, "rt", rule->rt); - nvlist_add_number(nvl, "return_ttl", rule->return_ttl); - nvlist_add_number(nvl, "tos", rule->tos); - nvlist_add_number(nvl, "set_tos", rule->set_tos); - nvlist_add_number(nvl, "anchor_relative", rule->anchor_relative); - nvlist_add_number(nvl, "anchor_wildcard", rule->anchor_wildcard); - - nvlist_add_number(nvl, "flush", rule->flush); - nvlist_add_number(nvl, "prio", rule->prio); - - pf_uint8_array_nv(nvl, "set_prio", &rule->prio, 2); - - tmp = pf_divert_to_nvdivert(rule); - if (tmp == NULL) - goto error; - nvlist_add_nvlist(nvl, "divert", tmp); - nvlist_destroy(tmp); - - return (nvl); - -error: - nvlist_destroy(nvl); - return (NULL); -} - static int pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) { @@ -2571,219 +1921,6 @@ pf_state_kill_to_kstate_kill(const struct pfioc_state_kill *psk, return (0); } -static int -pf_nvstate_cmp_to_state_cmp(const nvlist_t *nvl, struct pf_state_cmp *cmp) -{ - int error = 0; - - bzero(cmp, sizeof(*cmp)); - - PFNV_CHK(pf_nvuint64(nvl, "id", &cmp->id)); - PFNV_CHK(pf_nvuint32(nvl, "creatorid", &cmp->creatorid)); - PFNV_CHK(pf_nvuint8(nvl, "direction", &cmp->direction)); - -errout: - return (error); -} - -static int -pf_nvstate_kill_to_kstate_kill(const nvlist_t *nvl, - struct pf_kstate_kill *kill) -{ - int error = 0; - - bzero(kill, sizeof(*kill)); - - if (! nvlist_exists_nvlist(nvl, "cmp")) - return (EINVAL); - - PFNV_CHK(pf_nvstate_cmp_to_state_cmp(nvlist_get_nvlist(nvl, "cmp"), - &kill->psk_pfcmp)); - PFNV_CHK(pf_nvuint8(nvl, "af", &kill->psk_af)); - PFNV_CHK(pf_nvint(nvl, "proto", &kill->psk_proto)); - - if (! nvlist_exists_nvlist(nvl, "src")) - return (EINVAL); - PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "src"), - &kill->psk_src)); - if (! nvlist_exists_nvlist(nvl, "dst")) - return (EINVAL); - PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"), - &kill->psk_dst)); - if (nvlist_exists_nvlist(nvl, "rt_addr")) { - PFNV_CHK(pf_nvrule_addr_to_rule_addr( - nvlist_get_nvlist(nvl, "rt_addr"), &kill->psk_rt_addr)); - } - - PFNV_CHK(pf_nvstring(nvl, "ifname", kill->psk_ifname, - sizeof(kill->psk_ifname))); - PFNV_CHK(pf_nvstring(nvl, "label", kill->psk_label, - sizeof(kill->psk_label))); - if (nvlist_exists_bool(nvl, "kill_match")) - kill->psk_kill_match = nvlist_get_bool(nvl, "kill_match"); - -errout: - return (error); -} - -static nvlist_t * -pf_state_key_to_nvstate_key(const struct pf_state_key *key) -{ - nvlist_t *nvl, *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - for (int i = 0; i < 2; i++) { - tmp = pf_addr_to_nvaddr(&key->addr[i]); - if (tmp == NULL) - goto errout; - nvlist_append_nvlist_array(nvl, "addr", tmp); - nvlist_append_number_array(nvl, "port", key->port[i]); - } - nvlist_add_number(nvl, "af", key->af); - nvlist_add_number(nvl, "proto", key->proto); - - return (nvl); - -errout: - nvlist_destroy(nvl); - return (NULL); -} - -static nvlist_t * -pf_state_scrub_to_nvstate_scrub(const struct pf_state_scrub *scrub) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_bool(nvl, "timestamp", scrub->pfss_flags & PFSS_TIMESTAMP); - nvlist_add_number(nvl, "ttl", scrub->pfss_ttl); - nvlist_add_number(nvl, "ts_mod", scrub->pfss_ts_mod); - - return (nvl); -} - -static nvlist_t * -pf_state_peer_to_nvstate_peer(const struct pf_state_peer *peer) -{ - nvlist_t *nvl, *tmp; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - if (peer->scrub) { - tmp = pf_state_scrub_to_nvstate_scrub(peer->scrub); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "scrub", tmp); - nvlist_destroy(tmp); - } - - nvlist_add_number(nvl, "seqlo", peer->seqlo); - nvlist_add_number(nvl, "seqhi", peer->seqhi); - nvlist_add_number(nvl, "seqdiff", peer->seqdiff); - nvlist_add_number(nvl, "max_win", peer->max_win); - nvlist_add_number(nvl, "mss", peer->mss); - nvlist_add_number(nvl, "state", peer->state); - nvlist_add_number(nvl, "wscale", peer->wscale); - - return (nvl); - -errout: - nvlist_destroy(nvl); - return (NULL); -} - - -static nvlist_t * -pf_state_to_nvstate(const struct pf_state *s) -{ - nvlist_t *nvl, *tmp; - uint32_t expire, flags = 0; - - nvl = nvlist_create(0); - if (nvl == NULL) - return (NULL); - - nvlist_add_number(nvl, "id", s->id); - nvlist_add_string(nvl, "ifname", s->kif->pfik_name); - nvlist_add_string(nvl, "orig_ifname", s->orig_kif->pfik_name); - - tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_STACK]); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "stack_key", tmp); - nvlist_destroy(tmp); - - tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_WIRE]); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "wire_key", tmp); - nvlist_destroy(tmp); - - tmp = pf_state_peer_to_nvstate_peer(&s->src); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "src", tmp); - nvlist_destroy(tmp); - - tmp = pf_state_peer_to_nvstate_peer(&s->dst); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "dst", tmp); - nvlist_destroy(tmp); - - tmp = pf_addr_to_nvaddr(&s->rt_addr); - if (tmp == NULL) - goto errout; - nvlist_add_nvlist(nvl, "rt_addr", tmp); - nvlist_destroy(tmp); - - nvlist_add_number(nvl, "rule", s->rule.ptr ? s->rule.ptr->nr : -1); - nvlist_add_number(nvl, "anchor", - s->anchor.ptr ? s->anchor.ptr->nr : -1); - nvlist_add_number(nvl, "nat_rule", - s->nat_rule.ptr ? s->nat_rule.ptr->nr : -1); - nvlist_add_number(nvl, "creation", s->creation); - - expire = pf_state_expires(s); - if (expire <= time_uptime) - expire = 0; - else - expire = expire - time_uptime; - nvlist_add_number(nvl, "expire", expire); - - for (int i = 0; i < 2; i++) { - nvlist_append_number_array(nvl, "packets", - counter_u64_fetch(s->packets[i])); - nvlist_append_number_array(nvl, "bytes", - counter_u64_fetch(s->bytes[i])); - } - - nvlist_add_number(nvl, "creatorid", s->creatorid); - nvlist_add_number(nvl, "direction", s->direction); - nvlist_add_number(nvl, "log", s->log); - nvlist_add_number(nvl, "state_flags", s->state_flags); - nvlist_add_number(nvl, "timeout", s->timeout); - if (s->src_node) - flags |= PFSYNC_FLAG_SRCNODE; - if (s->nat_src_node) - flags |= PFSYNC_FLAG_NATSRCNODE; - nvlist_add_number(nvl, "sync_flags", flags); - - return (nvl); - -errout: - nvlist_destroy(nvl); - return (NULL); -} - static int pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, uint32_t pool_ticket, const char *anchor, const char *anchor_call, @@ -3139,8 +2276,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td if (! nvlist_exists_nvlist(nvl, "rule")) ERROUT(EINVAL); + rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK | M_ZERO); error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"), - &rule); + rule); if (error) ERROUT(error); diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 1fdb52e5fad0..863259dbf9aa 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -28,9 +28,13 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_inet.h" +#include "opt_inet6.h" + #include #include #include +#include #include #include @@ -137,3 +141,850 @@ pf_nvstring(const nvlist_t *nvl, const char *name, char *str, size_t maxlen) return (0); } + +static int +pf_nvaddr_to_addr(const nvlist_t *nvl, struct pf_addr *paddr) +{ + return (pf_nvbinary(nvl, "addr", paddr, sizeof(*paddr))); +} + +static nvlist_t * +pf_addr_to_nvaddr(const struct pf_addr *paddr) +{ + nvlist_t *nvl; + + nvl = nvlist_create(0); + if (nvl == NULL) + return (NULL); + + nvlist_add_binary(nvl, "addr", paddr, sizeof(*paddr)); + + return (nvl); +} + +static int +pf_nvmape_to_mape(const nvlist_t *nvl, struct pf_mape_portset *mape) +{ + int error = 0; + + bzero(mape, sizeof(*mape)); + PFNV_CHK(pf_nvuint8(nvl, "offset", &mape->offset)); + PFNV_CHK(pf_nvuint8(nvl, "psidlen", &mape->psidlen)); + PFNV_CHK(pf_nvuint16(nvl, "psid", &mape->psid)); + +errout: + return (error); +} + +static nvlist_t * +pf_mape_to_nvmape(const struct pf_mape_portset *mape) +{ *** 869 LINES SKIPPED ***