Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
[firefly-linux-kernel-4.4.55.git] / net / ipv4 / ip_output.c
index 6ca5873d617553b27be5d1bcb315e145087c3d4c..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(skb, &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(skb, &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;
@@ -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(skb, &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;
@@ -1497,12 +1497,14 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
                        daddr = replyopts.opt.opt.faddr;
        }
 
-       flowi4_init_output(&fl4, arg->bound_dev_if, 0,
+       flowi4_init_output(&fl4, arg->bound_dev_if,
+                          IP4_REPLY_MARK(net, skb->mark),
                           RT_TOS(arg->tos),
                           RT_SCOPE_UNIVERSE, ip_hdr(skb)->protocol,
                           ip_reply_arg_flowi_flags(arg),
                           daddr, saddr,
-                          tcp_hdr(skb)->source, tcp_hdr(skb)->dest);
+                          tcp_hdr(skb)->source, tcp_hdr(skb)->dest,
+                          arg->uid);
        security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
        rt = ip_route_output_key(net, &fl4);
        if (IS_ERR(rt))
@@ -1518,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)
@@ -1531,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);