From owner-p4-projects@FreeBSD.ORG Thu Jul 24 08:11:33 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 834311065672; Thu, 24 Jul 2008 08:11:33 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 44E6E106566C for ; Thu, 24 Jul 2008 08:11:33 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 134D18FC08 for ; Thu, 24 Jul 2008 08:11:33 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m6O8BXSV005109 for ; Thu, 24 Jul 2008 08:11:33 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6O8BXht005107 for perforce@freebsd.org; Thu, 24 Jul 2008 08:11:33 GMT (envelope-from gk@FreeBSD.org) Date: Thu, 24 Jul 2008 08:11:33 GMT Message-Id: <200807240811.m6O8BXht005107@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Cc: Subject: PERFORCE change 145768 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Jul 2008 08:11:33 -0000 http://perforce.freebsd.org/chv.cgi?CH=145768 Change 145768 by gk@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 *,