while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
                offset = seq - TCP_SKB_CB(skb)->seq;
-               if (tcp_hdr(skb)->syn)
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
                        offset--;
-               if (offset < skb->len || tcp_hdr(skb)->fin) {
+               if (offset < skb->len || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) {
                        *off = offset;
                        return skb;
                }
                        if (offset + 1 != skb->len)
                                continue;
                }
-               if (tcp_hdr(skb)->fin) {
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) {
                        sk_eat_skb(sk, skb, false);
                        ++seq;
                        break;
                                break;
 
                        offset = *seq - TCP_SKB_CB(skb)->seq;
-                       if (tcp_hdr(skb)->syn)
+                       if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
                                offset--;
                        if (offset < skb->len)
                                goto found_ok_skb;
-                       if (tcp_hdr(skb)->fin)
+                       if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
                                goto found_fin_ok;
                        WARN(!(flags & MSG_PEEK),
                             "recvmsg bug 2: copied %X seq %X rcvnxt %X fl %X\n",
                if (used + offset < skb->len)
                        continue;
 
-               if (tcp_hdr(skb)->fin)
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
                        goto found_fin_ok;
                if (!(flags & MSG_PEEK)) {
                        sk_eat_skb(sk, skb, copied_early);
         *  reader process may not have drained the data yet!
         */
        while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-               u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq -
-                         tcp_hdr(skb)->fin;
+               u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq;
+
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
+                       len--;
                data_was_unread += len;
                __kfree_skb(skb);
        }
 
                __skb_unlink(skb, &tp->out_of_order_queue);
                __skb_queue_tail(&sk->sk_receive_queue, skb);
                tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
-               if (tcp_hdr(skb)->fin)
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
                        tcp_fin(sk);
        }
 }
                 * - bloated or contains data before "start" or
                 *   overlaps to the next one.
                 */
-               if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin &&
+               if (!(TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN)) &&
                    (tcp_win_from_space(skb->truesize) > skb->len ||
                     before(TCP_SKB_CB(skb)->seq, start))) {
                        end_of_skbs = false;
                /* Decided to skip this, advance start seq. */
                start = TCP_SKB_CB(skb)->end_seq;
        }
-       if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin)
+       if (end_of_skbs ||
+           (TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN)))
                return;
 
        while (before(start, end)) {
                                skb = tcp_collapse_one(sk, skb, list);
                                if (!skb ||
                                    skb == tail ||
-                                   tcp_hdr(skb)->syn ||
-                                   tcp_hdr(skb)->fin)
+                                   (TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN)))
                                        return;
                        }
                }
 
        TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
                                    skb->len - th->doff * 4);
        TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
+       TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
        TCP_SKB_CB(skb)->tcp_tw_isn = 0;
        TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
        TCP_SKB_CB(skb)->sacked  = 0;
 
        TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
                                    skb->len - th->doff*4);
        TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
+       TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
        TCP_SKB_CB(skb)->tcp_tw_isn = 0;
        TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
        TCP_SKB_CB(skb)->sacked = 0;