tcp: must unclone packets before mangling them
[pandora-kernel.git] / net / ipv4 / ip_output.c
index 8c65633..daf408e 100644 (file)
@@ -162,7 +162,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
        iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
        iph->saddr    = saddr;
        iph->protocol = sk->sk_protocol;
-       ip_select_ident(iph, &rt->dst, sk);
+       ip_select_ident(skb, &rt->dst, sk);
 
        if (opt && opt->opt.optlen) {
                iph->ihl += opt->opt.optlen>>2;
@@ -390,7 +390,7 @@ packet_routed:
                ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
        }
 
-       ip_select_ident_more(iph, &rt->dst, sk,
+       ip_select_ident_more(skb, &rt->dst, sk,
                             (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
        skb->priority = sk->sk_priority;
@@ -989,13 +989,13 @@ alloc_new_skb:
                        if (page && (left = PAGE_SIZE - off) > 0) {
                                if (copy >= left)
                                        copy = left;
-                               if (page != frag->page) {
+                               if (page != skb_frag_page(frag)) {
                                        if (i == MAX_SKB_FRAGS) {
                                                err = -EMSGSIZE;
                                                goto error;
                                        }
-                                       get_page(page);
                                        skb_fill_page_desc(skb, i, page, off, 0);
+                                       skb_frag_ref(skb, i);
                                        frag = &skb_shinfo(skb)->frags[i];
                                }
                        } else if (i < MAX_SKB_FRAGS) {
@@ -1015,12 +1015,13 @@ alloc_new_skb:
                                err = -EMSGSIZE;
                                goto error;
                        }
-                       if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) {
+                       if (getfrag(from, skb_frag_address(frag)+skb_frag_size(frag),
+                                   offset, copy, skb->len, skb) < 0) {
                                err = -EFAULT;
                                goto error;
                        }
                        cork->off += copy;
-                       frag->size += copy;
+                       skb_frag_size_add(frag, copy);
                        skb->len += copy;
                        skb->data_len += copy;
                        skb->truesize += copy;
@@ -1229,7 +1230,7 @@ ssize_t   ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
                if (len > size)
                        len = size;
                if (skb_can_coalesce(skb, i, page, offset)) {
-                       skb_shinfo(skb)->frags[i-1].size += len;
+                       skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], len);
                } else if (i < MAX_SKB_FRAGS) {
                        get_page(page);
                        skb_fill_page_desc(skb, i, page, offset, len);
@@ -1333,7 +1334,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
        iph->ihl = 5;
        iph->tos = inet->tos;
        iph->frag_off = df;
-       ip_select_ident(iph, &rt->dst, sk);
+       ip_select_ident(skb, &rt->dst, sk);
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
        iph->saddr = fl4->saddr;
@@ -1465,7 +1466,7 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset,
  *             structure to pass arguments.
  */
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
-                  struct ip_reply_arg *arg, unsigned int len)
+                  const struct ip_reply_arg *arg, unsigned int len)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct ip_options_data replyopts;
@@ -1488,7 +1489,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
        }
 
        flowi4_init_output(&fl4, arg->bound_dev_if, 0,
-                          RT_TOS(ip_hdr(skb)->tos),
+                          RT_TOS(arg->tos),
                           RT_SCOPE_UNIVERSE, sk->sk_protocol,
                           ip_reply_arg_flowi_flags(arg),
                           daddr, rt->rt_spec_dst,
@@ -1505,7 +1506,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
           with locally disabled BH and that sk cannot be already spinlocked.
         */
        bh_lock_sock(sk);
-       inet->tos = ip_hdr(skb)->tos;
+       inet->tos = arg->tos;
        sk->sk_priority = skb->priority;
        sk->sk_protocol = ip_hdr(skb)->protocol;
        sk->sk_bound_dev_if = arg->bound_dev_if;