Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
Show All 27 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_route.h" | #include "opt_route.h" | ||||
#include "opt_sctp.h" | #include "opt_sctp.h" | ||||
#include "opt_rss.h" | #include "opt_rss.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
▲ Show 20 Lines • Show All 598 Lines • ▼ Show 20 Lines | if (ip_len <= mtu || | ||||
* incorrect because we count the IP+TCP headers only | * incorrect because we count the IP+TCP headers only | ||||
* once instead of for every generated packet. | * once instead of for every generated packet. | ||||
*/ | */ | ||||
if (!(flags & IP_FORWARDING) && ia) { | if (!(flags & IP_FORWARDING) && ia) { | ||||
if (m->m_pkthdr.csum_flags & CSUM_TSO) | if (m->m_pkthdr.csum_flags & CSUM_TSO) | ||||
counter_u64_add(ia->ia_ifa.ifa_opackets, | counter_u64_add(ia->ia_ifa.ifa_opackets, | ||||
m->m_pkthdr.len / m->m_pkthdr.tso_segsz); | m->m_pkthdr.len / m->m_pkthdr.tso_segsz); | ||||
else | else | ||||
counter_u64_add(ia->ia_ifa.ifa_opackets, 1); | counter_u64_add(ia->ia_ifa.ifa_opackets, 1); | ||||
jtl: I'm not convinced this is a good idea. Imagine you have a flow that is flopping between cards. | |||||
Done Inline ActionsWill be fixed. Please wait for updated patch. hselasky: Will be fixed. Please wait for updated patch. | |||||
counter_u64_add(ia->ia_ifa.ifa_obytes, m->m_pkthdr.len); | counter_u64_add(ia->ia_ifa.ifa_obytes, m->m_pkthdr.len); | ||||
} | } | ||||
#ifdef MBUF_STRESS_TEST | #ifdef MBUF_STRESS_TEST | ||||
if (mbuf_frag_size && m->m_pkthdr.len > mbuf_frag_size) | if (mbuf_frag_size && m->m_pkthdr.len > mbuf_frag_size) | ||||
m = m_fragment(m, M_NOWAIT, mbuf_frag_size); | m = m_fragment(m, M_NOWAIT, mbuf_frag_size); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Reset layer specific mbuf flags | * Reset layer specific mbuf flags | ||||
* to avoid confusing lower layers. | * to avoid confusing lower layers. | ||||
*/ | */ | ||||
m_clrprotoflags(m); | m_clrprotoflags(m); | ||||
IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | ||||
#ifdef RATELIMIT | |||||
if (inp != NULL) { | |||||
if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED) | |||||
in_pcboutput_txrtlmt(inp, ifp, m); | |||||
/* stamp send tag on mbuf */ | |||||
m->m_pkthdr.snd_tag = inp->inp_snd_tag; | |||||
} else { | |||||
m->m_pkthdr.snd_tag = NULL; | |||||
} | |||||
#endif | |||||
error = (*ifp->if_output)(ifp, m, | error = (*ifp->if_output)(ifp, m, | ||||
(const struct sockaddr *)gw, ro); | (const struct sockaddr *)gw, ro); | ||||
#ifdef RATELIMIT | |||||
/* check for route change */ | |||||
if (error == EAGAIN) | |||||
in_pcboutput_eagain(inp); | |||||
#endif | |||||
goto done; | goto done; | ||||
} | } | ||||
/* Balk when DF bit is set or the interface didn't support TSO. */ | /* Balk when DF bit is set or the interface didn't support TSO. */ | ||||
if ((ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) { | if ((ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) { | ||||
error = EMSGSIZE; | error = EMSGSIZE; | ||||
IPSTAT_INC(ips_cantfrag); | IPSTAT_INC(ips_cantfrag); | ||||
goto bad; | goto bad; | ||||
Show All 18 Lines | if (error == 0) { | ||||
} | } | ||||
/* | /* | ||||
* Reset layer specific mbuf flags | * Reset layer specific mbuf flags | ||||
* to avoid confusing upper layers. | * to avoid confusing upper layers. | ||||
*/ | */ | ||||
m_clrprotoflags(m); | m_clrprotoflags(m); | ||||
IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); | ||||
#ifdef RATELIMIT | |||||
if (inp != NULL) { | |||||
if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED) | |||||
in_pcboutput_txrtlmt(inp, ifp, m); | |||||
/* stamp send tag on mbuf */ | |||||
m->m_pkthdr.snd_tag = inp->inp_snd_tag; | |||||
} else { | |||||
m->m_pkthdr.snd_tag = NULL; | |||||
} | |||||
#endif | |||||
error = (*ifp->if_output)(ifp, m, | error = (*ifp->if_output)(ifp, m, | ||||
(const struct sockaddr *)gw, ro); | (const struct sockaddr *)gw, ro); | ||||
#ifdef RATELIMIT | |||||
/* check for route change */ | |||||
if (error == EAGAIN) | |||||
in_pcboutput_eagain(inp); | |||||
#endif | |||||
} else | } else | ||||
m_freem(m); | m_freem(m); | ||||
} | } | ||||
if (error == 0) | if (error == 0) | ||||
IPSTAT_INC(ips_fragmented); | IPSTAT_INC(ips_fragmented); | ||||
done: | done: | ||||
▲ Show 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | if (sopt->sopt_level == SOL_SOCKET && | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = 0; | error = 0; | ||||
break; | break; | ||||
case SO_SETFIB: | case SO_SETFIB: | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
inp->inp_inc.inc_fibnum = so->so_fibnum; | inp->inp_inc.inc_fibnum = so->so_fibnum; | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = 0; | error = 0; | ||||
break; | |||||
case SO_MAX_PACING_RATE: | |||||
#ifdef RATELIMIT | |||||
INP_WLOCK(inp); | |||||
inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED; | |||||
INP_WUNLOCK(inp); | |||||
error = 0; | |||||
#else | |||||
error = EOPNOTSUPP; | |||||
#endif | |||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 435 Lines • Show Last 20 Lines |
I'm not convinced this is a good idea. Imagine you have a flow that is flopping between cards. One card runs into a problem and won't allocate a ring ID. But, the flow then gets moved to a different card, which would allocate a ring ID... except, you don't ask because you just changed the pacing rate to 0.