tcp: Missing mfree in rack and bbr
Recently (Nov) we added logic that protects against a peer negotiating a timestamp, and then not including a timestamp. This involved in the input path doing a goto done_with_input label. Now I suspect the code was cribbed from one in Rack that has to do with the SYN. This had a bug, i.e. it should have a m_freem(m) before going to the label (bbr had this missing m_freem() but rack did not). This then caused the missing m_freem to show up in both BBR and Rack. Also looking at the code referencing m->m_pkthdr.lro_nsegs later (after processing) is not a good idea, even though its only for logging. Best to copy that off before any frees can take place. Reviewed by: mtuexen Sponsored by: Netflix Inc Differential Revision: https://reviews.freebsd.org/D30727
This commit is contained in:
parent
6847ea5019
commit
ba1b3e48f5
@ -11441,6 +11441,7 @@ bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) &&
|
||||
((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) {
|
||||
retval = 0;
|
||||
m_freem(m);
|
||||
goto done_with_input;
|
||||
}
|
||||
/*
|
||||
|
@ -13454,6 +13454,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
#ifdef TCP_ACCOUNTING
|
||||
int ack_val_set = 0xf;
|
||||
#endif
|
||||
int nsegs;
|
||||
uint32_t us_cts;
|
||||
/*
|
||||
* tv passed from common code is from either M_TSTMP_LRO or
|
||||
@ -13465,6 +13466,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
if (m->m_flags & M_ACKCMP) {
|
||||
panic("Impossible reach m has ackcmp? m:%p tp:%p", m, tp);
|
||||
}
|
||||
nsegs = m->m_pkthdr.lro_nsegs;
|
||||
counter_u64_add(rack_proc_non_comp_ack, 1);
|
||||
thflags = th->th_flags;
|
||||
#ifdef TCP_ACCOUNTING
|
||||
@ -13607,6 +13609,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) {
|
||||
way_out = 4;
|
||||
retval = 0;
|
||||
m_freem(m);
|
||||
goto done_with_input;
|
||||
}
|
||||
/*
|
||||
@ -13641,6 +13644,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) {
|
||||
way_out = 5;
|
||||
retval = 0;
|
||||
m_freem(m);
|
||||
goto done_with_input;
|
||||
}
|
||||
|
||||
@ -13944,7 +13948,7 @@ do_output_now:
|
||||
way_out = 2;
|
||||
}
|
||||
done_with_input:
|
||||
rack_log_doseg_done(rack, cts, nxt_pkt, did_out, way_out, max(1, m->m_pkthdr.lro_nsegs));
|
||||
rack_log_doseg_done(rack, cts, nxt_pkt, did_out, way_out, max(1, nsegs));
|
||||
if (did_out)
|
||||
rack->r_wanted_output = 0;
|
||||
#ifdef INVARIANTS
|
||||
|
Loading…
x
Reference in New Issue
Block a user