Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / net / ipv6 / ip6_output.c
index 64d6073731d368e54073f9ca97ac6ad0cecdd415..40e7581374f7006c6f8c436ed686919ac93c2b19 100644 (file)
@@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb)
                return ip6_finish_output2(skb);
 }
 
-int ip6_output(struct sk_buff *skb)
+int ip6_output(struct sock *sk, struct sk_buff *skb)
 {
        struct net_device *dev = skb_dst(skb)->dev;
        struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
@@ -367,6 +367,9 @@ int ip6_forward(struct sk_buff *skb)
        if (net->ipv6.devconf_all->forwarding == 0)
                goto error;
 
+       if (skb->pkt_type != PACKET_HOST)
+               goto drop;
+
        if (skb_warn_if_lro(skb))
                goto drop;
 
@@ -376,9 +379,6 @@ int ip6_forward(struct sk_buff *skb)
                goto drop;
        }
 
-       if (skb->pkt_type != PACKET_HOST)
-               goto drop;
-
        skb_forward_csum(skb);
 
        /*
@@ -1230,8 +1230,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
                              sizeof(struct frag_hdr) : 0) +
                             rt->rt6i_nfheader_len;
 
-               maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ?
-                                mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
+               if (ip6_sk_local_df(sk))
+                       maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
+               else
+                       maxnonfragsize = mtu;
 
                /* dontfrag active */
                if ((cork->length + length > mtu - headersize) && dontfrag &&
@@ -1538,8 +1540,7 @@ int ip6_push_pending_frames(struct sock *sk)
        }
 
        /* Allow local fragmentation. */
-       if (np->pmtudisc < IPV6_PMTUDISC_DO)
-               skb->local_df = 1;
+       skb->local_df = ip6_sk_local_df(sk);
 
        *final_dst = fl6->daddr;
        __skb_pull(skb, skb_network_header_len(skb));
@@ -1566,8 +1567,8 @@ int ip6_push_pending_frames(struct sock *sk)
        if (proto == IPPROTO_ICMPV6) {
                struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
-               ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
-               ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
+               ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
+               ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
        }
 
        err = ip6_local_out(skb);