aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c6bc0c4d19c6..77ea45da0fe9 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1591,6 +1591,34 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb)
1591} 1591}
1592EXPORT_SYMBOL(tcp_filter); 1592EXPORT_SYMBOL(tcp_filter);
1593 1593
1594static 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
1600static 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 * From tcp_input.c 1623 * From tcp_input.c
1596 */ 1624 */
@@ -1631,24 +1659,6 @@ int tcp_v4_rcv(struct sk_buff *skb)
1631 1659
1632 th = (const struct tcphdr *)skb->data; 1660 th = (const struct tcphdr *)skb->data;
1633 iph = ip_hdr(skb); 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
1652lookup: 1662lookup:
1653 sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, 1663 sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
1654 th->dest, sdif, &refcounted); 1664 th->dest, sdif, &refcounted);
@@ -1679,14 +1689,19 @@ process:
1679 sock_hold(sk); 1689 sock_hold(sk);
1680 refcounted = true; 1690 refcounted = true;
1681 nsk = NULL; 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 nsk = tcp_check_req(sk, skb, req, false); 1696 nsk = tcp_check_req(sk, skb, req, false);
1697 }
1684 if (!nsk) { 1698 if (!nsk) {
1685 reqsk_put(req); 1699 reqsk_put(req);
1686 goto discard_and_relse; 1700 goto discard_and_relse;
1687 } 1701 }
1688 if (nsk == sk) { 1702 if (nsk == sk) {
1689 reqsk_put(req); 1703 reqsk_put(req);
1704 tcp_v4_restore_cb(skb);
1690 } else if (tcp_child_process(sk, nsk, skb)) { 1705 } else if (tcp_child_process(sk, nsk, skb)) {
1691 tcp_v4_send_reset(nsk, skb); 1706 tcp_v4_send_reset(nsk, skb);
1692 goto discard_and_relse; 1707 goto discard_and_relse;
@@ -1712,6 +1727,7 @@ process:
1712 goto discard_and_relse; 1727 goto discard_and_relse;
1713 th = (const struct tcphdr *)skb->data; 1728 th = (const struct tcphdr *)skb->data;
1714 iph = ip_hdr(skb); 1729 iph = ip_hdr(skb);
1730 tcp_v4_fill_cb(skb, iph, th);
1715 1731
1716 skb->dev = NULL; 1732 skb->dev = NULL;
1717 1733
@@ -1742,6 +1758,8 @@ no_tcp_socket:
1742 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) 1758 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
1743 goto discard_it; 1759 goto discard_it;
1744 1760
1761 tcp_v4_fill_cb(skb, iph, th);
1762
1745 if (tcp_checksum_complete(skb)) { 1763 if (tcp_checksum_complete(skb)) {
1746csum_error: 1764csum_error:
1747 __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); 1765 __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS);
@@ -1768,6 +1786,8 @@ do_time_wait:
1768 goto discard_it; 1786 goto discard_it;
1769 } 1787 }
1770 1788
1789 tcp_v4_fill_cb(skb, iph, th);
1790
1771 if (tcp_checksum_complete(skb)) { 1791 if (tcp_checksum_complete(skb)) {
1772 inet_twsk_put(inet_twsk(sk)); 1792 inet_twsk_put(inet_twsk(sk));
1773 goto csum_error; 1793 goto csum_error;
@@ -1784,6 +1804,7 @@ do_time_wait:
1784 if (sk2) { 1804 if (sk2) {
1785 inet_twsk_deschedule_put(inet_twsk(sk)); 1805 inet_twsk_deschedule_put(inet_twsk(sk));
1786 sk = sk2; 1806 sk = sk2;
1807 tcp_v4_restore_cb(skb);
1787 refcounted = false; 1808 refcounted = false;
1788 goto process; 1809 goto process;
1789 } 1810 }