@@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
1591
1591
}
1592
1592
EXPORT_SYMBOL (tcp_filter );
1593
1593
1594
+ static void tcp_v4_restore_cb (struct sk_buff * skb )
1595
+ {
1596
+ memmove (IPCB (skb ), & TCP_SKB_CB (skb )-> header .h4 ,
1597
+ sizeof (struct inet_skb_parm ));
1598
+ }
1599
+
1600
+ static void tcp_v4_fill_cb (struct sk_buff * skb , const struct iphdr * iph ,
1601
+ const struct tcphdr * th )
1602
+ {
1603
+ /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1604
+ * barrier() makes sure compiler wont play fool^Waliasing games.
1605
+ */
1606
+ memmove (& TCP_SKB_CB (skb )-> header .h4 , IPCB (skb ),
1607
+ sizeof (struct inet_skb_parm ));
1608
+ barrier ();
1609
+
1610
+ TCP_SKB_CB (skb )-> seq = ntohl (th -> seq );
1611
+ TCP_SKB_CB (skb )-> end_seq = (TCP_SKB_CB (skb )-> seq + th -> syn + th -> fin +
1612
+ skb -> len - th -> doff * 4 );
1613
+ TCP_SKB_CB (skb )-> ack_seq = ntohl (th -> ack_seq );
1614
+ TCP_SKB_CB (skb )-> tcp_flags = tcp_flag_byte (th );
1615
+ TCP_SKB_CB (skb )-> tcp_tw_isn = 0 ;
1616
+ TCP_SKB_CB (skb )-> ip_dsfield = ipv4_get_dsfield (iph );
1617
+ TCP_SKB_CB (skb )-> sacked = 0 ;
1618
+ TCP_SKB_CB (skb )-> has_rxtstamp =
1619
+ skb -> tstamp || skb_hwtstamps (skb )-> hwtstamp ;
1620
+ }
1621
+
1594
1622
/*
1595
1623
* From tcp_input.c
1596
1624
*/
@@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
1631
1659
1632
1660
th = (const struct tcphdr * )skb -> data ;
1633
1661
iph = ip_hdr (skb );
1634
- /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1635
- * barrier() makes sure compiler wont play fool^Waliasing games.
1636
- */
1637
- memmove (& TCP_SKB_CB (skb )-> header .h4 , IPCB (skb ),
1638
- sizeof (struct inet_skb_parm ));
1639
- barrier ();
1640
-
1641
- TCP_SKB_CB (skb )-> seq = ntohl (th -> seq );
1642
- TCP_SKB_CB (skb )-> end_seq = (TCP_SKB_CB (skb )-> seq + th -> syn + th -> fin +
1643
- skb -> len - th -> doff * 4 );
1644
- TCP_SKB_CB (skb )-> ack_seq = ntohl (th -> ack_seq );
1645
- TCP_SKB_CB (skb )-> tcp_flags = tcp_flag_byte (th );
1646
- TCP_SKB_CB (skb )-> tcp_tw_isn = 0 ;
1647
- TCP_SKB_CB (skb )-> ip_dsfield = ipv4_get_dsfield (iph );
1648
- TCP_SKB_CB (skb )-> sacked = 0 ;
1649
- TCP_SKB_CB (skb )-> has_rxtstamp =
1650
- skb -> tstamp || skb_hwtstamps (skb )-> hwtstamp ;
1651
-
1652
1662
lookup :
1653
1663
sk = __inet_lookup_skb (& tcp_hashinfo , skb , __tcp_hdrlen (th ), th -> source ,
1654
1664
th -> dest , sdif , & refcounted );
@@ -1679,14 +1689,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
1679
1689
sock_hold (sk );
1680
1690
refcounted = true;
1681
1691
nsk = NULL ;
1682
- if (!tcp_filter (sk , skb ))
1692
+ if (!tcp_filter (sk , skb )) {
1693
+ th = (const struct tcphdr * )skb -> data ;
1694
+ iph = ip_hdr (skb );
1695
+ tcp_v4_fill_cb (skb , iph , th );
1683
1696
nsk = tcp_check_req (sk , skb , req , false);
1697
+ }
1684
1698
if (!nsk ) {
1685
1699
reqsk_put (req );
1686
1700
goto discard_and_relse ;
1687
1701
}
1688
1702
if (nsk == sk ) {
1689
1703
reqsk_put (req );
1704
+ tcp_v4_restore_cb (skb );
1690
1705
} else if (tcp_child_process (sk , nsk , skb )) {
1691
1706
tcp_v4_send_reset (nsk , skb );
1692
1707
goto discard_and_relse ;
@@ -1712,6 +1727,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1712
1727
goto discard_and_relse ;
1713
1728
th = (const struct tcphdr * )skb -> data ;
1714
1729
iph = ip_hdr (skb );
1730
+ tcp_v4_fill_cb (skb , iph , th );
1715
1731
1716
1732
skb -> dev = NULL ;
1717
1733
@@ -1742,6 +1758,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
1742
1758
if (!xfrm4_policy_check (NULL , XFRM_POLICY_IN , skb ))
1743
1759
goto discard_it ;
1744
1760
1761
+ tcp_v4_fill_cb (skb , iph , th );
1762
+
1745
1763
if (tcp_checksum_complete (skb )) {
1746
1764
csum_error :
1747
1765
__TCP_INC_STATS (net , TCP_MIB_CSUMERRORS );
@@ -1768,6 +1786,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
1768
1786
goto discard_it ;
1769
1787
}
1770
1788
1789
+ tcp_v4_fill_cb (skb , iph , th );
1790
+
1771
1791
if (tcp_checksum_complete (skb )) {
1772
1792
inet_twsk_put (inet_twsk (sk ));
1773
1793
goto csum_error ;
@@ -1784,6 +1804,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1784
1804
if (sk2 ) {
1785
1805
inet_twsk_deschedule_put (inet_twsk (sk ));
1786
1806
sk = sk2 ;
1807
+ tcp_v4_restore_cb (skb );
1787
1808
refcounted = false;
1788
1809
goto process ;
1789
1810
}
0 commit comments