@@ -1587,6 +1587,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
1587
1587
}
1588
1588
EXPORT_SYMBOL (tcp_filter );
1589
1589
1590
+ static void tcp_v4_restore_cb (struct sk_buff * skb )
1591
+ {
1592
+ memmove (IPCB (skb ), & TCP_SKB_CB (skb )-> header .h4 ,
1593
+ sizeof (struct inet_skb_parm ));
1594
+ }
1595
+
1596
+ static void tcp_v4_fill_cb (struct sk_buff * skb , const struct iphdr * iph ,
1597
+ const struct tcphdr * th )
1598
+ {
1599
+ /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1600
+ * barrier() makes sure compiler wont play fool^Waliasing games.
1601
+ */
1602
+ memmove (& TCP_SKB_CB (skb )-> header .h4 , IPCB (skb ),
1603
+ sizeof (struct inet_skb_parm ));
1604
+ barrier ();
1605
+
1606
+ TCP_SKB_CB (skb )-> seq = ntohl (th -> seq );
1607
+ TCP_SKB_CB (skb )-> end_seq = (TCP_SKB_CB (skb )-> seq + th -> syn + th -> fin +
1608
+ skb -> len - th -> doff * 4 );
1609
+ TCP_SKB_CB (skb )-> ack_seq = ntohl (th -> ack_seq );
1610
+ TCP_SKB_CB (skb )-> tcp_flags = tcp_flag_byte (th );
1611
+ TCP_SKB_CB (skb )-> tcp_tw_isn = 0 ;
1612
+ TCP_SKB_CB (skb )-> ip_dsfield = ipv4_get_dsfield (iph );
1613
+ TCP_SKB_CB (skb )-> sacked = 0 ;
1614
+ TCP_SKB_CB (skb )-> has_rxtstamp =
1615
+ skb -> tstamp || skb_hwtstamps (skb )-> hwtstamp ;
1616
+ }
1617
+
1590
1618
/*
1591
1619
* From tcp_input.c
1592
1620
*/
@@ -1627,24 +1655,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
1627
1655
1628
1656
th = (const struct tcphdr * )skb -> data ;
1629
1657
iph = ip_hdr (skb );
1630
- /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1631
- * barrier() makes sure compiler wont play fool^Waliasing games.
1632
- */
1633
- memmove (& TCP_SKB_CB (skb )-> header .h4 , IPCB (skb ),
1634
- sizeof (struct inet_skb_parm ));
1635
- barrier ();
1636
-
1637
- TCP_SKB_CB (skb )-> seq = ntohl (th -> seq );
1638
- TCP_SKB_CB (skb )-> end_seq = (TCP_SKB_CB (skb )-> seq + th -> syn + th -> fin +
1639
- skb -> len - th -> doff * 4 );
1640
- TCP_SKB_CB (skb )-> ack_seq = ntohl (th -> ack_seq );
1641
- TCP_SKB_CB (skb )-> tcp_flags = tcp_flag_byte (th );
1642
- TCP_SKB_CB (skb )-> tcp_tw_isn = 0 ;
1643
- TCP_SKB_CB (skb )-> ip_dsfield = ipv4_get_dsfield (iph );
1644
- TCP_SKB_CB (skb )-> sacked = 0 ;
1645
- TCP_SKB_CB (skb )-> has_rxtstamp =
1646
- skb -> tstamp || skb_hwtstamps (skb )-> hwtstamp ;
1647
-
1648
1658
lookup :
1649
1659
sk = __inet_lookup_skb (& tcp_hashinfo , skb , __tcp_hdrlen (th ), th -> source ,
1650
1660
th -> dest , sdif , & refcounted );
@@ -1675,14 +1685,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
1675
1685
sock_hold (sk );
1676
1686
refcounted = true;
1677
1687
nsk = NULL ;
1678
- if (!tcp_filter (sk , skb ))
1688
+ if (!tcp_filter (sk , skb )) {
1689
+ th = (const struct tcphdr * )skb -> data ;
1690
+ iph = ip_hdr (skb );
1691
+ tcp_v4_fill_cb (skb , iph , th );
1679
1692
nsk = tcp_check_req (sk , skb , req , false);
1693
+ }
1680
1694
if (!nsk ) {
1681
1695
reqsk_put (req );
1682
1696
goto discard_and_relse ;
1683
1697
}
1684
1698
if (nsk == sk ) {
1685
1699
reqsk_put (req );
1700
+ tcp_v4_restore_cb (skb );
1686
1701
} else if (tcp_child_process (sk , nsk , skb )) {
1687
1702
tcp_v4_send_reset (nsk , skb );
1688
1703
goto discard_and_relse ;
@@ -1708,6 +1723,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1708
1723
goto discard_and_relse ;
1709
1724
th = (const struct tcphdr * )skb -> data ;
1710
1725
iph = ip_hdr (skb );
1726
+ tcp_v4_fill_cb (skb , iph , th );
1711
1727
1712
1728
skb -> dev = NULL ;
1713
1729
@@ -1738,6 +1754,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
1738
1754
if (!xfrm4_policy_check (NULL , XFRM_POLICY_IN , skb ))
1739
1755
goto discard_it ;
1740
1756
1757
+ tcp_v4_fill_cb (skb , iph , th );
1758
+
1741
1759
if (tcp_checksum_complete (skb )) {
1742
1760
csum_error :
1743
1761
__TCP_INC_STATS (net , TCP_MIB_CSUMERRORS );
@@ -1764,6 +1782,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
1764
1782
goto discard_it ;
1765
1783
}
1766
1784
1785
+ tcp_v4_fill_cb (skb , iph , th );
1786
+
1767
1787
if (tcp_checksum_complete (skb )) {
1768
1788
inet_twsk_put (inet_twsk (sk ));
1769
1789
goto csum_error ;
@@ -1780,6 +1800,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1780
1800
if (sk2 ) {
1781
1801
inet_twsk_deschedule_put (inet_twsk (sk ));
1782
1802
sk = sk2 ;
1803
+ tcp_v4_restore_cb (skb );
1783
1804
refcounted = false;
1784
1805
goto process ;
1785
1806
}
0 commit comments