Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
[firefly-linux-kernel-4.4.55.git] / net / ipv4 / ip_output.c
index 8e20e9405582fc9bb2bb3cb0ba4c03d1c253f83f..1bb117130e3ed599f319a6b986295d97fafcfbf7 100644 (file)
@@ -148,7 +148,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, sk);
 
        if (opt && opt->opt.optlen) {
                iph->ihl += opt->opt.optlen>>2;
@@ -394,8 +394,7 @@ packet_routed:
                ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
        }
 
-       ip_select_ident_more(iph, &rt->dst, sk,
-                            (skb_shinfo(skb)->gso_segs ?: 1) - 1);
+       ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1);
 
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
@@ -844,7 +843,7 @@ static int __ip_append_data(struct sock *sk,
                csummode = CHECKSUM_PARTIAL;
 
        cork->length += length;
-       if (((length > mtu) || (skb && skb_is_gso(skb))) &&
+       if (((length > mtu) || (skb && skb_has_frags(skb))) &&
            (sk->sk_protocol == IPPROTO_UDP) &&
            (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
                err = ip_ufo_append_data(sk, queue, getfrag, from, length,
@@ -1324,7 +1323,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
        else
                ttl = ip_select_ttl(inet, &rt->dst);
 
-       iph = (struct iphdr *)skb->data;
+       iph = ip_hdr(skb);
        iph->version = 4;
        iph->ihl = 5;
        iph->tos = inet->tos;
@@ -1332,7 +1331,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
        ip_copy_addrs(iph, fl4);
-       ip_select_ident(iph, &rt->dst, sk);
+       ip_select_ident(skb, sk);
 
        if (opt) {
                iph->ihl += opt->optlen>>2;
@@ -1482,6 +1481,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
        struct sk_buff *nskb;
        struct sock *sk;
        struct inet_sock *inet;
+       int err;
 
        if (ip_options_echo(&replyopts.opt.opt, skb))
                return;
@@ -1520,8 +1520,13 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
        sock_net_set(sk, net);
        __skb_queue_head_init(&sk->sk_write_queue);
        sk->sk_sndbuf = sysctl_wmem_default;
-       ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
-                      &ipc, &rt, MSG_DONTWAIT);
+       err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
+                            len, 0, &ipc, &rt, MSG_DONTWAIT);
+       if (unlikely(err)) {
+               ip_flush_pending_frames(sk);
+               goto out;
+       }
+
        nskb = skb_peek(&sk->sk_write_queue);
        if (nskb) {
                if (arg->csumoffset >= 0)
@@ -1533,7 +1538,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
                skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
                ip_push_pending_frames(sk, &fl4);
        }
-
+out:
        put_cpu_var(unicast_sock);
 
        ip_rt_put(rt);