TCP_MD5UNEXPECTED)                                   \
        EM(SKB_DROP_REASON_TCP_MD5FAILURE, TCP_MD5FAILURE)      \
        EM(SKB_DROP_REASON_SOCKET_BACKLOG, SOCKET_BACKLOG)      \
+       EM(SKB_DROP_REASON_TCP_FLAGS, TCP_FLAGS)                \
        EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
 
  */
 void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
 {
+       enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
        const struct tcphdr *th = (const struct tcphdr *)skb->data;
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned int len = skb->len;
                                tp->rcv_rtt_last_tsecr = tp->rx_opt.rcv_tsecr;
                                return;
                        } else { /* Header too small */
+                               reason = SKB_DROP_REASON_PKT_TOO_SMALL;
                                TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
                                goto discard;
                        }
        if (len < (th->doff << 2) || tcp_checksum_complete(skb))
                goto csum_error;
 
-       if (!th->ack && !th->rst && !th->syn)
+       if (!th->ack && !th->rst && !th->syn) {
+               reason = SKB_DROP_REASON_TCP_FLAGS;
                goto discard;
+       }
 
        /*
         *      Standard slow path.
        return;
 
 csum_error:
+       reason = SKB_DROP_REASON_TCP_CSUM;
        trace_tcp_bad_csum(skb);
        TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
        TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
 
 discard:
-       tcp_drop(sk, skb);
+       tcp_drop_reason(sk, skb, reason);
 }
 EXPORT_SYMBOL(tcp_rcv_established);