PERFORCE change 145768 for review
Gleb Kurtsou
gk at FreeBSD.org
Thu Jul 24 08:11:33 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145768
Change 145768 by gk at gk_h1 on 2008/07/24 08:11:07
make PF_MISMATCHAW work as expected
fix src and dst address selection in stateful filtering
add support for ethernet addresses in table entries
Affected files ...
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pf_print_state.c#4 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl.h#4 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_parser.c#4 edit
.. //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_table.c#2 edit
.. //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf.c#6 edit
.. //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf_table.c#2 edit
.. //depot/projects/soc2008/gk_l2filter/sys-pf/net/pfvar.h#5 edit
Differences ...
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pf_print_state.c#4 (text+ko) ====
@@ -50,7 +50,6 @@
#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)
@@ -124,7 +123,7 @@
print_addr_ether(&addr->v.a.addr_ether, verbose);
}
-static void
+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#4 (text+ko) ====
@@ -117,6 +117,7 @@
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#4 (text+ko) ====
@@ -1425,6 +1425,10 @@
struct pf_addr_ether *addr;
struct node_host *h = NULL;
+ if (strcmp(s, "any") == 0) {
+ return (NULL);
+ }
+
h = calloc(1, sizeof(*h));
if (h == NULL)
err(1, "host_ether: malloc");
@@ -1632,16 +1636,37 @@
int
append_addr(struct pfr_buffer *b, char *s, int test)
{
- char *r;
+ char *r, *rs, *p;
struct node_host *h, *n;
+ struct pf_addr_ether addr_ether;
int rv, not = 0;
for (r = s; *r == '!'; r++)
not = !not;
- if ((n = host(r)) == NULL) {
+ if ((rs = strdup(r)) == NULL)
+ err(1, "append_addr: strdup");
+ bzero(&addr_ether, sizeof (addr_ether));
+ if ((p = strstr(rs, "ether")) != NULL) {
+ char *s_ether = p + strlen("ether");
+ if (p > rs && isspace(*(p - 1)) && isspace(*s_ether++)) {
+ while (isspace(*s_ether))
+ s_ether++;
+ h = host_ether(s_ether);
+ if (h) {
+ addr_ether = h->addr.v.a.addr_ether;
+ free(h);
+ h = NULL;
+ }
+ for (p--; p >= rs && isspace(*p); p--)
+ *p = 0;
+ }
+ }
+ if ((n = host(rs)) == NULL) {
errno = 0;
return (-1);
}
+ n->addr.v.a.addr_ether = addr_ether;
+ free(rs);
rv = append_addr_host(b, n, test, not);
do {
h = n;
@@ -1687,6 +1712,7 @@
errno = EINVAL;
return (-1);
}
+ addr.pfra_ether = n->addr.v.a.addr_ether;
if (pfr_buf_add(b, &addr))
return (-1);
} while ((n = n->next) != NULL);
==== //depot/projects/soc2008/gk_l2filter/sbin-pfctl/pfctl_table.c#2 (text+ko) ====
@@ -438,6 +438,7 @@
printf("%c %c%s", ch, (ad->pfra_not?'!':' '), buf);
if (ad->pfra_net < hostnet)
printf("/%d", ad->pfra_net);
+ print_addr_ether(&ad->pfra_ether, 0);
if (rad != NULL && fback != PFR_FB_NONE) {
if (strlcpy(buf, "{error}", sizeof(buf)) >= sizeof(buf))
errx(1, "print_addrx: strlcpy");
==== //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf.c#6 (text+ko) ====
@@ -706,12 +706,12 @@
{
struct pf_addr_ether *src, *dst;
- if (state->direction == PF_OUT) {
- src = &state->gwy.addr_ether;
+ if (direction == PF_IN) {
+ src = &state->ext.addr_ether;
+ dst = &state->gwy.addr_ether;
+ } else {
+ src = &state->lan.addr_ether;
dst = &state->ext.addr_ether;
- } else {
- dst = &state->lan.addr_ether;
- src = &state->ext.addr_ether;
}
if (pf_match_addr_ether(src, &pd->src_ether, 1) &&
==== //depot/projects/soc2008/gk_l2filter/sys-pf/net/pf_table.c#2 (text+ko) ====
@@ -917,6 +917,7 @@
ke->pfrke_net = ad->pfra_net;
ke->pfrke_not = ad->pfra_not;
ke->pfrke_intrpool = intr;
+ ke->pfrke_ether = ad->pfra_ether;
return (ke);
}
@@ -1145,6 +1146,7 @@
ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
else if (ad->pfra_af == AF_INET6)
ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
+ ad->pfra_ether = ke->pfrke_ether;
}
int
@@ -2089,6 +2091,12 @@
int
pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
{
+ return pfr_match_addr_ether(kt, a, af, NULL);
+}
+
+int
+pfr_match_addr_ether(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af, struct pf_addr_ether *ae)
+{
struct pfr_kentry *ke = NULL;
int match;
@@ -2115,7 +2123,10 @@
break;
#endif /* INET6 */
}
- match = (ke && !ke->pfrke_not);
+ match = (ke != NULL);
+ if (match && ae)
+ match = pf_match_addr_ether(&ke->pfrke_ether, ae, 0);
+ match = (match && !ke->pfrke_not);
if (match)
kt->pfrkt_match++;
else
==== //depot/projects/soc2008/gk_l2filter/sys-pf/net/pfvar.h#5 (text+ko) ====
@@ -419,15 +419,16 @@
((aw)->type == PF_ADDR_RTLABEL && \
!pf_rtlabel_match((x), (af), (aw))) || \
((aw)->type == PF_ADDR_TABLE && \
- !pfr_match_addr((aw)->p.tbl, (x), (af))) || \
+ !pfr_match_addr_ether((aw)->p.tbl, (x), \
+ (af), (xl2))) || \
((aw)->type == PF_ADDR_DYNIFTL && \
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
((aw)->type == PF_ADDR_ADDRMASK && \
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
- !PF_MATCHA(0, &(aw)->v.a.addr, \
+ !(PF_MATCHA(0, &(aw)->v.a.addr, \
&(aw)->v.a.mask, (x), (af)) && \
- !pf_match_addr_ether(&(aw)->v.a.addr_ether, \
- xl2, 0)))) != \
+ pf_match_addr_ether(&(aw)->v.a.addr_ether, \
+ (xl2), 0))))) != \
(neg) \
)
@@ -918,6 +919,7 @@
u_int8_t pfra_net;
u_int8_t pfra_not;
u_int8_t pfra_fback;
+ struct pf_addr_ether pfra_ether;
};
#define pfra_ip4addr pfra_u._pfra_ip4addr
#define pfra_ip6addr pfra_u._pfra_ip6addr
@@ -961,6 +963,7 @@
struct pfr_kentry {
struct radix_node pfrke_node[2];
union sockaddr_union pfrke_sa;
+ struct pf_addr_ether pfrke_ether;
u_int64_t pfrke_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
u_int64_t pfrke_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
SLIST_ENTRY(pfr_kentry) pfrke_workq;
@@ -1701,6 +1704,7 @@
#endif
void pfr_initialize(void);
int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
+int pfr_match_addr_ether(struct pfr_ktable *, struct pf_addr *, sa_family_t, struct pf_addr_ether *);
void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
u_int64_t, int, int, int);
int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
More information about the p4-projects
mailing list