Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_fastfwd.c
Show First 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct ip *ip; | struct ip *ip; | ||||
struct mbuf *m0 = NULL; | struct mbuf *m0 = NULL; | ||||
struct nhop4_basic nh; | struct nhop4_basic nh; | ||||
struct sockaddr_in dst; | struct sockaddr_in dst; | ||||
struct in_addr odest, dest; | struct in_addr odest, dest; | ||||
uint16_t ip_len, ip_off; | uint16_t ip_len, ip_off; | ||||
int error = 0; | int error = 0; | ||||
struct m_tag *fwd_tag = NULL; | |||||
/* | /* | ||||
* Are we active and forwarding packets? | * Are we active and forwarding packets? | ||||
*/ | */ | ||||
M_ASSERTVALID(m); | M_ASSERTVALID(m); | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | #endif | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
dest.s_addr = ip->ip_dst.s_addr; | dest.s_addr = ip->ip_dst.s_addr; | ||||
/* | /* | ||||
* Destination address changed? | * Destination address changed? | ||||
*/ | */ | ||||
if (m->m_flags & M_IP_NEXTHOP) | if (odest.s_addr != dest.s_addr || | ||||
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); | (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, &dst, NULL))) { | ||||
if (odest.s_addr != dest.s_addr || fwd_tag != NULL) { | |||||
/* | /* | ||||
* Is it now for a local address on this host? | * Is it now for a local address on this host? | ||||
*/ | */ | ||||
if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { | if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { | ||||
forwardlocal: | forwardlocal: | ||||
/* | /* | ||||
* Return packet for processing by ip_input(). | * Return packet for processing by ip_input(). | ||||
*/ | */ | ||||
m->m_flags |= M_FASTFWD_OURS; | m->m_flags |= M_FASTFWD_OURS; | ||||
return (m); | return (m); | ||||
} | } | ||||
if (IP_HAS_NEXTHOP(m)) { | |||||
dest.s_addr = dst.sin_addr.s_addr; | |||||
ip_flush_fwdtag(m); | |||||
} | |||||
/* | /* | ||||
* Redo route lookup with new destination address | * Redo route lookup with new destination address | ||||
*/ | */ | ||||
if (fwd_tag) { | |||||
dest.s_addr = ((struct sockaddr_in *) | |||||
(fwd_tag + 1))->sin_addr.s_addr; | |||||
m_tag_delete(m, fwd_tag); | |||||
m->m_flags &= ~M_IP_NEXTHOP; | |||||
} | |||||
if (ip_findroute(&nh, dest, m) != 0) | if (ip_findroute(&nh, dest, m) != 0) | ||||
return (NULL); /* icmp unreach already sent */ | return (NULL); /* icmp unreach already sent */ | ||||
} | } | ||||
passout: | passout: | ||||
/* | /* | ||||
* Step 6: send off the packet | * Step 6: send off the packet | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |