svn commit: r270022 - head/sys/netpfil/pf

Gleb Smirnoff glebius at FreeBSD.org
Fri Aug 15 14:02:25 UTC 2014


Author: glebius
Date: Fri Aug 15 14:02:24 2014
New Revision: 270022
URL: http://svnweb.freebsd.org/changeset/base/270022

Log:
  pf_map_addr() can fail and in this case we should drop the packet,
  otherwise bad consequences including a routing loop can occur.
  
  Move pf_set_rt_ifp() earlier in state creation sequence and
  inline it, cutting some extra code.
  
  PR:		183997
  Submitted by:	Kajetan Staszkiewicz <vegeta tuxpowered.net>
  Sponsored by:	InnoGames GmbH

Modified:
  head/sys/netpfil/pf/pf.c
  head/sys/netpfil/pf/pf.h

Modified: head/sys/netpfil/pf/pf.c
==============================================================================
--- head/sys/netpfil/pf/pf.c	Fri Aug 15 12:58:32 2014	(r270021)
+++ head/sys/netpfil/pf/pf.c	Fri Aug 15 14:02:24 2014	(r270022)
@@ -266,8 +266,6 @@ static u_int16_t	 pf_get_mss(struct mbuf
 			    sa_family_t);
 static u_int16_t	 pf_calc_mss(struct pf_addr *, sa_family_t,
 				int, u_int16_t);
-static void		 pf_set_rt_ifp(struct pf_state *,
-			    struct pf_addr *);
 static int		 pf_check_proto_cksum(struct mbuf *, int, int,
 			    u_int8_t, sa_family_t);
 static void		 pf_print_state_parts(struct pf_state *,
@@ -2957,31 +2955,6 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
 	return (mss);
 }
 
-static void
-pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
-{
-	struct pf_rule *r = s->rule.ptr;
-	struct pf_src_node *sn = NULL;
-
-	s->rt_kif = NULL;
-	if (!r->rt || r->rt == PF_FASTROUTE)
-		return;
-	switch (s->key[PF_SK_WIRE]->af) {
-#ifdef INET
-	case AF_INET:
-		pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn);
-		s->rt_kif = r->rpool.cur->kif;
-		break;
-#endif /* INET */
-#ifdef INET6
-	case AF_INET6:
-		pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn);
-		s->rt_kif = r->rpool.cur->kif;
-		break;
-#endif /* INET6 */
-	}
-}
-
 static u_int32_t
 pf_tcp_iss(struct pf_pdesc *pd)
 {
@@ -3544,6 +3517,19 @@ pf_create_state(struct pf_rule *r, struc
 		s->timeout = PFTM_OTHER_FIRST_PACKET;
 	}
 
+	if (r->rt && r->rt != PF_FASTROUTE) {
+		struct pf_src_node *sn = NULL;
+
+		if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
+			REASON_SET(&reason, PFRES_MAPFAILED);
+			pf_src_tree_remove_state(s);
+			STATE_DEC_COUNTERS(s);
+			uma_zfree(V_pf_state_z, s);
+			goto csfailed;
+		}
+		s->rt_kif = r->rpool.cur->kif;
+	}
+
 	s->creation = time_uptime;
 	s->expire = time_uptime;
 
@@ -3609,7 +3595,6 @@ pf_create_state(struct pf_rule *r, struc
 	} else
 		*sm = s;
 
-	pf_set_rt_ifp(s, pd->src);	/* needs s->state_key set */
 	if (tag > 0)
 		s->tag = tag;
 	if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==

Modified: head/sys/netpfil/pf/pf.h
==============================================================================
--- head/sys/netpfil/pf/pf.h	Fri Aug 15 12:58:32 2014	(r270021)
+++ head/sys/netpfil/pf/pf.h	Fri Aug 15 14:02:24 2014	(r270022)
@@ -124,7 +124,8 @@ enum	{ PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE
 #define PFRES_MAXSTATES	12		/* State limit */
 #define PFRES_SRCLIMIT	13		/* Source node/conn limit */
 #define PFRES_SYNPROXY	14		/* SYN proxy */
-#define PFRES_MAX	15		/* total+1 */
+#define PFRES_MAPFAILED	15		/* pf_map_addr() failed */
+#define PFRES_MAX	16		/* total+1 */
 
 #define PFRES_NAMES { \
 	"match", \
@@ -142,6 +143,7 @@ enum	{ PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE
 	"state-limit", \
 	"src-limit", \
 	"synproxy", \
+	"map-failed", \
 	NULL \
 }
 


More information about the svn-src-head mailing list