mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
pf: convert DIOCXBEGIN, DIOCXROLLBACK, DIOCXCOMMIT to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
1 parent
0974ef03b4
commit
a7aad5bbcd
11 files changed
+673
-76
No files matched your search
@@ -4594,6 +4594,206 @@ out:
|
||||
return (e.error);
|
||||
}
|
||||
|
||||
struct pfctl_trans_e {
|
||||
int rs_num;
|
||||
char anchor[MAXPATHLEN];
|
||||
uint32_t ticket;
|
||||
TAILQ_ENTRY(pfctl_trans_e) entry;
|
||||
};
|
||||
|
||||
struct pfctl_trans {
|
||||
struct pfctl_trans_e tmp;
|
||||
TAILQ_HEAD(, pfctl_trans_e) elms;
|
||||
};
|
||||
|
||||
struct pfctl_trans *
|
||||
pfctl_trans_alloc(void)
|
||||
{
|
||||
struct pfctl_trans *t = malloc(sizeof(struct pfctl_trans));
|
||||
|
||||
bzero(t, sizeof(*t));
|
||||
|
||||
TAILQ_INIT(&t->elms);
|
||||
|
||||
return (t);
|
||||
}
|
||||
|
||||
void
|
||||
pfctl_trans_free(struct pfctl_trans *t)
|
||||
{
|
||||
struct pfctl_trans_e *e, *et;
|
||||
|
||||
TAILQ_FOREACH_SAFE(e, &t->elms, entry, et)
|
||||
free(e);
|
||||
|
||||
free(t);
|
||||
}
|
||||
|
||||
size_t
|
||||
pfctl_trans_size(struct pfctl_trans *t)
|
||||
{
|
||||
struct pfctl_trans_e *e;
|
||||
size_t s = 0;
|
||||
|
||||
TAILQ_FOREACH(e, &t->elms, entry)
|
||||
s++;
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_trans_add(struct pfctl_trans *t, int rs_num, const char *anchor)
|
||||
{
|
||||
struct pfctl_trans_e *e;
|
||||
|
||||
e = malloc(sizeof(*e));
|
||||
if (e == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
e->rs_num = rs_num;
|
||||
e->ticket = 0;
|
||||
strlcpy(e->anchor, anchor, sizeof(e->anchor));
|
||||
|
||||
TAILQ_INSERT_TAIL(&t->elms, e, entry);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pfctl_get_ticket(struct pfctl_trans *t, int rs_num, const char *anchor)
|
||||
{
|
||||
struct pfctl_trans_e *e;
|
||||
|
||||
TAILQ_FOREACH(e, &t->elms, entry) {
|
||||
if (e->rs_num != rs_num)
|
||||
continue;
|
||||
if (strcmp(e->anchor, anchor) != 0)
|
||||
continue;
|
||||
|
||||
return (e->ticket);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
snl_add_msg_attr_trans_e(struct snl_writer *nw, uint32_t type,
|
||||
const struct pfctl_trans_e *e)
|
||||
{
|
||||
int off = snl_add_msg_attr_nested(nw, type);
|
||||
|
||||
snl_add_msg_attr_u32(nw, PF_TE_RULESET_NUM, e->rs_num);
|
||||
snl_add_msg_attr_string(nw, PF_TE_ANCHOR, e->anchor);
|
||||
snl_add_msg_attr_u32(nw, PF_TE_TICKET, e->ticket);
|
||||
|
||||
snl_end_attr_nested(nw, off);
|
||||
}
|
||||
|
||||
#define _OUT(_field) offsetof(struct pfctl_trans_e, _field)
|
||||
static const struct snl_attr_parser ap_trans_e[] = {
|
||||
{ .type = PF_TE_RULESET_NUM, .off = _OUT(rs_num), .cb = snl_attr_get_uint32 },
|
||||
{ .type = PF_TE_ANCHOR, .off = _OUT(anchor), .arg_u32 = MAXPATHLEN, .cb = snl_attr_copy_string },
|
||||
{ .type = PF_TE_TICKET, .off = _OUT(ticket), .cb = snl_attr_get_uint32 },
|
||||
};
|
||||
#undef _OUT
|
||||
|
||||
static bool
|
||||
_pfctl_trans_e_post(struct snl_state *ss, void *target)
|
||||
{
|
||||
struct pfctl_trans *t = (struct pfctl_trans *)target;
|
||||
struct pfctl_trans_e *e;
|
||||
|
||||
(void)ss;
|
||||
|
||||
TAILQ_FOREACH(e, &t->elms, entry) {
|
||||
if (e->rs_num != t->tmp.rs_num)
|
||||
continue;
|
||||
if (strcmp(e->anchor, t->tmp.anchor) != 0)
|
||||
continue;
|
||||
e->ticket = t->tmp.ticket;
|
||||
return (true);
|
||||
}
|
||||
|
||||
e = malloc(sizeof(*e));
|
||||
if (! e)
|
||||
return (false);
|
||||
|
||||
memcpy(e, &t->tmp, sizeof(*e));
|
||||
|
||||
TAILQ_INSERT_TAIL(&t->elms, e, entry);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
SNL_DECLARE_ATTR_PARSER_EXT(trans_e_parser, 0, ap_trans_e, _pfctl_trans_e_post);
|
||||
|
||||
static struct snl_attr_parser ap_trans[] = {
|
||||
{ .type = PF_TR_TRANS, .arg = &trans_e_parser, .cb = snl_attr_get_nested },
|
||||
};
|
||||
SNL_DECLARE_PARSER(trans_parser, struct genlmsghdr, snl_f_p_empty, ap_trans);
|
||||
|
||||
static int
|
||||
_pfctl_trans(struct pfctl_handle *h, struct pfctl_trans *t, size_t off, int cmd)
|
||||
{
|
||||
struct snl_writer nw;
|
||||
struct snl_errmsg_data e = {};
|
||||
struct nlmsghdr *hdr;
|
||||
struct pfctl_trans_e *te;
|
||||
uint32_t seq_id;
|
||||
|
||||
snl_init_writer(&h->ss, &nw);
|
||||
hdr = snl_create_genl_msg_request(&nw, h->family_id,
|
||||
cmd);
|
||||
|
||||
snl_add_msg_attr_u32(&nw, PF_TR_UNSPEC, 0);
|
||||
TAILQ_FOREACH(te, &t->elms, entry) {
|
||||
if (off) {
|
||||
off--;
|
||||
continue;
|
||||
}
|
||||
|
||||
snl_add_msg_attr_trans_e(&nw, PF_TR_TRANS, te);
|
||||
}
|
||||
|
||||
if ((hdr = snl_finalize_msg(&nw)) == NULL) {
|
||||
e.error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
seq_id = hdr->nlmsg_seq;
|
||||
|
||||
if (! snl_send_message(&h->ss, hdr)) {
|
||||
e.error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
|
||||
if (! snl_parse_nlmsg(&h->ss, hdr, &trans_parser, t))
|
||||
continue;
|
||||
}
|
||||
|
||||
out:
|
||||
snl_clear_lb(&h->ss);
|
||||
return (e.error);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_trans_begin(struct pfctl_handle *h, struct pfctl_trans *t, size_t off)
|
||||
{
|
||||
return (_pfctl_trans(h, t, off, PFNL_CMD_BEGIN));
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_trans_commit(struct pfctl_handle *h, struct pfctl_trans *t, size_t off)
|
||||
{
|
||||
return (_pfctl_trans(h, t, off, PFNL_CMD_COMMIT));
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_trans_rollback(struct pfctl_handle *h, struct pfctl_trans *t, size_t off)
|
||||
{
|
||||
return (_pfctl_trans(h, t, off, PFNL_CMD_ROLLBACK));
|
||||
}
|
||||
|
||||
static const struct snl_hdr_parser *all_parsers[] = {
|
||||
&begin_addrs_parser,
|
||||
&clear_states_parser,
|
||||
|
||||
@@ -699,4 +699,16 @@ int pfctl_flush_fingerprints(struct pfctl_handle *h);
|
||||
int pfctl_get_fingerprint(struct pfctl_handle *h, int idx, struct pf_osfp_ioctl *fp);
|
||||
int pfctl_add_fingerprint(struct pfctl_handle *h, struct pf_osfp_ioctl *fp);
|
||||
|
||||
struct pfctl_trans;
|
||||
|
||||
struct pfctl_trans* pfctl_trans_alloc(void);
|
||||
void pfctl_trans_free(struct pfctl_trans *t);
|
||||
size_t pfctl_trans_size(struct pfctl_trans *t);
|
||||
int pfctl_trans_add(struct pfctl_trans *t, int rs_num, const char *anchor);
|
||||
uint32_t pfctl_get_ticket(struct pfctl_trans *t, int rs_num, const char *anchor);
|
||||
|
||||
int pfctl_trans_begin(struct pfctl_handle *h, struct pfctl_trans *t, size_t off);
|
||||
int pfctl_trans_commit(struct pfctl_handle *h, struct pfctl_trans *t, size_t off);
|
||||
int pfctl_trans_rollback(struct pfctl_handle *h, struct pfctl_trans *t, size_t off);
|
||||
|
||||
#endif
|
||||
@@ -347,6 +347,18 @@ static const struct nlattr_decoder nla_d_ruleset[] = {
|
||||
};
|
||||
NL_DECLARE_ATTR_DECODER(ruleset_decoder, nla_d_ruleset);
|
||||
|
||||
static const struct nlattr_decoder nla_d_trans_e[] = {
|
||||
{ .type = PF_TE_RULESET_NUM, .attr_name = "rs_num", .cb = nlattr_decode_uint32 },
|
||||
{ .type = PF_TE_ANCHOR, .attr_name="anchor", .cb = nlattr_decode_string },
|
||||
{ .type = PF_TE_TICKET, .attr_name = "ticket", .cb = nlattr_decode_uint32 },
|
||||
};
|
||||
NL_DECLARE_ATTR_DECODER(trans_e_decoder, nla_d_trans_e);
|
||||
|
||||
static const struct nlattr_decoder nla_d_trans[] = {
|
||||
{ .type = PF_TR_TRANS, .attr_name = "trans", .cb = nlattr_decode_nested, .args = &trans_e_decoder },
|
||||
};
|
||||
NL_DECLARE_ATTR_DECODER(trans_decoder, nla_d_trans);
|
||||
|
||||
static inline void
|
||||
nl_verify_decoders(const struct nlattr_decoder_set **decoder, size_t count)
|
||||
{
|
||||
@@ -368,6 +380,7 @@ static const struct nlattr_decoder_set *all_decoders[] = {
|
||||
&rule_addr_decoder,
|
||||
&killclear_states_decoder,
|
||||
&ruleset_decoder,
|
||||
&trans_decoder,
|
||||
};
|
||||
|
||||
static const struct pfnl_cmd_decoder cmd_decoder[] = {
|
||||
@@ -378,6 +391,9 @@ static const struct pfnl_cmd_decoder cmd_decoder[] = {
|
||||
{ .cmd_num = PFNL_CMD_GET_ADDR, .ds = &addr_decoder },
|
||||
{ .cmd_num = PFNL_CMD_GET_RULESETS, .ds = &ruleset_decoder },
|
||||
{ .cmd_num = PFNL_CMD_GET_RULESET, .ds = &ruleset_decoder },
|
||||
{ .cmd_num = PFNL_CMD_BEGIN, .ds = &trans_decoder },
|
||||
{ .cmd_num = PFNL_CMD_COMMIT, .ds = &trans_decoder },
|
||||
{ .cmd_num = PFNL_CMD_ROLLBACK, .ds = &trans_decoder },
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
||||
Reference in new issue
Block a user