Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf.c
Show First 20 Lines • Show All 6,450 Lines • ▼ Show 20 Lines | if ((rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) || | ||||
(rr->info & IPFW_IS_DUMMYNET)) { | (rr->info & IPFW_IS_DUMMYNET)) { | ||||
if (pd.pf_mtag == NULL && | if (pd.pf_mtag == NULL && | ||||
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { | ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { | ||||
action = PF_DROP; | action = PF_DROP; | ||||
goto done; | goto done; | ||||
} | } | ||||
pd.pf_mtag->flags |= PF_PACKET_LOOPED; | pd.pf_mtag->flags |= PF_PACKET_LOOPED; | ||||
m_tag_delete(m, ipfwtag); | m_tag_delete(m, ipfwtag); | ||||
if (rr->info & IPFW_IS_DUMMYNET) { | |||||
/* Dummynet re-injects packets after they've | |||||
* completed their delay. We've already | |||||
* processed them, so pass unconditionally. */ | |||||
PF_RULES_RUNLOCK(); | |||||
return (PF_PASS); | |||||
} | } | ||||
} | |||||
if (pd.pf_mtag && pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) { | if (pd.pf_mtag && pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) { | ||||
m->m_flags |= M_FASTFWD_OURS; | m->m_flags |= M_FASTFWD_OURS; | ||||
pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT; | pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT; | ||||
} | } | ||||
} else if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { | } else if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { | ||||
/* We do IP header normalization and packet reassembly here */ | /* We do IP header normalization and packet reassembly here */ | ||||
action = PF_DROP; | action = PF_DROP; | ||||
goto done; | goto done; | ||||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | if (pd.pf_mtag == NULL && | ||||
else | else | ||||
pd.pf_mtag->qid = pd.act.qid; | pd.pf_mtag->qid = pd.act.qid; | ||||
/* Add hints for ecn. */ | /* Add hints for ecn. */ | ||||
pd.pf_mtag->hdr = h; | pd.pf_mtag->hdr = h; | ||||
} | } | ||||
} | } | ||||
#endif /* ALTQ */ | #endif /* ALTQ */ | ||||
if (s && (s->dnpipe || s->dnrpipe)) { | |||||
pd.act.dnpipe = s->dnpipe; | |||||
pd.act.dnrpipe = s->dnrpipe; | |||||
pd.act.flags = s->state_flags; | |||||
} else if (r->dnpipe || r->dnrpipe) { | |||||
pd.act.dnpipe = r->dnpipe; | |||||
pd.act.dnrpipe = r->dnrpipe; | |||||
pd.act.flags = r->free_flags; | |||||
} | |||||
if ((pd.act.dnpipe || pd.act.dnrpipe) && !PACKET_LOOPED(&pd)) { | |||||
if (ip_dn_io_ptr == NULL) { | |||||
action = PF_DROP; | |||||
REASON_SET(&reason, PFRES_MEMORY); | |||||
} else { | |||||
struct ip_fw_args dnflow; | |||||
if (pd.pf_mtag == NULL && | |||||
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { | |||||
action = PF_DROP; | |||||
REASON_SET(&reason, PFRES_MEMORY); | |||||
if (s) | |||||
PF_STATE_UNLOCK(s); | |||||
return (action); | |||||
} | |||||
if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { | |||||
ip_dn_io_ptr(m0, &dnflow); | |||||
if (*m0 == NULL) { | |||||
if (s) | |||||
PF_STATE_UNLOCK(s); | |||||
return (action); | |||||
} else { | |||||
/* This is dummynet fast io processing */ | |||||
m_tag_delete(*m0, m_tag_first(*m0)); | |||||
pd.pf_mtag->flags &= ~PF_PACKET_LOOPED; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
/* | /* | ||||
* connections redirected to loopback should not match sockets | * connections redirected to loopback should not match sockets | ||||
* bound specifically to loopback due to security implications, | * bound specifically to loopback due to security implications, | ||||
* see tcp_input() and in_pcblookup_listen(). | * see tcp_input() and in_pcblookup_listen(). | ||||
*/ | */ | ||||
if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || | if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || | ||||
pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && | pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && | ||||
(s->nat_rule.ptr->action == PF_RDR || | (s->nat_rule.ptr->action == PF_RDR || | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | case PF_DROP: | ||||
m_freem(*m0); | m_freem(*m0); | ||||
*m0 = NULL; | *m0 = NULL; | ||||
break; | break; | ||||
default: | default: | ||||
/* pf_route() returns unlocked. */ | /* pf_route() returns unlocked. */ | ||||
if (r->rt) { | if (r->rt) { | ||||
pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp); | pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp); | ||||
return (action); | return (action); | ||||
} | |||||
/* Dummynet processing. */ | |||||
if (s && (s->dnpipe || s->dnrpipe)) { | |||||
pd.act.dnpipe = s->dnpipe; | |||||
pd.act.dnrpipe = s->dnrpipe; | |||||
pd.act.flags = s->state_flags; | |||||
} else if (r->dnpipe || r->dnrpipe) { | |||||
pd.act.dnpipe = r->dnpipe; | |||||
pd.act.dnrpipe = r->dnrpipe; | |||||
pd.act.flags = r->free_flags; | |||||
} | |||||
if (pd.act.dnpipe || pd.act.dnrpipe) { | |||||
if (ip_dn_io_ptr == NULL) { | |||||
m_freem(*m0); | |||||
*m0 = NULL; | |||||
REASON_SET(&reason, PFRES_MEMORY); | |||||
} else { | |||||
struct ip_fw_args dnflow; | |||||
if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { | |||||
ip_dn_io_ptr(m0, &dnflow); | |||||
if (*m0 == NULL) | |||||
action = PF_DROP; | |||||
} | |||||
} | |||||
} | } | ||||
break; | break; | ||||
} | } | ||||
SDT_PROBE4(pf, ip, test, done, action, reason, r, s); | SDT_PROBE4(pf, ip, test, done, action, reason, r, s); | ||||
if (s) | if (s) | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
▲ Show 20 Lines • Show All 473 Lines • Show Last 20 Lines |