PERFORCE change 145552 for review
Gleb Kurtsou
gk at FreeBSD.org
Mon Jul 21 10:11:39 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145552
Change 145552 by gk at gk_h1 on 2008/07/21 10:11:02
save ethernet address in pf_addr_wrap.
improve stateful filtering: check against ether addresses from packet
but not from rule created the state.
extend PF_MISMATCHAW to support ethernet addresses: PF_MISMATCHAW_L2.
nuke now unused pf_rule_match_addr_ether.
Affected files ...
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/parse.y#3 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pf_print_state.c#3 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl.h#3 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_parser.c#3 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_parser.h#3 edit
.. //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf.c#4 edit
.. //depot/projects/soc2008/gk_l2filter/sys-pf/net/pfvar.h#4 edit
Differences ...
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/parse.y#3 (text+ko) ====
@@ -2483,7 +2483,7 @@
n->not = $1;
$$ = $2;
if ($3) {
- $$->addr_ether = $3->addr_ether;
+ $$->addr.v.a.addr_ether = $3->addr.v.a.addr_ether;
free($3);
}
}
@@ -4732,13 +4732,11 @@
r->ifnot = interface->not;
r->proto = proto->proto;
r->src.addr = src_host->addr;
- r->src.addr_ether = src_host->addr_ether;
r->src.neg = src_host->not;
r->src.port[0] = src_port->port[0];
r->src.port[1] = src_port->port[1];
r->src.port_op = src_port->op;
r->dst.addr = dst_host->addr;
- r->dst.addr_ether = dst_host->addr_ether;
r->dst.neg = dst_host->not;
r->dst.port[0] = dst_port->port[0];
r->dst.port[1] = dst_port->port[1];
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pf_print_state.c#3 (text+ko) ====
@@ -50,6 +50,7 @@
#include "pfctl.h"
void print_name(struct pf_addr *, sa_family_t);
+static void print_addr_ether(struct pf_addr_ether *, int );
void
print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
@@ -119,9 +120,11 @@
if (bits != (af == AF_INET ? 32 : 128))
printf("/%d", bits);
}
+
+ print_addr_ether(&addr->v.a.addr_ether, verbose);
}
-void
+static void
print_addr_ether(struct pf_addr_ether *addr, int verbose)
{
if ((addr->flags & PFAE_CHECK) == 0)
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl.h#3 (text+ko) ====
@@ -117,7 +117,6 @@
char *rate2str(double);
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
-void print_addr_ether(struct pf_addr_ether *, int);
void print_host(struct pf_state_host *, sa_family_t, int);
void print_seq(struct pf_state_peer *);
void print_state(struct pf_state *, int);
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_parser.c#3 (text+ko) ====
@@ -382,7 +382,6 @@
if (src->neg)
printf("! ");
print_addr(&src->addr, af, verbose);
- print_addr_ether(&src->addr_ether, verbose);
if (src->port_op)
print_port(src->port_op, src->port[0],
src->port[1],
@@ -395,7 +394,6 @@
if (dst->neg)
printf("! ");
print_addr(&dst->addr, af, verbose);
- print_addr_ether(&dst->addr_ether, verbose);
if (dst->port_op)
print_port(dst->port_op, dst->port[0],
dst->port[1],
@@ -1424,24 +1422,24 @@
struct node_host *
host_ether(const char *s)
{
- struct ether_addr addr;
+ struct pf_addr_ether *addr;
struct node_host *h = NULL;
h = calloc(1, sizeof(*h));
if (h == NULL)
err(1, "host_ether: malloc");
+ addr = &h->addr.v.a.addr_ether;
if (strcmp(s, "multicast") == 0) {
- h->addr_ether.flags = PFAE_CHECK | PFAE_MULTICAST;
+ addr->flags = PFAE_CHECK | PFAE_MULTICAST;
return (h);
}
- if (!ether_aton_r(s, &addr)) {
+ if (!ether_aton_r(s, (struct ether_addr*)addr->octet)) {
fprintf(stderr, "can't parse ethernet address: %s\n", s);
free(h);
return (NULL);
}
- memcpy(h->addr_ether.octet, addr.octet, ETHER_ADDR_LEN);
- h->addr_ether.flags = PFAE_CHECK;
+ addr->flags = PFAE_CHECK;
return (h);
}
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_parser.h#3 (text+ko) ====
@@ -112,7 +112,6 @@
struct node_host {
struct pf_addr_wrap addr;
- struct pf_addr_ether addr_ether;
struct pf_addr bcast;
struct pf_addr peer;
sa_family_t af;
==== //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf.c#4 (text+ko) ====
@@ -702,49 +702,16 @@
}
static __inline int
-pf_match_addr_ether(struct pf_addr_ether *want, struct pf_addr_ether *a, int match_empty)
-{
- static struct pf_addr_ether mask = {
- .octet = { 0xff, 0xff, 0xff, 0xff, 0xff,0xff },
- .flags = 0
- };
- if ((want->flags & PFAE_CHECK) == 0)
- return (1);
- if ((a->flags & PFAE_CHECK) == 0)
- return (match_empty);
- if (want->flags & PFAE_MULTICAST) {
- return (ETHER_IS_MULTICAST(a->octet));
- }
-
-#define EA_CMP(x) (*((u_int64_t*)(x)) & *((u_int64_t*)&mask))
- return (EA_CMP(want) == EA_CMP(a));
-#undef EA_CMP
-}
-
-static __inline int
-pf_rule_match_addr_ether(struct pf_rule *r, struct pf_pdesc *pd)
-{
- if (pf_match_addr_ether(&r->src.addr_ether, &pd->src_ether, 0) &&
- pf_match_addr_ether(&r->dst.addr_ether, &pd->dst_ether, 0))
- return (1);
-
- return (0);
-}
-
-static __inline int
pf_state_match_addr_ether(struct pf_state *state, struct pf_pdesc *pd, int direction)
{
- struct pf_rule *r;
struct pf_addr_ether *src, *dst;
- r = state->rule.ptr;
-
- if (direction == state->direction) {
- src = &r->src.addr_ether;
- dst = &r->dst.addr_ether;
+ if (state->direction == PF_OUT) {
+ src = &state->gwy.addr_ether;
+ dst = &state->ext.addr_ether;
} else {
- src = &r->dst.addr_ether;
- dst = &r->src.addr_ether;
+ dst = &state->lan.addr_ether;
+ src = &state->ext.addr_ether;
}
if (pf_match_addr_ether(src, &pd->src_ether, 1) &&
@@ -2161,6 +2128,26 @@
}
int
+pf_match_addr_ether(struct pf_addr_ether *want, struct pf_addr_ether *a, int match_empty)
+{
+ static struct pf_addr_ether mask = {
+ .octet = { 0xff, 0xff, 0xff, 0xff, 0xff,0xff },
+ .flags = 0
+ };
+ if (want == NULL || (want->flags & PFAE_CHECK) == 0)
+ return (1);
+ if (a == NULL || (a->flags & PFAE_CHECK) == 0)
+ return (match_empty);
+
+ if (want->flags & PFAE_MULTICAST) {
+ return (ETHER_IS_MULTICAST(a->octet));
+ }
+#define EA_CMP(x) (*((u_int64_t*)(x)) & *((u_int64_t*)&mask))
+ return (EA_CMP(want) == EA_CMP(a));
+#undef EA_CMP
+}
+
+int
pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
{
switch (op) {
@@ -3368,14 +3355,14 @@
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != IPPROTO_TCP)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
- r->src.neg, kif))
+ else if (PF_MISMATCHAW_L2(&r->src.addr, saddr, &pd->src_ether,
+ af, r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
- r->dst.neg, NULL))
+ else if (PF_MISMATCHAW_L2(&r->dst.addr, daddr, &pd->dst_ether,
+ af, r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
@@ -3411,8 +3398,6 @@
else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
r = TAILQ_NEXT(r, entries);
- else if (!pf_rule_match_addr_ether(r, pd))
- r = TAILQ_NEXT(r, entries);
else {
if (r->tag)
tag = r->tag;
@@ -3564,8 +3549,10 @@
if (direction == PF_OUT) {
PF_ACPY(&s->gwy.addr, saddr, af);
s->gwy.port = th->th_sport; /* sport */
+ s->gwy.addr_ether = pd->src_ether;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = th->th_dport;
+ s->ext.addr_ether = pd->dst_ether;
if (nr != NULL) {
PF_ACPY(&s->lan.addr, &pd->baddr, af);
s->lan.port = bport;
@@ -3576,8 +3563,10 @@
} else {
PF_ACPY(&s->lan.addr, daddr, af);
s->lan.port = th->th_dport;
+ s->lan.addr_ether = pd->dst_ether;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = th->th_sport;
+ s->ext.addr_ether = pd->src_ether;
if (nr != NULL) {
PF_ACPY(&s->gwy.addr, &pd->baddr, af);
s->gwy.port = bport;
@@ -3792,14 +3781,14 @@
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != IPPROTO_UDP)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
- r->src.neg, kif))
+ else if (PF_MISMATCHAW_L2(&r->src.addr, saddr, &pd->src_ether,
+ af, r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], uh->uh_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
- r->dst.neg, NULL))
+ else if (PF_MISMATCHAW_L2(&r->dst.addr, daddr, &pd->dst_ether,
+ af, r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], uh->uh_dport))
@@ -3832,8 +3821,6 @@
r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY)
r = TAILQ_NEXT(r, entries);
- else if (!pf_rule_match_addr_ether(r, pd))
- r = TAILQ_NEXT(r, entries);
else {
if (r->tag)
tag = r->tag;
@@ -3963,8 +3950,10 @@
if (direction == PF_OUT) {
PF_ACPY(&s->gwy.addr, saddr, af);
s->gwy.port = uh->uh_sport;
+ s->gwy.addr_ether = pd->src_ether;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = uh->uh_dport;
+ s->ext.addr_ether = pd->dst_ether;
if (nr != NULL) {
PF_ACPY(&s->lan.addr, &pd->baddr, af);
s->lan.port = bport;
@@ -3975,8 +3964,10 @@
} else {
PF_ACPY(&s->lan.addr, daddr, af);
s->lan.port = uh->uh_dport;
+ s->lan.addr_ether = pd->dst_ether;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = uh->uh_sport;
+ s->ext.addr_ether = pd->src_ether;
if (nr != NULL) {
PF_ACPY(&s->gwy.addr, &pd->baddr, af);
s->gwy.port = bport;
@@ -4151,11 +4142,11 @@
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
- r->src.neg, kif))
+ else if (PF_MISMATCHAW_L2(&r->src.addr, saddr, &pd->src_ether,
+ af, r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
- r->dst.neg, NULL))
+ else if (PF_MISMATCHAW_L2(&r->dst.addr, daddr, &pd->dst_ether,
+ af, r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->type && r->type != icmptype + 1)
r = TAILQ_NEXT(r, entries);
@@ -4171,8 +4162,6 @@
r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY)
r = TAILQ_NEXT(r, entries);
- else if (!pf_rule_match_addr_ether(r, pd))
- r = TAILQ_NEXT(r, entries);
else {
if (r->tag)
tag = r->tag;
@@ -4278,8 +4267,10 @@
if (direction == PF_OUT) {
PF_ACPY(&s->gwy.addr, saddr, af);
s->gwy.port = nport;
+ s->gwy.addr_ether = pd->src_ether;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = 0;
+ s->ext.addr_ether = pd->dst_ether;
if (nr != NULL) {
PF_ACPY(&s->lan.addr, &pd->baddr, af);
s->lan.port = bport;
@@ -4290,8 +4281,10 @@
} else {
PF_ACPY(&s->lan.addr, daddr, af);
s->lan.port = nport;
+ s->lan.addr_ether = pd->dst_ether;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = 0;
+ s->ext.addr_ether = pd->src_ether;
if (nr != NULL) {
PF_ACPY(&s->gwy.addr, &pd->baddr, af);
s->gwy.port = bport;
@@ -4416,11 +4409,11 @@
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
- r->src.neg, kif))
+ else if (PF_MISMATCHAW_L2(&r->src.addr, pd->src, &pd->src_ether,
+ af, r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
- r->dst.neg, NULL))
+ else if (PF_MISMATCHAW_L2(&r->dst.addr, pd->dst, &pd->dst_ether,
+ af, r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->tos && !(r->tos == pd->tos))
r = TAILQ_NEXT(r, entries);
@@ -4432,8 +4425,6 @@
r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY)
r = TAILQ_NEXT(r, entries);
- else if (!pf_rule_match_addr_ether(r, pd))
- r = TAILQ_NEXT(r, entries);
else {
if (r->tag)
tag = r->tag;
@@ -4566,14 +4557,18 @@
s->af = af;
if (direction == PF_OUT) {
PF_ACPY(&s->gwy.addr, saddr, af);
+ s->gwy.addr_ether = pd->src_ether;
PF_ACPY(&s->ext.addr, daddr, af);
+ s->ext.addr_ether = pd->dst_ether;
if (nr != NULL)
PF_ACPY(&s->lan.addr, &pd->baddr, af);
else
PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
} else {
PF_ACPY(&s->lan.addr, daddr, af);
+ s->lan.addr_ether = pd->dst_ether;
PF_ACPY(&s->ext.addr, saddr, af);
+ s->ext.addr_ether = pd->src_ether;
if (nr != NULL)
PF_ACPY(&s->gwy.addr, &pd->baddr, af);
else
@@ -4635,11 +4630,11 @@
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
- r->src.neg, kif))
+ else if (PF_MISMATCHAW_L2(&r->src.addr, pd->src, &pd->src_ether,
+ af, r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
- r->dst.neg, NULL))
+ else if (PF_MISMATCHAW_L2(&r->dst.addr, pd->dst, &pd->dst_ether,
+ af, r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->tos && !(r->tos == pd->tos))
r = TAILQ_NEXT(r, entries);
@@ -4659,8 +4654,6 @@
r = TAILQ_NEXT(r, entries);
else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
r = TAILQ_NEXT(r, entries);
- else if (!pf_rule_match_addr_ether(r, pd))
- r = TAILQ_NEXT(r, entries);
else {
if (r->anchor == NULL) {
match = 1;
==== //depot/projects/soc2008/gk_l2filter/sys-pf/net/pfvar.h#4 (text+ko) ====
@@ -178,6 +178,7 @@
struct {
struct pf_addr addr;
struct pf_addr mask;
+ struct pf_addr_ether addr_ether;
} a;
char ifname[IFNAMSIZ];
char tblname[PF_TABLE_NAME_SIZE];
@@ -409,7 +410,7 @@
#endif /* PF_INET6_ONLY */
#endif /* PF_INET_INET6 */
-#define PF_MISMATCHAW(aw, x, af, neg, ifp) \
+#define PF_MISMATCHAW_L2(aw, x, xl2, af, neg, ifp) \
( \
(((aw)->type == PF_ADDR_NOROUTE && \
pf_routable((x), (af), NULL)) || \
@@ -424,11 +425,16 @@
((aw)->type == PF_ADDR_ADDRMASK && \
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
!PF_MATCHA(0, &(aw)->v.a.addr, \
- &(aw)->v.a.mask, (x), (af))))) != \
+ &(aw)->v.a.mask, (x), (af)) && \
+ !pf_match_addr_ether(&(aw)->v.a.addr_ether, \
+ xl2, 0)))) != \
(neg) \
)
+#define PF_MISMATCHAW(aw, x, af, neg, ifp) \
+ PF_MISMATCHAW_L2(aw, x, NULL, af, neg, ifp)
+
struct pf_rule_uid {
uid_t uid[2];
u_int8_t op;
@@ -444,7 +450,6 @@
u_int16_t port[2];
u_int8_t neg;
u_int8_t port_op;
- struct pf_addr_ether addr_ether;
};
struct pf_pooladdr {
@@ -761,6 +766,8 @@
struct pf_state_host {
struct pf_addr addr;
+ struct pf_addr_ether
+ addr_ether;
u_int16_t port;
u_int16_t pad;
};
@@ -1663,6 +1670,7 @@
struct pf_pdesc *);
int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
struct pf_addr *, sa_family_t);
+int pf_match_addr_ether(struct pf_addr_ether *, struct pf_addr_ether *, int);
int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);
More information about the p4-projects
mailing list