diff options
| author | Kristof Provost <kp@FreeBSD.org> | 2026-09-23 15:42:44 +0000 |
|---|---|---|
| committer | Kristof Provost <kp@FreeBSD.org> | 2026-09-25 15:45:43 +0000 |
| commit | 219ce30638405481cf56ebc6921ac891ce9f9909 (patch) | |
| tree | ce2dfec483a23f509452f24bc27e7eca60353b19 /sys | |
| parent | 754d2c69f3589cdd0bc4649d9e85ecd59935d9d3 (diff) | |
pf: convert DIOCRINADEFINE to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/netpfil/pf/pf_nl.c | 63 | ||||
| -rw-r--r-- | sys/netpfil/pf/pf_nl.h | 11 |
2 files changed, 74 insertions, 0 deletions
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index ef047da9965b..c1c34451e73c 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -2885,6 +2885,60 @@ pf_handle_source_clear(struct nlmsghdr *hdr, struct nl_pstate *npt) return (error); } +struct nl_parsed_ina_define { + struct pfr_table table; + struct nl_parsed_table_addrs addrs; + size_t addr_count; + uint32_t ticket; + uint32_t flags; +}; + +#define _OUT(_field) offsetof(struct nl_parsed_ina_define, _field) +static const struct nlattr_parser nla_ina_define_parser[] = { + { .type = PF_ID_TABLE, .off = _OUT(table), .arg = &nested_table_parser, .cb = nlattr_get_nested }, + { .type = PF_ID_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 }, + { .type = PF_ID_FLAGS, .off = _OUT(flags), .cb = nlattr_get_uint32 }, + { .type = PF_ID_ADDR, .off = _OUT(addrs), .cb = nlattr_get_pfr_addr }, +}; +NL_DECLARE_PARSER(ina_define_parser, struct genlmsghdr, nlf_p_empty, nla_ina_define_parser); + +static int +pf_handle_ina_define(struct nlmsghdr *hdr, struct nl_pstate *npt) +{ + struct nl_parsed_ina_define attrs = { 0 }; + struct nl_writer *nw = npt->nw; + struct genlmsghdr *ghdr_new; + int nadd, naddr; + int error; + + error = nl_parse_nlmsg(hdr, &ina_define_parser, npt, &attrs); + if (error != 0) + return (error); + + PF_RULES_WLOCK(); + error = pfr_ina_define(&attrs.table, attrs.addrs.addrs, + attrs.addrs.addr_count, &nadd, &naddr, + attrs.ticket, attrs.flags | PFR_FLAG_USERIOCTL); + PF_RULES_WUNLOCK(); + + if (error != 0) + return (error); + + if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) + return (ENOMEM); + + ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); + ghdr_new->cmd = PFNL_CMD_INA_DEFINE; + + nlattr_add_u32(nw, PF_ID_NADD, nadd); + nlattr_add_u32(nw, PF_ID_NADDR, naddr); + + if (!nlmsg_end(nw)) + return (ENOMEM); + + return (0); +} + static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser, @@ -2905,6 +2959,7 @@ static const struct nlhdr_parser *all_parsers[] = { &source_limiter_parser, &source_parser, &source_clear_parser, + &ina_define_parser, }; static uint16_t family_id; @@ -3286,6 +3341,14 @@ static const struct genl_cmd pf_cmds[] = { .cmd_priv = PRIV_NETINET_PF, .cmd_securelevel = 4, }, + { + .cmd_num = PFNL_CMD_INA_DEFINE, + .cmd_name = "INA_DEFINE", + .cmd_cb = pf_handle_ina_define, + .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL, + .cmd_priv = PRIV_NETINET_PF, + .cmd_securelevel = 3, + }, }; void diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index 4d0186ea86a5..d730fc12da5a 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -83,6 +83,7 @@ enum { PFNL_CMD_SOURCE_NGET = 45, PFNL_CMD_SOURCE_CLEAR = 46, PFNL_CMD_TABLE_TEST_ADDRS = 47, + PFNL_CMD_INA_DEFINE = 48, __PFNL_CMD_MAX, }; #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1) @@ -593,6 +594,16 @@ enum pf_source_clear_t { PF_SC_ADDR = 5, /* in6_addr */ }; +enum pf_ina_define_t { + PF_ID_UNSPEC, + PF_ID_TABLE = 1, /* pfr_table */ + PF_ID_TICKET = 2, /* u32 */ + PF_ID_FLAGS = 3, /* u32 */ + PF_ID_ADDR = 4, /* pfr_addr */ + PF_ID_NADD = 5, /* u32 */ + PF_ID_NADDR = 6, /* u32 */ +}; + #ifdef _KERNEL void pf_nl_register(void); |
