Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159081381
D42279.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
D42279.id.diff
View Options
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -438,40 +438,6 @@
addr->port_op = nvlist_get_number(nvl, "port_op");
}
-static void
-pfctl_nv_add_mape(nvlist_t *nvparent, const char *name,
- const struct pf_mape_portset *mape)
-{
- nvlist_t *nvl = nvlist_create(0);
-
- nvlist_add_number(nvl, "offset", mape->offset);
- nvlist_add_number(nvl, "psidlen", mape->psidlen);
- nvlist_add_number(nvl, "psid", mape->psid);
- nvlist_add_nvlist(nvparent, name, nvl);
- nvlist_destroy(nvl);
-}
-
-static void
-pfctl_nv_add_pool(nvlist_t *nvparent, const char *name,
- const struct pfctl_pool *pool)
-{
- uint64_t ports[2];
- nvlist_t *nvl = nvlist_create(0);
-
- nvlist_add_binary(nvl, "key", &pool->key, sizeof(pool->key));
- pfctl_nv_add_addr(nvl, "counter", &pool->counter);
- nvlist_add_number(nvl, "tblidx", pool->tblidx);
-
- ports[0] = pool->proxy_port[0];
- ports[1] = pool->proxy_port[1];
- nvlist_add_number_array(nvl, "proxy_port", ports, 2);
- nvlist_add_number(nvl, "opts", pool->opts);
- pfctl_nv_add_mape(nvl, "mape", &pool->mape);
-
- nvlist_add_nvlist(nvparent, name, nvl);
- nvlist_destroy(nvl);
-}
-
static void
pf_nvmape_to_mape(const nvlist_t *nvl, struct pf_mape_portset *mape)
{
@@ -500,22 +466,6 @@
pf_nvmape_to_mape(nvlist_get_nvlist(nvl, "mape"), &pool->mape);
}
-static void
-pfctl_nv_add_uid(nvlist_t *nvparent, const char *name,
- const struct pf_rule_uid *uid)
-{
- uint64_t uids[2];
- nvlist_t *nvl = nvlist_create(0);
-
- uids[0] = uid->uid[0];
- uids[1] = uid->uid[1];
- nvlist_add_number_array(nvl, "uid", uids, 2);
- nvlist_add_number(nvl, "op", uid->op);
-
- nvlist_add_nvlist(nvparent, name, nvl);
- nvlist_destroy(nvl);
-}
-
static void
pf_nvrule_uid_to_rule_uid(const nvlist_t *nvl, struct pf_rule_uid *uid)
{
@@ -523,19 +473,6 @@
uid->op = nvlist_get_number(nvl, "op");
}
-static void
-pfctl_nv_add_divert(nvlist_t *nvparent, const char *name,
- const struct pfctl_rule *r)
-{
- nvlist_t *nvl = nvlist_create(0);
-
- pfctl_nv_add_addr(nvl, "addr", &r->divert.addr);
- nvlist_add_number(nvl, "port", r->divert.port);
-
- nvlist_add_nvlist(nvparent, name, nvl);
- nvlist_destroy(nvl);
-}
-
static void
pf_nvdivert_to_divert(const nvlist_t *nvl, struct pfctl_rule *rule)
{
@@ -926,127 +863,235 @@
return (error);
}
-int
-pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor,
- const char *anchor_call, uint32_t ticket, uint32_t pool_ticket)
+static void
+snl_add_msg_attr_addr_wrap(struct snl_writer *nw, uint32_t type, const struct pf_addr_wrap *addr)
{
- struct pfioc_nv nv;
- uint64_t timeouts[PFTM_MAX];
- uint64_t set_prio[2];
- nvlist_t *nvl, *nvlr;
- size_t labelcount;
- int ret;
+ int off;
- nvl = nvlist_create(0);
- nvlr = nvlist_create(0);
+ off = snl_add_msg_attr_nested(nw, type);
- nvlist_add_number(nvl, "ticket", ticket);
- nvlist_add_number(nvl, "pool_ticket", pool_ticket);
- nvlist_add_string(nvl, "anchor", anchor);
- nvlist_add_string(nvl, "anchor_call", anchor_call);
+ snl_add_msg_attr_ip6(nw, PF_AT_ADDR, &addr->v.a.addr.v6);
+ snl_add_msg_attr_ip6(nw, PF_AT_MASK, &addr->v.a.mask.v6);
- nvlist_add_number(nvlr, "nr", r->nr);
- pfctl_nv_add_rule_addr(nvlr, "src", &r->src);
- pfctl_nv_add_rule_addr(nvlr, "dst", &r->dst);
+ if (addr->type == PF_ADDR_DYNIFTL)
+ snl_add_msg_attr_string(nw, PF_AT_IFNAME, addr->v.ifname);
+ if (addr->type == PF_ADDR_TABLE)
+ snl_add_msg_attr_string(nw, PF_AT_TABLENAME, addr->v.tblname);
+ snl_add_msg_attr_u8(nw, PF_AT_TYPE, addr->type);
+ snl_add_msg_attr_u8(nw, PF_AT_IFLAGS, addr->iflags);
- labelcount = 0;
- while (r->label[labelcount][0] != 0 &&
- labelcount < PF_RULE_MAX_LABEL_COUNT) {
- nvlist_append_string_array(nvlr, "labels",
- r->label[labelcount]);
- labelcount++;
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_rule_addr(struct snl_writer *nw, uint32_t type, const struct pf_rule_addr *addr)
+{
+ int off;
+
+ off = snl_add_msg_attr_nested(nw, type);
+
+ snl_add_msg_attr_addr_wrap(nw, PF_RAT_ADDR, &addr->addr);
+ snl_add_msg_attr_u16(nw, PF_RAT_SRC_PORT, addr->port[0]);
+ snl_add_msg_attr_u16(nw, PF_RAT_DST_PORT, addr->port[1]);
+ snl_add_msg_attr_u8(nw, PF_RAT_NEG, addr->neg);
+ snl_add_msg_attr_u8(nw, PF_RAT_OP, addr->port_op);
+
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_rule_labels(struct snl_writer *nw, uint32_t type, const char labels[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE])
+{
+ int off, i = 0;
+
+ off = snl_add_msg_attr_nested(nw, type);
+
+ while (labels[i][0] != 0 &&
+ i < PF_RULE_MAX_LABEL_COUNT) {
+ snl_add_msg_attr_string(nw, PF_LT_LABEL, labels[i]);
+ i++;
}
- nvlist_add_number(nvlr, "ridentifier", r->ridentifier);
- nvlist_add_string(nvlr, "ifname", r->ifname);
- nvlist_add_string(nvlr, "qname", r->qname);
- nvlist_add_string(nvlr, "pqname", r->pqname);
- nvlist_add_string(nvlr, "tagname", r->tagname);
- nvlist_add_string(nvlr, "match_tagname", r->match_tagname);
- nvlist_add_string(nvlr, "overload_tblname", r->overload_tblname);
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_mape(struct snl_writer *nw, uint32_t type, const struct pf_mape_portset *me)
+{
+ int off;
+
+ off = snl_add_msg_attr_nested(nw, type);
+
+ snl_add_msg_attr_u8(nw, PF_MET_OFFSET, me->offset);
+ snl_add_msg_attr_u8(nw, PF_MET_PSID_LEN, me->psidlen);
+ snl_add_msg_attr_u16(nw, PF_MET_PSID, me->psid);
+
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_rpool(struct snl_writer *nw, uint32_t type, const struct pfctl_pool *pool)
+{
+ int off;
+
+ off = snl_add_msg_attr_nested(nw, type);
- pfctl_nv_add_pool(nvlr, "rpool", &r->rpool);
+ snl_add_msg_attr(nw, PF_PT_KEY, sizeof(pool->key), &pool->key);
+ snl_add_msg_attr_ip6(nw, PF_PT_COUNTER, &pool->counter.v6);
+ snl_add_msg_attr_u32(nw, PF_PT_TBLIDX, pool->tblidx);
+ snl_add_msg_attr_u16(nw, PF_PT_PROXY_SRC_PORT, pool->proxy_port[0]);
+ snl_add_msg_attr_u16(nw, PF_PT_PROXY_DST_PORT, pool->proxy_port[1]);
+ snl_add_msg_attr_u8(nw, PF_PT_OPTS, pool->opts);
+ snl_add_msg_attr_mape(nw, PF_PT_MAPE, &pool->mape);
- nvlist_add_number(nvlr, "os_fingerprint", r->os_fingerprint);
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_timeouts(struct snl_writer *nw, uint32_t type, const uint32_t *timeouts)
+{
+ int off;
+
+ off = snl_add_msg_attr_nested(nw, type);
- nvlist_add_number(nvlr, "rtableid", r->rtableid);
for (int i = 0; i < PFTM_MAX; i++)
- timeouts[i] = r->timeout[i];
- nvlist_add_number_array(nvlr, "timeout", timeouts, PFTM_MAX);
- nvlist_add_number(nvlr, "max_states", r->max_states);
- nvlist_add_number(nvlr, "max_src_nodes", r->max_src_nodes);
- nvlist_add_number(nvlr, "max_src_states", r->max_src_states);
- nvlist_add_number(nvlr, "max_src_conn", r->max_src_conn);
- nvlist_add_number(nvlr, "max_src_conn_rate.limit",
- r->max_src_conn_rate.limit);
- nvlist_add_number(nvlr, "max_src_conn_rate.seconds",
- r->max_src_conn_rate.seconds);
- nvlist_add_number(nvlr, "dnpipe", r->dnpipe);
- nvlist_add_number(nvlr, "dnrpipe", r->dnrpipe);
- nvlist_add_number(nvlr, "dnflags", r->free_flags);
- nvlist_add_number(nvlr, "prob", r->prob);
- nvlist_add_number(nvlr, "cuid", r->cuid);
- nvlist_add_number(nvlr, "cpid", r->cpid);
-
- nvlist_add_number(nvlr, "return_icmp", r->return_icmp);
- nvlist_add_number(nvlr, "return_icmp6", r->return_icmp6);
-
- nvlist_add_number(nvlr, "max_mss", r->max_mss);
- nvlist_add_number(nvlr, "scrub_flags", r->scrub_flags);
-
- pfctl_nv_add_uid(nvlr, "uid", &r->uid);
- pfctl_nv_add_uid(nvlr, "gid", (const struct pf_rule_uid *)&r->gid);
-
- nvlist_add_number(nvlr, "rule_flag", r->rule_flag);
- nvlist_add_number(nvlr, "action", r->action);
- nvlist_add_number(nvlr, "direction", r->direction);
- nvlist_add_number(nvlr, "log", r->log);
- nvlist_add_number(nvlr, "logif", r->logif);
- nvlist_add_number(nvlr, "quick", r->quick);
- nvlist_add_number(nvlr, "ifnot", r->ifnot);
- nvlist_add_number(nvlr, "match_tag_not", r->match_tag_not);
- nvlist_add_number(nvlr, "natpass", r->natpass);
-
- nvlist_add_number(nvlr, "keep_state", r->keep_state);
- nvlist_add_number(nvlr, "af", r->af);
- nvlist_add_number(nvlr, "proto", r->proto);
- nvlist_add_number(nvlr, "type", r->type);
- nvlist_add_number(nvlr, "code", r->code);
- nvlist_add_number(nvlr, "flags", r->flags);
- nvlist_add_number(nvlr, "flagset", r->flagset);
- nvlist_add_number(nvlr, "min_ttl", r->min_ttl);
- nvlist_add_number(nvlr, "allow_opts", r->allow_opts);
- nvlist_add_number(nvlr, "rt", r->rt);
- nvlist_add_number(nvlr, "return_ttl", r->return_ttl);
- nvlist_add_number(nvlr, "tos", r->tos);
- nvlist_add_number(nvlr, "set_tos", r->set_tos);
- nvlist_add_number(nvlr, "anchor_relative", r->anchor_relative);
- nvlist_add_number(nvlr, "anchor_wildcard", r->anchor_wildcard);
-
- nvlist_add_number(nvlr, "flush", r->flush);
-
- nvlist_add_number(nvlr, "prio", r->prio);
- set_prio[0] = r->set_prio[0];
- set_prio[1] = r->set_prio[1];
- nvlist_add_number_array(nvlr, "set_prio", set_prio, 2);
-
- pfctl_nv_add_divert(nvlr, "divert", r);
-
- nvlist_add_nvlist(nvl, "rule", nvlr);
- nvlist_destroy(nvlr);
-
- /* Now do the call. */
- nv.data = nvlist_pack(nvl, &nv.len);
- nv.size = nv.len;
+ snl_add_msg_attr_u32(nw, PF_TT_TIMEOUT, timeouts[i]);
- ret = ioctl(dev, DIOCADDRULENV, &nv);
- if (ret == -1)
- ret = errno;
+ snl_end_attr_nested(nw, off);
+}
- free(nv.data);
- nvlist_destroy(nvl);
+static void
+snl_add_msg_attr_uid(struct snl_writer *nw, uint32_t type, const struct pf_rule_uid *uid)
+{
+ int off;
- return (ret);
+ off = snl_add_msg_attr_nested(nw, type);
+
+ snl_add_msg_attr_u32(nw, PF_RUT_UID_LOW, uid->uid[0]);
+ snl_add_msg_attr_u32(nw, PF_RUT_UID_HIGH, uid->uid[1]);
+ snl_add_msg_attr_u8(nw, PF_RUT_OP, uid->op);
+
+ snl_end_attr_nested(nw, off);
+}
+
+static void
+snl_add_msg_attr_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfctl_rule *r)
+{
+ int off;
+
+ off = snl_add_msg_attr_nested(nw, type);
+
+ snl_add_msg_attr_rule_addr(nw, PF_RT_SRC, &r->src);
+ snl_add_msg_attr_rule_addr(nw, PF_RT_DST, &r->dst);
+ snl_add_msg_attr_rule_labels(nw, PF_RT_LABELS, r->label);
+ snl_add_msg_attr_u32(nw, PF_RT_RIDENTIFIER, r->ridentifier);
+ snl_add_msg_attr_string(nw, PF_RT_IFNAME, r->ifname);
+ snl_add_msg_attr_string(nw, PF_RT_QNAME, r->qname);
+ snl_add_msg_attr_string(nw, PF_RT_PQNAME, r->pqname);
+ snl_add_msg_attr_string(nw, PF_RT_TAGNAME, r->tagname);
+ snl_add_msg_attr_string(nw, PF_RT_MATCH_TAGNAME, r->match_tagname);
+ snl_add_msg_attr_string(nw, PF_RT_OVERLOAD_TBLNAME, r->overload_tblname);
+ snl_add_msg_attr_rpool(nw, PF_RT_RPOOL, &r->rpool);
+ snl_add_msg_attr_u32(nw, PF_RT_OS_FINGERPRINT, r->os_fingerprint);
+ snl_add_msg_attr_u32(nw, PF_RT_RTABLEID, r->rtableid);
+ snl_add_msg_attr_timeouts(nw, PF_RT_TIMEOUT, r->timeout);
+ snl_add_msg_attr_u32(nw, PF_RT_MAX_STATES, r->max_states);
+ snl_add_msg_attr_u32(nw, PF_RT_MAX_SRC_NODES, r->max_src_nodes);
+ snl_add_msg_attr_u32(nw, PF_RT_MAX_SRC_STATES, r->max_src_states);
+ snl_add_msg_attr_u32(nw, PF_RT_MAX_SRC_CONN_RATE_LIMIT, r->max_src_conn_rate.limit);
+ snl_add_msg_attr_u32(nw, PF_RT_MAX_SRC_CONN_RATE_SECS, r->max_src_conn_rate.seconds);
+
+ snl_add_msg_attr_u16(nw, PF_RT_DNPIPE, r->dnpipe);
+ snl_add_msg_attr_u16(nw, PF_RT_DNRPIPE, r->dnrpipe);
+ snl_add_msg_attr_u32(nw, PF_RT_DNFLAGS, r->free_flags);
+
+ snl_add_msg_attr_u32(nw, PF_RT_NR, r->nr);
+ snl_add_msg_attr_u32(nw, PF_RT_PROB, r->prob);
+ snl_add_msg_attr_u32(nw, PF_RT_CUID, r->cuid);
+ snl_add_msg_attr_u32(nw, PF_RT_CPID, r->cpid);
+
+ snl_add_msg_attr_u16(nw, PF_RT_RETURN_ICMP, r->return_icmp);
+ snl_add_msg_attr_u16(nw, PF_RT_RETURN_ICMP6, r->return_icmp6);
+ snl_add_msg_attr_u16(nw, PF_RT_MAX_MSS, r->max_mss);
+ snl_add_msg_attr_u16(nw, PF_RT_SCRUB_FLAGS, r->scrub_flags);
+
+ snl_add_msg_attr_uid(nw, PF_RT_UID, &r->uid);
+ snl_add_msg_attr_uid(nw, PF_RT_GID, (const struct pf_rule_uid *)&r->gid);
+
+ snl_add_msg_attr_u32(nw, PF_RT_RULE_FLAG, r->rule_flag);
+ snl_add_msg_attr_u8(nw, PF_RT_ACTION, r->action);
+ snl_add_msg_attr_u8(nw, PF_RT_DIRECTION, r->direction);
+ snl_add_msg_attr_u8(nw, PF_RT_LOG, r->log);
+ snl_add_msg_attr_u8(nw, PF_RT_LOGIF, r->logif);
+ snl_add_msg_attr_u8(nw, PF_RT_QUICK, r->quick);
+ snl_add_msg_attr_u8(nw, PF_RT_IF_NOT, r->ifnot);
+ snl_add_msg_attr_u8(nw, PF_RT_MATCH_TAG_NOT, r->match_tag_not);
+ snl_add_msg_attr_u8(nw, PF_RT_NATPASS, r->natpass);
+ snl_add_msg_attr_u8(nw, PF_RT_KEEP_STATE, r->keep_state);
+ snl_add_msg_attr_u8(nw, PF_RT_AF, r->af);
+ snl_add_msg_attr_u8(nw, PF_RT_PROTO, r->proto);
+ snl_add_msg_attr_u8(nw, PF_RT_TYPE, r->type);
+ snl_add_msg_attr_u8(nw, PF_RT_CODE, r->code);
+ snl_add_msg_attr_u8(nw, PF_RT_FLAGS, r->flags);
+ snl_add_msg_attr_u8(nw, PF_RT_FLAGSET, r->flagset);
+ snl_add_msg_attr_u8(nw, PF_RT_MIN_TTL, r->min_ttl);
+ snl_add_msg_attr_u8(nw, PF_RT_ALLOW_OPTS, r->allow_opts);
+ snl_add_msg_attr_u8(nw, PF_RT_RT, r->rt);
+ snl_add_msg_attr_u8(nw, PF_RT_RETURN_TTL, r->return_ttl);
+ snl_add_msg_attr_u8(nw, PF_RT_TOS, r->tos);
+ snl_add_msg_attr_u8(nw, PF_RT_SET_TOS, r->set_tos);
+
+ snl_add_msg_attr_u8(nw, PF_RT_ANCHOR_RELATIVE, r->anchor_relative);
+ snl_add_msg_attr_u8(nw, PF_RT_ANCHOR_WILDCARD, r->anchor_wildcard);
+ snl_add_msg_attr_u8(nw, PF_RT_FLUSH, r->flush);
+ snl_add_msg_attr_u8(nw, PF_RT_PRIO, r->prio);
+ snl_add_msg_attr_u8(nw, PF_RT_SET_PRIO, r->set_prio[0]);
+ snl_add_msg_attr_u8(nw, PF_RT_SET_PRIO_REPLY, r->set_prio[1]);
+
+ snl_add_msg_attr_ip6(nw, PF_RT_DIVERT_ADDRESS, &r->divert.addr.v6);
+ snl_add_msg_attr_u16(nw, PF_RT_DIVERT_PORT, r->divert.port);
+
+ snl_end_attr_nested(nw, off);
+}
+
+int
+pfctl_add_rule(int dev __unused, const struct pfctl_rule *r, const char *anchor,
+ const char *anchor_call, uint32_t ticket, uint32_t pool_ticket)
+{
+ struct snl_writer nw;
+ struct snl_state ss = {};
+ struct snl_errmsg_data e = {};
+ struct nlmsghdr *hdr;
+ uint32_t seq_id;
+ int family_id;
+
+ snl_init(&ss, NETLINK_GENERIC);
+ family_id = snl_get_genl_family(&ss, PFNL_FAMILY_NAME);
+
+ snl_init_writer(&ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_ADDRULE);
+ hdr->nlmsg_flags |= NLM_F_DUMP;
+ snl_add_msg_attr_u32(&nw, PF_ART_TICKET, ticket);
+ snl_add_msg_attr_u32(&nw, PF_ART_POOL_TICKET, pool_ticket);
+ snl_add_msg_attr_string(&nw, PF_ART_ANCHOR, anchor);
+ snl_add_msg_attr_string(&nw, PF_ART_ANCHOR_CALL, anchor_call);
+
+ snl_add_msg_attr_pf_rule(&nw, PF_ART_RULE, r);
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL)
+ return (ENXIO);
+
+ seq_id = hdr->nlmsg_seq;
+
+ if (! snl_send_message(&ss, hdr)) {
+ printf("Send failed\n");
+ return (ENXIO);
+ }
+
+ while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) {
+ }
+
+ return (e.error);
}
int
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2465,6 +2465,10 @@
struct pf_keth_ruleset *pf_find_or_create_keth_ruleset(const char *);
void pf_keth_anchor_remove(struct pf_keth_rule *);
+int pf_ioctl_addrule(struct pf_krule *, uint32_t,
+ uint32_t, const char *, const char *, uid_t uid,
+ pid_t);
+
void pf_krule_free(struct pf_krule *);
#endif
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2016,10 +2016,10 @@
return (0);
}
-static int
+int
pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
uint32_t pool_ticket, const char *anchor, const char *anchor_call,
- struct thread *td)
+ uid_t uid, pid_t pid)
{
struct pf_kruleset *ruleset;
struct pf_krule *tail;
@@ -2045,8 +2045,8 @@
rule->states_cur = counter_u64_alloc(M_WAITOK);
rule->states_tot = counter_u64_alloc(M_WAITOK);
rule->src_nodes = counter_u64_alloc(M_WAITOK);
- rule->cuid = td->td_ucred->cr_ruid;
- rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
+ rule->cuid = uid;
+ rule->cpid = pid;
TAILQ_INIT(&rule->rpool.list);
PF_CONFIG_LOCK();
@@ -3076,7 +3076,8 @@
/* Frees rule on error */
error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor,
- anchor_call, td);
+ anchor_call, td->td_ucred->cr_ruid,
+ td->td_proc ? td->td_proc->p_pid : 0);
nvlist_destroy(nvl);
free(nvlpacked, M_NVLIST);
@@ -3104,7 +3105,8 @@
/* Frees rule on error */
error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket,
- pr->anchor, pr->anchor_call, td);
+ pr->anchor, pr->anchor_call, td->td_ucred->cr_ruid,
+ td->td_proc ? td->td_proc->p_pid : 0);
break;
}
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -40,6 +40,7 @@
PFNL_CMD_GETCREATORS = 2,
PFNL_CMD_START = 3,
PFNL_CMD_STOP = 4,
+ PFNL_CMD_ADDRULE = 5,
__PFNL_CMD_MAX,
};
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -98,6 +99,137 @@
PF_ST_VERSION = 28, /* u64 */
};
+enum pf_addr_type_t {
+ PF_AT_UNSPEC,
+ PF_AT_ADDR = 1, /* in6_addr */
+ PF_AT_MASK = 2, /* in6_addr */
+ PF_AT_IFNAME = 3, /* string */
+ PF_AT_TABLENAME = 4, /* string */
+ PF_AT_TYPE = 5, /* u8 */
+ PF_AT_IFLAGS = 6, /* u8 */
+};
+
+enum pfrule_addr_type_t {
+ PF_RAT_UNSPEC,
+ PF_RAT_ADDR = 1, /* nested, pf_addr_type_t */
+ PF_RAT_SRC_PORT = 2, /* u16 */
+ PF_RAT_DST_PORT = 3, /* u16 */
+ PF_RAT_NEG = 4, /* u8 */
+ PF_RAT_OP = 5, /* u8 */
+};
+
+enum pf_labels_type_t {
+ PF_LT_UNSPEC,
+ PF_LT_LABEL = 1, /* string */
+};
+
+enum pf_mape_portset_type_t
+{
+ PF_MET_UNSPEC,
+ PF_MET_OFFSET = 1, /* u8 */
+ PF_MET_PSID_LEN = 2, /* u8 */
+ PF_MET_PSID = 3, /* u16 */
+};
+
+enum pf_rpool_type_t
+{
+ PF_PT_UNSPEC,
+ PF_PT_KEY = 1, /* bytes, sizeof(struct pf_poolhashkey) */
+ PF_PT_COUNTER = 2, /* in6_addr */
+ PF_PT_TBLIDX = 3, /* u32 */
+ PF_PT_PROXY_SRC_PORT = 4, /* u16 */
+ PF_PT_PROXY_DST_PORT = 5, /* u16 */
+ PF_PT_OPTS = 6, /* u8 */
+ PF_PT_MAPE = 7, /* nested, pf_mape_portset_type_t */
+};
+
+enum pf_timeout_type_t {
+ PF_TT_UNSPEC,
+ PF_TT_TIMEOUT = 1, /* u32 */
+};
+
+enum pf_rule_uid_type_t {
+ PF_RUT_UNSPEC,
+ PF_RUT_UID_LOW = 1, /* u32 */
+ PF_RUT_UID_HIGH = 2, /* u32 */
+ PF_RUT_OP = 3, /* u8 */
+};
+
+enum pf_rule_type_t {
+ PF_RT_UNSPEC,
+ PF_RT_SRC = 1, /* nested, pf_rule_addr_type_t */
+ PF_RT_DST = 2, /* nested, pf_rule_addr_type_t */
+ PF_RT_RIDENTIFIER = 3, /* u32 */
+ PF_RT_LABELS = 4, /* nested, pf_labels_type_t */
+ PF_RT_IFNAME = 5, /* string */
+ PF_RT_QNAME = 6, /* string */
+ PF_RT_PQNAME = 7, /* string */
+ PF_RT_TAGNAME = 8, /* string */
+ PF_RT_MATCH_TAGNAME = 9, /* string */
+ PF_RT_OVERLOAD_TBLNAME = 10, /* string */
+ PF_RT_RPOOL = 11, /* nested, pf_rpool_type_t */
+ PF_RT_OS_FINGERPRINT = 12, /* u32 */
+ PF_RT_RTABLEID = 13, /* u32 */
+ PF_RT_TIMEOUT = 14, /* nested, pf_timeout_type_t */
+ PF_RT_MAX_STATES = 15, /* u32 */
+ PF_RT_MAX_SRC_NODES = 16, /* u32 */
+ PF_RT_MAX_SRC_STATES = 17, /* u32 */
+ PF_RT_MAX_SRC_CONN_RATE_LIMIT = 18, /* u32 */
+ PF_RT_MAX_SRC_CONN_RATE_SECS = 19, /* u32 */
+ PF_RT_DNPIPE = 20, /* u16 */
+ PF_RT_DNRPIPE = 21, /* u16 */
+ PF_RT_DNFLAGS = 22, /* u32 */
+ PF_RT_NR = 23, /* u32 */
+ PF_RT_PROB = 24, /* u32 */
+ PF_RT_CUID = 25, /* u32 */
+ PF_RT_CPID = 26, /* u32 */
+ PF_RT_RETURN_ICMP = 27, /* u16 */
+ PF_RT_RETURN_ICMP6 = 28, /* u16 */
+ PF_RT_MAX_MSS = 29, /* u16 */
+ PF_RT_SCRUB_FLAGS = 30, /* u16 */
+ PF_RT_UID = 31, /* nested, pf_rule_uid_type_t */
+ PF_RT_GID = 32, /* nested, pf_rule_uid_type_t */
+ PF_RT_RULE_FLAG = 33, /* u32 */
+ PF_RT_ACTION = 34, /* u8 */
+ PF_RT_DIRECTION = 35, /* u8 */
+ PF_RT_LOG = 36, /* u8 */
+ PF_RT_LOGIF = 37, /* u8 */
+ PF_RT_QUICK = 38, /* u8 */
+ PF_RT_IF_NOT = 39, /* u8 */
+ PF_RT_MATCH_TAG_NOT = 40, /* u8 */
+ PF_RT_NATPASS = 41, /* u8 */
+ PF_RT_KEEP_STATE = 42, /* u8 */
+ PF_RT_AF = 43, /* u8 */
+ PF_RT_PROTO = 44, /* u8 */
+ PF_RT_TYPE = 45, /* u8 */
+ PF_RT_CODE = 46, /* u8 */
+ PF_RT_FLAGS = 47, /* u8 */
+ PF_RT_FLAGSET = 48, /* u8 */
+ PF_RT_MIN_TTL = 49, /* u8 */
+ PF_RT_ALLOW_OPTS = 50, /* u8 */
+ PF_RT_RT = 51, /* u8 */
+ PF_RT_RETURN_TTL = 52, /* u8 */
+ PF_RT_TOS = 53, /* u8 */
+ PF_RT_SET_TOS = 54, /* u8 */
+ PF_RT_ANCHOR_RELATIVE = 55, /* u8 */
+ PF_RT_ANCHOR_WILDCARD = 56, /* u8 */
+ PF_RT_FLUSH = 57, /* u8 */
+ PF_RT_PRIO = 58, /* u8 */
+ PF_RT_SET_PRIO = 59, /* u8 */
+ PF_RT_SET_PRIO_REPLY = 60, /* u8 */
+ PF_RT_DIVERT_ADDRESS = 61, /* in6_addr */
+ PF_RT_DIVERT_PORT = 62, /* u16 */
+};
+
+enum pf_addrule_type_t {
+ PF_ART_UNSPEC,
+ PF_ART_TICKET = 1, /* u32 */
+ PF_ART_POOL_TICKET = 2, /* u32 */
+ PF_ART_ANCHOR = 3, /* string */
+ PF_ART_ANCHOR_CALL = 4, /* string */
+ PF_ART_RULE = 5, /* nested, pfrule_type_t */
+};
+
#ifdef _KERNEL
void pf_nl_register(void);
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -348,7 +348,265 @@
return (pf_stop());
}
-static const struct nlhdr_parser *all_parsers[] = { &state_parser };
+#define _OUT(_field) offsetof(struct pf_addr_wrap, _field)
+static const struct nlattr_parser nla_p_addr_wrap[] = {
+ { .type = PF_AT_ADDR, .off = _OUT(v.a.addr), .cb = nlattr_get_in6_addr },
+ { .type = PF_AT_MASK, .off = _OUT(v.a.mask), .cb = nlattr_get_in6_addr },
+ { .type = PF_AT_IFNAME, .off = _OUT(v.ifname), .arg = (void *)IFNAMSIZ,.cb = nlattr_get_chara },
+ { .type = PF_AT_TABLENAME, .off = _OUT(v.tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_AT_TYPE, .off = _OUT(type), .cb = nlattr_get_uint8 },
+ { .type = PF_AT_IFLAGS, .off = _OUT(iflags), .cb = nlattr_get_uint8 },
+};
+NL_DECLARE_ATTR_PARSER(addr_wrap_parser, nla_p_addr_wrap);
+#undef _OUT
+
+#define _OUT(_field) offsetof(struct pf_rule_addr, _field)
+static const struct nlattr_parser nla_p_ruleaddr[] = {
+ { .type = PF_RAT_ADDR, .off = _OUT(addr), .arg = &addr_wrap_parser, .cb = nlattr_get_nested },
+ { .type = PF_RAT_SRC_PORT, .off = _OUT(port[0]), .cb = nlattr_get_uint16 },
+ { .type = PF_RAT_DST_PORT, .off = _OUT(port[1]), .cb = nlattr_get_uint16 },
+ { .type = PF_RAT_NEG, .off = _OUT(neg), .cb = nlattr_get_uint8 },
+ { .type = PF_RAT_OP, .off = _OUT(port_op), .cb = nlattr_get_uint8 },
+};
+NL_DECLARE_ATTR_PARSER(rule_addr_parser, nla_p_ruleaddr);
+#undef _OUT
+
+#define _OUT(_field) offsetof(struct pf_mape_portset, _field)
+static const struct nlattr_parser nla_p_mape_portset[] = {
+ { .type = PF_MET_OFFSET, .off = _OUT(offset), .cb = nlattr_get_uint8 },
+ { .type = PF_MET_PSID_LEN, .off = _OUT(psidlen), .cb = nlattr_get_uint8 },
+ {. type = PF_MET_PSID, .off = _OUT(psid), .cb = nlattr_get_uint16 },
+};
+NL_DECLARE_ATTR_PARSER(mape_portset_parser, nla_p_mape_portset);
+#undef _OUT
+
+struct nl_parsed_labels
+{
+ char labels[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
+ uint32_t i;
+};
+
+static int
+nlattr_get_pf_rule_labels(struct nlattr *nla, struct nl_pstate *npt,
+ const void *arg, void *target)
+{
+ struct nl_parsed_labels *l = (struct nl_parsed_labels *)target;
+ int ret;
+
+ if (l->i >= PF_RULE_MAX_LABEL_COUNT)
+ return (E2BIG);
+
+ ret = nlattr_get_chara(nla, npt, (void *)PF_RULE_LABEL_SIZE,
+ l->labels[l->i]);
+ if (ret == 0)
+ l->i++;
+
+ return (ret);
+}
+
+#define _OUT(_field) offsetof(struct nl_parsed_labels, _field)
+static const struct nlattr_parser nla_p_labels[] = {
+ { .type = PF_LT_LABEL, .off = 0, .cb = nlattr_get_pf_rule_labels },
+};
+NL_DECLARE_ATTR_PARSER(rule_labels_parser, nla_p_labels);
+#undef _OUT
+
+static int
+nlattr_get_nested_pf_rule_labels(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
+{
+ struct nl_parsed_labels parsed_labels = { };
+ int error;
+
+ /* Assumes target points to the beginning of the structure */
+ error = nl_parse_header(NLA_DATA(nla), NLA_DATA_LEN(nla), &rule_labels_parser, npt, &parsed_labels);
+ if (error != 0)
+ return (error);
+
+ memcpy(target, parsed_labels.labels, sizeof(parsed_labels));
+
+ return (0);
+}
+
+#define _OUT(_field) offsetof(struct pf_kpool, _field)
+static const struct nlattr_parser nla_p_pool[] = {
+ { .type = PF_PT_KEY, .off = _OUT(key), .arg = (void *)sizeof(struct pf_poolhashkey), .cb = nlattr_get_bytes },
+ { .type = PF_PT_COUNTER, .off = _OUT(counter), .cb = nlattr_get_in6_addr },
+ { .type = PF_PT_TBLIDX, .off = _OUT(tblidx), .cb = nlattr_get_uint32 },
+ { .type = PF_PT_PROXY_SRC_PORT, .off = _OUT(proxy_port[0]), .cb = nlattr_get_uint16 },
+ { .type = PF_PT_PROXY_DST_PORT, .off = _OUT(proxy_port[1]), .cb = nlattr_get_uint16 },
+ { .type = PF_PT_OPTS, .off = _OUT(opts), .cb = nlattr_get_uint8 },
+ { .type = PF_PT_MAPE, .off = _OUT(mape), .arg = &mape_portset_parser, .cb = nlattr_get_nested },
+};
+NL_DECLARE_ATTR_PARSER(pool_parser, nla_p_pool);
+#undef _OUT
+
+#define _OUT(_field) offsetof(struct pf_rule_uid, _field)
+static const struct nlattr_parser nla_p_rule_uid[] = {
+ { .type = PF_RUT_UID_LOW, .off = _OUT(uid[0]), .cb = nlattr_get_uint32 },
+ { .type = PF_RUT_UID_HIGH, .off = _OUT(uid[1]), .cb = nlattr_get_uint32 },
+ { .type = PF_RUT_OP, .off = _OUT(op), .cb = nlattr_get_uint8 },
+};
+NL_DECLARE_ATTR_PARSER(rule_uid_parser, nla_p_rule_uid);
+#undef _OUT
+
+struct nl_parsed_timeouts
+{
+ uint32_t timeouts[PFTM_MAX];
+ uint32_t i;
+};
+
+static int
+nlattr_get_pf_timeout(struct nlattr *nla, struct nl_pstate *npt,
+ const void *arg, void *target)
+{
+ struct nl_parsed_timeouts *t = (struct nl_parsed_timeouts *)target;
+ int ret;
+
+ if (t->i >= PFTM_MAX)
+ return (E2BIG);
+
+ ret = nlattr_get_uint32(nla, npt, NULL, &t->timeouts[t->i]);
+ if (ret == 0)
+ t->i++;
+
+ return (ret);
+}
+
+#define _OUT(_field) offsetof(struct nl_parsed_timeout, _field)
+static const struct nlattr_parser nla_p_timeouts[] = {
+ { .type = PF_TT_TIMEOUT, .off = 0, .cb = nlattr_get_pf_timeout },
+};
+NL_DECLARE_ATTR_PARSER(timeout_parser, nla_p_timeouts);
+#undef _OUT
+
+static int
+nlattr_get_nested_timeouts(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
+{
+ struct nl_parsed_timeouts parsed_timeouts = { };
+ int error;
+
+ /* Assumes target points to the beginning of the structure */
+ error = nl_parse_header(NLA_DATA(nla), NLA_DATA_LEN(nla), &timeout_parser, npt, &parsed_timeouts);
+ if (error != 0)
+ return (error);
+
+ memcpy(target, parsed_timeouts.timeouts, sizeof(parsed_timeouts.timeouts));
+
+ return (0);
+}
+
+#define _OUT(_field) offsetof(struct pf_krule, _field)
+static const struct nlattr_parser nla_p_rule[] = {
+ { .type = PF_RT_SRC, .off = _OUT(src), .arg = &rule_addr_parser,.cb = nlattr_get_nested },
+ { .type = PF_RT_DST, .off = _OUT(dst), .arg = &rule_addr_parser,.cb = nlattr_get_nested },
+ { .type = PF_RT_RIDENTIFIER, .off = _OUT(ridentifier), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_LABELS, .off = _OUT(label), .arg = &rule_labels_parser,.cb = nlattr_get_nested_pf_rule_labels },
+ { .type = PF_RT_IFNAME, .off = _OUT(ifname), .arg = (void *)IFNAMSIZ, .cb = nlattr_get_chara },
+ { .type = PF_RT_QNAME, .off = _OUT(qname), .arg = (void *)PF_QNAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_RT_PQNAME, .off = _OUT(pqname), .arg = (void *)PF_QNAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_RT_TAGNAME, .off = _OUT(tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_RT_MATCH_TAGNAME, .off = _OUT(match_tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_RT_OVERLOAD_TBLNAME, .off = _OUT(overload_tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = nlattr_get_chara },
+ { .type = PF_RT_RPOOL, .off = _OUT(rpool), .arg = &pool_parser, .cb = nlattr_get_nested },
+ { .type = PF_RT_OS_FINGERPRINT, .off = _OUT(os_fingerprint), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_RTABLEID, .off = _OUT(rtableid), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_TIMEOUT, .off = _OUT(timeout), .arg = &timeout_parser, .cb = nlattr_get_nested_timeouts },
+ { .type = PF_RT_MAX_STATES, .off = _OUT(max_states), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_MAX_SRC_NODES, .off = _OUT(max_src_nodes), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_MAX_SRC_STATES, .off = _OUT(max_src_states), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_MAX_SRC_CONN_RATE_LIMIT, .off = _OUT(max_src_conn_rate.limit), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_MAX_SRC_CONN_RATE_SECS, .off = _OUT(max_src_conn_rate.seconds), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_DNPIPE, .off = _OUT(dnpipe), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_DNRPIPE, .off = _OUT(dnrpipe), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_DNFLAGS, .off = _OUT(free_flags), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_NR, .off = _OUT(nr), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_PROB, .off = _OUT(prob), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_CUID, .off = _OUT(cuid), .cb = nlattr_get_uint32 },
+ {. type = PF_RT_CPID, .off = _OUT(cpid), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_RETURN_ICMP, .off = _OUT(return_icmp), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_RETURN_ICMP6, .off = _OUT(return_icmp6), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_MAX_MSS, .off = _OUT(max_mss), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_SCRUB_FLAGS, .off = _OUT(scrub_flags), .cb = nlattr_get_uint16 },
+ { .type = PF_RT_UID, .off = _OUT(uid), .arg = &rule_uid_parser, .cb = nlattr_get_nested },
+ { .type = PF_RT_GID, .off = _OUT(gid), .arg = &rule_uid_parser, .cb = nlattr_get_nested },
+ { .type = PF_RT_RULE_FLAG, .off = _OUT(rule_flag), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_ACTION, .off = _OUT(action), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_DIRECTION, .off = _OUT(direction), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_LOG, .off = _OUT(log), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_LOGIF, .off = _OUT(logif), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_QUICK, .off = _OUT(quick), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_IF_NOT, .off = _OUT(ifnot), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_MATCH_TAG_NOT, .off = _OUT(match_tag_not), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_NATPASS, .off = _OUT(natpass), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_KEEP_STATE, .off = _OUT(keep_state), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_AF, .off = _OUT(af), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_PROTO, .off = _OUT(proto), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_TYPE, .off = _OUT(type), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_CODE, .off = _OUT(code), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_FLAGS, .off = _OUT(flags), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_FLAGSET, .off = _OUT(flagset), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_MIN_TTL, .off = _OUT(min_ttl), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_ALLOW_OPTS, .off = _OUT(allow_opts), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_RT, .off = _OUT(rt), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_RETURN_TTL, .off = _OUT(return_ttl), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_TOS, .off = _OUT(tos), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_SET_TOS, .off = _OUT(set_tos), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_ANCHOR_RELATIVE, .off = _OUT(anchor_relative), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_ANCHOR_WILDCARD, .off = _OUT(anchor_wildcard), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_FLUSH, .off = _OUT(flush), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_PRIO, .off = _OUT(prio), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_SET_PRIO, .off = _OUT(set_prio[0]), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_SET_PRIO_REPLY, .off = _OUT(set_prio[1]), .cb = nlattr_get_uint8 },
+ { .type = PF_RT_DIVERT_ADDRESS, .off = _OUT(divert.addr), .cb = nlattr_get_in6_addr },
+ { .type = PF_RT_DIVERT_PORT, .off = _OUT(divert.port), .cb = nlattr_get_uint16 },
+};
+NL_DECLARE_ATTR_PARSER(rule_parser, nla_p_rule);
+#undef _OUT
+struct nl_parsed_addrule {
+ struct pf_krule *rule;
+ uint32_t ticket;
+ uint32_t pool_ticket;
+ char *anchor;
+ char *anchor_call;
+};
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct nl_parsed_addrule, _field)
+static const struct nlattr_parser nla_p_addrule[] = {
+ { .type = PF_ART_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
+ { .type = PF_ART_POOL_TICKET, .off = _OUT(pool_ticket), .cb = nlattr_get_uint32 },
+ { .type = PF_ART_ANCHOR, .off = _OUT(anchor), .cb = nlattr_get_string },
+ { .type = PF_ART_ANCHOR_CALL, .off = _OUT(anchor_call), .cb = nlattr_get_string },
+ { .type = PF_ART_RULE, .off = _OUT(rule), .arg = &rule_parser, .cb = nlattr_get_nested_ptr }
+};
+static const struct nlfield_parser nlf_p_addrule[] = {
+};
+#undef _IN
+#undef _OUT
+NL_DECLARE_PARSER(addrule_parser, struct genlmsghdr, nlf_p_addrule, nla_p_addrule);
+
+static int
+pf_handle_addrule(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ int error;
+ struct nl_parsed_addrule attrs = {};
+
+ attrs.rule = pf_krule_alloc();
+
+ error = nl_parse_nlmsg(hdr, &addrule_parser, npt, &attrs);
+ if (error != 0)
+ return (error);
+
+ error = pf_ioctl_addrule(attrs.rule, attrs.ticket, attrs.pool_ticket,
+ attrs.anchor, attrs.anchor_call, nlp_get_cred(npt->nlp)->cr_uid,
+ hdr->nlmsg_pid);
+
+ if (error != 0)
+ pf_krule_free(attrs.rule);
+
+ return (error);
+}
+
+static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser };
static int family_id;
@@ -377,12 +635,20 @@
.cmd_cb = pf_handle_stop,
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
},
+ {
+ .cmd_num = PFNL_CMD_ADDRULE,
+ .cmd_name = "ADDRULE",
+ .cmd_cb = pf_handle_addrule,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+ },
+
};
void
pf_nl_register(void)
{
NL_VERIFY_PARSERS(all_parsers);
+
family_id = genl_register_family(PFNL_FAMILY_NAME, 0, 2, PFNL_CMD_MAX);
genl_register_cmds(PFNL_FAMILY_NAME, pf_cmds, NL_ARRAY_LEN(pf_cmds));
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jun 10, 9:53 PM (19 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33859525
Default Alt Text
D42279.id.diff (32 KB)
Attached To
Mode
D42279: pf: convert rule addition to netlink
Attached
Detach File
Event Timeline
Log In to Comment