Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_input.c
Show First 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | ip_input(struct mbuf *m) | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int checkif, hlen = 0; | int checkif, hlen = 0; | ||||
uint16_t sum, ip_len; | uint16_t sum, ip_len; | ||||
int dchg = 0; /* dest changed after fw */ | int dchg = 0; /* dest changed after fw */ | ||||
struct in_addr odst; /* original dst address */ | struct in_addr odst; /* original dst address */ | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
NET_EPOCH_ASSERT(); | |||||
if (m->m_flags & M_FASTFWD_OURS) { | if (m->m_flags & M_FASTFWD_OURS) { | ||||
m->m_flags &= ~M_FASTFWD_OURS; | m->m_flags &= ~M_FASTFWD_OURS; | ||||
/* Set up some basics that will be used later. */ | /* Set up some basics that will be used later. */ | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
hlen = ip->ip_hl << 2; | hlen = ip->ip_hl << 2; | ||||
ip_len = ntohs(ip->ip_len); | ip_len = ntohs(ip->ip_len); | ||||
goto ours; | goto ours; | ||||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | passin: | ||||
* Check for broadcast addresses. | * Check for broadcast addresses. | ||||
* | * | ||||
* Only accept broadcast packets that arrive via the matching | * Only accept broadcast packets that arrive via the matching | ||||
* interface. Reception of forwarded directed broadcasts would | * interface. Reception of forwarded directed broadcasts would | ||||
* be handled via ip_forward() and ether_output() with the loopback | * be handled via ip_forward() and ether_output() with the loopback | ||||
* into the stack for SIMPLEX interfaces handled by ether_output(). | * into the stack for SIMPLEX interfaces handled by ether_output(). | ||||
*/ | */ | ||||
if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) { | if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) { | ||||
struct epoch_tracker et; | |||||
NET_EPOCH_ENTER(et); | |||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | ||||
if (ifa->ifa_addr->sa_family != AF_INET) | if (ifa->ifa_addr->sa_family != AF_INET) | ||||
continue; | continue; | ||||
ia = ifatoia(ifa); | ia = ifatoia(ifa); | ||||
if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == | if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == | ||||
ip->ip_dst.s_addr) { | ip->ip_dst.s_addr) { | ||||
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); | counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); | ||||
counter_u64_add(ia->ia_ifa.ifa_ibytes, | counter_u64_add(ia->ia_ifa.ifa_ibytes, | ||||
m->m_pkthdr.len); | m->m_pkthdr.len); | ||||
NET_EPOCH_EXIT(et); | |||||
goto ours; | goto ours; | ||||
} | } | ||||
#ifdef BOOTP_COMPAT | #ifdef BOOTP_COMPAT | ||||
if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY) { | if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY) { | ||||
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); | counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); | ||||
counter_u64_add(ia->ia_ifa.ifa_ibytes, | counter_u64_add(ia->ia_ifa.ifa_ibytes, | ||||
m->m_pkthdr.len); | m->m_pkthdr.len); | ||||
NET_EPOCH_EXIT(et); | |||||
goto ours; | goto ours; | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | |||||
ia = NULL; | ia = NULL; | ||||
} | } | ||||
/* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */ | /* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */ | ||||
if (IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) { | if (IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) { | ||||
IPSTAT_INC(ips_cantforward); | IPSTAT_INC(ips_cantforward); | ||||
m_freem(m); | m_freem(m); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
ip_forward(struct mbuf *m, int srcrt) | ip_forward(struct mbuf *m, int srcrt) | ||||
{ | { | ||||
struct ip *ip = mtod(m, struct ip *); | struct ip *ip = mtod(m, struct ip *); | ||||
struct in_ifaddr *ia; | struct in_ifaddr *ia; | ||||
struct mbuf *mcopy; | struct mbuf *mcopy; | ||||
struct sockaddr_in *sin; | struct sockaddr_in *sin; | ||||
struct in_addr dest; | struct in_addr dest; | ||||
struct route ro; | struct route ro; | ||||
struct epoch_tracker et; | |||||
int error, type = 0, code = 0, mtu = 0; | int error, type = 0, code = 0, mtu = 0; | ||||
NET_EPOCH_ASSERT(); | |||||
if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { | if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { | ||||
IPSTAT_INC(ips_cantforward); | IPSTAT_INC(ips_cantforward); | ||||
m_freem(m); | m_freem(m); | ||||
return; | return; | ||||
} | } | ||||
if ( | if ( | ||||
#ifdef IPSTEALTH | #ifdef IPSTEALTH | ||||
V_ipstealth == 0 && | V_ipstealth == 0 && | ||||
Show All 10 Lines | #endif | ||||
sin->sin_addr = ip->ip_dst; | sin->sin_addr = ip->ip_dst; | ||||
#ifdef RADIX_MPATH | #ifdef RADIX_MPATH | ||||
rtalloc_mpath_fib(&ro, | rtalloc_mpath_fib(&ro, | ||||
ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr), | ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr), | ||||
M_GETFIB(m)); | M_GETFIB(m)); | ||||
#else | #else | ||||
in_rtalloc_ign(&ro, 0, M_GETFIB(m)); | in_rtalloc_ign(&ro, 0, M_GETFIB(m)); | ||||
#endif | #endif | ||||
NET_EPOCH_ENTER(et); | |||||
if (ro.ro_rt != NULL) { | if (ro.ro_rt != NULL) { | ||||
ia = ifatoia(ro.ro_rt->rt_ifa); | ia = ifatoia(ro.ro_rt->rt_ifa); | ||||
} else | } else | ||||
ia = NULL; | ia = NULL; | ||||
/* | /* | ||||
* Save the IP header and at most 8 bytes of the payload, | * Save the IP header and at most 8 bytes of the payload, | ||||
* in case we need to generate an ICMP message to the src. | * in case we need to generate an ICMP message to the src. | ||||
* | * | ||||
Show All 31 Lines | #endif | ||||
ip->ip_ttl -= IPTTLDEC; | ip->ip_ttl -= IPTTLDEC; | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) | ||||
if (IPSEC_ENABLED(ipv4)) { | if (IPSEC_ENABLED(ipv4)) { | ||||
if ((error = IPSEC_FORWARD(ipv4, m)) != 0) { | if ((error = IPSEC_FORWARD(ipv4, m)) != 0) { | ||||
/* mbuf consumed by IPsec */ | /* mbuf consumed by IPsec */ | ||||
m_freem(mcopy); | m_freem(mcopy); | ||||
if (error != EINPROGRESS) | if (error != EINPROGRESS) | ||||
IPSTAT_INC(ips_cantforward); | IPSTAT_INC(ips_cantforward); | ||||
goto out; | return; | ||||
} | } | ||||
/* No IPsec processing required */ | /* No IPsec processing required */ | ||||
} | } | ||||
#endif /* IPSEC */ | #endif /* IPSEC */ | ||||
/* | /* | ||||
* If forwarding packet using same interface that it came in on, | * If forwarding packet using same interface that it came in on, | ||||
* perhaps should send a redirect to sender to shortcut a hop. | * perhaps should send a redirect to sender to shortcut a hop. | ||||
* Only send redirect if source is sending directly to us, | * Only send redirect if source is sending directly to us, | ||||
Show All 36 Lines | if (error) | ||||
IPSTAT_INC(ips_cantforward); | IPSTAT_INC(ips_cantforward); | ||||
else { | else { | ||||
IPSTAT_INC(ips_forward); | IPSTAT_INC(ips_forward); | ||||
if (type) | if (type) | ||||
IPSTAT_INC(ips_redirectsent); | IPSTAT_INC(ips_redirectsent); | ||||
else { | else { | ||||
if (mcopy) | if (mcopy) | ||||
m_freem(mcopy); | m_freem(mcopy); | ||||
goto out; | return; | ||||
} | } | ||||
} | } | ||||
if (mcopy == NULL) | if (mcopy == NULL) | ||||
goto out; | return; | ||||
switch (error) { | switch (error) { | ||||
case 0: /* forwarded, but need redirect */ | case 0: /* forwarded, but need redirect */ | ||||
/* type, code set above */ | /* type, code set above */ | ||||
break; | break; | ||||
Show All 26 Lines | if (mtu != 0) { | ||||
mtu = ip_next_mtu(ntohs(ip->ip_len), 0); | mtu = ip_next_mtu(ntohs(ip->ip_len), 0); | ||||
} | } | ||||
IPSTAT_INC(ips_cantfrag); | IPSTAT_INC(ips_cantfrag); | ||||
break; | break; | ||||
case ENOBUFS: | case ENOBUFS: | ||||
case EACCES: /* ipfw denied packet */ | case EACCES: /* ipfw denied packet */ | ||||
m_freem(mcopy); | m_freem(mcopy); | ||||
goto out; | return; | ||||
} | } | ||||
icmp_error(mcopy, type, code, dest.s_addr, mtu); | icmp_error(mcopy, type, code, dest.s_addr, mtu); | ||||
out: | |||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
#define CHECK_SO_CT(sp, ct) \ | #define CHECK_SO_CT(sp, ct) \ | ||||
(((sp->so_options & SO_TIMESTAMP) && (sp->so_ts_clock == ct)) ? 1 : 0) | (((sp->so_options & SO_TIMESTAMP) && (sp->so_ts_clock == ct)) ? 1 : 0) | ||||
void | void | ||||
ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip, | ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip, | ||||
struct mbuf *m) | struct mbuf *m) | ||||
▲ Show 20 Lines • Show All 287 Lines • Show Last 20 Lines |