diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 28ab90382c01..9ce3eac02957 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -886,18 +886,16 @@ EXPORT_SYMBOL(tcp_syn_flood_action); | |||
886 | */ | 886 | */ |
887 | static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) | 887 | static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) |
888 | { | 888 | { |
889 | const struct ip_options *opt = &(IPCB(skb)->opt); | 889 | const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; |
890 | struct ip_options_rcu *dopt = NULL; | 890 | struct ip_options_rcu *dopt = NULL; |
891 | 891 | ||
892 | if (opt && opt->optlen) { | 892 | if (opt && opt->optlen) { |
893 | int opt_size = sizeof(*dopt) + opt->optlen; | 893 | int opt_size = sizeof(*dopt) + opt->optlen; |
894 | 894 | ||
895 | dopt = kmalloc(opt_size, GFP_ATOMIC); | 895 | dopt = kmalloc(opt_size, GFP_ATOMIC); |
896 | if (dopt) { | 896 | if (dopt && __ip_options_echo(&dopt->opt, skb, opt)) { |
897 | if (ip_options_echo(&dopt->opt, skb)) { | 897 | kfree(dopt); |
898 | kfree(dopt); | 898 | dopt = NULL; |
899 | dopt = NULL; | ||
900 | } | ||
901 | } | 899 | } |
902 | } | 900 | } |
903 | return dopt; | 901 | return dopt; |
@@ -1431,7 +1429,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
1431 | 1429 | ||
1432 | #ifdef CONFIG_SYN_COOKIES | 1430 | #ifdef CONFIG_SYN_COOKIES |
1433 | if (!th->syn) | 1431 | if (!th->syn) |
1434 | sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt)); | 1432 | sk = cookie_v4_check(sk, skb, &TCP_SKB_CB(skb)->header.h4.opt); |
1435 | #endif | 1433 | #endif |
1436 | return sk; | 1434 | return sk; |
1437 | } | 1435 | } |
@@ -1636,6 +1634,13 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1636 | 1634 | ||
1637 | th = tcp_hdr(skb); | 1635 | th = tcp_hdr(skb); |
1638 | iph = ip_hdr(skb); | 1636 | iph = ip_hdr(skb); |
1637 | /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB() | ||
1638 | * barrier() makes sure compiler wont play fool^Waliasing games. | ||
1639 | */ | ||
1640 | memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb), | ||
1641 | sizeof(struct inet_skb_parm)); | ||
1642 | barrier(); | ||
1643 | |||
1639 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | 1644 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); |
1640 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | 1645 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + |
1641 | skb->len - th->doff * 4); | 1646 | skb->len - th->doff * 4); |