Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_lro.c
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
#include <netinet6/ip6_var.h> | #include <netinet6/ip6_var.h> | ||||
#include <machine/in_cksum.h> | #include <machine/in_cksum.h> | ||||
#ifndef LRO_ENTRIES | #ifndef LRO_ENTRIES | ||||
#define LRO_ENTRIES 8 /* # of LRO entries per RX queue. */ | #define LRO_ENTRIES 8 /* # of LRO entries per RX queue. */ | ||||
#endif | #endif | ||||
#ifndef LRO_PLEN_MAX | |||||
#define LRO_PLEN_MAX 1048575 /* 1 MByte */ | |||||
#endif | |||||
#define TCP_LRO_UPDATE_CSUM 1 | #define TCP_LRO_UPDATE_CSUM 1 | ||||
#ifndef TCP_LRO_UPDATE_CSUM | #ifndef TCP_LRO_UPDATE_CSUM | ||||
#define TCP_LRO_INVALID_CSUM 0x0000 | #define TCP_LRO_INVALID_CSUM 0x0000 | ||||
#endif | #endif | ||||
int | int | ||||
tcp_lro_init(struct lro_ctrl *lc) | tcp_lro_init(struct lro_ctrl *lc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void | void | ||||
tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le) | tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le) | ||||
{ | { | ||||
if (le->append_cnt > 0) { | if (le->append_cnt > 0) { | ||||
struct tcphdr *th; | struct tcphdr *th; | ||||
uint16_t p_len; | /* | ||||
* The TCP/IP stack should use the "m_pkthdr.len" | |||||
* field instead of the IP-payload length field to | |||||
* compute the total TCP payload length when it | |||||
* recognizes the M_HASHTYPE_LRO_TCP hash type. This | |||||
* allows accumulation of more than 64Kbytes worth of | |||||
* payload data. | |||||
*/ | |||||
enum { p_len = htons(65535) }; | |||||
imp: This really isn't a compile time constant (though I think FreeBSD has magic to kinda make it… | |||||
hselaskyAuthorUnsubmitted Not Done Inline ActionsThis is a dummy value which should not be used in the new LRO implementation. 65535 is chosen to make the packet drop as invalid in case some code that is not updated, if any, decides to check the "p_len" with "m_pkthdr.len". hselasky: This is a dummy value which should not be used in the new LRO implementation. 65535 is chosen… | |||||
p_len = htons(le->p_len); | M_HASHTYPE_SET(le->m_head, M_HASHTYPE_LRO_TCP); | ||||
switch (le->eh_type) { | switch (le->eh_type) { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
case ETHERTYPE_IPV6: | case ETHERTYPE_IPV6: | ||||
{ | { | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
ip6 = le->le_ip6; | ip6 = le->le_ip6; | ||||
ip6->ip6_plen = p_len; | ip6->ip6_plen = p_len; | ||||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | case ETHERTYPE_IP: | ||||
if (le->source_ip4 != ip4->ip_src.s_addr || | if (le->source_ip4 != ip4->ip_src.s_addr || | ||||
le->dest_ip4 != ip4->ip_dst.s_addr) | le->dest_ip4 != ip4->ip_dst.s_addr) | ||||
continue; | continue; | ||||
break; | break; | ||||
#endif | #endif | ||||
} | } | ||||
/* Flush now if appending will result in overflow. */ | /* Flush now if appending will result in overflow. */ | ||||
if (le->p_len > (65535 - tcp_data_len)) { | if (le->p_len > (LRO_PLEN_MAX - tcp_data_len)) { | ||||
SLIST_REMOVE(&lc->lro_active, le, lro_entry, next); | SLIST_REMOVE(&lc->lro_active, le, lro_entry, next); | ||||
tcp_lro_flush(lc, le); | tcp_lro_flush(lc, le); | ||||
break; | break; | ||||
} | } | ||||
/* Try to append the new segment. */ | /* Try to append the new segment. */ | ||||
if (__predict_false(seq != le->next_seq || | if (__predict_false(seq != le->next_seq || | ||||
(tcp_data_len == 0 && le->ack_seq == th->th_ack))) { | (tcp_data_len == 0 && le->ack_seq == th->th_ack))) { | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | #endif | ||||
le->m_tail->m_next = m; | le->m_tail->m_next = m; | ||||
le->m_tail = m_last(m); | le->m_tail = m_last(m); | ||||
/* | /* | ||||
* If a possible next full length packet would cause an | * If a possible next full length packet would cause an | ||||
* overflow, pro-actively flush now. | * overflow, pro-actively flush now. | ||||
*/ | */ | ||||
if (le->p_len > (65535 - lc->ifp->if_mtu)) { | if (le->p_len > (LRO_PLEN_MAX - lc->ifp->if_mtu)) { | ||||
SLIST_REMOVE(&lc->lro_active, le, lro_entry, next); | SLIST_REMOVE(&lc->lro_active, le, lro_entry, next); | ||||
tcp_lro_flush(lc, le); | tcp_lro_flush(lc, le); | ||||
} else | } else | ||||
getmicrotime(&le->mtime); | getmicrotime(&le->mtime); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |
This really isn't a compile time constant (though I think FreeBSD has magic to kinda make it such). I don't see what's wrong with uint16_t p_len = htons(65535) honestly. The enum type is also signed, which may cause some grief with subtle assumptions in the code.