Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Jul 2008 08:11:33 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 145768 for review
Message-ID:  <200807240811.m6O8BXht005107@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 *,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807240811.m6O8BXht005107>