Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110097390
D34482.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D34482.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -89,6 +89,7 @@
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/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -598,6 +598,11 @@
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 @@
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 @@
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/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -350,7 +350,8 @@
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 @@
%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 @@
%type <v.icmp> icmp_list icmp_item
%type <v.icmp> icmp6_list icmp6_item
%type <v.number> reticmpspec reticmp6spec
-%type <v.fromto> fromto
+%type <v.fromto> fromto l3fromto
%type <v.peer> ipportspec from to
%type <v.host> ipspec toipspec xhost host dynaddr host_list
%type <v.host> redir_host_list redirspec
@@ -1182,7 +1183,7 @@
}
;
-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 @@
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 @@
| /* 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 @@
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 @@
}
;
+l3fromto : /* empty */ {
+ bzero(&$$, sizeof($$));
+ }
+ | L3 fromto {
+ $$ = $2;
+ }
+ ;
etherfromto : ALL {
$$.src = NULL;
$$.dst = NULL;
@@ -5733,23 +5743,45 @@
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 @@
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 @@
{ "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
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -782,7 +782,12 @@
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
--- 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 @@
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
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -646,6 +646,7 @@
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
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -279,7 +279,7 @@
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 @@
}
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 @@
"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 @@
"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 @@
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
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -1071,6 +1071,22 @@
}
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 @@
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)));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Feb 14, 2:15 PM (20 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16643563
Default Alt Text
D34482.diff (12 KB)
Attached To
Mode
D34482: pf: support basic L3 filtering in the Ethernet rules
Attached
Detach File
Event Timeline
Log In to Comment