tcp: Access all 12 TCP header flags via inline function

In order to consistently provide access to all
(including reserved) TCP header flag bits,
use an accessor function tcp_get_flags and
tcp_set_flags. Also expand any flag variable from
uint8_t / char to uint16_t.

Reviewed By: hselasky, tuexen, glebius, #transport
Sponsored by:        NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D34130
This commit is contained in:
Richard Scheffenegger 2022-02-03 16:21:25 +01:00
parent 03399cd6e0
commit 1ebf460758
11 changed files with 73 additions and 63 deletions

View File

@ -189,11 +189,11 @@ tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen,
else
printf("%x", seq);
printf("@%x, urp=%x", ack, th->th_urp);
flags = th->th_flags;
flags = tcp_get_flags(th);
if (flags) {
char *cp = "<";
#define pf(f) { \
if (th->th_flags & TH_##f) { \
if (tcp_get_flags(th) & TH_##f) { \
printf("%s%s", cp, #f); \
cp = ","; \
} \

View File

@ -548,7 +548,7 @@ cc_ecnpkt_handler_flags(struct tcpcb *tp, uint16_t flags, uint8_t iptos)
void inline
cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos)
{
cc_ecnpkt_handler_flags(tp, th->th_flags, iptos);
cc_ecnpkt_handler_flags(tp, tcp_get_flags(th), iptos);
}
/*
@ -799,7 +799,7 @@ tcp_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port)
optlen = off - sizeof (struct tcphdr);
optp = (u_char *)(th + 1);
}
thflags = th->th_flags;
thflags = tcp_get_flags(th);
/*
* Convert TCP protocol specific fields to host format.
@ -1537,7 +1537,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct tcphdr tcp_savetcp;
short ostate = 0;
#endif
thflags = th->th_flags;
thflags = tcp_get_flags(th);
inc = &tp->t_inpcb->inp_inc;
tp->sackhint.last_sack_ack = 0;
sack_changed = 0;
@ -3176,7 +3176,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (tp->t_fbyte_out && tp->t_fbyte_in)
tp->t_flags2 |= TF2_FBYTES_COMPLETE;
}
thflags = th->th_flags & TH_FIN;
thflags = tcp_get_flags(th) & TH_FIN;
TCPSTAT_INC(tcps_rcvpack);
TCPSTAT_ADD(tcps_rcvbyte, tlen);
SOCKBUF_LOCK(&so->so_rcv);
@ -3401,7 +3401,7 @@ tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
}
/* Don't bother if destination was broadcast/multicast. */
if ((th->th_flags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST))
if ((tcp_get_flags(th) & TH_RST) || m->m_flags & (M_BCAST|M_MCAST))
goto drop;
#ifdef INET6
if (mtod(m, struct ip *)->ip_v == 6) {
@ -3431,13 +3431,13 @@ tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
goto drop;
/* tcp_respond consumes the mbuf chain. */
if (th->th_flags & TH_ACK) {
if (tcp_get_flags(th) & TH_ACK) {
tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0,
th->th_ack, TH_RST);
} else {
if (th->th_flags & TH_SYN)
if (tcp_get_flags(th) & TH_SYN)
tlen++;
if (th->th_flags & TH_FIN)
if (tcp_get_flags(th) & TH_FIN)
tlen++;
tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen,
(tcp_seq)0, TH_RST|TH_ACK);

View File

@ -921,7 +921,7 @@ tcp_set_entry_to_mbuf(struct lro_ctrl *lc, struct lro_entry *le,
le->next_seq = ntohl(th->th_seq) + tcp_data_len;
le->ack_seq = th->th_ack;
le->window = th->th_win;
le->flags = (th->th_x2 << 8) | th->th_flags;
le->flags = tcp_get_flags(th);
le->needs_merge = 0;
/* Setup new data pointers. */
@ -1033,7 +1033,7 @@ tcp_lro_condense(struct lro_ctrl *lc, struct lro_entry *le)
tcp_push_and_replace(lc, le, m);
goto again;
}
if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH)) != 0) {
if ((tcp_get_flags(th) & ~(TH_ACK | TH_PUSH)) != 0) {
/*
* Make sure that previously seen segments/ACKs are delivered
* before this segment, e.g. FIN.
@ -1077,7 +1077,7 @@ tcp_lro_condense(struct lro_ctrl *lc, struct lro_entry *le)
tcp_push_and_replace(lc, le, m);
goto again;
}
if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH)) != 0) {
if ((tcp_get_flags(th) & ~(TH_ACK | TH_PUSH)) != 0) {
tcp_push_and_replace(lc, le, m);
goto again;
}
@ -1093,7 +1093,7 @@ tcp_lro_condense(struct lro_ctrl *lc, struct lro_entry *le)
}
/* Try to append the new segment. */
if (__predict_false(ntohl(th->th_seq) != le->next_seq ||
((th->th_flags & TH_ACK) !=
((tcp_get_flags(th) & TH_ACK) !=
(le->flags & TH_ACK)) ||
(tcp_data_len == 0 &&
le->ack_seq == th->th_ack &&
@ -1265,14 +1265,14 @@ tcp_lro_ack_valid(struct mbuf *m, struct tcphdr *th, uint32_t **ppts, bool *othe
break;
}
/* For ACKCMP we only accept ACK, PUSH, ECE and CWR. */
if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH | TH_ECE | TH_CWR)) != 0)
if ((tcp_get_flags(th) & ~(TH_ACK | TH_PUSH | TH_ECE | TH_CWR)) != 0)
ret = false;
/* If it has data on it we cannot compress it */
if (m->m_pkthdr.lro_tcp_d_len)
ret = false;
/* ACK flag must be set. */
if (!(th->th_flags & TH_ACK))
if (!(tcp_get_flags(th) & TH_ACK))
ret = false;
return (ret);
}
@ -1576,7 +1576,7 @@ build_ack_entry(struct tcp_ackent *ae, struct tcphdr *th, struct mbuf *m,
ae->flags = TSTMP_HDWR;
ae->seq = ntohl(th->th_seq);
ae->ack = ntohl(th->th_ack);
ae->flags |= (th->th_x2 << 8) | th->th_flags;
ae->flags |= tcp_get_flags(th);
if (ts_ptr != NULL) {
ae->ts_value = ntohl(ts_ptr[1]);
ae->ts_echo = ntohl(ts_ptr[2]);
@ -1831,7 +1831,7 @@ tcp_lro_rx_common(struct lro_ctrl *lc, struct mbuf *m, uint32_t csum, bool use_h
th = pa->tcp;
/* Don't process SYN packets. */
if (__predict_false(th->th_flags & TH_SYN))
if (__predict_false(tcp_get_flags(th) & TH_SYN))
return (TCP_LRO_CANNOT);
/* Get total TCP header length and compute payload length. */

View File

@ -1287,7 +1287,7 @@ tcp_default_output(struct tcpcb *tp)
bcopy(opt, th + 1, optlen);
th->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
}
th->th_flags = flags;
tcp_set_flags(th, flags);
/*
* Calculate receive window. Don't shrink window,
* but avoid silly window syndrome.

View File

@ -332,7 +332,7 @@ tcp_reass_append(struct tcpcb *tp, struct tseg_qent *last,
last->tqe_len += tlen;
last->tqe_m->m_pkthdr.len += tlen;
/* Preserve the FIN bit if its there */
last->tqe_flags |= (th->th_flags & TH_FIN);
last->tqe_flags |= (tcp_get_flags(th) & TH_FIN);
last->tqe_last->m_next = m;
last->tqe_last = mlast;
last->tqe_mbuf_cnt += lenofoh;
@ -384,7 +384,7 @@ tcp_reass_prepend(struct tcpcb *tp, struct tseg_qent *first, struct mbuf *m, str
static void
tcp_reass_replace(struct tcpcb *tp, struct tseg_qent *q, struct mbuf *m,
tcp_seq seq, int len, struct mbuf *mlast, int mbufoh, uint8_t flags)
tcp_seq seq, int len, struct mbuf *mlast, int mbufoh, uint16_t flags)
{
/*
* Free the data in q, and replace
@ -564,7 +564,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
/*
* Check for zero length data.
*/
if ((*tlenp == 0) && ((th->th_flags & TH_FIN) == 0)) {
if ((*tlenp == 0) && ((tcp_get_flags(th) & TH_FIN) == 0)) {
/*
* A zero length segment does no
* one any good. We could check
@ -581,7 +581,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
#endif
return (0);
} else if ((*tlenp == 0) &&
(th->th_flags & TH_FIN) &&
(tcp_get_flags(th) & TH_FIN) &&
!TCPS_HAVEESTABLISHED(tp->t_state)) {
/*
* We have not established, and we
@ -628,7 +628,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
*/
last = TAILQ_LAST_FAST(&tp->t_segq, tseg_qent, tqe_q);
if (last != NULL) {
if ((th->th_flags & TH_FIN) &&
if ((tcp_get_flags(th) & TH_FIN) &&
SEQ_LT((th->th_seq + *tlenp), (last->tqe_start + last->tqe_len))) {
/*
* Someone is trying to game us, dump
@ -915,7 +915,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
#ifdef TCP_REASS_COUNTERS
counter_u64_add(reass_path7, 1);
#endif
tcp_reass_replace(tp, q, m, th->th_seq, *tlenp, mlast, lenofoh, th->th_flags);
tcp_reass_replace(tp, q, m, th->th_seq, *tlenp, mlast, lenofoh, tcp_get_flags(th));
} else {
/*
* We just need to prepend the data
@ -964,7 +964,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
new_entry:
if (th->th_seq == tp->rcv_nxt && TCPS_HAVEESTABLISHED(tp->t_state)) {
tp->rcv_nxt += *tlenp;
flags = th->th_flags & TH_FIN;
flags = tcp_get_flags(th) & TH_FIN;
TCPSTAT_INC(tcps_rcvoopack);
TCPSTAT_ADD(tcps_rcvoobyte, *tlenp);
SOCKBUF_LOCK(&so->so_rcv);
@ -1039,7 +1039,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
TCPSTAT_ADD(tcps_rcvoobyte, *tlenp);
/* Insert the new segment queue entry into place. */
te->tqe_m = m;
te->tqe_flags = th->th_flags;
te->tqe_flags = tcp_get_flags(th);
te->tqe_len = *tlenp;
te->tqe_start = th->th_seq;
te->tqe_last = mlast;

View File

@ -5907,7 +5907,7 @@ tcp_bbr_tso_size_check(struct tcp_bbr *bbr, uint32_t cts)
static void
bbr_log_output(struct tcp_bbr *bbr, struct tcpcb *tp, struct tcpopt *to, int32_t len,
uint32_t seq_out, uint8_t th_flags, int32_t err, uint32_t cts,
uint32_t seq_out, uint16_t th_flags, int32_t err, uint32_t cts,
struct mbuf *mb, int32_t * abandon, struct bbr_sendmap *hintrsm, uint32_t delay_calc,
struct sockbuf *sb)
{
@ -7337,7 +7337,7 @@ bbr_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th,
uint32_t p_maxseg, maxseg, p_acked = 0;
INP_WLOCK_ASSERT(tp->t_inpcb);
if (th->th_flags & TH_RST) {
if (tcp_get_flags(th) & TH_RST) {
/* We don't log resets */
return (0);
}
@ -8282,7 +8282,7 @@ bbr_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (tp->t_fbyte_out && tp->t_fbyte_in)
tp->t_flags2 |= TF2_FBYTES_COMPLETE;
}
thflags = th->th_flags & TH_FIN;
thflags = tcp_get_flags(th) & TH_FIN;
KMOD_TCPSTAT_ADD(tcps_rcvpack, (int)nsegs);
KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen);
SOCKBUF_LOCK(&so->so_rcv);
@ -11363,7 +11363,7 @@ bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
/* add in our stats */
kern_prefetch(bbr, &prev_state);
prev_state = 0;
thflags = th->th_flags;
thflags = tcp_get_flags(th);
/*
* If this is either a state-changing packet or current state isn't
* established, we require a write lock on tcbinfo. Otherwise, we
@ -13450,7 +13450,7 @@ bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv)
bcopy(opt, th + 1, optlen);
th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
}
th->th_flags = flags;
tcp_set_flags(th, flags);
/*
* Calculate receive window. Don't shrink window, but avoid silly
* window syndrome.

View File

@ -489,7 +489,7 @@ rack_log_ack(struct tcpcb *tp, struct tcpopt *to,
struct tcphdr *th, int entered_rec, int dup_ack_struck);
static void
rack_log_output(struct tcpcb *tp, struct tcpopt *to, int32_t len,
uint32_t seq_out, uint8_t th_flags, int32_t err, uint64_t ts,
uint32_t seq_out, uint16_t th_flags, int32_t err, uint64_t ts,
struct rack_sendmap *hintrsm, uint16_t add_flags, struct mbuf *s_mb, uint32_t s_moff, int hw_tls);
static void
@ -7413,7 +7413,7 @@ rack_update_entry(struct tcpcb *tp, struct tcp_rack *rack,
static void
rack_log_output(struct tcpcb *tp, struct tcpopt *to, int32_t len,
uint32_t seq_out, uint8_t th_flags, int32_t err, uint64_t cts,
uint32_t seq_out, uint16_t th_flags, int32_t err, uint64_t cts,
struct rack_sendmap *hintrsm, uint16_t add_flag, struct mbuf *s_mb, uint32_t s_moff, int hw_tls)
{
struct tcp_rack *rack;
@ -9648,7 +9648,7 @@ rack_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, int entered
INP_WLOCK_ASSERT(tp->t_inpcb);
if (th->th_flags & TH_RST) {
if (tcp_get_flags(th) & TH_RST) {
/* We don't log resets */
return;
}
@ -10800,7 +10800,7 @@ rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (tp->t_fbyte_out && tp->t_fbyte_in)
tp->t_flags2 |= TF2_FBYTES_COMPLETE;
}
thflags = th->th_flags & TH_FIN;
thflags = tcp_get_flags(th) & TH_FIN;
KMOD_TCPSTAT_ADD(tcps_rcvpack, nsegs);
KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen);
SOCKBUF_LOCK(&so->so_rcv);
@ -13409,7 +13409,7 @@ rack_log_input_packet(struct tcpcb *tp, struct tcp_rack *rack, struct tcp_ackent
/* Now fill in the ports */
th->th_sport = tp->t_inpcb->inp_fport;
th->th_dport = tp->t_inpcb->inp_lport;
th->th_flags = ae->flags & 0xff;
tcp_set_flags(th, ae->flags);
/* Now do we have a timestamp option? */
if (ae->flags & HAS_TSTMP) {
u_char *cp;
@ -14242,7 +14242,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
ms_cts = tcp_tv_to_mssectick(tv);
nsegs = m->m_pkthdr.lro_nsegs;
counter_u64_add(rack_proc_non_comp_ack, 1);
thflags = th->th_flags;
thflags = tcp_get_flags(th);
#ifdef TCP_ACCOUNTING
sched_pin();
if (thflags & TH_ACK)
@ -14598,7 +14598,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
}
rack_clear_rate_sample(rack);
if ((rack->forced_ack) &&
((th->th_flags & TH_RST) == 0)) {
((tcp_get_flags(th) & TH_RST) == 0)) {
rack_handle_probe_response(rack, tiwin, us_cts);
}
/*
@ -16006,7 +16006,7 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendma
if ((rsm->r_flags & RACK_HAD_PUSH) &&
(len == (rsm->r_end - rsm->r_start)))
flags |= TH_PUSH;
th->th_flags = flags;
tcp_set_flags(th, flags);
th->th_win = htons((u_short)(rack->r_ctl.fsb.recwin >> tp->rcv_scale));
if (th->th_win == 0) {
tp->t_sndzerowin++;
@ -16483,7 +16483,7 @@ rack_fast_output(struct tcpcb *tp, struct tcp_rack *rack, uint64_t ts_val,
sb_offset = tp->snd_max - tp->snd_una;
th->th_seq = htonl(tp->snd_max);
th->th_ack = htonl(tp->rcv_nxt);
th->th_flags = flags;
tcp_set_flags(th, flags);
th->th_win = htons((u_short)(rack->r_ctl.fsb.recwin >> tp->rcv_scale));
if (th->th_win == 0) {
tp->t_sndzerowin++;
@ -16514,7 +16514,7 @@ rack_fast_output(struct tcpcb *tp, struct tcp_rack *rack, uint64_t ts_val,
}
if (rack->r_ctl.fsb.rfo_apply_push &&
(len == rack->r_ctl.fsb.left_to_send)) {
th->th_flags |= TH_PUSH;
tcp_set_flags(th, flags | TH_PUSH);
add_flag |= RACK_HAD_PUSH;
}
if ((m->m_next == NULL) || (len <= 0)){
@ -18656,7 +18656,7 @@ rack_output(struct tcpcb *tp)
rack_seq = rsm->r_start;
}
th->th_ack = htonl(tp->rcv_nxt);
th->th_flags = flags;
tcp_set_flags(th, flags);
/*
* Calculate receive window. Don't shrink window, but avoid silly
* window syndrome.

View File

@ -1686,9 +1686,8 @@ tcpip_fillheaders(struct inpcb *inp, uint16_t port, void *ip_ptr, void *tcp_ptr)
th->th_dport = inp->inp_fport;
th->th_seq = 0;
th->th_ack = 0;
th->th_x2 = 0;
th->th_off = 5;
th->th_flags = 0;
tcp_set_flags(th, 0);
th->th_win = 0;
th->th_urp = 0;
th->th_sum = 0; /* in_pseudo() is called later for ipv4 */
@ -1746,7 +1745,7 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
uint16_t port;
int output_ret;
#ifdef INVARIANTS
int thflags = th->th_flags;
int thflags = tcp_get_flags(th);
#endif
KASSERT(tp != NULL || m != NULL, ("tcp_respond: tp and m both NULL"));
@ -2016,9 +2015,8 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
#endif
nth->th_seq = htonl(seq);
nth->th_ack = htonl(ack);
nth->th_x2 = 0;
nth->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
nth->th_flags = flags;
tcp_set_flags(nth, flags);
if (tp != NULL)
nth->th_win = htons((u_short) (win >> tp->rcv_scale));
else
@ -4061,7 +4059,7 @@ tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr,
}
sp = s + strlen(s);
if (th)
sprintf(sp, " tcpflags 0x%b", th->th_flags, PRINT_TH_FLAGS);
sprintf(sp, " tcpflags 0x%b", tcp_get_flags(th), PRINT_TH_FLAGS);
if (*(s + size - 1) != '\0')
panic("%s: string too long", __func__);
return (s);

View File

@ -627,7 +627,7 @@ syncache_chkrst(struct in_conninfo *inc, struct tcphdr *th, struct mbuf *m,
* Any RST to our SYN|ACK must not carry ACK, SYN or FIN flags.
* See RFC 793 page 65, section SEGMENT ARRIVES.
*/
if (th->th_flags & (TH_ACK|TH_SYN|TH_FIN)) {
if (tcp_get_flags(th) & (TH_ACK|TH_SYN|TH_FIN)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
log(LOG_DEBUG, "%s; %s: Spurious RST with ACK, SYN or "
"FIN flag set, segment ignored\n", s, __func__);
@ -1097,7 +1097,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
bool locked;
NET_EPOCH_ASSERT();
KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK,
KASSERT((tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK,
("%s: can handle only ACK", __func__));
if (syncache_cookiesonly()) {
@ -1426,7 +1426,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
bool locked;
INP_RLOCK_ASSERT(inp); /* listen socket */
KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN,
KASSERT((tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN,
("%s: unexpected tcp flags", __func__));
/*
@ -1579,7 +1579,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* Disable ECN if needed.
*/
if ((sc->sc_flags & SCF_ECN) &&
((th->th_flags & (TH_ECE|TH_CWR)) != (TH_ECE|TH_CWR))) {
((tcp_get_flags(th) & (TH_ECE|TH_CWR)) != (TH_ECE|TH_CWR))) {
sc->sc_flags &= ~SCF_ECN;
}
#ifdef MAC
@ -1743,7 +1743,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
sc->sc_peer_mss = to->to_mss; /* peer mss may be zero */
if (ltflags & TF_NOOPT)
sc->sc_flags |= SCF_NOOPT;
if (((th->th_flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) &&
if (((tcp_get_flags(th) & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) &&
V_tcp_do_ecn)
sc->sc_flags |= SCF_ECN;
@ -1935,15 +1935,14 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags)
th->th_seq = htonl(sc->sc_iss + 1);
th->th_ack = htonl(sc->sc_irs + 1);
th->th_off = sizeof(struct tcphdr) >> 2;
th->th_x2 = 0;
th->th_flags = flags;
th->th_win = htons(sc->sc_wnd);
th->th_urp = 0;
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ECN)) {
th->th_flags |= TH_ECE;
flags |= TH_ECE;
TCPSTAT_INC(tcps_ecn_shs);
}
tcp_set_flags(th, flags);
/* Tack on the TCP options. */
if ((sc->sc_flags & SCF_NOOPT) == 0) {

View File

@ -409,7 +409,7 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
if (tw == NULL)
goto drop;
thflags = th->th_flags;
thflags = tcp_get_flags(th);
#ifdef INVARIANTS
if ((thflags & (TH_SYN | TH_ACK)) == TH_SYN)
INP_RLOCK_ASSERT(inp);
@ -475,13 +475,13 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
* Send RST if UDP port numbers don't match
*/
if (tw->t_port != m->m_pkthdr.tcp_tun_port) {
if (th->th_flags & TH_ACK) {
if (tcp_get_flags(th) & TH_ACK) {
tcp_respond(NULL, mtod(m, void *), th, m,
(tcp_seq)0, th->th_ack, TH_RST);
} else {
if (th->th_flags & TH_SYN)
if (tcp_get_flags(th) & TH_SYN)
tlen++;
if (th->th_flags & TH_FIN)
if (tcp_get_flags(th) & TH_FIN)
tlen++;
tcp_respond(NULL, mtod(m, void *), th, m,
th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK);
@ -692,7 +692,7 @@ tcp_twrespond(struct tcptw *tw, int flags)
th->th_seq = htonl(tw->snd_nxt);
th->th_ack = htonl(tw->rcv_nxt);
th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
th->th_flags = flags;
tcp_set_flags(th, flags);
th->th_win = htons(tw->last_win);
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)

View File

@ -88,7 +88,7 @@ struct tseg_qent {
struct mbuf *tqe_last; /* last mbuf in chain */
tcp_seq tqe_start; /* TCP Sequence number start */
int tqe_len; /* TCP segment data length */
uint32_t tqe_flags; /* The flags from the th->th_flags */
uint32_t tqe_flags; /* The flags from tcp_get_flags() */
uint32_t tqe_mbuf_cnt; /* Count of mbuf overhead */
};
TAILQ_HEAD(tsegqe_head, tseg_qent);
@ -1257,6 +1257,19 @@ tcp_fields_to_net(struct tcphdr *th)
th->th_urp = htons(th->th_urp);
}
static inline uint16_t
tcp_get_flags(const struct tcphdr *th)
{
return (((uint16_t)th->th_x2 << 8) | th->th_flags);
}
static inline void
tcp_set_flags(struct tcphdr *th, uint16_t flags)
{
th->th_x2 = (flags >> 8) & 0x0f;
th->th_flags = flags & 0xff;
}
static inline void
tcp_account_for_send(struct tcpcb *tp, uint32_t len, uint8_t is_rxt,
uint8_t is_tlp, int hw_tls)