aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2024-10-11 09:02:27 +0000
committerKristof Provost <kp@FreeBSD.org>2024-10-15 14:29:11 +0000
commit9c125336727b48c576bf3598d7d2c52daa5909d7 (patch)
treee2c74acba40f37732e8f4e86f337f56238aa9888 /sys
parent96f1dfc1be9cf5525152941d06f07c6889e60071 (diff)
pf: convert DIOCGETSRCNODES to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
Diffstat (limited to 'sys')
-rw-r--r--sys/netpfil/pf/pf_nl.c78
-rw-r--r--sys/netpfil/pf/pf_nl.h27
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);