@@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
15911591}
15921592EXPORT_SYMBOL (tcp_filter );
15931593
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+
15941622/*
15951623 * From tcp_input.c
15961624 */
@@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
16311659
16321660 th = (const struct tcphdr * )skb -> data ;
16331661 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-
16521662lookup :
16531663 sk = __inet_lookup_skb (& tcp_hashinfo , skb , __tcp_hdrlen (th ), th -> source ,
16541664 th -> dest , sdif , & refcounted );
@@ -1679,14 +1689,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
16791689 sock_hold (sk );
16801690 refcounted = true;
16811691 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 );
16831696 nsk = tcp_check_req (sk , skb , req , false);
1697+ }
16841698 if (!nsk ) {
16851699 reqsk_put (req );
16861700 goto discard_and_relse ;
16871701 }
16881702 if (nsk == sk ) {
16891703 reqsk_put (req );
1704+ tcp_v4_restore_cb (skb );
16901705 } else if (tcp_child_process (sk , nsk , skb )) {
16911706 tcp_v4_send_reset (nsk , skb );
16921707 goto discard_and_relse ;
@@ -1712,6 +1727,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
17121727 goto discard_and_relse ;
17131728 th = (const struct tcphdr * )skb -> data ;
17141729 iph = ip_hdr (skb );
1730+ tcp_v4_fill_cb (skb , iph , th );
17151731
17161732 skb -> dev = NULL ;
17171733
@@ -1742,6 +1758,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
17421758 if (!xfrm4_policy_check (NULL , XFRM_POLICY_IN , skb ))
17431759 goto discard_it ;
17441760
1761+ tcp_v4_fill_cb (skb , iph , th );
1762+
17451763 if (tcp_checksum_complete (skb )) {
17461764csum_error :
17471765 __TCP_INC_STATS (net , TCP_MIB_CSUMERRORS );
@@ -1768,6 +1786,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
17681786 goto discard_it ;
17691787 }
17701788
1789+ tcp_v4_fill_cb (skb , iph , th );
1790+
17711791 if (tcp_checksum_complete (skb )) {
17721792 inet_twsk_put (inet_twsk (sk ));
17731793 goto csum_error ;
@@ -1784,6 +1804,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
17841804 if (sk2 ) {
17851805 inet_twsk_deschedule_put (inet_twsk (sk ));
17861806 sk = sk2 ;
1807+ tcp_v4_restore_cb (skb );
17871808 refcounted = false;
17881809 goto process ;
17891810 }
0 commit comments