From nobody Wed Mar 02 16:01:00 2022 X-Original-To: dev-commits-src-all@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 6015319E136A; Wed, 2 Mar 2022 16:01:03 +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 4K7zP91Wp7z3NWV; Wed, 2 Mar 2022 16:01:01 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646236862; 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=ZyonwzyDYXO2mORWXt3oGoZxqYK98ilIsQX48oaY4bA=; b=GXRWl8yl+uPUBCj7E4dQ+jv7wzilxrtI7lEgZItn3LlqBFJzMTCWM01t7ave4qLtbKj3Yt 4AvcsdqKTGwwCvA0jV8nowitbKiSPsBCI8+wHAIkjQU3WB2mHslEIDhuj5cHECrFMSA00i SXWSrMUmIxxmHN261tdtT23ZFymTK6BwHJn9btY+fM4cpeqgJp1JRjJUiqcAZ9bDCVidO9 TojjkVAdVtQpn+Ox1fuejildKt1ARHmJ7fcVEIZpqD1yDB+uGpvJxNvitLqk3gKYg004Wv eRKfMPiT9pAO0hhFd9ZZr/I6Y1NXDFOooxkwm5ASt3T2BadB1+PMY39zvRzykw== 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 C0F97264EB; Wed, 2 Mar 2022 16:01:00 +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 222G105x091379; Wed, 2 Mar 2022 16:01:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 222G10DC091378; Wed, 2 Mar 2022 16:01:00 GMT (envelope-from git) Date: Wed, 2 Mar 2022 16:01:00 GMT Message-Id: <202203021601.222G10DC091378@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: 87a89d6e14ac - main - pfctl: support lists of mac addresses List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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: 87a89d6e14ac5730572d454ec12a3a30d492816e Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646236862; 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=ZyonwzyDYXO2mORWXt3oGoZxqYK98ilIsQX48oaY4bA=; b=xXKlSqEejSj4gPDH1kko1ZdsNQNLucYB4RdV5sslldMGNv6AQJRI4DQxR3Kd17lzOHbRzV 3gzgVXeZ7vjXKWFO3sSidDjcqb0eL8d5bhifBbBGkdf2ZKV2N4mekPl3VoKRP/0pFUA8Sd FxIlHo/nL/yQE940kliVYpJVPYIOZV2d1V9VGQAYKE5RCsMAXBGoANGD6WZ91+0hwlpQWX 5ZWUyquIspmiQQ7BaNxkZAAcOvZqfnQ1CZI/3kYyqPCDtslT83oG5reGSNBWbNX2cT6Ake oWFNJ7AKaiMW6/xNvzgiWqI5Br5yZiAebZ+qexUBTUofnQoHQweB3uWYg6hQ6A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646236862; a=rsa-sha256; cv=none; b=jGfZwLOyUO02rfuII7yvM7WyQXtA0qrvzVSK2qkQkhIkf+lJykp0e9MMy3HoVxWYZZlE7C D4lZXExAmnfcnsgOvqEq61arm7YrwymwDnJHjFYLv4pg54/YoXu510ue+Q46ZF5IvNBtvG zbUBw+5pB3nzIcqMAkNc84m/wF12dHQzwd4JvUx7mt4dJ6QretMpSCGF5YHVtc7/gI1Z6Y 6gxvher73nkK6LaSOF12CPDYgPeh/dcURbzh7bMdF6eU34iR69FTWofG7ROq0o8cSA0SD7 ud37g216iN5bPiclO3GYnIloMsouw4vuaIGBT+ebW3EHiOAYOuTdZlZoDMvMyg== 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=87a89d6e14ac5730572d454ec12a3a30d492816e commit 87a89d6e14ac5730572d454ec12a3a30d492816e Author: Kristof Provost AuthorDate: 2021-09-30 15:09:57 +0000 Commit: Kristof Provost CommitDate: 2022-03-02 16:00:07 +0000 pfctl: support lists of mac addresses Teach the 'ether' rules to accept { mac1, mac2, ... } lists, similar to the lists of interfaces or IP addresses we already supported for layer 3 filtering. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D32481 --- sbin/pfctl/parse.y | 98 ++++++++++++++++++++++++++++--------------- sbin/pfctl/pfctl_parser.h | 7 ++++ tests/sys/netpfil/pf/ether.sh | 15 +++++++ 3 files changed, 87 insertions(+), 33 deletions(-) diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index a2d8cfef8232..b856621ecf41 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -349,7 +349,8 @@ void expand_label_proto(const char *, char *, size_t, u_int8_t); 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_if *, struct node_etherproto *, + struct node_mac *, struct node_mac *); 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 *, @@ -419,15 +420,12 @@ typedef struct { struct node_os *src_os; } fromto; struct { - u_int8_t src[ETHER_ADDR_LEN]; - u_int8_t srcneg; - u_int8_t dst[ETHER_ADDR_LEN]; - u_int8_t dstneg; + struct node_mac *src; + struct node_mac *dst; } etherfromto; - u_int8_t mac[ETHER_ADDR_LEN]; + struct node_mac *mac; struct { - uint8_t mac[ETHER_ADDR_LEN]; - u_int8_t neg; + struct node_mac *mac; } etheraddr; struct { struct node_host *host; @@ -560,7 +558,7 @@ int parseport(char *, struct range *r, int); %type etherproto etherproto_list etherproto_item %type etherfromto %type etherfrom etherto -%type mac +%type xmac mac mac_list macspec %% ruleset : /* empty */ @@ -1191,11 +1189,6 @@ etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_ r.action = $2.b1; r.direction = $3; r.quick = $4.quick; - /* XXX TODO: ! support */ - memcpy(&r.src.addr, $7.src, sizeof(r.src.addr)); - r.src.neg = $7.srcneg; - memcpy(&r.dst.addr, $7.dst, sizeof(r.dst.addr)); - r.dst.neg = $7.dstneg; if ($8.tag != NULL) memcpy(&r.tagname, $8.tag, sizeof(r.tagname)); if ($8.queues.qname != NULL) @@ -1203,7 +1196,7 @@ etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_ r.dnpipe = $8.dnpipe; r.dnflags = $8.free_flags; - expand_eth_rule(&r, $5, $6); + expand_eth_rule(&r, $5, $6, $7.src, $7.dst); } ; @@ -3169,48 +3162,78 @@ protoval : STRING { ; etherfromto : ALL { - bzero($$.src, sizeof($$.src)); - $$.srcneg = 0; - bzero($$.dst, sizeof($$.dst)); - $$.dstneg = 0; + $$.src = NULL; + $$.dst = NULL; } | etherfrom etherto { - memcpy(&$$.src, $1.mac, sizeof($$.src)); - $$.srcneg = $1.neg; - memcpy(&$$.dst, $2.mac, sizeof($$.dst)); - $$.dstneg = $2.neg; + $$.src = $1.mac; + $$.dst = $2.mac; } ; etherfrom : /* emtpy */ { bzero(&$$, sizeof($$)); } - | FROM not mac { - memcpy(&$$.mac, $3, sizeof($$)); - $$.neg = $2; + | FROM macspec { + $$.mac = $2; } ; etherto : /* empty */ { bzero(&$$, sizeof($$)); } - | TO not mac { - memcpy(&$$.mac, $3, sizeof($$)); - $$.neg = $2; + | TO macspec { + $$.mac = $2; } ; mac : string { + $$ = calloc(1, sizeof(struct node_mac)); + if ($$ == NULL) + err(1, "mac: calloc"); + if (sscanf($1, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &$$[0], &$$[1], &$$[2], &$$[3], &$$[4], - &$$[5]) != 6) { + &$$->mac[0], &$$->mac[1], &$$->mac[2], &$$->mac[3], &$$->mac[4], + &$$->mac[5]) != 6) { free($$); free($1); yyerror("invalid MAC address"); YYERROR; } + free($1); + $$->next = NULL; + $$->tail = $$; + } +xmac : not mac { + struct node_mac *n; + + for (n = $2; n != NULL; n = n->next) + n->neg = $1; + $$ = $2; } ; +macspec : xmac { + $$ = $1; + } + | '{' optnl mac_list '}' + { + $$ = $3; + } + ; +mac_list : xmac optnl { + $$ = $1; + } + | mac_list comma xmac { + if ($3 == NULL) + $$ = $1; + else if ($1 == NULL) + $$ = $3; + else { + $1->tail->next = $3; + $1->tail = $3->tail; + $$ = $1; + } + } fromto : ALL { $$.src.host = NULL; @@ -5616,27 +5639,36 @@ expand_queue(struct pf_altq *a, struct node_if *interfaces, void expand_eth_rule(struct pfctl_eth_rule *r, - struct node_if *interfaces, struct node_etherproto *protos) + struct node_if *interfaces, struct node_etherproto *protos, + struct node_mac *srcs, struct node_mac *dsts) { struct pfctl_eth_rule *rule; 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, r->nr = pf->eth_nr++; strlcpy(r->ifname, interface->ifname, sizeof(r->ifname)); r->ifnot = interface->not; r->proto = proto->proto; + bcopy(src->mac, r->src.addr, ETHER_ADDR_LEN); + r->src.neg = src->neg; + bcopy(dst->mac, r->dst.addr, ETHER_ADDR_LEN); + r->dst.neg = dst->neg; if ((rule = calloc(1, sizeof(*rule))) == NULL) err(1, "calloc"); bcopy(r, rule, sizeof(*rule)); TAILQ_INSERT_TAIL(&pf->eth_rules, rule, entries); - )); + )))); FREE_LIST(struct node_if, interfaces); FREE_LIST(struct node_etherproto, protos); + FREE_LIST(struct node_mac, srcs); + FREE_LIST(struct node_mac, dsts); } void diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 1d69682b1b6c..990f860fe8e3 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -135,6 +135,13 @@ struct node_host { struct node_host *tail; }; +struct node_mac { + u_int8_t mac[ETHER_ADDR_LEN]; + bool neg; + struct node_mac *next; + struct node_mac *tail; +}; + struct node_os { char *os; pf_osfp_t fingerprint; diff --git a/tests/sys/netpfil/pf/ether.sh b/tests/sys/netpfil/pf/ether.sh index a7e23779396f..8ca8d3fbf0c8 100644 --- a/tests/sys/netpfil/pf/ether.sh +++ b/tests/sys/netpfil/pf/ether.sh @@ -66,6 +66,11 @@ mac_body() "ether block to 00:01:02:03:04:05" atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 + # Should still fail for 'to', even if it's in a list + pft_set_rules alcatraz \ + "ether block to { ${epair_a_mac}, 00:01:02:0:04:05 }" + atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 + # Now try this with an interface specified pft_set_rules alcatraz \ "ether block on ${epair}b from ${epair_a_mac}" @@ -84,6 +89,16 @@ mac_body() pft_set_rules alcatraz \ "ether block out on ${epair}b to ! ${epair_a_mac}" atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 + + # Block everything not us + pft_set_rules alcatraz \ + "ether block out on ${epair}b to { ! ${epair_a_mac} }" + atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 + + # Block us now + pft_set_rules alcatraz \ + "ether block out on ${epair}b to { ! 00:01:02:03:04:05 }" + atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 } mac_cleanup()