Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
#include <net/if_vlan_var.h> | #include <net/if_vlan_var.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <net/radix_mpath.h> | #include <net/radix_mpath.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <net/pfil.h> | |||||
#include <net/pfvar.h> | #include <net/pfvar.h> | ||||
#include <net/if_pflog.h> | #include <net/if_pflog.h> | ||||
#include <net/if_pfsync.h> | #include <net/if_pfsync.h> | ||||
#include <netinet/in_pcb.h> | #include <netinet/in_pcb.h> | ||||
#include <netinet/in_var.h> | #include <netinet/in_var.h> | ||||
#include <netinet/in_fib.h> | #include <netinet/in_fib.h> | ||||
#include <netinet/ip.h> | #include <netinet/ip.h> | ||||
▲ Show 20 Lines • Show All 5,395 Lines • ▼ Show 20 Lines | if (!PF_AZERO(&s->rt_addr, AF_INET)) | ||||
s->rt_addr.v4.s_addr; | s->rt_addr.v4.s_addr; | ||||
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; | ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
} | } | ||||
if (ifp == NULL) | if (ifp == NULL) | ||||
goto bad; | goto bad; | ||||
if (oifp != ifp) { | if (oifp != ifp) { | ||||
if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) | if (pf_test(PF_OUT, 0, ifp, &m0, NULL) != PF_PASS) | ||||
goto bad; | goto bad; | ||||
else if (m0 == NULL) | else if (m0 == NULL) | ||||
goto done; | goto done; | ||||
if (m0->m_len < sizeof(struct ip)) { | if (m0->m_len < sizeof(struct ip)) { | ||||
DPFPRINTF(PF_DEBUG_URGENT, | DPFPRINTF(PF_DEBUG_URGENT, | ||||
("%s: m0->m_len < sizeof(struct ip)\n", __func__)); | ("%s: m0->m_len < sizeof(struct ip)\n", __func__)); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, | ||||
if (s) | if (s) | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
if (ifp == NULL) | if (ifp == NULL) | ||||
goto bad; | goto bad; | ||||
if (oifp != ifp) { | if (oifp != ifp) { | ||||
if (pf_test6(PF_FWD, ifp, &m0, NULL) != PF_PASS) | if (pf_test6(PF_OUT, PFIL_FWD, ifp, &m0, NULL) != PF_PASS) | ||||
goto bad; | goto bad; | ||||
else if (m0 == NULL) | else if (m0 == NULL) | ||||
goto done; | goto done; | ||||
if (m0->m_len < sizeof(struct ip6_hdr)) { | if (m0->m_len < sizeof(struct ip6_hdr)) { | ||||
DPFPRINTF(PF_DEBUG_URGENT, | DPFPRINTF(PF_DEBUG_URGENT, | ||||
("%s: m0->m_len < sizeof(struct ip6_hdr)\n", | ("%s: m0->m_len < sizeof(struct ip6_hdr)\n", | ||||
__func__)); | __func__)); | ||||
goto bad; | goto bad; | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef INET | #ifdef INET | ||||
int | int | ||||
pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | ||||
{ | { | ||||
struct pfi_kif *kif; | struct pfi_kif *kif; | ||||
u_short action, reason = 0, log = 0; | u_short action, reason = 0, log = 0; | ||||
struct mbuf *m = *m0; | struct mbuf *m = *m0; | ||||
struct ip *h = NULL; | struct ip *h = NULL; | ||||
struct m_tag *ipfwtag; | struct m_tag *ipfwtag; | ||||
struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; | struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; | ||||
struct pf_state *s = NULL; | struct pf_state *s = NULL; | ||||
▲ Show 20 Lines • Show All 370 Lines • ▼ Show 20 Lines | if (s) | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
return (action); | return (action); | ||||
} | } | ||||
#endif /* INET */ | #endif /* INET */ | ||||
#ifdef INET6 | #ifdef INET6 | ||||
int | int | ||||
pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | ||||
{ | { | ||||
struct pfi_kif *kif; | struct pfi_kif *kif; | ||||
u_short action, reason = 0, log = 0; | u_short action, reason = 0, log = 0; | ||||
struct mbuf *m = *m0, *n = NULL; | struct mbuf *m = *m0, *n = NULL; | ||||
struct m_tag *mtag; | struct m_tag *mtag; | ||||
struct ip6_hdr *h = NULL; | struct ip6_hdr *h = NULL; | ||||
struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; | struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; | ||||
struct pf_state *s = NULL; | struct pf_state *s = NULL; | ||||
struct pf_ruleset *ruleset = NULL; | struct pf_ruleset *ruleset = NULL; | ||||
struct pf_pdesc pd; | struct pf_pdesc pd; | ||||
int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0; | int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0; | ||||
int fwdir = dir; | |||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
/* Detect packet forwarding. | |||||
* If the input interface is different from the output interface we're | |||||
* forwarding. | |||||
* We do need to be careful about bridges. If the | |||||
* net.link.bridge.pfil_bridge sysctl is set we can be filtering on a | |||||
* bridge, so if the input interface is a bridge member and the output | |||||
* interface is its bridge or a member of the same bridge we're not | |||||
* actually forwarding but bridging. | |||||
*/ | |||||
if (dir == PF_OUT && m->m_pkthdr.rcvif && ifp != m->m_pkthdr.rcvif && | |||||
(m->m_pkthdr.rcvif->if_bridge == NULL || | |||||
(m->m_pkthdr.rcvif->if_bridge != ifp->if_softc && | |||||
m->m_pkthdr.rcvif->if_bridge != ifp->if_bridge))) | |||||
fwdir = PF_FWD; | |||||
if (dir == PF_FWD) | |||||
dir = PF_OUT; | |||||
if (!V_pf_status.running) | if (!V_pf_status.running) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
memset(&pd, 0, sizeof(pd)); | memset(&pd, 0, sizeof(pd)); | ||||
pd.pf_mtag = pf_find_mtag(m); | pd.pf_mtag = pf_find_mtag(m); | ||||
if (pd.pf_mtag && pd.pf_mtag->flags & PF_TAG_GENERATED) | if (pd.pf_mtag && pd.pf_mtag->flags & PF_TAG_GENERATED) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Lines | default: | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
if (s) | if (s) | ||||
PF_STATE_UNLOCK(s); | PF_STATE_UNLOCK(s); | ||||
/* If reassembled packet passed, create new fragments. */ | /* If reassembled packet passed, create new fragments. */ | ||||
if (action == PF_PASS && *m0 && fwdir == PF_FWD && | if (action == PF_PASS && *m0 && (pflags & PFIL_FWD) && | ||||
(mtag = m_tag_find(m, PF_REASSEMBLED, NULL)) != NULL) | (mtag = m_tag_find(m, PF_REASSEMBLED, NULL)) != NULL) | ||||
action = pf_refragment6(ifp, m0, mtag); | action = pf_refragment6(ifp, m0, mtag); | ||||
return (action); | return (action); | ||||
} | } | ||||
#endif /* INET6 */ | #endif /* INET6 */ |