From nobody Tue Mar 19 15:30:34 2024 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 4TzbJq25M3z5FfkS; Tue, 19 Mar 2024 15:30:35 +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 4TzbJq0RSPz4Lp6; Tue, 19 Mar 2024 15:30:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1710862235; 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=Yf+tzHUd8tRlXmBSFmBUnaUhdoEOyPexljg/qfo3m90=; b=Y3EieRxZk1bMB7v0xc4pJCwm2eNo9j6c6ef4cwi09mzBBeBEolmVqDT0zUzsX81Bkh2/JJ b6nBqX3XXpSQaYXFqTQDSepIOtUf11RsIvaQjikK/dxSWtRkQFu6FPoIuz065QTwde9QLz 4zPbEth5v1dh1kfIjSTG4UMZ4AKN4jxTmZa0cOSV60LZfMTF5IxiJLN3je1YGbHxJcn2hP mBn50B6GM737WQ9ELib+P7g4q92xvEjNGBubdST3vbP/d//1/pbXIstpfBFBNi01sCYj8a kO3H4znI7gGNCkBu/KZsat5Jqc1Y6GPgshOSZ8QEtC3sJVcJACB0DBvesIRtqQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1710862235; a=rsa-sha256; cv=none; b=wMktB0q6TWI4KFeZ+oMOYOzw8Ly9mX5a+EQa6KcTBgkJVC6MbnrMV6HAAbHzKdb8gFcmzm k3v/2ztRc+tQoOiZzDuMBZT2PhPLhjZFGUY0EzoSZUYJlisQpHVpEyeI5xmASxnATbJhJF 4t09aVdBFKsuVTheGnUW7begONlkaKE9Lbh0cYYmam1C7H4alfnqjVOov2ATKOvSNhgwvr XQd2JK5C5yw80IZC1diwKJqA/a0oHrs3GSJjWgnWBEf9xDPoegb8ewcSwno87tsMxWaiDI 8CYXVMwYIHfTVdJdUy9c4wRjzM15nUhJyueLMqQBGB4i8U9GMmG6dIW8A+yReg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1710862235; 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=Yf+tzHUd8tRlXmBSFmBUnaUhdoEOyPexljg/qfo3m90=; b=IfhQw/0bUMMJbsB+fT0+TsHEmEw7+k2cvyBmyJ3H4ylXPclQgsbljATwwrzXsEbZSS/nts sXPYZgWhUzAZhN96O+gpZf+iEreYbsjLHmXmE5PGdJGAkZUpVbjFfZt638GIwC5YgBud+6 X+/rV3QIvIt2ctUtkJ+Br7Ep1DmKPW2LnSjL8IhRTdCLYZftAOddiyk9gOGVpN72XBxiLl 2lFAJmDcPc4s8wbtVBxNQ5ZnUmImYylfcjelkGDvC4fy+RWMJlC1AVlMBGwdVdJ9jaxhhQ t598N06yW4ciWrLc3Ny+KxkMajhV+FQ/hs01kWAoWjWc6Y7/tMxplvy/DlAhNA== 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 4TzbJp6vksz1Bq5; Tue, 19 Mar 2024 15:30:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 42JFUYxf096854; Tue, 19 Mar 2024 15:30:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 42JFUYOb096851; Tue, 19 Mar 2024 15:30:34 GMT (envelope-from git) Date: Tue, 19 Mar 2024 15:30:34 GMT Message-Id: <202403191530.42JFUYOb096851@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: 470a2b334661 - main - pf: convert DIOCSETSTATUSIF to netlink 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: 470a2b3346612fbf2f6415ec8df63c92703035dd Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=470a2b3346612fbf2f6415ec8df63c92703035dd commit 470a2b3346612fbf2f6415ec8df63c92703035dd Author: Kristof Provost AuthorDate: 2024-03-18 09:56:25 +0000 Commit: Kristof Provost CommitDate: 2024-03-19 15:30:08 +0000 pf: convert DIOCSETSTATUSIF to netlink While here also add a basic test case for it. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D44368 --- lib/libpfctl/libpfctl.c | 32 +++++++++++++ lib/libpfctl/libpfctl.h | 2 + sbin/pfctl/pfctl.c | 12 +---- sys/netpfil/pf/pf_nl.c | 38 ++++++++++++++++ sys/netpfil/pf/pf_nl.h | 5 +++ tests/sys/netpfil/pf/Makefile | 1 + tests/sys/netpfil/pf/loginterface.sh | 87 ++++++++++++++++++++++++++++++++++++ 7 files changed, 167 insertions(+), 10 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index f12e45291fc1..e732c8eef854 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -2218,3 +2218,35 @@ int pfctl_table_get_addrs(int dev, struct pfr_table *tbl, struct pfr_addr *addr, *size = io.pfrio_size; return (0); } + +int +pfctl_set_statusif(struct pfctl_handle *h, const char *ifname) +{ + struct snl_writer nw; + struct snl_errmsg_data e = {}; + struct nlmsghdr *hdr; + uint32_t seq_id; + int family_id; + + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); + if (family_id == 0) + return (ENOTSUP); + + snl_init_writer(&h->ss, &nw); + hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_SET_STATUSIF); + + snl_add_msg_attr_string(&nw, PF_SS_IFNAME, ifname); + + if ((hdr = snl_finalize_msg(&nw)) == NULL) + return (ENXIO); + + seq_id = hdr->nlmsg_seq; + + if (! snl_send_message(&h->ss, hdr)) + return (ENXIO); + + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { + } + + return (e.error); +} diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index b16caf1f6480..4e06981a79c7 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -464,4 +464,6 @@ int pfctl_table_set_addrs(int dev, struct pfr_table *tbl, struct pfr_addr int flags); int pfctl_table_get_addrs(int dev, struct pfr_table *tbl, struct pfr_addr *addr, int *size, int flags); +int pfctl_set_statusif(struct pfctl_handle *h, const char *ifname); + #endif diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index f8ecded066d2..8d59871701f8 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -2547,19 +2547,11 @@ pfctl_set_logif(struct pfctl *pf, char *ifname) int pfctl_load_logif(struct pfctl *pf, char *ifname) { - struct pfioc_if pi; - - memset(&pi, 0, sizeof(pi)); - if (ifname && strlcpy(pi.ifname, ifname, - sizeof(pi.ifname)) >= sizeof(pi.ifname)) { + if (ifname != NULL && strlen(ifname) >= IFNAMSIZ) { warnx("pfctl_load_logif: strlcpy"); return (1); } - if (ioctl(pf->dev, DIOCSETSTATUSIF, &pi)) { - warnx("DIOCSETSTATUSIF"); - return (1); - } - return (0); + return (pfctl_set_statusif(pfh, ifname ? ifname : "")); } int diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index e4558c156aef..5f33e49b4a2e 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -1079,11 +1079,42 @@ pf_handle_kill_states(struct nlmsghdr *hdr, struct nl_pstate *npt) return (pf_handle_killclear_states(hdr, npt, PFNL_CMD_KILLSTATES)); } +struct nl_parsed_set_statusif { + char ifname[IFNAMSIZ]; +}; +#define _IN(_field) offsetof(struct genlmsghdr, _field) +#define _OUT(_field) offsetof(struct nl_parsed_set_statusif, _field) +static const struct nlattr_parser nla_p_set_statusif[] = { + { .type = PF_SS_IFNAME, .off = _OUT(ifname), .arg = (const void *)IFNAMSIZ, .cb = nlattr_get_chara }, +}; +static const struct nlfield_parser nlf_p_set_statusif[] = {}; +#undef _IN +#undef _OUT +NL_DECLARE_PARSER(set_statusif_parser, struct genlmsghdr, nlf_p_set_statusif, nla_p_set_statusif); + +static int +pf_handle_set_statusif(struct nlmsghdr *hdr, struct nl_pstate *npt) +{ + int error; + struct nl_parsed_set_statusif attrs = {}; + + error = nl_parse_nlmsg(hdr, &set_statusif_parser, npt, &attrs); + if (error != 0) + return (error); + + PF_RULES_WLOCK(); + strlcpy(V_pf_status.ifname, attrs.ifname, IFNAMSIZ); + PF_RULES_WUNLOCK(); + + return (0); +} + static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser, &getrules_parser, &clear_states_parser, + &set_statusif_parser, }; static int family_id; @@ -1152,6 +1183,13 @@ static const struct genl_cmd pf_cmds[] = { .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, .cmd_priv = PRIV_NETINET_PF, }, + { + .cmd_num = PFNL_CMD_SET_STATUSIF, + .cmd_name = "SETSTATUSIF", + .cmd_cb = pf_handle_set_statusif, + .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL, + .cmd_priv = PRIV_NETINET_PF, + } }; void diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index 0ae4a9283072..c44e331722b7 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -45,6 +45,7 @@ enum { PFNL_CMD_GETRULE = 7, PFNL_CMD_CLRSTATES = 8, PFNL_CMD_KILLSTATES = 9, + PFNL_CMD_SET_STATUSIF = 10, __PFNL_CMD_MAX, }; #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1) @@ -281,6 +282,10 @@ enum pf_clear_states_type_t { PF_CS_KILLED = 13, /* u32 */ }; +enum pf_set_statusif_types_t { + PF_SS_UNSPEC, + PF_SS_IFNAME = 1, /* string */ +}; #ifdef _KERNEL void pf_nl_register(void); diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index ce718c4ba900..867b98e5f6c2 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -16,6 +16,7 @@ ATF_TESTS_SH+= altq \ fragmentation_no_reassembly \ get_state \ icmp \ + loginterface \ killstate \ macro \ map_e \ diff --git a/tests/sys/netpfil/pf/loginterface.sh b/tests/sys/netpfil/pf/loginterface.sh new file mode 100644 index 000000000000..6decb69fe63d --- /dev/null +++ b/tests/sys/netpfil/pf/loginterface.sh @@ -0,0 +1,87 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 Rubicon Communications, LLC (Netgate) +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +. $(atf_get_srcdir)/utils.subr + + +atf_test_case "basic" "cleanup" +basic_head() +{ + atf_set descr 'Basic loginterface test' + atf_set require.user root +} + +basic_body() +{ + pft_init + + epair=$(vnet_mkepair) + + ifconfig ${epair}a 192.0.2.2/24 up + + vnet_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up + + # Sanity check + atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 + + # No interface stats until we configure a loginterface + atf_check -o not-match:"Interface Stats for" \ + jexec alcatraz pfctl -s info + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "set loginterface ${epair}b" \ + "pass" + + # We do get Interface Stats listed when we've configured a loginterface + atf_check -o match:"Interface Stats for ${epair}b" \ + jexec alcatraz pfctl -s info + + # And after we've sent traffic there's non-zero counters + atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 + + atf_check -o match:"Interface Stats for ${epair}b" \ + jexec alcatraz pfctl -s info + atf_check -o match:"Passed 1" \ + jexec alcatraz pfctl -s info + + # And no interface stats once we remove the loginterface + pft_set_rules alcatraz \ + "pass" + atf_check -o not-match:"Interface Stats for ${epair}b" \ + jexec alcatraz pfctl -s info +} + +basic_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "basic" +}