From nobody Mon Mar 14 21:43:55 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 753541A13800; Mon, 14 Mar 2022 21:43:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KHVRH2rwSz3kVN; Mon, 14 Mar 2022 21:43:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647294235; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=I6wkGHjzh+QB36CLtJc9CTfvJGgYxxW1CPWj7l+71VI=; b=POyIyLpPpV9Y0Wbrx7/wm06ypSAOq4jRiOoguH3pXY8ZKS4QeEWqmJI30wpHt5q+yzjrEw BVqJ8iIMJZNm20LhpgEWvlctgZvekhaVyNYUbgZ0ITItWYTjVZtC2KKBpTivZ0/LFfet5i +Z7dIP+cqF3jDDDdGyKyxJYhTveKGCcV+t+OySJ2PDZi7qAT6bzojcUwTugNrUm9+w8R9d MI6RE2lx1THe/qHegIA5IntDI9DxBi0qB0/CQRsRf9giapEg67P/C9vxYTe2kHyZyYM8eb Qup8Nd6HnX7siE/bY4SZivqZICg79/naitahP7fC7r+RDoJL2I5CpffJWnlKlA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 41C051580A; Mon, 14 Mar 2022 21:43:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22ELht7F017406; Mon, 14 Mar 2022 21:43:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22ELhtbI017405; Mon, 14 Mar 2022 21:43:55 GMT (envelope-from git) Date: Mon, 14 Mar 2022 21:43:55 GMT Message-Id: <202203142143.22ELhtbI017405@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 8a42005d1e49 - main - pf: support basic L3 filtering in the Ethernet rules List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8a42005d1e491932666eb9f0be3e70ea1a28a3f7 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647294235; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=I6wkGHjzh+QB36CLtJc9CTfvJGgYxxW1CPWj7l+71VI=; b=CDXka0Vhip0hTdVeHQLemj73bKmcuwt43Wtrc01V8vpmxHOozIQgKhsuB18TH6Naybynvt 65owYDLNgZb++B2ErmyH8NTEMzOGSqGwsmaLrHmrgNYTigtOarT+kCmQJZlM/axrAxYpPd KPpsE2NJPKsGmlc5ez6DjIWlu2ZMtldcQAm39ogNJRkZGESYfRDijMoPq9M2QQPea+/Xc4 XIzPfQVxargyl2IC4U3kz1eE/4lSNUkE3ehyDogMdD26Ho22izMnF9rn4G+IWs/wSR5wke Ifrrugjnee8sZIWCXPcpOAgpTx6PFqs2YcJwBu6c17SSiq6ZXJgm6zaKJLZqXg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1647294235; a=rsa-sha256; cv=none; b=W4VHqzaqz/UzuG/wgo+UsjbUdJgudquveKxgJCIxqgdlC5XEp6ZUPG7YEdK7l7BnHAeB0X ThZtcljMCvg2EUg2sq2ARStHDEE+OizLnoBdZiNsRj/i8paA7jP1N19dH+kWJemPFSdbI9 ofhGUpViyIPo5ymH7CzMOTvqvoEQpu5pgNbEmfUBTDlps5qjxwktyJMId+SN9oIii/6Hco GK5fWhcEkvoNTeUJK9L1SZNuti5Aw4PcAFGR054HkiVAygsT6Ff0gfaSQhSEwmy9OVSB1a W5qn6Sioz3OEIjlQU3u01FtC8ziBsjkYKuBVnE1jPXVkx1p/Rx/0+m2kA4KBjw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=8a42005d1e491932666eb9f0be3e70ea1a28a3f7 commit 8a42005d1e491932666eb9f0be3e70ea1a28a3f7 Author: Kristof Provost AuthorDate: 2022-03-08 08:48:11 +0000 Commit: Kristof Provost CommitDate: 2022-03-14 21:42:37 +0000 pf: support basic L3 filtering in the Ethernet rules Allow filtering based on the source or destination IP/IPv6 address in the Ethernet layer rules. Reviewed by: pauamma_gundo.com (man), debdrup (man) Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D34482 --- lib/libpfctl/libpfctl.c | 10 +++++++- lib/libpfctl/libpfctl.h | 1 + sbin/pfctl/parse.y | 63 +++++++++++++++++++++++++++++++++++----------- sbin/pfctl/pfctl_parser.c | 7 +++++- share/man/man5/pf.conf.5 | 4 +-- sys/net/pfvar.h | 1 + sys/netpfil/pf/pf.c | 64 +++++++++++++++++++++++++++++++++++++++++------ sys/netpfil/pf/pf_nv.c | 30 ++++++++++++++++++++++ 8 files changed, 154 insertions(+), 26 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 896ae1829e1a..8f064594260b 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -598,6 +598,11 @@ pfctl_nveth_rule_to_eth_rule(const nvlist_t *nvl, struct pfctl_eth_rule *rule) pfctl_nveth_addr_to_eth_addr(nvlist_get_nvlist(nvl, "dst"), &rule->dst); + pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "ipsrc"), + &rule->ipsrc); + pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "ipdst"), + &rule->ipdst); + rule->evaluations = nvlist_get_number(nvl, "evaluations"); rule->packets[0] = nvlist_get_number(nvl, "packets-in"); rule->packets[1] = nvlist_get_number(nvl, "packets-out"); @@ -659,7 +664,7 @@ pfctl_get_eth_rule(int dev, uint32_t nr, uint32_t ticket, const char *path, struct pfctl_eth_rule *rule, bool clear, char *anchor_call) { - uint8_t buf[1024]; + uint8_t buf[2048]; struct pfioc_nv nv; nvlist_t *nvl; void *data; @@ -738,6 +743,9 @@ pfctl_add_eth_rule(int dev, const struct pfctl_eth_rule *r, const char *anchor, nvlist_add_nvlist(nvl, "dst", addr); nvlist_destroy(addr); + pfctl_nv_add_rule_addr(nvl, "ipsrc", &r->ipsrc); + pfctl_nv_add_rule_addr(nvl, "ipdst", &r->ipdst); + nvlist_add_string(nvl, "qname", r->qname); nvlist_add_string(nvl, "tagname", r->tagname); nvlist_add_number(nvl, "dnpipe", r->dnpipe); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 02781403a3a2..b7f703b64def 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -89,6 +89,7 @@ struct pfctl_eth_rule { uint8_t direction; uint16_t proto; struct pfctl_eth_addr src, dst; + struct pf_rule_addr ipsrc, ipdst; /* Stats */ uint64_t evaluations; diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 8a0aa4279337..bcbbfe872c6c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -350,7 +350,8 @@ void expand_label_nr(const char *, char *, size_t, struct pfctl_rule *); void expand_eth_rule(struct pfctl_eth_rule *, struct node_if *, struct node_etherproto *, - struct node_mac *, struct node_mac *, const char *); + struct node_mac *, struct node_mac *, + struct node_host *, struct node_host *, const char *); void expand_rule(struct pfctl_rule *, struct node_if *, struct node_host *, struct node_proto *, struct node_os *, struct node_host *, struct node_port *, struct node_host *, @@ -492,7 +493,7 @@ int parseport(char *, struct range *r, int); %token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR %token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY FAILPOLICY %token RANDOMID REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID -%token ANTISPOOF FOR INCLUDE KEEPCOUNTERS SYNCOOKIES +%token ANTISPOOF FOR INCLUDE KEEPCOUNTERS SYNCOOKIES L3 %token ETHER %token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY MAPEPORTSET %token ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME @@ -523,7 +524,7 @@ int parseport(char *, struct range *r, int); %type icmp_list icmp_item %type icmp6_list icmp6_item %type reticmpspec reticmp6spec -%type fromto +%type fromto l3fromto %type ipportspec from to %type ipspec toipspec xhost host dynaddr host_list %type redir_host_list redirspec @@ -1182,7 +1183,7 @@ scrubaction : no SCRUB { } ; -etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_opts +etherrule : ETHER action dir quick interface etherproto etherfromto l3fromto etherfilter_opts { struct pfctl_eth_rule r; @@ -1194,14 +1195,15 @@ etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_ r.action = $2.b1; r.direction = $3; r.quick = $4.quick; - if ($8.tag != NULL) - memcpy(&r.tagname, $8.tag, sizeof(r.tagname)); - if ($8.queues.qname != NULL) - memcpy(&r.qname, $8.queues.qname, sizeof(r.qname)); - r.dnpipe = $8.dnpipe; - r.dnflags = $8.free_flags; + if ($9.tag != NULL) + memcpy(&r.tagname, $9.tag, sizeof(r.tagname)); + if ($9.queues.qname != NULL) + memcpy(&r.qname, $9.queues.qname, sizeof(r.qname)); + r.dnpipe = $9.dnpipe; + r.dnflags = $9.free_flags; - expand_eth_rule(&r, $5, $6, $7.src, $7.dst, ""); + expand_eth_rule(&r, $5, $6, $7.src, $7.dst, + $8.src.host, $8.dst.host, ""); } ; @@ -1236,7 +1238,7 @@ etherpfa_anchor : '{' | /* empty */ ; -etheranchorrule : ETHER ANCHOR anchorname dir quick interface etherproto etherfromto etherpfa_anchor +etheranchorrule : ETHER ANCHOR anchorname dir quick interface etherproto etherfromto l3fromto etherpfa_anchor { struct pfctl_eth_rule r; @@ -1286,6 +1288,7 @@ etheranchorrule : ETHER ANCHOR anchorname dir quick interface etherproto etherfr r.quick = $5.quick; expand_eth_rule(&r, $6, $7, $8.src, $8.dst, + $9.src.host, $9.dst.host, pf->eastack[pf->asd + 1] ? pf->ealast->name : $3); free($3); @@ -3254,6 +3257,13 @@ protoval : STRING { } ; +l3fromto : /* empty */ { + bzero(&$$, sizeof($$)); + } + | L3 fromto { + $$ = $2; + } + ; etherfromto : ALL { $$.src = NULL; $$.dst = NULL; @@ -5733,23 +5743,45 @@ expand_queue(struct pf_altq *a, struct node_if *interfaces, return (0); } +static int +pf_af_to_proto(sa_family_t af) +{ + if (af == AF_INET) + return (ETHERTYPE_IP); + if (af == AF_INET6) + return (ETHERTYPE_IPV6); + + return (0); +} + void expand_eth_rule(struct pfctl_eth_rule *r, struct node_if *interfaces, struct node_etherproto *protos, - struct node_mac *srcs, struct node_mac *dsts, const char *anchor_call) + struct node_mac *srcs, struct node_mac *dsts, + struct node_host *ipsrcs, struct node_host *ipdsts, const char *anchor_call) { LOOP_THROUGH(struct node_if, interface, interfaces, LOOP_THROUGH(struct node_etherproto, proto, protos, LOOP_THROUGH(struct node_mac, src, srcs, LOOP_THROUGH(struct node_mac, dst, dsts, + LOOP_THROUGH(struct node_host, ipsrc, ipsrcs, + LOOP_THROUGH(struct node_host, ipdst, ipdsts, strlcpy(r->ifname, interface->ifname, sizeof(r->ifname)); r->ifnot = interface->not; r->proto = proto->proto; + if (!r->proto && ipsrc->af) + r->proto = pf_af_to_proto(ipsrc->af); + else if (!r->proto && ipdst->af) + r->proto = pf_af_to_proto(ipdst->af); bcopy(src->mac, r->src.addr, ETHER_ADDR_LEN); bcopy(src->mask, r->src.mask, ETHER_ADDR_LEN); r->src.neg = src->neg; r->src.isset = src->isset; + r->ipsrc.addr = ipsrc->addr; + r->ipsrc.neg = ipsrc->not; + r->ipdst.addr = ipdst->addr; + r->ipdst.neg = ipdst->not; bcopy(dst->mac, r->dst.addr, ETHER_ADDR_LEN); bcopy(dst->mask, r->dst.mask, ETHER_ADDR_LEN); r->dst.neg = dst->neg; @@ -5757,12 +5789,14 @@ expand_eth_rule(struct pfctl_eth_rule *r, r->nr = pf->eastack[pf->asd]->match++; pfctl_append_eth_rule(pf, r, anchor_call); - )))); + )))))); FREE_LIST(struct node_if, interfaces); FREE_LIST(struct node_etherproto, protos); FREE_LIST(struct node_mac, srcs); FREE_LIST(struct node_mac, dsts); + FREE_LIST(struct node_host, ipsrcs); + FREE_LIST(struct node_host, ipdsts); } void @@ -6052,6 +6086,7 @@ lookup(char *s) { "interval", INTERVAL}, { "keep", KEEP}, { "keepcounters", KEEPCOUNTERS}, + { "l3", L3}, { "label", LABEL}, { "limit", LIMIT}, { "linkshare", LINKSHARE}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 1637d7358d0d..b6d1ebc127e1 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -782,7 +782,12 @@ print_eth_rule(struct pfctl_eth_rule *r, const char *anchor_call, printf(" to "); print_eth_addr(&r->dst); } - + if (r->proto == ETHERTYPE_IP || r->proto == ETHERTYPE_IPV6) { + printf(" l3"); + print_fromto(&r->ipsrc, PF_OSFP_ANY, &r->ipdst, + r->proto == ETHERTYPE_IP ? AF_INET : AF_INET6, 0, + 0, 0); + } if (r->qname[0]) printf(" queue %s", r->qname); if (r->tagname[0]) diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index 13ff88586d8e..d136d9887cd5 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -28,7 +28,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 25, 2021 +.Dd March 9, 2022 .Dt PF.CONF 5 .Os .Sh NAME @@ -3072,7 +3072,7 @@ option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] | ether-rule = "ether" etheraction [ ( "in" | "out" ) ] [ "quick" ] [ "on" ifspec ] [ etherprotospec ] - etherhosts [ etherfilteropt-list ] + etherhosts [ "l3" hosts ] [ etherfilteropt-list ] pf-rule = action [ ( "in" | "out" ) ] [ "log" [ "(" logopts ")"] ] [ "quick" ] diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 57acab788b20..a61feb07334f 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -646,6 +646,7 @@ struct pf_keth_rule { uint8_t direction; uint16_t proto; struct pf_keth_rule_addr src, dst; + struct pf_rule_addr ipsrc, ipdst; /* Stats */ counter_u64_t evaluations; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index fb0abc8cd035..a900da0b8bd1 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -279,7 +279,7 @@ static u_int32_t pf_tcp_iss(struct pf_pdesc *); void pf_rule_to_actions(struct pf_krule *, struct pf_rule_actions *); static int pf_test_eth_rule(int, struct pfi_kkif *, - struct mbuf *); + struct mbuf **); static int pf_test_rule(struct pf_krule **, struct pf_kstate **, int, struct pfi_kkif *, struct mbuf *, int, struct pf_pdesc *, struct pf_krule **, @@ -3826,31 +3826,67 @@ pf_match_eth_addr(const uint8_t *a, const struct pf_keth_rule_addr *r) } static int -pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf *m) +pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0) { + struct mbuf *m = *m0; struct ether_header *e; struct pf_keth_rule *r, *rm, *a = NULL; struct pf_keth_ruleset *ruleset = NULL; struct pf_mtag *mtag; struct pf_keth_ruleq *rules; + struct pf_addr *src, *dst; + sa_family_t af = 0; + uint16_t proto; int asd = 0, match = 0; uint8_t action; struct pf_keth_anchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; - NET_EPOCH_ASSERT(); - MPASS(kif->pfik_ifp->if_vnet == curvnet); NET_EPOCH_ASSERT(); SDT_PROBE3(pf, eth, test_rule, entry, dir, kif->pfik_ifp, m); - e = mtod(m, struct ether_header *); - ruleset = V_pf_keth; rules = ck_pr_load_ptr(&ruleset->active.rules); r = TAILQ_FIRST(rules); rm = NULL; + e = mtod(m, struct ether_header *); + proto = ntohs(e->ether_type); + + switch (proto) { + case ETHERTYPE_IP: { + struct ip *ip; + m = m_pullup(m, sizeof(struct ether_header) + + sizeof(struct ip)); + if (m == NULL) { + *m0 = NULL; + return (PF_DROP); + } + af = AF_INET; + ip = mtodo(m, sizeof(struct ether_header)); + src = (struct pf_addr *)&ip->ip_src; + dst = (struct pf_addr *)&ip->ip_dst; + break; + } + case ETHERTYPE_IPV6: { + struct ip6_hdr *ip6; + m = m_pullup(m, sizeof(struct ether_header) + + sizeof(struct ip6_hdr)); + if (m == NULL) { + *m0 = NULL; + return (PF_DROP); + } + af = AF_INET6; + ip6 = mtodo(m, sizeof(struct ether_header)); + src = (struct pf_addr *)&ip6->ip6_src; + dst = (struct pf_addr *)&ip6->ip6_dst; + break; + } + } + e = mtod(m, struct ether_header *); + *m0 = m; + while (r != NULL) { counter_u64_add(r->evaluations, 1); SDT_PROBE2(pf, eth, test_rule, test, r->nr, r); @@ -3865,7 +3901,7 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf *m) "dir"); r = r->skip[PFE_SKIP_DIR].ptr; } - else if (r->proto && r->proto != ntohs(e->ether_type)) { + else if (r->proto && r->proto != proto) { SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r, "proto"); r = r->skip[PFE_SKIP_PROTO].ptr; @@ -3880,6 +3916,18 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf *m) "dst"); r = TAILQ_NEXT(r, entries); } + else if (af != 0 && PF_MISMATCHAW(&r->ipsrc.addr, src, af, + r->ipsrc.neg, kif, M_GETFIB(m))) { + SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r, + "ip_src"); + r = TAILQ_NEXT(r, entries); + } + else if (af != 0 && PF_MISMATCHAW(&r->ipdst.addr, dst, af, + r->ipdst.neg, kif, M_GETFIB(m))) { + SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r, + "ip_dst"); + r = TAILQ_NEXT(r, entries); + } else { if (r->anchor == NULL) { /* Rule matches */ @@ -6737,7 +6785,7 @@ pf_test_eth(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, return (PF_PASS); /* Stateless! */ - return (pf_test_eth_rule(dir, kif, m)); + return (pf_test_eth_rule(dir, kif, m0)); } #ifdef INET diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 42434dabf565..3b0d92cc5d20 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -1071,6 +1071,22 @@ pf_keth_rule_to_nveth_rule(const struct pf_keth_rule *krule) } nvlist_add_nvlist(nvl, "dst", addr); + addr = pf_rule_addr_to_nvrule_addr(&krule->ipsrc); + if (addr == NULL) { + nvlist_destroy(nvl); + return (NULL); + } + nvlist_add_nvlist(nvl, "ipsrc", addr); + nvlist_destroy(addr); + + addr = pf_rule_addr_to_nvrule_addr(&krule->ipdst); + if (addr == NULL) { + nvlist_destroy(nvl); + return (NULL); + } + nvlist_add_nvlist(nvl, "ipdst", addr); + nvlist_destroy(addr); + nvlist_add_number(nvl, "evaluations", counter_u64_fetch(krule->evaluations)); nvlist_add_number(nvl, "packets-in", @@ -1125,6 +1141,20 @@ pf_nveth_rule_to_keth_rule(const nvlist_t *nvl, return (error); } + if (nvlist_exists_nvlist(nvl, "ipsrc")) { + error = pf_nvrule_addr_to_rule_addr( + nvlist_get_nvlist(nvl, "ipsrc"), &krule->ipsrc); + if (error != 0) + return (error); + } + + if (nvlist_exists_nvlist(nvl, "ipdst")) { + error = pf_nvrule_addr_to_rule_addr( + nvlist_get_nvlist(nvl, "ipdst"), &krule->ipdst); + if (error != 0) + return (error); + } + PFNV_CHK(pf_nvstring(nvl, "qname", krule->qname, sizeof(krule->qname))); PFNV_CHK(pf_nvstring(nvl, "tagname", krule->tagname, sizeof(krule->tagname)));