Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/ip6_fastfwd.c
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | ip6_findroute(struct nhop6_basic *pnh, const struct sockaddr_in6 *dst, | ||||
return (0); | return (0); | ||||
} | } | ||||
struct mbuf* | struct mbuf* | ||||
ip6_tryforward(struct mbuf *m) | ip6_tryforward(struct mbuf *m) | ||||
{ | { | ||||
struct sockaddr_in6 dst; | struct sockaddr_in6 dst; | ||||
struct nhop6_basic nh; | struct nhop6_basic nh; | ||||
struct m_tag *fwd_tag; | |||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
struct ifnet *rcvif; | struct ifnet *rcvif; | ||||
uint32_t plen; | uint32_t plen; | ||||
int error; | int error; | ||||
/* | /* | ||||
* Fallback conditions to ip6_input for slow path processing. | * Fallback conditions to ip6_input for slow path processing. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (pfil_run_hooks(&V_inet6_pfil_hook, &m, rcvif, PFIL_IN, | ||||
goto dropin; | goto dropin; | ||||
/* | /* | ||||
* If packet filter sets the M_FASTFWD_OURS flag, this means | * If packet filter sets the M_FASTFWD_OURS flag, this means | ||||
* that new destination or next hop is our local address. | * that new destination or next hop is our local address. | ||||
* So, we can just go back to ip6_input. | * So, we can just go back to ip6_input. | ||||
* XXX: should we decrement ip6_hlim in such case? | * XXX: should we decrement ip6_hlim in such case? | ||||
* | * | ||||
* Also it can forward packet to another destination, e.g. | * Also it can forward packet to another destination, e.g. | ||||
* M_IP6_NEXTHOP flag is set and fwd_tag is attached to mbuf. | * M_IP6_NEXTHOP flag set and forward tag attached to mbuf. | ||||
*/ | */ | ||||
if (m->m_flags & M_FASTFWD_OURS) | if (m->m_flags & M_FASTFWD_OURS) | ||||
return (m); | return (m); | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
if ((m->m_flags & M_IP6_NEXTHOP) && | if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &dst, NULL)) { | ||||
(fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) { | /* Request from pfil to forward to destination */ | ||||
/* | ip6_flush_fwdtag(m); | ||||
* Now we will find route to forwarded by pfil destination. | |||||
*/ | |||||
bcopy((fwd_tag + 1), &dst, sizeof(dst)); | |||||
m->m_flags &= ~M_IP6_NEXTHOP; | |||||
m_tag_delete(m, fwd_tag); | |||||
} else { | } else { | ||||
/* Update dst since pfil could change it */ | /* Update dst since pfil could change it */ | ||||
dst.sin6_addr = ip6->ip6_dst; | dst.sin6_addr = ip6->ip6_dst; | ||||
} | } | ||||
passin: | passin: | ||||
/* | /* | ||||
* Find route to destination. | * Find route to destination. | ||||
*/ | */ | ||||
if (ip6_findroute(&nh, &dst, m) != 0) { | if (ip6_findroute(&nh, &dst, m) != 0) { | ||||
m = NULL; | m = NULL; | ||||
in6_ifstat_inc(rcvif, ifs6_in_noroute); | in6_ifstat_inc(rcvif, ifs6_in_noroute); | ||||
goto dropin; | goto dropin; | ||||
Show All 18 Lines | if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, | ||||
NULL) != 0 || m == NULL) | NULL) != 0 || m == NULL) | ||||
goto dropout; | goto dropout; | ||||
/* | /* | ||||
* If packet filter sets the M_FASTFWD_OURS flag, this means | * If packet filter sets the M_FASTFWD_OURS flag, this means | ||||
* that new destination or next hop is our local address. | * that new destination or next hop is our local address. | ||||
* So, we can just go back to ip6_input. | * So, we can just go back to ip6_input. | ||||
* | * | ||||
* Also it can forward packet to another destination, e.g. | * Also it can forward packet to another destination, e.g. | ||||
* M_IP6_NEXTHOP flag is set and fwd_tag is attached to mbuf. | * M_IP6_NEXTHOP flag set and forward tag attached to mbuf. | ||||
*/ | */ | ||||
if (m->m_flags & M_FASTFWD_OURS) { | if (m->m_flags & M_FASTFWD_OURS) { | ||||
/* | /* | ||||
* XXX: we did one hop and should decrement hop limit. But | * XXX: we did one hop and should decrement hop limit. But | ||||
* now we are the destination and just don't pay attention. | * now we are the destination and just don't pay attention. | ||||
*/ | */ | ||||
return (m); | return (m); | ||||
} | } | ||||
/* | /* | ||||
* Again. A packet filter could change the destination address. | * Again. A packet filter could change the destination address. | ||||
*/ | */ | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
if (m->m_flags & M_IP6_NEXTHOP) | if (IP6_HAS_NEXTHOP(m) && !ip6_get_fwdtag(m, &dst, NULL)) { | ||||
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); | ip6_flush_fwdtag(m); | ||||
else | |||||
fwd_tag = NULL; | |||||
if (fwd_tag != NULL || | /* | ||||
!IN6_ARE_ADDR_EQUAL(&dst.sin6_addr, &ip6->ip6_dst)) { | * Redo route lookup with new destination address | ||||
if (fwd_tag != NULL) { | */ | ||||
bcopy((fwd_tag + 1), &dst, sizeof(dst)); | if (ip6_findroute(&nh, &dst, m) != 0) { | ||||
m->m_flags &= ~M_IP6_NEXTHOP; | m = NULL; | ||||
m_tag_delete(m, fwd_tag); | goto dropout; | ||||
} else | } | ||||
} else if (!IN6_ARE_ADDR_EQUAL(&dst.sin6_addr, &ip6->ip6_dst)) { | |||||
dst.sin6_addr = ip6->ip6_dst; | dst.sin6_addr = ip6->ip6_dst; | ||||
/* | /* | ||||
* Redo route lookup with new destination address | * Redo route lookup with new destination address | ||||
*/ | */ | ||||
if (ip6_findroute(&nh, &dst, m) != 0) { | if (ip6_findroute(&nh, &dst, m) != 0) { | ||||
m = NULL; | m = NULL; | ||||
goto dropout; | goto dropout; | ||||
} | } | ||||
} | } | ||||
franco_opnsense.org: error here, should be else if | |||||
passout: | passout: | ||||
#ifdef IPSTEALTH | #ifdef IPSTEALTH | ||||
if (!V_ip6stealth) | if (!V_ip6stealth) | ||||
#endif | #endif | ||||
Not Done Inline ActionsLogic was very intertwined, ended up copying this block to make it easier to follow. franco_opnsense.org: Logic was very intertwined, ended up copying this block to make it easier to follow. | |||||
{ | { | ||||
ip6->ip6_hlim -= IPV6_HLIMDEC; | ip6->ip6_hlim -= IPV6_HLIMDEC; | ||||
} | } | ||||
m_clrprotoflags(m); /* Avoid confusing lower layers. */ | m_clrprotoflags(m); /* Avoid confusing lower layers. */ | ||||
IP_PROBE(send, NULL, NULL, ip6, nh.nh_ifp, NULL, ip6); | IP_PROBE(send, NULL, NULL, ip6, nh.nh_ifp, NULL, ip6); | ||||
/* | /* | ||||
Show All 28 Lines |
error here, should be else if