Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/iflib.c
Show First 20 Lines • Show All 2,461 Lines • ▼ Show 20 Lines | #endif | ||||
m->m_pkthdr.flowid = ri->iri_flowid; | m->m_pkthdr.flowid = ri->iri_flowid; | ||||
M_HASHTYPE_SET(m, ri->iri_rsstype); | M_HASHTYPE_SET(m, ri->iri_rsstype); | ||||
m->m_pkthdr.csum_flags = ri->iri_csum_flags; | m->m_pkthdr.csum_flags = ri->iri_csum_flags; | ||||
m->m_pkthdr.csum_data = ri->iri_csum_data; | m->m_pkthdr.csum_data = ri->iri_csum_data; | ||||
return (m); | return (m); | ||||
} | } | ||||
#if defined(INET6) || defined(INET) | #if defined(INET6) || defined(INET) | ||||
static void | |||||
iflib_get_ip_forwarding(struct lro_ctrl *lc, bool *v4, bool *v6) | |||||
{ | |||||
CURVNET_SET(lc->ifp->if_vnet); | |||||
#if defined(INET6) | |||||
*v6 = VNET(ip6_forwarding); | |||||
#endif | |||||
#if defined(INET) | |||||
*v4 = VNET(ipforwarding); | |||||
#endif | |||||
CURVNET_RESTORE(); | |||||
} | |||||
/* | /* | ||||
* Returns true if it's possible this packet could be LROed. | * Returns true if it's possible this packet could be LROed. | ||||
* if it returns false, it is guaranteed that tcp_lro_rx() | * if it returns false, it is guaranteed that tcp_lro_rx() | ||||
* would not return zero. | * would not return zero. | ||||
*/ | */ | ||||
static bool | static bool | ||||
iflib_check_lro_possible(struct lro_ctrl *lc, struct mbuf *m) | iflib_check_lro_possible(struct mbuf *m, bool v4_forwarding, bool v6_forwarding) | ||||
{ | { | ||||
struct ether_header *eh; | struct ether_header *eh; | ||||
uint16_t eh_type; | uint16_t eh_type; | ||||
eh = mtod(m, struct ether_header *); | eh = mtod(m, struct ether_header *); | ||||
eh_type = ntohs(eh->ether_type); | eh_type = ntohs(eh->ether_type); | ||||
switch (eh_type) { | switch (eh_type) { | ||||
#if defined(INET6) | #if defined(INET6) | ||||
case ETHERTYPE_IPV6: | case ETHERTYPE_IPV6: | ||||
{ | return !v6_forwarding; | ||||
CURVNET_SET(lc->ifp->if_vnet); | |||||
if (VNET(ip6_forwarding) == 0) { | |||||
CURVNET_RESTORE(); | |||||
return true; | |||||
} | |||||
CURVNET_RESTORE(); | |||||
break; | |||||
} | |||||
#endif | #endif | ||||
#if defined (INET) | #if defined (INET) | ||||
case ETHERTYPE_IP: | case ETHERTYPE_IP: | ||||
{ | return !v4_forwarding; | ||||
CURVNET_SET(lc->ifp->if_vnet); | |||||
if (VNET(ipforwarding) == 0) { | |||||
CURVNET_RESTORE(); | |||||
return true; | |||||
} | |||||
CURVNET_RESTORE(); | |||||
break; | |||||
} | |||||
#endif | #endif | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
#else | |||||
static void | |||||
iflib_get_ip_forwarding(struct lro_ctrl *lc __unused, bool *v4 __unused, bool *v6 __unused) | |||||
{ | |||||
} | |||||
#endif | #endif | ||||
static bool | static bool | ||||
iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) | iflib_rxeof(iflib_rxq_t rxq, qidx_t budget) | ||||
{ | { | ||||
if_ctx_t ctx = rxq->ifr_ctx; | if_ctx_t ctx = rxq->ifr_ctx; | ||||
if_shared_ctx_t sctx = ctx->ifc_sctx; | if_shared_ctx_t sctx = ctx->ifc_sctx; | ||||
if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; | if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; | ||||
int avail, i; | int avail, i; | ||||
qidx_t *cidxp; | qidx_t *cidxp; | ||||
struct if_rxd_info ri; | struct if_rxd_info ri; | ||||
int err, budget_left, rx_bytes, rx_pkts; | int err, budget_left, rx_bytes, rx_pkts; | ||||
iflib_fl_t fl; | iflib_fl_t fl; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int lro_enabled; | int lro_enabled; | ||||
bool lro_possible = false; | bool lro_possible = false; | ||||
bool v4_forwarding, v6_forwarding; | |||||
/* | /* | ||||
* XXX early demux data packets so that if_input processing only handles | * XXX early demux data packets so that if_input processing only handles | ||||
* acks in interrupt context | * acks in interrupt context | ||||
*/ | */ | ||||
struct mbuf *m, *mh, *mt, *mf; | struct mbuf *m, *mh, *mt, *mf; | ||||
ifp = ctx->ifc_ifp; | ifp = ctx->ifc_ifp; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | else { | ||||
mt = m; | mt = m; | ||||
} | } | ||||
} | } | ||||
/* make sure that we can refill faster than drain */ | /* make sure that we can refill faster than drain */ | ||||
for (i = 0, fl = &rxq->ifr_fl[0]; i < sctx->isc_nfl; i++, fl++) | for (i = 0, fl = &rxq->ifr_fl[0]; i < sctx->isc_nfl; i++, fl++) | ||||
__iflib_fl_refill_lt(ctx, fl, budget + 8); | __iflib_fl_refill_lt(ctx, fl, budget + 8); | ||||
lro_enabled = (if_getcapenable(ifp) & IFCAP_LRO); | lro_enabled = (if_getcapenable(ifp) & IFCAP_LRO); | ||||
if (lro_enabled) | |||||
iflib_get_ip_forwarding(&rxq->ifr_lc, &v4_forwarding, &v6_forwarding); | |||||
mt = mf = NULL; | mt = mf = NULL; | ||||
while (mh != NULL) { | while (mh != NULL) { | ||||
m = mh; | m = mh; | ||||
mh = mh->m_nextpkt; | mh = mh->m_nextpkt; | ||||
m->m_nextpkt = NULL; | m->m_nextpkt = NULL; | ||||
#ifndef __NO_STRICT_ALIGNMENT | #ifndef __NO_STRICT_ALIGNMENT | ||||
if (!IP_ALIGNED(m) && (m = iflib_fixup_rx(m)) == NULL) | if (!IP_ALIGNED(m) && (m = iflib_fixup_rx(m)) == NULL) | ||||
continue; | continue; | ||||
#endif | #endif | ||||
rx_bytes += m->m_pkthdr.len; | rx_bytes += m->m_pkthdr.len; | ||||
rx_pkts++; | rx_pkts++; | ||||
#if defined(INET6) || defined(INET) | #if defined(INET6) || defined(INET) | ||||
if (lro_enabled) { | if (lro_enabled) { | ||||
if (!lro_possible) { | if (!lro_possible) { | ||||
lro_possible = iflib_check_lro_possible(&rxq->ifr_lc, m); | lro_possible = iflib_check_lro_possible(m, v4_forwarding, v6_forwarding); | ||||
if (lro_possible && mf != NULL) { | if (lro_possible && mf != NULL) { | ||||
ifp->if_input(ifp, mf); | ifp->if_input(ifp, mf); | ||||
DBG_COUNTER_INC(rx_if_input); | DBG_COUNTER_INC(rx_if_input); | ||||
mt = mf = NULL; | mt = mf = NULL; | ||||
} | } | ||||
} | } | ||||
if (lro_possible && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0) | if (lro_possible && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0) | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 3,159 Lines • Show Last 20 Lines |