net/mlx4_en: Fix mixed PFC and Global pause user control requests
[pandora-kernel.git] / net / ipv4 / ip_output.c
index 0bc95f3..c3a2b80 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, sk);
 
        if (opt && opt->opt.optlen) {
                iph->ihl += opt->opt.optlen>>2;
@@ -390,8 +390,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;
@@ -833,9 +832,10 @@ 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) {
+           (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
+           (sk->sk_type == SOCK_DGRAM)) {
                err = ip_ufo_append_data(sk, queue, getfrag, from, length,
                                         hh_len, fragheaderlen, transhdrlen,
                                         maxfraglen, flags);
@@ -1334,11 +1334,11 @@ 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);
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
        iph->saddr = fl4->saddr;
        iph->daddr = fl4->daddr;
+       ip_select_ident(skb, sk);
 
        if (opt) {
                iph->ihl += opt->optlen>>2;
@@ -1473,6 +1473,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
        struct ipcm_cookie ipc;
        struct flowi4 fl4;
        struct rtable *rt = skb_rtable(skb);
+       int err;
 
        if (ip_options_echo(&replyopts.opt.opt, skb))
                return;
@@ -1510,8 +1511,13 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
        sk->sk_priority = skb->priority;
        sk->sk_protocol = ip_hdr(skb)->protocol;
        sk->sk_bound_dev_if = arg->bound_dev_if;
-       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;
+       }
+
        if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
                if (arg->csumoffset >= 0)
                        *((__sum16 *)skb_transport_header(skb) +
@@ -1520,7 +1526,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
                skb->ip_summed = CHECKSUM_NONE;
                ip_push_pending_frames(sk, &fl4);
        }
-
+out:
        bh_unlock_sock(sk);
 
        ip_rt_put(rt);