diff options
| author | Kristof Provost <kp@FreeBSD.org> | 2024-10-11 09:02:27 +0000 |
|---|---|---|
| committer | Kristof Provost <kp@FreeBSD.org> | 2024-10-15 14:29:11 +0000 |
| commit | 9c125336727b48c576bf3598d7d2c52daa5909d7 (patch) | |
| tree | e2c74acba40f37732e8f4e86f337f56238aa9888 /sys | |
| parent | 96f1dfc1be9cf5525152941d06f07c6889e60071 (diff) | |
pf: convert DIOCGETSRCNODES to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/netpfil/pf/pf_nl.c | 78 | ||||
| -rw-r--r-- | sys/netpfil/pf/pf_nl.h | 27 |
2 files changed, 105 insertions, 0 deletions
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); |
