summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2014-08-25 15:49:41 +0000
committerglebius <glebius@FreeBSD.org>2014-08-25 15:49:41 +0000
commitdbdbc550bee655a838b53b1473548aef324b33b6 (patch)
tree89e7e7a9bf9c478a54be77511cee8b7199e444f2 /sys/netpfil
parent59e5a700b1e4de81862182bd63cf0ce0e81172d1 (diff)
downloadFreeBSD-src-dbdbc550bee655a838b53b1473548aef324b33b6.zip
FreeBSD-src-dbdbc550bee655a838b53b1473548aef324b33b6.tar.gz
Merge r270022 from head:
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
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/pf/pf.c41
-rw-r--r--sys/netpfil/pf/pf.h4
2 files changed, 16 insertions, 29 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index a3442ea..256204e 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -265,8 +265,6 @@ static u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
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 *,
@@ -2960,31 +2958,6 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
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)
{
@@ -3547,6 +3520,19 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
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;
@@ -3612,7 +3598,6 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
} 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)) ==
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
index 3ea66d3..630cd3f 100644
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -125,7 +125,8 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
#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", \
@@ -143,6 +144,7 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
"state-limit", \
"src-limit", \
"synproxy", \
+ "map-failed", \
NULL \
}
OpenPOWER on IntegriCloud