[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pf match on route labels



clean some bitrot from my hdd - let pf match on route labels

pass from route "foo"
block to route "bar"

etc

please test and comment...

Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.463
diff -u -p -r1.463 pf.c
--- sys/net/pf.c	19 Nov 2004 18:20:10 -0000	1.463
+++ sys/net/pf.c	23 Nov 2004 13:33:25 -0000
@@ -4959,6 +4959,49 @@ pf_routable(struct pf_addr *addr, sa_fam
 	return (0);
 }
 
+int
+pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
+{
+	struct sockaddr_in	*dst;
+#ifdef INET6
+	struct sockaddr_in6	*dst6;
+	struct route_in6	 ro;
+#else
+	struct route		 ro;
+#endif
+	int			 ret = 0;
+
+	bzero(&ro, sizeof(ro));
+	switch (af) {
+	case AF_INET:
+		dst = satosin(&ro.ro_dst);
+		dst->sin_family = AF_INET;
+		dst->sin_len = sizeof(*dst);
+		dst->sin_addr = addr->v4;
+		break;
+#ifdef INET6
+	case AF_INET6:
+		dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
+		dst6->sin6_family = AF_INET6;
+		dst6->sin6_len = sizeof(*dst6);
+		dst6->sin6_addr = addr->v6;
+		break;
+#endif /* INET6 */
+	default:
+		return (0);
+	}
+
+	rtalloc_noclone((struct route *)&ro, NO_CLONING);
+
+	if (ro.ro_rt != NULL) {
+		if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
+			ret = 1;
+		RTFREE(ro.ro_rt);
+	}
+
+	return (ret);
+}
+
 #ifdef INET
 void
 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
Index: sys/net/pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.131
diff -u -p -r1.131 pf_ioctl.c
--- sys/net/pf_ioctl.c	21 Sep 2004 16:59:12 -0000	1.131
+++ sys/net/pf_ioctl.c	23 Nov 2004 13:33:26 -0000
@@ -121,6 +121,9 @@ TAILQ_HEAD(pf_tags, pf_tagname)	pf_tags 
 static u_int16_t	 tagname2tag(struct pf_tags *, char *);
 static void		 tag2tagname(struct pf_tags *, u_int16_t, char *);
 static void		 tag_unref(struct pf_tags *, u_int16_t);
+int			 pf_rtlabel_add(struct pf_addr_wrap *);
+void			 pf_rtlabel_remove(struct pf_addr_wrap *);
+void			 pf_rtlabel_copyout(struct pf_addr_wrap *);
 
 #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
 
@@ -591,6 +594,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeu
 		pf_qid_unref(rule->pqid);
 	pf_qid_unref(rule->qid);
 #endif
+	pf_rtlabel_remove(&rule->src.addr);
+	pf_rtlabel_remove(&rule->dst.addr);
 	pfi_dynaddr_remove(&rule->src.addr);
 	pfi_dynaddr_remove(&rule->dst.addr);
 	if (rulequeue == NULL) {
@@ -698,6 +703,37 @@ pf_tag_unref(u_int16_t tag)
 	return (tag_unref(&pf_tags, tag));
 }
 
+int
+pf_rtlabel_add(struct pf_addr_wrap *a)
+{
+	if (a->type == PF_ADDR_RTLABEL &&
+	    (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
+		return (-1);
+	return (0);
+}
+
+void
+pf_rtlabel_remove(struct pf_addr_wrap *a)
+{
+	if (a->type == PF_ADDR_RTLABEL)
+		rtlabel_unref(a->v.rtlabel);
+}
+
+void
+pf_rtlabel_copyout(struct pf_addr_wrap *a)
+{
+	const char	*name;
+
+	if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
+		if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
+			strlcpy(a->v.rtlabelname, "?",
+			    sizeof(a->v.rtlabelname));
+		else
+			strlcpy(a->v.rtlabelname, name,
+			    sizeof(a->v.rtlabelname));
+	}
+}
+
 #ifdef ALTQ
 u_int32_t
 pf_qname2qid(char *qname)
@@ -1163,6 +1199,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 				error = EBUSY;
 		if (rule->rt && !rule->direction)
 			error = EINVAL;
+		if (pf_rtlabel_add(&rule->src.addr) ||
+		    pf_rtlabel_add(&rule->dst.addr))
+			error = EBUSY;
 		if (pfi_dynaddr_setup(&rule->src.addr, rule->af))
 			error = EINVAL;
 		if (pfi_dynaddr_setup(&rule->dst.addr, rule->af))
@@ -1264,6 +1303,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 		pfi_dynaddr_copyout(&pr->rule.dst.addr);
 		pf_tbladdr_copyout(&pr->rule.src.addr);
 		pf_tbladdr_copyout(&pr->rule.dst.addr);
+		pf_rtlabel_copyout(&pr->rule.src.addr);
+		pf_rtlabel_copyout(&pr->rule.dst.addr);
 		for (i = 0; i < PF_SKIP_COUNT; ++i)
 			if (rule->skip[i].ptr == NULL)
 				pr->rule.skip[i].nr = -1;
@@ -1376,9 +1417,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 				if ((newrule->match_tag = pf_tagname2tag(
 				    newrule->match_tagname)) == 0)
 					error = EBUSY;
-
 			if (newrule->rt && !newrule->direction)
 				error = EINVAL;
+			if (pf_rtlabel_add(&newrule->src.addr) ||
+			    pf_rtlabel_add(&newrule->dst.addr))
+				error = EBUSY;
 			if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af))
 				error = EINVAL;
 			if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af))
@@ -2083,6 +2126,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 		bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
 		pfi_dynaddr_copyout(&pp->addr.addr);
 		pf_tbladdr_copyout(&pp->addr.addr);
+		pf_rtlabel_copyout(&pp->addr.addr);
 		splx(s);
 		break;
 	}
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.204
diff -u -p -r1.204 pfvar.h
--- sys/net/pfvar.h	16 Nov 2004 20:07:57 -0000	1.204
+++ sys/net/pfvar.h	23 Nov 2004 13:33:27 -0000
@@ -39,6 +39,7 @@
 #include <sys/tree.h>
 
 #include <net/radix.h>
+#include <net/route.h>
 #include <netinet/ip_ipsp.h>
 #include <netinet/tcp_fsm.h>
 
@@ -77,7 +78,7 @@ enum	{ PF_LIMIT_STATES, PF_LIMIT_SRC_NOD
 enum	{ PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
 	  PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
 enum	{ PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
-	  PF_ADDR_TABLE };
+	  PF_ADDR_TABLE, PF_ADDR_RTLABEL };
 #define PF_POOL_TYPEMASK	0x0f
 #define PF_POOL_STICKYADDR	0x20
 #define	PF_WSCALE_FLAG		0x80
@@ -114,6 +115,8 @@ struct pf_addr_wrap {
 		}			 a;
 		char			 ifname[IFNAMSIZ];
 		char			 tblname[PF_TABLE_NAME_SIZE];
+		char			 rtlabelname[RTLABEL_LEN];
+		u_int32_t		 rtlabel;
 	}			 v;
 	union {
 		struct pfi_dynaddr	*dyn;
@@ -279,6 +282,9 @@ struct pfi_dynaddr {
 	(							\
 		(((aw)->type == PF_ADDR_NOROUTE &&		\
 		    pf_routable((x), (af))) ||			\
+		((aw)->type == PF_ADDR_RTLABEL &&		\
+		    pf_rtlabel_match((x), (af), (aw))) !=	\
+		    (neg) ||					\
 		((aw)->type == PF_ADDR_TABLE &&			\
 		    !pfr_match_addr((aw)->p.tbl, (x), (af))) ||	\
 		((aw)->type == PF_ADDR_DYNIFTL &&		\
@@ -1381,6 +1387,7 @@ u_int32_t
 	pf_state_expires(const struct pf_state *);
 void	pf_purge_expired_fragments(void);
 int	pf_routable(struct pf_addr *addr, sa_family_t af);
+int	pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *);
 void	pfr_initialize(void);
 int	pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
 void	pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.460
diff -u -p -r1.460 parse.y
--- sbin/pfctl/parse.y	21 Sep 2004 16:59:11 -0000	1.460
+++ sbin/pfctl/parse.y	23 Nov 2004 13:33:29 -0000
@@ -393,7 +393,7 @@ typedef struct {
 %token	QUEUE PRIORITY QLIMIT
 %token	LOAD
 %token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
-%token	TAGGED TAG IFBOUND GRBOUND FLOATING STATEPOLICY
+%token	TAGGED TAG IFBOUND GRBOUND FLOATING STATEPOLICY ROUTE
 %token	<v.string>		STRING
 %token	<v.i>			PORTBINARY
 %type	<v.interface>		interface if_list if_item_not if_item
@@ -2164,6 +2164,21 @@ host		: STRING			{
 			$$->next = NULL;
 			$$->tail = $$;
 		}
+		| ROUTE	STRING		{
+			$$ = calloc(1, sizeof(struct node_host));
+			if ($$ == NULL)
+				err(1, "host: calloc");
+			$$->addr.type = PF_ADDR_RTLABEL;
+			if (strlcpy($$->addr.v.rtlabelname, $2,
+			    sizeof($$->addr.v.rtlabelname)) >=
+			    sizeof($$->addr.v.rtlabelname)) {
+				yyerror("route label too long, max %u chars",
+				    sizeof($$->addr.v.rtlabelname) - 1);
+				YYERROR;
+			}
+			$$->next = NULL;
+			$$->tail = $$;
+		}
 		;
 
 number		: STRING			{
@@ -4400,6 +4415,7 @@ lookup(char *s)
 		{ "return-icmp6",	RETURNICMP6},
 		{ "return-rst",		RETURNRST},
 		{ "round-robin",	ROUNDROBIN},
+		{ "route",		ROUTE},
 		{ "route-to",		ROUTETO},
 		{ "rule",		RULE},
 		{ "scrub",		SCRUB},
Index: sbin/pfctl/pf_print_state.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pf_print_state.c,v
retrieving revision 1.39
diff -u -p -r1.39 pf_print_state.c
--- sbin/pfctl/pf_print_state.c	10 Feb 2004 17:48:08 -0000	1.39
+++ sbin/pfctl/pf_print_state.c	23 Nov 2004 13:33:29 -0000
@@ -96,6 +96,9 @@ print_addr(struct pf_addr_wrap *addr, sa
 	case PF_ADDR_NOROUTE:
 		printf("no-route");
 		return;
+	case PF_ADDR_RTLABEL:
+		printf("route \"%s\"", addr->v.rtlabelname);
+		return;
 	default:
 		printf("?");
 		return;



Visit your host, monkey.org