Changeset View
Standalone View
sys/netinet/tcp_lro.c
Context not available. | |||||||
struct mbuf *m; | struct mbuf *m; | ||||||
struct tcphdr *th; | struct tcphdr *th; | ||||||
uint16_t tcp_data_len, csum_upd; | uint16_t tcp_data_len, csum_upd; | ||||||
int l; | int l, have_tstmp_opt; | ||||||
/* | /* | ||||||
* First we must check the lead (m_head) | * First we must check the lead (m_head) | ||||||
Context not available. | |||||||
tcp_push_and_replace(tp, lc, le, m); | tcp_push_and_replace(tp, lc, le, m); | ||||||
goto again; | goto again; | ||||||
} | } | ||||||
if (l != 0 && (__predict_false(l != TCPOLEN_TSTAMP_APPA) || | if (l && (__predict_true(l == TCPOLEN_TSTAMP_APPA) && | ||||||
hselasky: You can remove the outer "l && " check. It is now superfluous. You already compare "l" with… | |||||||
(*ts_ptr != ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| | (*ts_ptr == ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| | ||||||
TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) { | TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) | ||||||
have_tstmp_opt = 1; | |||||||
else | |||||||
have_tstmp_opt = 0; | |||||||
if (l != 0 && (__predict_false(have_tstmp_opt == 0))) { | |||||||
Not Done Inline Actionsshould be && here once you changed == to != :-) hselasky: should be && here once you changed == to != :-) | |||||||
Done Inline ActionsHmm yeah I wonder why it was not && before, thinking about it if rrs: Hmm yeah I wonder why it was not && before, thinking about it if
we would have had a option… | |||||||
Done Inline ActionsAhh wait it was looking for the opposite before.. duh :) rrs: Ahh wait it was looking for the opposite before.. duh :) | |||||||
/* | /* | ||||||
* Maybe a sack in the new one? We need to | * Maybe a sack in the new one? We need to | ||||||
* start all over after flushing the | * start all over after flushing the | ||||||
Context not available. | |||||||
tcp_push_and_replace(tp, lc, le, m); | tcp_push_and_replace(tp, lc, le, m); | ||||||
goto again; | goto again; | ||||||
} | } | ||||||
if (l != 0) { | if (have_tstmp_opt) { | ||||||
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. */ | ||||||
if (TSTMP_GT(le->tsval, tsval)) { | if (TSTMP_GT(le->tsval, tsval)) { | ||||||
Context not available. | |||||||
if ((tcplro_stacks_wanting_mbufq == 0) || (le->m_head->m_flags & M_VLANTAG)) | if ((tcplro_stacks_wanting_mbufq == 0) || (le->m_head->m_flags & M_VLANTAG)) | ||||||
goto skip_lookup; | goto skip_lookup; | ||||||
if (le->inp == NULL) { | if (le->inp != NULL) { | ||||||
le->inp = inp = tcp_lro_lookup(lc, le); | |||||||
if (inp && ((inp->inp_flags & (INP_DROPPED|INP_TIMEWAIT)) || | |||||||
(inp->inp_flags2 & INP_FREED))) { | |||||||
/* | |||||||
* We can't present these to the inp since | |||||||
* it will not support the stripped ethernet | |||||||
* header that these have nor if a compressed | |||||||
* ack is presnet. | |||||||
*/ | |||||||
INP_WUNLOCK(inp); | |||||||
lro_free_mbuf_chain(le->m_head); | |||||||
goto done; | |||||||
} | |||||||
if ((le->flags & HAS_COMP_ENTRIES) && | |||||||
((inp->inp_flags2 & INP_MBUF_ACKCMP) == 0)) { | |||||||
/* | |||||||
* It swapped to off, must be a stack | |||||||
* switch. We need to ditch all the packets | |||||||
* and the peer will just have to retransmit. | |||||||
*/ | |||||||
INP_WUNLOCK(inp); | |||||||
lro_free_mbuf_chain(le->m_head); | |||||||
goto done; | |||||||
} | |||||||
} else { | |||||||
/* We have a reference on the inp lets lock and release it */ | /* We have a reference on the inp lets lock and release it */ | ||||||
inp = le->inp; | inp = le->inp; | ||||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||||
Context not available. | |||||||
uint32_t *ts_ptr; | uint32_t *ts_ptr; | ||||||
tcp_seq seq; | tcp_seq seq; | ||||||
int error, ip_len, hdr_len, locked = 0; | int error, ip_len, hdr_len, locked = 0; | ||||||
uint16_t eh_type, tcp_data_len, need_flush; | uint16_t eh_type, tcp_data_len, need_flush, have_tstmp_opt; | ||||||
#ifdef TCPHPTS | #ifdef TCPHPTS | ||||||
uint16_t iptos; | uint16_t iptos; | ||||||
#endif | #endif | ||||||
Context not available. | |||||||
m->m_flags &= ~(M_ACKCMP|M_LRO_EHDRSTRP); | m->m_flags &= ~(M_ACKCMP|M_LRO_EHDRSTRP); | ||||||
/* We expect a contiguous header [eh, ip, tcp]. */ | /* We expect a contiguous header [eh, ip, tcp]. */ | ||||||
nanouptime(&arrv); | |||||||
if ((m->m_flags & (M_TSTMP_LRO|M_TSTMP)) == 0) { | if ((m->m_flags & (M_TSTMP_LRO|M_TSTMP)) == 0) { | ||||||
/* If no hardware or arrival stamp on the packet add arrival */ | /* If no hardware or arrival stamp on the packet add arrival */ | ||||||
nanouptime(&arrv); | |||||||
m->m_pkthdr.rcv_tstmp = (arrv.tv_sec * 1000000000) + arrv.tv_nsec; | m->m_pkthdr.rcv_tstmp = (arrv.tv_sec * 1000000000) + arrv.tv_nsec; | ||||||
m->m_flags |= M_TSTMP_LRO; | m->m_flags |= M_TSTMP_LRO; | ||||||
} | } | ||||||
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) { | ||||||
Context not available. | |||||||
ts_ptr = (uint32_t *)(th + 1); | ts_ptr = (uint32_t *)(th + 1); | ||||||
tcp_data_len -= hdr_len; | tcp_data_len -= hdr_len; | ||||||
hdr_len -= sizeof(*th); | hdr_len -= sizeof(*th); | ||||||
if (hdr_len && (__predict_true(hdr_len == TCPOLEN_TSTAMP_APPA) && | |||||||
Not Done Inline Actions
hselasky: || -> && (ditto) | |||||||
hselaskyUnsubmitted Not Done Inline Actionsditto: "hdr_len && " is superfluous. hselasky: ditto: "hdr_len && " is superfluous. | |||||||
(*ts_ptr == ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| | |||||||
TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) | |||||||
have_tstmp_opt = 1; | |||||||
else | |||||||
have_tstmp_opt = 0; | |||||||
if (th->th_flags & TH_SYN) | if (th->th_flags & TH_SYN) | ||||||
return (TCP_LRO_CANNOT); | return (TCP_LRO_CANNOT); | ||||||
if ((th->th_flags & ~(TH_ACK | TH_PUSH)) != 0) { | if ((th->th_flags & ~(TH_ACK | TH_PUSH)) != 0) { | ||||||
need_flush = 1; | need_flush = 1; | ||||||
} else | } else | ||||||
need_flush = 0; | need_flush = 0; | ||||||
if (hdr_len != 0 && (__predict_false(hdr_len != TCPOLEN_TSTAMP_APPA) || | if (hdr_len != 0 && (__predict_false(have_tstmp_opt == 0))) { | ||||||
(*ts_ptr != ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| | |||||||
TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) { | |||||||
/* | /* | ||||||
* We have an option besides Timestamps, maybe | * We have an option besides Timestamps, maybe | ||||||
* it is a sack (most likely) which means we | * it is a sack (most likely) which means we | ||||||
Not Done Inline ActionsSetting 1 in both cases here?? hselasky: Setting 1 in both cases here?? | |||||||
Not Done Inline ActionsThe hdr_len value is propagated into some other functions which also only checks for non-zero value. Maybe it is better to set hdr_len to zero. hselasky: The hdr_len value is propagated into some other functions which also only checks for non-zero… | |||||||
Done Inline Actionshdr_len is used other places so I dislike changing it to 0 since you clearly do have a hdr in rrs: hdr_len is used other places so I dislike changing it to 0 since you clearly do have a hdr in… | |||||||
Done Inline Actionsto 1 in both cases is a typo ;) rrs: to 1 in both cases is a typo ;) | |||||||
Context not available. | |||||||
nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); | nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); | ||||||
else { | else { | ||||||
nm = m_gethdr(M_NOWAIT, MT_DATA); | nm = m_gethdr(M_NOWAIT, MT_DATA); | ||||||
nm->m_flags |= M_ACKCMP; | if (nm) | ||||||
nm->m_flags |= M_ACKCMP; | |||||||
} | } | ||||||
if (nm) { | if (nm) { | ||||||
nm->m_pkthdr.rcvif = lc->ifp; | nm->m_pkthdr.rcvif = lc->ifp; | ||||||
Context not available. | |||||||
le->next_seq = seq + tcp_data_len; | le->next_seq = seq + tcp_data_len; | ||||||
le->ack_seq = th->th_ack; | le->ack_seq = th->th_ack; | ||||||
le->window = th->th_win; | le->window = th->th_win; | ||||||
if (hdr_len != 0) { | if (have_tstmp_opt) { | ||||||
le->timestamp = 1; | le->timestamp = 1; | ||||||
le->tsval = ntohl(*(ts_ptr + 1)); | le->tsval = ntohl(*(ts_ptr + 1)); | ||||||
le->tsecr = *(ts_ptr + 2); | le->tsecr = *(ts_ptr + 2); | ||||||
Not Done Inline Actionsif "have_tstmp_opt" you don't need to check hdr_len != 0 ?? hselasky: if "have_tstmp_opt" you don't need to check hdr_len != 0 ?? | |||||||
Done Inline ActionsGood point. rrs: Good point. | |||||||
Context not available. | |||||||
nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); | nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); | ||||||
else { | else { | ||||||
nm = m_gethdr(M_NOWAIT, MT_DATA); | nm = m_gethdr(M_NOWAIT, MT_DATA); | ||||||
nm->m_flags |= M_ACKCMP; | if (nm) | ||||||
nm->m_flags |= M_ACKCMP; | |||||||
} | } | ||||||
if (nm) { | if (nm) { | ||||||
nm->m_pkthdr.rcvif = lc->ifp; | nm->m_pkthdr.rcvif = lc->ifp; | ||||||
Context not available. |
You can remove the outer "l && " check. It is now superfluous. You already compare "l" with TCPOLEN_TSTAMP_APPA.