Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_fastfwd.c
Show First 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | |||||
* to ip_input for full processing. | * to ip_input for full processing. | ||||
*/ | */ | ||||
struct mbuf * | struct mbuf * | ||||
ip_tryforward(struct mbuf *m) | ip_tryforward(struct mbuf *m) | ||||
{ | { | ||||
struct ip *ip; | struct ip *ip; | ||||
struct mbuf *m0 = NULL; | struct mbuf *m0 = NULL; | ||||
struct nhop_object *nh = NULL; | struct nhop_object *nh = NULL; | ||||
struct sockaddr_in dst; | struct route ro; | ||||
struct sockaddr_in *dst; | |||||
const struct sockaddr *gw; | |||||
struct in_addr dest, odest, rtdest; | struct in_addr dest, odest, rtdest; | ||||
uint16_t ip_len, ip_off; | uint16_t ip_len, ip_off; | ||||
int error = 0; | int error = 0; | ||||
struct m_tag *fwd_tag = NULL; | struct m_tag *fwd_tag = NULL; | ||||
struct mbuf *mcopy = NULL; | struct mbuf *mcopy = NULL; | ||||
struct in_addr redest; | struct in_addr redest; | ||||
/* | /* | ||||
* Are we active and forwarding packets? | * Are we active and forwarding packets? | ||||
▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | |||||
passout: | passout: | ||||
/* | /* | ||||
* Step 6: send off the packet | * Step 6: send off the packet | ||||
*/ | */ | ||||
ip_len = ntohs(ip->ip_len); | ip_len = ntohs(ip->ip_len); | ||||
ip_off = ntohs(ip->ip_off); | ip_off = ntohs(ip->ip_off); | ||||
bzero(&dst, sizeof(dst)); | bzero(&ro, sizeof(ro)); | ||||
dst.sin_family = AF_INET; | dst = (struct sockaddr_in *)&ro.ro_dst; | ||||
dst.sin_len = sizeof(dst); | dst->sin_family = AF_INET; | ||||
if (nh->nh_flags & NHF_GATEWAY) | dst->sin_len = sizeof(*dst); | ||||
dst.sin_addr = nh->gw4_sa.sin_addr; | dst->sin_addr = dest; | ||||
else | if (nh->nh_flags & NHF_GATEWAY) { | ||||
dst.sin_addr = dest; | gw = &nh->gw_sa; | ||||
ro.ro_flags |= RT_HAS_GW; | |||||
} else | |||||
gw = (const struct sockaddr *)dst; | |||||
/* | /* | ||||
* Handle redirect case. | * Handle redirect case. | ||||
*/ | */ | ||||
redest.s_addr = 0; | redest.s_addr = 0; | ||||
if (V_ipsendredirects && (nh->nh_ifp == m->m_pkthdr.rcvif)) | if (V_ipsendredirects && (nh->nh_ifp == m->m_pkthdr.rcvif) && | ||||
gw->sa_family == AF_INET) | |||||
mcopy = ip_redir_alloc(m, nh, ip, &redest.s_addr); | mcopy = ip_redir_alloc(m, nh, ip, &redest.s_addr); | ||||
/* | /* | ||||
* Check if packet fits MTU or if hardware will fragment for us | * Check if packet fits MTU or if hardware will fragment for us | ||||
*/ | */ | ||||
if (ip_len <= nh->nh_mtu) { | if (ip_len <= nh->nh_mtu) { | ||||
/* | /* | ||||
* Avoid confusing lower layers. | * Avoid confusing lower layers. | ||||
*/ | */ | ||||
m_clrprotoflags(m); | m_clrprotoflags(m); | ||||
/* | /* | ||||
* Send off the packet via outgoing interface | * Send off the packet via outgoing interface | ||||
*/ | */ | ||||
IP_PROBE(send, NULL, NULL, ip, nh->nh_ifp, ip, NULL); | IP_PROBE(send, NULL, NULL, ip, nh->nh_ifp, ip, NULL); | ||||
error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m, | error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m, gw, &ro); | ||||
(struct sockaddr *)&dst, NULL); | |||||
} else { | } else { | ||||
/* | /* | ||||
* Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery | * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery | ||||
*/ | */ | ||||
if (ip_off & IP_DF) { | if (ip_off & IP_DF) { | ||||
IPSTAT_INC(ips_cantfrag); | IPSTAT_INC(ips_cantfrag); | ||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, | icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, | ||||
0, nh->nh_mtu); | 0, nh->nh_mtu); | ||||
Show All 18 Lines | if (ip_off & IP_DF) { | ||||
* Avoid confusing lower layers. | * Avoid confusing lower layers. | ||||
*/ | */ | ||||
m_clrprotoflags(m); | m_clrprotoflags(m); | ||||
IP_PROBE(send, NULL, NULL, | IP_PROBE(send, NULL, NULL, | ||||
mtod(m, struct ip *), nh->nh_ifp, | mtod(m, struct ip *), nh->nh_ifp, | ||||
mtod(m, struct ip *), NULL); | mtod(m, struct ip *), NULL); | ||||
error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m, | error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m, | ||||
(struct sockaddr *)&dst, NULL); | gw, &ro); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
} while ((m = m0) != NULL); | } while ((m = m0) != NULL); | ||||
if (error) { | if (error) { | ||||
/* Reclaim remaining fragments */ | /* Reclaim remaining fragments */ | ||||
for (m = m0; m; m = m0) { | for (m = m0; m; m = m0) { | ||||
m0 = m->m_nextpkt; | m0 = m->m_nextpkt; | ||||
m_freem(m); | m_freem(m); | ||||
Show All 28 Lines |