Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_lro.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/in_systm.h> | #include <netinet/in_systm.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/ip6.h> | #include <netinet/ip6.h> | ||||
#include <netinet/ip.h> | #include <netinet/ip.h> | ||||
#include <netinet/ip_var.h> | #include <netinet/ip_var.h> | ||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
#include <netinet/tcp_seq.h> | |||||
#include <netinet/tcp_lro.h> | #include <netinet/tcp_lro.h> | ||||
#include <netinet/tcp_var.h> | #include <netinet/tcp_var.h> | ||||
#include <netinet6/ip6_var.h> | #include <netinet6/ip6_var.h> | ||||
#include <machine/in_cksum.h> | #include <machine/in_cksum.h> | ||||
static MALLOC_DEFINE(M_LRO, "LRO", "LRO control structures"); | static MALLOC_DEFINE(M_LRO, "LRO", "LRO control structures"); | ||||
▲ Show 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | #endif | ||||
if (le->p_len > (lc->lro_length_lim - tcp_data_len)) { | if (le->p_len > (lc->lro_length_lim - tcp_data_len)) { | ||||
tcp_lro_active_remove(le); | tcp_lro_active_remove(le); | ||||
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 && | |||||
le->window == th->th_win))) { | |||||
/* Out of order packet or duplicate ACK. */ | /* Out of order packet or duplicate ACK. */ | ||||
tcp_lro_active_remove(le); | tcp_lro_active_remove(le); | ||||
tcp_lro_flush(lc, le); | tcp_lro_flush(lc, le); | ||||
return (TCP_LRO_CANNOT); | return (TCP_LRO_CANNOT); | ||||
} | } | ||||
if (l != 0) { | if (l != 0) { | ||||
uint32_t tsval = ntohl(*(ts_ptr + 1)); | uint32_t tsval = ntohl(*(ts_ptr + 1)); | ||||
/* Make sure timestamp values are increasing. */ | /* Make sure timestamp values are increasing. */ | ||||
/* XXX-BZ flip and use TSTMP_GEQ macro for this? */ | /* XXX-BZ flip and use TSTMP_GEQ macro for this? */ | ||||
if (__predict_false(le->tsval > tsval || | if (__predict_false(le->tsval > tsval || | ||||
*(ts_ptr + 2) == 0)) | *(ts_ptr + 2) == 0)) | ||||
return (TCP_LRO_CANNOT); | return (TCP_LRO_CANNOT); | ||||
le->tsval = tsval; | le->tsval = tsval; | ||||
le->tsecr = *(ts_ptr + 2); | le->tsecr = *(ts_ptr + 2); | ||||
} | } | ||||
if (tcp_data_len || SEQ_GT(ntohl(th->th_ack), ntohl(le->ack_seq))) { | |||||
le->next_seq += tcp_data_len; | le->next_seq += tcp_data_len; | ||||
le->ack_seq = th->th_ack; | le->ack_seq = th->th_ack; | ||||
rstone: Technically we should only do this (or look at th->th_ack at all) if TH_ACK is set | |||||
jason_eggnet.comUnsubmitted Not Done Inline ActionsOn the transport call we discussed that this should probably be handled in another patch as it is a generic issue with the LRO code. jason_eggnet.com: On the transport call we discussed that this should probably be handled in another patch as it… | |||||
le->window = th->th_win; | le->window = th->th_win; | ||||
le->append_cnt++; | le->append_cnt++; | ||||
} else if (th->th_ack == le->ack_seq) { | |||||
le->window = WIN_MAX(le->window, th->th_win); | |||||
le->append_cnt++; | |||||
} else { | |||||
/* no data and old ack */ | |||||
Not Done Inline ActionsI think that you mean "old ack" here. As far as I can tell, the only way to reach this point is to have a packet with no payload and th_ack < le->ack_seq. rstone: I think that you mean "old ack" here. As far as I can tell, the only way to reach this point… | |||||
Not Done Inline ActionsAgreed. jason_eggnet.com: Agreed. | |||||
le->append_cnt++; | |||||
m_freem(m); | |||||
return (0); | |||||
} | |||||
#ifdef TCP_LRO_UPDATE_CSUM | #ifdef TCP_LRO_UPDATE_CSUM | ||||
le->ulp_csum += tcp_lro_rx_csum_fixup(le, l3hdr, th, | le->ulp_csum += tcp_lro_rx_csum_fixup(le, l3hdr, th, | ||||
tcp_data_len, ~csum); | tcp_data_len, ~csum); | ||||
#endif | #endif | ||||
if (tcp_data_len == 0) { | if (tcp_data_len == 0) { | ||||
m_freem(m); | m_freem(m); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 151 Lines • Show Last 20 Lines |
Technically we should only do this (or look at th->th_ack at all) if TH_ACK is set