The branch main has been updated by rscheff:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1ebf460758723efcdb830aceb89164512d56051a

commit 1ebf460758723efcdb830aceb89164512d56051a
Author:     Richard Scheffenegger <[email protected]>
AuthorDate: 2022-02-03 15:21:25 +0000
Commit:     Richard Scheffenegger <[email protected]>
CommitDate: 2022-02-03 15:21:58 +0000

    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
---
 sys/netinet/tcp_debug.c       |  4 ++--
 sys/netinet/tcp_input.c       | 16 ++++++++--------
 sys/netinet/tcp_lro.c         | 16 ++++++++--------
 sys/netinet/tcp_output.c      |  2 +-
 sys/netinet/tcp_reass.c       | 16 ++++++++--------
 sys/netinet/tcp_stacks/bbr.c  | 10 +++++-----
 sys/netinet/tcp_stacks/rack.c | 22 +++++++++++-----------
 sys/netinet/tcp_subr.c        | 10 ++++------
 sys/netinet/tcp_syncache.c    | 15 +++++++--------
 sys/netinet/tcp_timewait.c    | 10 +++++-----
 sys/netinet/tcp_var.h         | 15 ++++++++++++++-
 11 files changed, 73 insertions(+), 63 deletions(-)

diff --git a/sys/netinet/tcp_debug.c b/sys/netinet/tcp_debug.c
index aedaa131095f..1c8924ea09dd 100644
--- a/sys/netinet/tcp_debug.c
+++ b/sys/netinet/tcp_debug.c
@@ -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 = ",";                       \
        }                                       \
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 5ffbf18b5991..9a1f3ace2541 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -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 @@ dodata:                                                   
/* XXX */
                                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);
diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
index c1d3b0d4f13f..2a20a5ce4e6d 100644
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -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 @@ again:
                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 @@ again:
                        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 @@ again:
                }
                /* 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. */
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index ff40e67767ab..dc512c8aad39 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1287,7 +1287,7 @@ send:
                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.
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 5b9255da3acf..27839c7d066e 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -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 @@ strip_fin:
 #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 @@ strip_fin:
         */
        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 @@ strip_fin:
 #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 @@ strip_fin:
 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 @@ new_entry:
        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;
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index c5cf8a46880f..a9abf72c3f93 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -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 @@ send:
                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.
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 93f5adc08a5b..7983c18620e2 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -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 @@ again:
        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 @@ again:
        }
        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 @@ send:
                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.
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 47b6ff173afe..1cd53db3bf99 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -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);
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 32ca3bc2209b..5fcafa44cc97 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -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 @@ skip_alloc:
                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) {
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 1efc93aef1f9..3a87821108c4 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -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)
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index ccfd9a8f11e2..4f2db050799e 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -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)

Reply via email to