From nobody Tue Oct 15 14:29:32 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XSc1T2CgJz5Z1gY; Tue, 15 Oct 2024 14:29:33 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XSc1T0lZFz40tZ; Tue, 15 Oct 2024 14:29:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729002573; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UIcckdRFcZ84HFcsAYutmHCvW0wwA8DejHhb/3D6sFs=; b=e+N/6P1Iw+GWkXKFuohifd8xiat8wnixUaIvhhZq0lzRw8CmU0c6DsdUr7+NJ1k0P+Qez+ XdMKBvFbIKMDfA46ZH6Mjf9sVgT4y7Flcxlx4ur0bA5s2EtUdgEmO/EEZwUZQ15q0CQvgQ lYV6IBu3+oc8K4Hrw+PTQRDC2l+K7Xb67zfTyEIvjHAmqBvYJhaM7HRF+lMprrYFzha5LG 09bcpFF8TevDspTn79OWB/d7qHq2i8y1a6umMqh80LZat6AHyfCVf+5f3osCI+3A7DYXpU Ymi//rspEb7W9bLWmJvihRj9J+FlWm/01P44pwMI+iZqMmfSEAG7ijaHVk7Qjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729002573; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=UIcckdRFcZ84HFcsAYutmHCvW0wwA8DejHhb/3D6sFs=; b=R0hzRsSaYN0cBZyRcqZGExeDkDvBqh07kEessfPWDhTRtGhh5t8PlXs8PAS+J6Ip80t5Qe 1T+p1b8rrKmKeXdSYtGDj0me9+vDLpFDGs6JBBD8yU7NW41GLjN4Lb05h/NVUdtMEUfIrS TYUWfUx62J2UJe1Is1jhOcuRsqrEuXhfo/br+MRsegDbWc6N5WzkfXbQM1oqQhTyMDSGSM tR2pmmNl5TfTQ5flKH3/6qKNpcXjozauAuAMmjkOtCzSMFgmr+/kf1M/S7lIYvtv5j7ven QT/BEuMvacGcVLufisqaRsVnBMO7+D7Xb+JCqzZ/lEh5/7o3EoeZE6QSv5youg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1729002573; a=rsa-sha256; cv=none; b=Acrectf6enw7G+Bx6qvj9EO7El/N/MlS0ZK8EbDlPrNaduz0ICjtnGjfF83C+pbQ1+qTeh OVomhR2dNxmwVLpL3k3q8OwiZPz2REkHxHcC6Li9o1Gychb4F0r+YyiOvR/FXjL4lovLHg rBgdwiz96eyTugx4qZz1BIiG2no451xgnCwScdC7P3T+7MT5T3snphHcIWE6j6rwlbb+Pe VxrDKlgbP9xTI5UFurgGZQly8un+vBvdZc+wkL+7m56OdNiGkipCxWtxfGAMwgK686fZ8B mBwv9IX6ypvAEwB5ZcPGnRi4aEnrrxVWk/FhpsIieB3Rbdwm90mA6wSgk/8adg== 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 4XSc1T04VvzQFm; Tue, 15 Oct 2024 14:29:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 49FETWZV020536; Tue, 15 Oct 2024 14:29:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49FETWuw020533; Tue, 15 Oct 2024 14:29:32 GMT (envelope-from git) Date: Tue, 15 Oct 2024 14:29:32 GMT Message-Id: <202410151429.49FETWuw020533@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: 9c125336727b - main - pf: convert DIOCGETSRCNODES to netlink List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org 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: 9c125336727b48c576bf3598d7d2c52daa5909d7 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=9c125336727b48c576bf3598d7d2c52daa5909d7 commit 9c125336727b48c576bf3598d7d2c52daa5909d7 Author: Kristof Provost AuthorDate: 2024-10-11 09:02:27 +0000 Commit: Kristof Provost CommitDate: 2024-10-15 14:29:11 +0000 pf: convert DIOCGETSRCNODES to netlink Sponsored by: Rubicon Communications, LLC ("Netgate") --- lib/libpfctl/libpfctl.c | 68 +++++++++++++++++++++++++++++++++++++++++ lib/libpfctl/libpfctl.h | 24 +++++++++++++++ sbin/pfctl/pfctl.c | 56 +++++++++++----------------------- sbin/pfctl/pfctl_parser.c | 29 ++++++++---------- sbin/pfctl/pfctl_parser.h | 2 +- sys/netpfil/pf/pf_nl.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ sys/netpfil/pf/pf_nl.h | 27 ++++++++++++++++ 7 files changed, 229 insertions(+), 55 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index e0d93041c551..4634fa99cb19 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -2998,3 +2998,71 @@ pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct return (e.error); } +#define _OUT(_field) offsetof(struct pfctl_threshold, _field) +static const struct snl_attr_parser ap_pfctl_threshold[] = { + { .type = PF_TH_LIMIT, .off = _OUT(limit), .cb = snl_attr_get_uint32 }, + { .type = PF_TH_SECONDS, .off = _OUT(seconds), .cb = snl_attr_get_uint32 }, + { .type = PF_TH_COUNT, .off = _OUT(count), .cb = snl_attr_get_uint32 }, + { .type = PF_TH_LAST, .off = _OUT(last), .cb = snl_attr_get_uint32 }, +}; +SNL_DECLARE_ATTR_PARSER(pfctl_threshold_parser, ap_pfctl_threshold); +#undef _OUT + +#define _OUT(_field) offsetof(struct pfctl_src_node, _field) +static struct snl_attr_parser ap_srcnode[] = { + { .type = PF_SN_ADDR, .off = _OUT(addr), .cb = snl_attr_get_in6_addr }, + { .type = PF_SN_RADDR, .off = _OUT(raddr), .cb = snl_attr_get_in6_addr }, + { .type = PF_SN_RULE_NR, .off = _OUT(rule), .cb = snl_attr_get_uint32 }, + { .type = PF_SN_BYTES_IN, .off = _OUT(bytes[0]), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_BYTES_OUT, .off = _OUT(bytes[1]), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_PACKETS_IN, .off = _OUT(packets[0]), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_PACKETS_OUT, .off = _OUT(packets[1]), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_STATES, .off = _OUT(states), .cb = snl_attr_get_uint32 }, + { .type = PF_SN_CONNECTIONS, .off = _OUT(conn), .cb = snl_attr_get_uint32 }, + { .type = PF_SN_AF, .off = _OUT(af), .cb = snl_attr_get_uint8 }, + { .type = PF_SN_RULE_TYPE, .off = _OUT(ruletype), .cb = snl_attr_get_uint8 }, + { .type = PF_SN_CREATION, .off = _OUT(creation), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_EXPIRE, .off = _OUT(expire), .cb = snl_attr_get_uint64 }, + { .type = PF_SN_CONNECTION_RATE, .off = _OUT(conn_rate), .arg = &pfctl_threshold_parser, .cb = snl_attr_get_nested }, +}; +static struct snl_field_parser fp_srcnode[] = {}; +#undef _OUT +SNL_DECLARE_PARSER(srcnode_parser, struct genlmsghdr, fp_srcnode, ap_srcnode); + +int +pfctl_get_srcnodes(struct pfctl_handle *h, pfctl_get_srcnode_fn fn, void *arg) +{ + struct snl_writer nw; + struct pfctl_src_node sn; + struct snl_errmsg_data e = {}; + struct nlmsghdr *hdr; + uint32_t seq_id; + int family_id; + int ret; + + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); + if (family_id == 0) + return (ENOTSUP); + + snl_init_writer(&h->ss, &nw); + hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GET_SRCNODES); + + if ((hdr = snl_finalize_msg(&nw)) == NULL) + return (ENXIO); + + seq_id = hdr->nlmsg_seq; + + if (!snl_send_message(&h->ss, hdr)) + return (ENXIO); + + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { + if (!snl_parse_nlmsg(&h->ss, hdr, &srcnode_parser, &sn)) + continue; + + ret = fn(&sn, arg); + if (ret != 0) + return (ret); + } + + return (e.error); +} diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 4da21774a958..5c3f1376960c 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -386,6 +386,28 @@ struct pfctl_syncookies { uint32_t halfopen_states; }; +struct pfctl_threshold { + uint32_t limit; + uint32_t seconds; + uint32_t count; + uint32_t last; +}; + +struct pfctl_src_node { + struct pf_addr addr; + struct pf_addr raddr; + int rule; + uint64_t bytes[2]; + uint64_t packets[2]; + uint32_t states; + uint32_t conn; + sa_family_t af; + uint8_t ruletype; + uint64_t creation; + uint64_t expire; + struct pfctl_threshold conn_rate; +}; + #define PF_DEVICE "/dev/pf" struct pfctl_handle; @@ -506,5 +528,7 @@ int pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num, uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa); int pfctl_get_rulesets(struct pfctl_handle *h, const char *path, uint32_t *nr); int pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct pfioc_ruleset *rs); +typedef int (*pfctl_get_srcnode_fn)(struct pfctl_src_node*, void *); +int pfctl_get_srcnodes(struct pfctl_handle *h, pfctl_get_srcnode_fn fn, void *arg); #endif diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 4ca77f6c5f4a..555c5181eac8 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1519,51 +1519,31 @@ pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth, return (0); } -int -pfctl_show_src_nodes(int dev, int opts) +static int +pfctl_print_src_node(struct pfctl_src_node *sn, void *arg) { - struct pfioc_src_nodes psn; - struct pf_src_node *p; - char *inbuf = NULL, *newinbuf = NULL; - unsigned int len = 0; - int i; + int *opts = (int *)arg; - memset(&psn, 0, sizeof(psn)); - for (;;) { - psn.psn_len = len; - if (len) { - newinbuf = realloc(inbuf, len); - if (newinbuf == NULL) - err(1, "realloc"); - psn.psn_buf = inbuf = newinbuf; - } - if (ioctl(dev, DIOCGETSRCNODES, &psn) < 0) { - warn("DIOCGETSRCNODES"); - free(inbuf); - return (-1); - } - if (psn.psn_len + sizeof(struct pfioc_src_nodes) < len) - break; - if (len == 0 && psn.psn_len == 0) - goto done; - if (len == 0 && psn.psn_len != 0) - len = psn.psn_len; - if (psn.psn_len == 0) - goto done; /* no src_nodes */ - len *= 2; - } - p = psn.psn_src_nodes; - if (psn.psn_len > 0 && (opts & PF_OPT_SHOWALL)) + if (*opts & PF_OPT_SHOWALL) { pfctl_print_title("SOURCE TRACKING NODES:"); - for (i = 0; i < psn.psn_len; i += sizeof(*p)) { - print_src_node(p, opts); - p++; + *opts &= ~PF_OPT_SHOWALL; } -done: - free(inbuf); + + print_src_node(sn, *opts); + return (0); } +int +pfctl_show_src_nodes(int dev, int opts) +{ + int error; + + error = pfctl_get_srcnodes(pfh, pfctl_print_src_node, &opts); + + return (error); +} + struct pfctl_show_state_arg { int opts; int dotitle; diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 70c2ad42ca55..c25e96e645fb 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include "pfctl_parser.h" @@ -648,10 +649,10 @@ print_running(struct pfctl_status *status) } void -print_src_node(struct pf_src_node *sn, int opts) +print_src_node(struct pfctl_src_node *sn, int opts) { struct pf_addr_wrap aw; - int min, sec; + uint64_t min, sec; memset(&aw, 0, sizeof(aw)); if (sn->af == AF_INET) @@ -672,36 +673,32 @@ print_src_node(struct pf_src_node *sn, int opts) sn->creation /= 60; min = sn->creation % 60; sn->creation /= 60; - printf(" age %.2u:%.2u:%.2u", sn->creation, min, sec); + printf(" age %.2" PRIu64 ":%.2" PRIu64 ":%.2" PRIu64, + sn->creation, min, sec); if (sn->states == 0) { sec = sn->expire % 60; sn->expire /= 60; min = sn->expire % 60; sn->expire /= 60; - printf(", expires in %.2u:%.2u:%.2u", + printf(", expires in %.2" PRIu64 ":%.2" PRIu64 ":%.2" PRIu64, sn->expire, min, sec); } - printf(", %llu pkts, %llu bytes", -#ifdef __FreeBSD__ - (unsigned long long)(sn->packets[0] + sn->packets[1]), - (unsigned long long)(sn->bytes[0] + sn->bytes[1])); -#else + printf(", %" PRIu64 " pkts, %" PRIu64 " bytes", sn->packets[0] + sn->packets[1], sn->bytes[0] + sn->bytes[1]); -#endif switch (sn->ruletype) { case PF_NAT: - if (sn->rule.nr != -1) - printf(", nat rule %u", sn->rule.nr); + if (sn->rule != -1) + printf(", nat rule %u", sn->rule); break; case PF_RDR: - if (sn->rule.nr != -1) - printf(", rdr rule %u", sn->rule.nr); + if (sn->rule != -1) + printf(", rdr rule %u", sn->rule); break; case PF_PASS: case PF_MATCH: - if (sn->rule.nr != -1) - printf(", filter rule %u", sn->rule.nr); + if (sn->rule != -1) + printf(", filter rule %u", sn->rule); break; } printf("\n"); diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 550005508f40..e6959e0b95a7 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -302,7 +302,7 @@ int parse_flags(char *); int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *); void print_pool(struct pfctl_pool *, u_int16_t, u_int16_t, sa_family_t, int); -void print_src_node(struct pf_src_node *, int); +void print_src_node(struct pfctl_src_node *, int); void print_eth_rule(struct pfctl_eth_rule *, const char *, int); void print_rule(struct pfctl_rule *, const char *, int, int); void print_tabledef(const char *, int, int, struct node_tinithead *); diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index c75af9091d08..67047a319fb8 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -1713,6 +1713,77 @@ pf_handle_get_ruleset(struct nlmsghdr *hdr, struct nl_pstate *npt) return (0); } +static bool +nlattr_add_pf_threshold(struct nl_writer *nw, int attrtype, struct pf_threshold *t) +{ + int off = nlattr_add_nested(nw, attrtype); + + nlattr_add_u32(nw, PF_TH_LIMIT, t->limit); + nlattr_add_u32(nw, PF_TH_SECONDS, t->seconds); + nlattr_add_u32(nw, PF_TH_COUNT, t->count); + nlattr_add_u32(nw, PF_TH_LAST, t->last); + + nlattr_set_len(nw, off); + + return (true); +} + +static int +pf_handle_get_srcnodes(struct nlmsghdr *hdr, struct nl_pstate *npt) +{ + struct nl_writer *nw = npt->nw; + struct genlmsghdr *ghdr_new; + struct pf_ksrc_node *n; + struct pf_srchash *sh; + int i; + + hdr->nlmsg_flags |= NLM_F_MULTI; + + for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; + i++, sh++) { + /* Avoid locking empty rows. */ + if (LIST_EMPTY(&sh->nodes)) + continue; + + PF_HASHROW_LOCK(sh); + LIST_FOREACH(n, &sh->nodes, entry) { + if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) { + nlmsg_abort(nw); + return (ENOMEM); + } + + ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); + ghdr_new->cmd = PFNL_CMD_GET_SRCNODES; + ghdr_new->version = 0; + ghdr_new->reserved = 0; + + nlattr_add_in6_addr(nw, PF_SN_ADDR, &n->addr.v6); + nlattr_add_in6_addr(nw, PF_SN_RADDR, &n->raddr.v6); + nlattr_add_u32(nw, PF_SN_RULE_NR, n->rule->nr); + nlattr_add_u64(nw, PF_SN_BYTES_IN, counter_u64_fetch(n->bytes[0])); + nlattr_add_u64(nw, PF_SN_BYTES_OUT, counter_u64_fetch(n->bytes[1])); + nlattr_add_u64(nw, PF_SN_PACKETS_IN, counter_u64_fetch(n->packets[0])); + nlattr_add_u64(nw, PF_SN_PACKETS_OUT, counter_u64_fetch(n->packets[1])); + nlattr_add_u32(nw, PF_SN_STATES, n->states); + nlattr_add_u32(nw, PF_SN_CONNECTIONS, n->conn); + nlattr_add_u8(nw, PF_SN_AF, n->af); + nlattr_add_u8(nw, PF_SN_RULE_TYPE, n->ruletype); + nlattr_add_u64(nw, PF_SN_CREATION, n->creation); + nlattr_add_u64(nw, PF_SN_EXPIRE, n->expire); + nlattr_add_pf_threshold(nw, PF_SN_CONNECTION_RATE, &n->conn_rate); + + if (!nlmsg_end(nw)) { + PF_HASHROW_UNLOCK(sh); + nlmsg_abort(nw); + return (ENOMEM); + } + } + PF_HASHROW_UNLOCK(sh); + } + + return (0); +} + static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser, @@ -1899,6 +1970,13 @@ static const struct genl_cmd pf_cmds[] = { .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, .cmd_priv = PRIV_NETINET_PF, }, + { + .cmd_num = PFNL_CMD_GET_SRCNODES, + .cmd_name = "GET_SRCNODES", + .cmd_cb = pf_handle_get_srcnodes, + .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, + .cmd_priv = PRIV_NETINET_PF, + }, }; void diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index 0ec68658dcf3..e0b8989ab255 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -60,6 +60,7 @@ enum { PFNL_CMD_GET_ADDR = 22, PFNL_CMD_GET_RULESETS = 23, PFNL_CMD_GET_RULESET = 24, + PFNL_CMD_GET_SRCNODES = 25, __PFNL_CMD_MAX, }; #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1) @@ -389,6 +390,32 @@ enum pf_get_rulesets_types_t { PF_RS_NAME = 3, /* string */ }; +enum pf_threshold_types_t { + PF_TH_UNSPEC, + PF_TH_LIMIT = 1, /* u32 */ + PF_TH_SECONDS = 2, /* u32 */ + PF_TH_COUNT = 3, /* u32 */ + PF_TH_LAST = 4, /* u32 */ +}; + +enum pf_srcnodes_types_t { + PF_SN_UNSPEC, + PF_SN_ADDR = 1, /* nested, pf_addr */ + PF_SN_RADDR = 2, /* nested, pf_addr */ + PF_SN_RULE_NR = 3, /* u32 */ + PF_SN_BYTES_IN = 4, /* u64 */ + PF_SN_BYTES_OUT = 5, /* u64 */ + PF_SN_PACKETS_IN = 6, /* u64 */ + PF_SN_PACKETS_OUT = 7, /* u64 */ + PF_SN_STATES = 8, /* u32 */ + PF_SN_CONNECTIONS = 9, /* u32 */ + PF_SN_AF = 10, /* u8 */ + PF_SN_RULE_TYPE = 11, /* u8 */ + PF_SN_CREATION = 12, /* u64 */ + PF_SN_EXPIRE = 13, /* u64 */ + PF_SN_CONNECTION_RATE = 14, /* nested, pf_threshold */ +}; + #ifdef _KERNEL void pf_nl_register(void);