aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil/pf/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netpfil/pf/pf.c')
-rw-r--r--sys/netpfil/pf/pf.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 127b29320acb..264830fcf534 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -327,7 +327,7 @@ int pf_change_icmp_af(struct mbuf *, int,
sa_family_t);
int pf_translate_icmp_af(int, void *);
static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
- int, sa_family_t, struct pf_krule *, int);
+ int, sa_family_t, int);
static void pf_detach_state(struct pf_kstate *);
static int pf_state_key_attach(struct pf_state_key *,
struct pf_state_key *, struct pf_kstate *);
@@ -4349,11 +4349,11 @@ pf_return(struct pf_krule *r, struct pf_krule *nr, struct pf_pdesc *pd,
} else if (pd->proto != IPPROTO_ICMP && pd->af == AF_INET &&
r->return_icmp)
pf_send_icmp(pd->m, r->return_icmp >> 8,
- r->return_icmp & 255, 0, pd->af, r, rtableid);
+ r->return_icmp & 255, 0, pd->af, rtableid);
else if (pd->proto != IPPROTO_ICMPV6 && pd->af == AF_INET6 &&
r->return_icmp6)
pf_send_icmp(pd->m, r->return_icmp6 >> 8,
- r->return_icmp6 & 255, 0, pd->af, r, rtableid);
+ r->return_icmp6 & 255, 0, pd->af, rtableid);
}
static int
@@ -4411,7 +4411,7 @@ pf_send_challenge_ack(struct pf_pdesc *pd, struct pf_kstate *s,
static void
pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, int mtu,
- sa_family_t af, struct pf_krule *r, int rtableid)
+ sa_family_t af, int rtableid)
{
struct pf_send_entry *pfse;
struct mbuf *m0;
@@ -4579,7 +4579,7 @@ pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
static int
pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
{
- if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
+ if (u == -1 && op != PF_OP_EQ && op != PF_OP_NE)
return (0);
return (pf_match(op, a1, a2, u));
}
@@ -4587,7 +4587,7 @@ pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
static int
pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
{
- if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
+ if (g == -1 && op != PF_OP_EQ && op != PF_OP_NE)
return (0);
return (pf_match(op, a1, a2, g));
}
@@ -4914,8 +4914,8 @@ pf_socket_lookup(struct pf_pdesc *pd)
struct inpcbinfo *pi;
struct inpcb *inp;
- pd->lookup.uid = UID_MAX;
- pd->lookup.gid = GID_MAX;
+ pd->lookup.uid = -1;
+ pd->lookup.gid = -1;
switch (pd->proto) {
case IPPROTO_TCP:
@@ -5901,18 +5901,17 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
M_SETFIB(pd->m, pd->act.rtableid);
if (r->rt) {
- struct pf_ksrc_node *sn = NULL;
- struct pf_srchash *snh = NULL;
/*
* Set act.rt here instead of in pf_rule_to_actions() because
* it is applied only from the last pass rule.
*/
pd->act.rt = r->rt;
- /* Don't use REASON_SET, pf_map_addr increases the reason counters */
- ctx.reason = pf_map_addr_sn(pd->af, r, pd->src, &pd->act.rt_addr,
- &pd->act.rt_kif, NULL, &sn, &snh, &(r->route), PF_SN_ROUTE);
- if (ctx.reason != 0)
+ if ((transerror = pf_map_addr_sn(pd->af, r, pd->src,
+ &pd->act.rt_addr, &pd->act.rt_kif, NULL, &(r->route),
+ PF_SN_ROUTE)) != PFRES_MATCH) {
+ REASON_SET(&ctx.reason, transerror);
goto cleanup;
+ }
}
if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
@@ -6056,9 +6055,16 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx,
/* src node for translation rule */
if (ctx->nr != NULL) {
KASSERT(ctx->nat_pool != NULL, ("%s: nat_pool is NULL", __func__));
+ /*
+ * The NAT addresses are chosen during ruleset parsing.
+ * The new afto code stores post-nat addresses in nsaddr.
+ * The old nat code (also used for new nat-to rules) creates
+ * state keys and stores addresses in them.
+ */
if ((ctx->nat_pool->opts & PF_POOL_STICKYADDR) &&
(sn_reason = pf_insert_src_node(sns, snhs, ctx->nr,
- &ctx->sk->addr[pd->sidx], pd->af, &ctx->nk->addr[1], NULL,
+ ctx->sk ? &(ctx->sk->addr[pd->sidx]) : pd->src, pd->af,
+ ctx->nk ? &(ctx->nk->addr[1]) : &(pd->nsaddr), NULL,
PF_SN_NAT)) != 0 ) {
REASON_SET(&ctx->reason, sn_reason);
goto csfailed;
@@ -6213,7 +6219,7 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx,
if (ctx->tag > 0)
s->tag = ctx->tag;
if (pd->proto == IPPROTO_TCP && (tcp_get_flags(th) & (TH_SYN|TH_ACK)) ==
- TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
+ TH_SYN && r->keep_state == PF_STATE_SYNPROXY && pd->dir == PF_IN) {
pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC);
pf_undo_nat(ctx->nr, pd, bip_sum);
s->src.seqhi = arc4random();
@@ -9010,7 +9016,7 @@ pf_route(struct pf_krule *r, struct ifnet *oifp,
if (ip->ip_ttl <= IPTTLDEC) {
if (r->rt != PF_DUPTO)
pf_send_icmp(m0, ICMP_TIMXCEED,
- ICMP_TIMXCEED_INTRANS, 0, pd->af, r,
+ ICMP_TIMXCEED_INTRANS, 0, pd->af,
pd->act.rtableid);
goto bad_locked;
}
@@ -9062,6 +9068,9 @@ pf_route(struct pf_krule *r, struct ifnet *oifp,
goto bad;
}
+ if (r->rt == PF_DUPTO)
+ skip_test = true;
+
if (pd->dir == PF_IN && !skip_test) {
if (pf_test(AF_INET, PF_OUT, PFIL_FWD, ifp, &m0, inp,
&pd->act) != PF_PASS) {
@@ -9153,7 +9162,7 @@ pf_route(struct pf_krule *r, struct ifnet *oifp,
}
pf_send_icmp(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
- ifp->if_mtu, pd->af, r, pd->act.rtableid);
+ ifp->if_mtu, pd->af, pd->act.rtableid);
}
SDT_PROBE1(pf, ip, route_to, drop, __LINE__);
goto bad;
@@ -9304,7 +9313,7 @@ pf_route6(struct pf_krule *r, struct ifnet *oifp,
if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
if (r->rt != PF_DUPTO)
pf_send_icmp(m0, ICMP6_TIME_EXCEEDED,
- ICMP6_TIME_EXCEED_TRANSIT, 0, pd->af, r,
+ ICMP6_TIME_EXCEED_TRANSIT, 0, pd->af,
pd->act.rtableid);
goto bad_locked;
}
@@ -9364,6 +9373,9 @@ pf_route6(struct pf_krule *r, struct ifnet *oifp,
goto bad;
}
+ if (r->rt == PF_DUPTO)
+ skip_test = true;
+
if (pd->dir == PF_IN && !skip_test) {
if (pf_test(AF_INET6, PF_OUT, PFIL_FWD | PF_PFIL_NOREFRAGMENT,
ifp, &m0, inp, &pd->act) != PF_PASS) {
@@ -9450,7 +9462,7 @@ pf_route6(struct pf_krule *r, struct ifnet *oifp,
if (r->rt != PF_DUPTO)
pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0,
- ifp->if_mtu, pd->af, r, pd->act.rtableid);
+ ifp->if_mtu, pd->af, pd->act.rtableid);
}
SDT_PROBE1(pf, ip6, route_to, drop, __LINE__);
goto bad;