Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
Show All 29 Lines | |||||
* | * | ||||
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94 | * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_inet.h" | #include "opt_inet.h" | ||||
#include "opt_ratelimit.h" | |||||
#include "opt_ipsec.h" | #include "opt_ipsec.h" | ||||
#include "opt_mbuf_stress_test.h" | #include "opt_mbuf_stress_test.h" | ||||
#include "opt_mpath.h" | #include "opt_mpath.h" | ||||
#include "opt_ratelimit.h" | |||||
#include "opt_route.h" | #include "opt_route.h" | ||||
#include "opt_sctp.h" | |||||
#include "opt_rss.h" | #include "opt_rss.h" | ||||
#include "opt_sctp.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
▲ Show 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, | ||||
struct in_ifaddr *ia; | struct in_ifaddr *ia; | ||||
struct in_addr src; | struct in_addr src; | ||||
int isbroadcast; | int isbroadcast; | ||||
uint16_t ip_len, ip_off; | uint16_t ip_len, ip_off; | ||||
uint32_t fibnum; | uint32_t fibnum; | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) | ||||
int no_route_but_check_spd = 0; | int no_route_but_check_spd = 0; | ||||
#endif | #endif | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
if (inp != NULL) { | if (inp != NULL) { | ||||
INP_LOCK_ASSERT(inp); | INP_LOCK_ASSERT(inp); | ||||
M_SETFIB(m, inp->inp_inc.inc_fibnum); | M_SETFIB(m, inp->inp_inc.inc_fibnum); | ||||
if ((flags & IP_NODEFAULTFLOWID) == 0) { | if ((flags & IP_NODEFAULTFLOWID) == 0) { | ||||
m->m_pkthdr.flowid = inp->inp_flowid; | m->m_pkthdr.flowid = inp->inp_flowid; | ||||
M_HASHTYPE_SET(m, inp->inp_flowtype); | M_HASHTYPE_SET(m, inp->inp_flowtype); | ||||
▲ Show 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | if ((ifp->if_flags & IFF_LOOPBACK) == 0) { | ||||
IPSTAT_INC(ips_badaddr); | IPSTAT_INC(ips_badaddr); | ||||
error = EADDRNOTAVAIL; | error = EADDRNOTAVAIL; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
} | } | ||||
m->m_pkthdr.csum_flags |= CSUM_IP; | m->m_pkthdr.csum_flags |= CSUM_IP; | ||||
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~ifp->if_hwassist) { | if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~ifp->if_hwassist) { | ||||
m = mb_unmapped_to_ext(m); | |||||
if (m == NULL) { | |||||
IPSTAT_INC(ips_odropped); | |||||
error = ENOBUFS; | |||||
goto bad; | |||||
} | |||||
in_delayed_cksum(m); | in_delayed_cksum(m); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; | m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; | ||||
} else if ((ifp->if_capenable & IFCAP_NOMAP) == 0) { | |||||
m = mb_unmapped_to_ext(m); | |||||
if (m == NULL) { | |||||
IPSTAT_INC(ips_odropped); | |||||
error = ENOBUFS; | |||||
goto bad; | |||||
} | } | ||||
} | |||||
#ifdef SCTP | #ifdef SCTP | ||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) { | if (m->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) { | ||||
m = mb_unmapped_to_ext(m); | |||||
if (m == NULL) { | |||||
IPSTAT_INC(ips_odropped); | |||||
error = ENOBUFS; | |||||
goto bad; | |||||
} | |||||
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | m->m_pkthdr.csum_flags &= ~CSUM_SCTP; | ||||
} | } | ||||
#endif | #endif | ||||
/* | /* | ||||
* If small enough for interface, or the interface will take | * If small enough for interface, or the interface will take | ||||
* care of the fragmentation for us, we can just send directly. | * care of the fragmentation for us, we can just send directly. | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, | ||||
if (len < 8) | if (len < 8) | ||||
return EMSGSIZE; | return EMSGSIZE; | ||||
/* | /* | ||||
* If the interface will not calculate checksums on | * If the interface will not calculate checksums on | ||||
* fragmented packets, then do it here. | * fragmented packets, then do it here. | ||||
*/ | */ | ||||
if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { | if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { | ||||
m0 = mb_unmapped_to_ext(m0); | |||||
if (m0 == NULL) { | |||||
error = ENOBUFS; | |||||
IPSTAT_INC(ips_odropped); | |||||
goto done; | |||||
} | |||||
in_delayed_cksum(m0); | in_delayed_cksum(m0); | ||||
m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; | m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; | ||||
} | } | ||||
#ifdef SCTP | #ifdef SCTP | ||||
if (m0->m_pkthdr.csum_flags & CSUM_SCTP) { | if (m0->m_pkthdr.csum_flags & CSUM_SCTP) { | ||||
m0 = mb_unmapped_to_ext(m0); | |||||
if (m0 == NULL) { | |||||
error = ENOBUFS; | |||||
IPSTAT_INC(ips_odropped); | |||||
goto done; | |||||
} | |||||
sctp_delayed_cksum(m0, hlen); | sctp_delayed_cksum(m0, hlen); | ||||
m0->m_pkthdr.csum_flags &= ~CSUM_SCTP; | m0->m_pkthdr.csum_flags &= ~CSUM_SCTP; | ||||
} | } | ||||
#endif | #endif | ||||
if (len > PAGE_SIZE) { | if (len > PAGE_SIZE) { | ||||
/* | /* | ||||
* Fragment large datagrams such that each segment | * Fragment large datagrams such that each segment | ||||
* contains a multiple of PAGE_SIZE amount of data, | * contains a multiple of PAGE_SIZE amount of data, | ||||
▲ Show 20 Lines • Show All 667 Lines • Show Last 20 Lines |