2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2021 Rubicon Communications, LLC (Netgate)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
32 #include "opt_inet6.h"
34 #include <sys/param.h>
35 #include <sys/errno.h>
36 #include <sys/limits.h>
37 #include <sys/queue.h>
38 #include <sys/systm.h>
40 #include <netpfil/pf/pf_nv.h>
42 #define PF_NV_IMPL_UINT(fnname, type, max) \
44 pf_nv ## fnname ## _opt(const nvlist_t *nvl, const char *name, \
45 type *val, type dflt) \
48 if (! nvlist_exists_number(nvl, name)) { \
52 raw = nvlist_get_number(nvl, name); \
59 pf_nv ## fnname(const nvlist_t *nvl, const char *name, type *val) \
62 if (! nvlist_exists_number(nvl, name)) \
64 raw = nvlist_get_number(nvl, name); \
71 pf_nv ## fnname ## _array(const nvlist_t *nvl, const char *name, \
72 type *array, size_t maxelems, size_t *nelems) \
76 bzero(array, sizeof(type) * maxelems); \
77 if (! nvlist_exists_number_array(nvl, name)) \
79 n = nvlist_get_number_array(nvl, name, &nitems); \
80 if (nitems != maxelems) \
84 for (size_t i = 0; i < nitems; i++) { \
87 array[i] = (type)n[i]; \
92 pf_ ## fnname ## _array_nv(nvlist_t *nvl, const char *name, \
93 const type *numbers, size_t count) \
96 for (size_t i = 0; i < count; i++) { \
98 nvlist_append_number_array(nvl, name, tmp); \
103 pf_nvbool(const nvlist_t *nvl, const char *name, bool *val)
105 if (! nvlist_exists_bool(nvl, name))
108 *val = nvlist_get_bool(nvl, name);
114 pf_nvbinary(const nvlist_t *nvl, const char *name, void *data,
115 size_t expected_size)
117 const uint8_t *nvdata;
120 bzero(data, expected_size);
122 if (! nvlist_exists_binary(nvl, name))
125 nvdata = (const uint8_t *)nvlist_get_binary(nvl, name, &len);
126 if (len > expected_size)
129 memcpy(data, nvdata, len);
134 PF_NV_IMPL_UINT(uint8, uint8_t, UINT8_MAX);
135 PF_NV_IMPL_UINT(uint16, uint16_t, UINT16_MAX);
136 PF_NV_IMPL_UINT(uint32, uint32_t, UINT32_MAX);
137 PF_NV_IMPL_UINT(uint64, uint64_t, UINT64_MAX);
140 pf_nvint(const nvlist_t *nvl, const char *name, int *val)
144 if (! nvlist_exists_number(nvl, name))
147 raw = nvlist_get_number(nvl, name);
148 if (raw > INT_MAX || raw < INT_MIN)
157 pf_nvstring(const nvlist_t *nvl, const char *name, char *str, size_t maxlen)
161 if (! nvlist_exists_string(nvl, name))
164 ret = strlcpy(str, nvlist_get_string(nvl, name), maxlen);
172 pf_nvaddr_to_addr(const nvlist_t *nvl, struct pf_addr *paddr)
174 return (pf_nvbinary(nvl, "addr", paddr, sizeof(*paddr)));
178 pf_addr_to_nvaddr(const struct pf_addr *paddr)
182 nvl = nvlist_create(0);
186 nvlist_add_binary(nvl, "addr", paddr, sizeof(*paddr));
192 pf_nvmape_to_mape(const nvlist_t *nvl, struct pf_mape_portset *mape)
196 bzero(mape, sizeof(*mape));
197 PFNV_CHK(pf_nvuint8(nvl, "offset", &mape->offset));
198 PFNV_CHK(pf_nvuint8(nvl, "psidlen", &mape->psidlen));
199 PFNV_CHK(pf_nvuint16(nvl, "psid", &mape->psid));
206 pf_mape_to_nvmape(const struct pf_mape_portset *mape)
210 nvl = nvlist_create(0);
214 nvlist_add_number(nvl, "offset", mape->offset);
215 nvlist_add_number(nvl, "psidlen", mape->psidlen);
216 nvlist_add_number(nvl, "psid", mape->psid);
222 pf_nvpool_to_pool(const nvlist_t *nvl, struct pf_kpool *kpool)
226 bzero(kpool, sizeof(*kpool));
228 PFNV_CHK(pf_nvbinary(nvl, "key", &kpool->key, sizeof(kpool->key)));
230 if (nvlist_exists_nvlist(nvl, "counter")) {
231 PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "counter"),
235 PFNV_CHK(pf_nvint(nvl, "tblidx", &kpool->tblidx));
236 PFNV_CHK(pf_nvuint16_array(nvl, "proxy_port", kpool->proxy_port, 2,
238 PFNV_CHK(pf_nvuint8(nvl, "opts", &kpool->opts));
240 if (nvlist_exists_nvlist(nvl, "mape")) {
241 PFNV_CHK(pf_nvmape_to_mape(nvlist_get_nvlist(nvl, "mape"),
250 pf_pool_to_nvpool(const struct pf_kpool *pool)
255 nvl = nvlist_create(0);
259 nvlist_add_binary(nvl, "key", &pool->key, sizeof(pool->key));
260 tmp = pf_addr_to_nvaddr(&pool->counter);
263 nvlist_add_nvlist(nvl, "counter", tmp);
266 nvlist_add_number(nvl, "tblidx", pool->tblidx);
267 pf_uint16_array_nv(nvl, "proxy_port", pool->proxy_port, 2);
268 nvlist_add_number(nvl, "opts", pool->opts);
270 tmp = pf_mape_to_nvmape(&pool->mape);
273 nvlist_add_nvlist(nvl, "mape", tmp);
284 pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr)
288 bzero(addr, sizeof(*addr));
290 PFNV_CHK(pf_nvuint8(nvl, "type", &addr->type));
291 PFNV_CHK(pf_nvuint8(nvl, "iflags", &addr->iflags));
292 if (addr->type == PF_ADDR_DYNIFTL)
293 PFNV_CHK(pf_nvstring(nvl, "ifname", addr->v.ifname,
294 sizeof(addr->v.ifname)));
295 if (addr->type == PF_ADDR_TABLE)
296 PFNV_CHK(pf_nvstring(nvl, "tblname", addr->v.tblname,
297 sizeof(addr->v.tblname)));
299 if (! nvlist_exists_nvlist(nvl, "addr"))
301 PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "addr"),
304 if (! nvlist_exists_nvlist(nvl, "mask"))
306 PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "mask"),
309 switch (addr->type) {
310 case PF_ADDR_DYNIFTL:
313 case PF_ADDR_ADDRMASK:
314 case PF_ADDR_NOROUTE:
315 case PF_ADDR_URPFFAILED:
326 pf_addr_wrap_to_nvaddr_wrap(const struct pf_addr_wrap *addr)
331 nvl = nvlist_create(0);
335 nvlist_add_number(nvl, "type", addr->type);
336 nvlist_add_number(nvl, "iflags", addr->iflags);
337 if (addr->type == PF_ADDR_DYNIFTL)
338 nvlist_add_string(nvl, "ifname", addr->v.ifname);
339 if (addr->type == PF_ADDR_TABLE)
340 nvlist_add_string(nvl, "tblname", addr->v.tblname);
342 tmp = pf_addr_to_nvaddr(&addr->v.a.addr);
345 nvlist_add_nvlist(nvl, "addr", tmp);
347 tmp = pf_addr_to_nvaddr(&addr->v.a.mask);
350 nvlist_add_nvlist(nvl, "mask", tmp);
361 pf_validate_op(uint8_t op)
383 pf_nvrule_addr_to_rule_addr(const nvlist_t *nvl, struct pf_rule_addr *addr)
387 if (! nvlist_exists_nvlist(nvl, "addr"))
390 PFNV_CHK(pf_nvaddr_wrap_to_addr_wrap(nvlist_get_nvlist(nvl, "addr"),
392 PFNV_CHK(pf_nvuint16_array(nvl, "port", addr->port, 2, NULL));
393 PFNV_CHK(pf_nvuint8(nvl, "neg", &addr->neg));
394 PFNV_CHK(pf_nvuint8(nvl, "port_op", &addr->port_op));
396 PFNV_CHK(pf_validate_op(addr->port_op));
403 pf_rule_addr_to_nvrule_addr(const struct pf_rule_addr *addr)
408 nvl = nvlist_create(0);
412 tmp = pf_addr_wrap_to_nvaddr_wrap(&addr->addr);
415 nvlist_add_nvlist(nvl, "addr", tmp);
417 pf_uint16_array_nv(nvl, "port", addr->port, 2);
418 nvlist_add_number(nvl, "neg", addr->neg);
419 nvlist_add_number(nvl, "port_op", addr->port_op);
429 pf_nvrule_uid_to_rule_uid(const nvlist_t *nvl, struct pf_rule_uid *uid)
433 bzero(uid, sizeof(*uid));
435 PFNV_CHK(pf_nvuint32_array(nvl, "uid", uid->uid, 2, NULL));
436 PFNV_CHK(pf_nvuint8(nvl, "op", &uid->op));
438 PFNV_CHK(pf_validate_op(uid->op));
445 pf_rule_uid_to_nvrule_uid(const struct pf_rule_uid *uid)
449 nvl = nvlist_create(0);
453 pf_uint32_array_nv(nvl, "uid", uid->uid, 2);
454 nvlist_add_number(nvl, "op", uid->op);
460 pf_nvrule_gid_to_rule_gid(const nvlist_t *nvl, struct pf_rule_gid *gid)
462 /* Cheat a little. These stucts are the same, other than the name of
463 * the first field. */
464 return (pf_nvrule_uid_to_rule_uid(nvl, (struct pf_rule_uid *)gid));
468 pf_check_rule_addr(const struct pf_rule_addr *addr)
471 switch (addr->addr.type) {
472 case PF_ADDR_ADDRMASK:
473 case PF_ADDR_NOROUTE:
474 case PF_ADDR_DYNIFTL:
476 case PF_ADDR_URPFFAILED:
483 if (addr->addr.p.dyn != NULL) {
492 pf_nvrule_to_krule(const nvlist_t *nvl, struct pf_krule *rule)
496 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
498 PFNV_CHK(pf_nvuint32(nvl, "nr", &rule->nr));
500 if (! nvlist_exists_nvlist(nvl, "src"))
503 error = pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "src"),
508 if (! nvlist_exists_nvlist(nvl, "dst"))
511 PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"),
514 if (nvlist_exists_string(nvl, "label")) {
515 PFNV_CHK(pf_nvstring(nvl, "label", rule->label[0],
516 sizeof(rule->label[0])));
517 } else if (nvlist_exists_string_array(nvl, "labels")) {
518 const char *const *strs;
522 strs = nvlist_get_string_array(nvl, "labels", &items);
523 if (items > PF_RULE_MAX_LABEL_COUNT)
526 for (size_t i = 0; i < items; i++) {
527 ret = strlcpy(rule->label[i], strs[i],
528 sizeof(rule->label[0]));
529 if (ret >= sizeof(rule->label[0]))
534 PFNV_CHK(pf_nvstring(nvl, "ifname", rule->ifname,
535 sizeof(rule->ifname)));
536 PFNV_CHK(pf_nvstring(nvl, "qname", rule->qname, sizeof(rule->qname)));
537 PFNV_CHK(pf_nvstring(nvl, "pqname", rule->pqname,
538 sizeof(rule->pqname)));
539 PFNV_CHK(pf_nvstring(nvl, "tagname", rule->tagname,
540 sizeof(rule->tagname)));
541 PFNV_CHK(pf_nvuint16_opt(nvl, "dnpipe", &rule->dnpipe, 0));
542 PFNV_CHK(pf_nvuint16_opt(nvl, "dnrpipe", &rule->dnrpipe, 0));
543 PFNV_CHK(pf_nvuint32_opt(nvl, "dnflags", &rule->free_flags, 0));
544 PFNV_CHK(pf_nvstring(nvl, "match_tagname", rule->match_tagname,
545 sizeof(rule->match_tagname)));
546 PFNV_CHK(pf_nvstring(nvl, "overload_tblname", rule->overload_tblname,
547 sizeof(rule->overload_tblname)));
549 if (! nvlist_exists_nvlist(nvl, "rpool"))
551 PFNV_CHK(pf_nvpool_to_pool(nvlist_get_nvlist(nvl, "rpool"),
554 PFNV_CHK(pf_nvuint32(nvl, "os_fingerprint", &rule->os_fingerprint));
556 PFNV_CHK(pf_nvint(nvl, "rtableid", &rule->rtableid));
557 PFNV_CHK(pf_nvuint32_array(nvl, "timeout", rule->timeout, PFTM_MAX, NULL));
558 PFNV_CHK(pf_nvuint32(nvl, "max_states", &rule->max_states));
559 PFNV_CHK(pf_nvuint32(nvl, "max_src_nodes", &rule->max_src_nodes));
560 PFNV_CHK(pf_nvuint32(nvl, "max_src_states", &rule->max_src_states));
561 PFNV_CHK(pf_nvuint32(nvl, "max_src_conn", &rule->max_src_conn));
562 PFNV_CHK(pf_nvuint32(nvl, "max_src_conn_rate.limit",
563 &rule->max_src_conn_rate.limit));
564 PFNV_CHK(pf_nvuint32(nvl, "max_src_conn_rate.seconds",
565 &rule->max_src_conn_rate.seconds));
566 PFNV_CHK(pf_nvuint32(nvl, "prob", &rule->prob));
567 PFNV_CHK(pf_nvuint32(nvl, "cuid", &rule->cuid));
568 PFNV_CHK(pf_nvuint32(nvl, "cpid", &rule->cpid));
570 PFNV_CHK(pf_nvuint16(nvl, "return_icmp", &rule->return_icmp));
571 PFNV_CHK(pf_nvuint16(nvl, "return_icmp6", &rule->return_icmp6));
573 PFNV_CHK(pf_nvuint16(nvl, "max_mss", &rule->max_mss));
574 PFNV_CHK(pf_nvuint16(nvl, "scrub_flags", &rule->scrub_flags));
576 if (! nvlist_exists_nvlist(nvl, "uid"))
578 PFNV_CHK(pf_nvrule_uid_to_rule_uid(nvlist_get_nvlist(nvl, "uid"),
581 if (! nvlist_exists_nvlist(nvl, "gid"))
583 PFNV_CHK(pf_nvrule_gid_to_rule_gid(nvlist_get_nvlist(nvl, "gid"),
586 PFNV_CHK(pf_nvuint32(nvl, "rule_flag", &rule->rule_flag));
587 PFNV_CHK(pf_nvuint8(nvl, "action", &rule->action));
588 PFNV_CHK(pf_nvuint8(nvl, "direction", &rule->direction));
589 PFNV_CHK(pf_nvuint8(nvl, "log", &rule->log));
590 PFNV_CHK(pf_nvuint8(nvl, "logif", &rule->logif));
591 PFNV_CHK(pf_nvuint8(nvl, "quick", &rule->quick));
592 PFNV_CHK(pf_nvuint8(nvl, "ifnot", &rule->ifnot));
593 PFNV_CHK(pf_nvuint8(nvl, "match_tag_not", &rule->match_tag_not));
594 PFNV_CHK(pf_nvuint8(nvl, "natpass", &rule->natpass));
596 PFNV_CHK(pf_nvuint8(nvl, "keep_state", &rule->keep_state));
597 PFNV_CHK(pf_nvuint8(nvl, "af", &rule->af));
598 PFNV_CHK(pf_nvuint8(nvl, "proto", &rule->proto));
599 PFNV_CHK(pf_nvuint8(nvl, "type", &rule->type));
600 PFNV_CHK(pf_nvuint8(nvl, "code", &rule->code));
601 PFNV_CHK(pf_nvuint8(nvl, "flags", &rule->flags));
602 PFNV_CHK(pf_nvuint8(nvl, "flagset", &rule->flagset));
603 PFNV_CHK(pf_nvuint8(nvl, "min_ttl", &rule->min_ttl));
604 PFNV_CHK(pf_nvuint8(nvl, "allow_opts", &rule->allow_opts));
605 PFNV_CHK(pf_nvuint8(nvl, "rt", &rule->rt));
606 PFNV_CHK(pf_nvuint8(nvl, "return_ttl", &rule->return_ttl));
607 PFNV_CHK(pf_nvuint8(nvl, "tos", &rule->tos));
608 PFNV_CHK(pf_nvuint8(nvl, "set_tos", &rule->set_tos));
610 PFNV_CHK(pf_nvuint8(nvl, "flush", &rule->flush));
611 PFNV_CHK(pf_nvuint8(nvl, "prio", &rule->prio));
613 PFNV_CHK(pf_nvuint8_array(nvl, "set_prio", &rule->prio, 2, NULL));
615 if (nvlist_exists_nvlist(nvl, "divert")) {
616 const nvlist_t *nvldivert = nvlist_get_nvlist(nvl, "divert");
618 if (! nvlist_exists_nvlist(nvldivert, "addr"))
620 PFNV_CHK(pf_nvaddr_to_addr(nvlist_get_nvlist(nvldivert, "addr"),
621 &rule->divert.addr));
622 PFNV_CHK(pf_nvuint16(nvldivert, "port", &rule->divert.port));
627 if (rule->af == AF_INET)
628 ERROUT(EAFNOSUPPORT);
631 if (rule->af == AF_INET6)
632 ERROUT(EAFNOSUPPORT);
635 PFNV_CHK(pf_check_rule_addr(&rule->src));
636 PFNV_CHK(pf_check_rule_addr(&rule->dst));
646 pf_divert_to_nvdivert(const struct pf_krule *rule)
651 nvl = nvlist_create(0);
655 tmp = pf_addr_to_nvaddr(&rule->divert.addr);
658 nvlist_add_nvlist(nvl, "addr", tmp);
660 nvlist_add_number(nvl, "port", rule->divert.port);
670 pf_krule_to_nvrule(struct pf_krule *rule)
674 nvl = nvlist_create(0);
678 nvlist_add_number(nvl, "nr", rule->nr);
679 tmp = pf_rule_addr_to_nvrule_addr(&rule->src);
682 nvlist_add_nvlist(nvl, "src", tmp);
684 tmp = pf_rule_addr_to_nvrule_addr(&rule->dst);
687 nvlist_add_nvlist(nvl, "dst", tmp);
690 for (int i = 0; i < PF_SKIP_COUNT; i++) {
691 nvlist_append_number_array(nvl, "skip",
692 rule->skip[i].ptr ? rule->skip[i].ptr->nr : -1);
695 for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) {
696 nvlist_append_string_array(nvl, "labels", rule->label[i]);
698 nvlist_add_string(nvl, "label", rule->label[0]);
699 nvlist_add_string(nvl, "ifname", rule->ifname);
700 nvlist_add_string(nvl, "qname", rule->qname);
701 nvlist_add_string(nvl, "pqname", rule->pqname);
702 nvlist_add_number(nvl, "dnpipe", rule->dnpipe);
703 nvlist_add_number(nvl, "dnrpipe", rule->dnrpipe);
704 nvlist_add_number(nvl, "dnflags", rule->free_flags);
705 nvlist_add_string(nvl, "tagname", rule->tagname);
706 nvlist_add_string(nvl, "match_tagname", rule->match_tagname);
707 nvlist_add_string(nvl, "overload_tblname", rule->overload_tblname);
709 tmp = pf_pool_to_nvpool(&rule->rpool);
712 nvlist_add_nvlist(nvl, "rpool", tmp);
715 nvlist_add_number(nvl, "evaluations",
716 pf_counter_u64_fetch(&rule->evaluations));
717 for (int i = 0; i < 2; i++) {
718 nvlist_append_number_array(nvl, "packets",
719 pf_counter_u64_fetch(&rule->packets[i]));
720 nvlist_append_number_array(nvl, "bytes",
721 pf_counter_u64_fetch(&rule->bytes[i]));
724 nvlist_add_number(nvl, "os_fingerprint", rule->os_fingerprint);
726 nvlist_add_number(nvl, "rtableid", rule->rtableid);
727 pf_uint32_array_nv(nvl, "timeout", rule->timeout, PFTM_MAX);
728 nvlist_add_number(nvl, "max_states", rule->max_states);
729 nvlist_add_number(nvl, "max_src_nodes", rule->max_src_nodes);
730 nvlist_add_number(nvl, "max_src_states", rule->max_src_states);
731 nvlist_add_number(nvl, "max_src_conn", rule->max_src_conn);
732 nvlist_add_number(nvl, "max_src_conn_rate.limit",
733 rule->max_src_conn_rate.limit);
734 nvlist_add_number(nvl, "max_src_conn_rate.seconds",
735 rule->max_src_conn_rate.seconds);
736 nvlist_add_number(nvl, "qid", rule->qid);
737 nvlist_add_number(nvl, "pqid", rule->pqid);
738 nvlist_add_number(nvl, "prob", rule->prob);
739 nvlist_add_number(nvl, "cuid", rule->cuid);
740 nvlist_add_number(nvl, "cpid", rule->cpid);
742 nvlist_add_number(nvl, "states_cur",
743 counter_u64_fetch(rule->states_cur));
744 nvlist_add_number(nvl, "states_tot",
745 counter_u64_fetch(rule->states_tot));
746 nvlist_add_number(nvl, "src_nodes",
747 counter_u64_fetch(rule->src_nodes));
749 nvlist_add_number(nvl, "return_icmp", rule->return_icmp);
750 nvlist_add_number(nvl, "return_icmp6", rule->return_icmp6);
752 nvlist_add_number(nvl, "max_mss", rule->max_mss);
753 nvlist_add_number(nvl, "scrub_flags", rule->scrub_flags);
755 tmp = pf_rule_uid_to_nvrule_uid(&rule->uid);
758 nvlist_add_nvlist(nvl, "uid", tmp);
760 tmp = pf_rule_uid_to_nvrule_uid((const struct pf_rule_uid *)&rule->gid);
763 nvlist_add_nvlist(nvl, "gid", tmp);
766 nvlist_add_number(nvl, "rule_flag", rule->rule_flag);
767 nvlist_add_number(nvl, "action", rule->action);
768 nvlist_add_number(nvl, "direction", rule->direction);
769 nvlist_add_number(nvl, "log", rule->log);
770 nvlist_add_number(nvl, "logif", rule->logif);
771 nvlist_add_number(nvl, "quick", rule->quick);
772 nvlist_add_number(nvl, "ifnot", rule->ifnot);
773 nvlist_add_number(nvl, "match_tag_not", rule->match_tag_not);
774 nvlist_add_number(nvl, "natpass", rule->natpass);
776 nvlist_add_number(nvl, "keep_state", rule->keep_state);
777 nvlist_add_number(nvl, "af", rule->af);
778 nvlist_add_number(nvl, "proto", rule->proto);
779 nvlist_add_number(nvl, "type", rule->type);
780 nvlist_add_number(nvl, "code", rule->code);
781 nvlist_add_number(nvl, "flags", rule->flags);
782 nvlist_add_number(nvl, "flagset", rule->flagset);
783 nvlist_add_number(nvl, "min_ttl", rule->min_ttl);
784 nvlist_add_number(nvl, "allow_opts", rule->allow_opts);
785 nvlist_add_number(nvl, "rt", rule->rt);
786 nvlist_add_number(nvl, "return_ttl", rule->return_ttl);
787 nvlist_add_number(nvl, "tos", rule->tos);
788 nvlist_add_number(nvl, "set_tos", rule->set_tos);
789 nvlist_add_number(nvl, "anchor_relative", rule->anchor_relative);
790 nvlist_add_number(nvl, "anchor_wildcard", rule->anchor_wildcard);
792 nvlist_add_number(nvl, "flush", rule->flush);
793 nvlist_add_number(nvl, "prio", rule->prio);
795 pf_uint8_array_nv(nvl, "set_prio", &rule->prio, 2);
797 tmp = pf_divert_to_nvdivert(rule);
800 nvlist_add_nvlist(nvl, "divert", tmp);
811 pf_nvstate_cmp_to_state_cmp(const nvlist_t *nvl, struct pf_state_cmp *cmp)
815 bzero(cmp, sizeof(*cmp));
817 PFNV_CHK(pf_nvuint64(nvl, "id", &cmp->id));
818 PFNV_CHK(pf_nvuint32(nvl, "creatorid", &cmp->creatorid));
819 PFNV_CHK(pf_nvuint8(nvl, "direction", &cmp->direction));
826 pf_nvstate_kill_to_kstate_kill(const nvlist_t *nvl,
827 struct pf_kstate_kill *kill)
831 bzero(kill, sizeof(*kill));
833 if (! nvlist_exists_nvlist(nvl, "cmp"))
836 PFNV_CHK(pf_nvstate_cmp_to_state_cmp(nvlist_get_nvlist(nvl, "cmp"),
838 PFNV_CHK(pf_nvuint8(nvl, "af", &kill->psk_af));
839 PFNV_CHK(pf_nvint(nvl, "proto", &kill->psk_proto));
841 if (! nvlist_exists_nvlist(nvl, "src"))
843 PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "src"),
845 if (! nvlist_exists_nvlist(nvl, "dst"))
847 PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"),
849 if (nvlist_exists_nvlist(nvl, "rt_addr")) {
850 PFNV_CHK(pf_nvrule_addr_to_rule_addr(
851 nvlist_get_nvlist(nvl, "rt_addr"), &kill->psk_rt_addr));
854 PFNV_CHK(pf_nvstring(nvl, "ifname", kill->psk_ifname,
855 sizeof(kill->psk_ifname)));
856 PFNV_CHK(pf_nvstring(nvl, "label", kill->psk_label,
857 sizeof(kill->psk_label)));
858 PFNV_CHK(pf_nvbool(nvl, "kill_match", &kill->psk_kill_match));
865 pf_state_key_to_nvstate_key(const struct pf_state_key *key)
869 nvl = nvlist_create(0);
873 for (int i = 0; i < 2; i++) {
874 tmp = pf_addr_to_nvaddr(&key->addr[i]);
877 nvlist_append_nvlist_array(nvl, "addr", tmp);
879 nvlist_append_number_array(nvl, "port", key->port[i]);
881 nvlist_add_number(nvl, "af", key->af);
882 nvlist_add_number(nvl, "proto", key->proto);
892 pf_state_peer_to_nvstate_peer(const struct pf_state_peer *peer)
896 nvl = nvlist_create(0);
900 nvlist_add_number(nvl, "seqlo", peer->seqlo);
901 nvlist_add_number(nvl, "seqhi", peer->seqhi);
902 nvlist_add_number(nvl, "seqdiff", peer->seqdiff);
903 nvlist_add_number(nvl, "state", peer->state);
904 nvlist_add_number(nvl, "wscale", peer->wscale);
910 pf_state_to_nvstate(const struct pf_kstate *s)
913 uint32_t expire, flags = 0;
915 nvl = nvlist_create(0);
919 nvlist_add_number(nvl, "id", s->id);
920 nvlist_add_string(nvl, "ifname", s->kif->pfik_name);
921 nvlist_add_string(nvl, "orig_ifname", s->orig_kif->pfik_name);
923 tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_STACK]);
926 nvlist_add_nvlist(nvl, "stack_key", tmp);
929 tmp = pf_state_key_to_nvstate_key(s->key[PF_SK_WIRE]);
932 nvlist_add_nvlist(nvl, "wire_key", tmp);
935 tmp = pf_state_peer_to_nvstate_peer(&s->src);
938 nvlist_add_nvlist(nvl, "src", tmp);
941 tmp = pf_state_peer_to_nvstate_peer(&s->dst);
944 nvlist_add_nvlist(nvl, "dst", tmp);
947 tmp = pf_addr_to_nvaddr(&s->rt_addr);
950 nvlist_add_nvlist(nvl, "rt_addr", tmp);
953 nvlist_add_number(nvl, "rule", s->rule.ptr ? s->rule.ptr->nr : -1);
954 nvlist_add_number(nvl, "anchor",
955 s->anchor.ptr ? s->anchor.ptr->nr : -1);
956 nvlist_add_number(nvl, "nat_rule",
957 s->nat_rule.ptr ? s->nat_rule.ptr->nr : -1);
958 nvlist_add_number(nvl, "creation", s->creation);
960 expire = pf_state_expires(s);
961 if (expire <= time_uptime)
964 expire = expire - time_uptime;
965 nvlist_add_number(nvl, "expire", expire);
967 for (int i = 0; i < 2; i++) {
968 nvlist_append_number_array(nvl, "packets",
970 nvlist_append_number_array(nvl, "bytes",
974 nvlist_add_number(nvl, "creatorid", s->creatorid);
975 nvlist_add_number(nvl, "direction", s->direction);
976 nvlist_add_number(nvl, "state_flags", s->state_flags);
978 flags |= PFSYNC_FLAG_SRCNODE;
980 flags |= PFSYNC_FLAG_NATSRCNODE;
981 nvlist_add_number(nvl, "sync_flags", flags);