]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/ipv4/ip_output.c
Merge tag 'char-misc-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / net / ipv4 / ip_output.c
index 3d8baaaf7086dba0c8fde178891734b2da7d7ec7..d84819893db96d813f4e91def912a59a87a48a7c 100644 (file)
@@ -240,8 +240,8 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
 static int ip_finish_output_gso(struct net *net, struct sock *sk,
                                struct sk_buff *skb, unsigned int mtu)
 {
+       struct sk_buff *segs, *nskb;
        netdev_features_t features;
-       struct sk_buff *segs;
        int ret = 0;
 
        /* common case: seglen is <= mtu
@@ -272,8 +272,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
 
        consume_skb(skb);
 
-       do {
-               struct sk_buff *nskb = segs->next;
+       skb_list_walk_safe(segs, segs, nskb) {
                int err;
 
                skb_mark_not_on_list(segs);
@@ -281,8 +280,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
 
                if (err && ret == 0)
                        ret = err;
-               segs = nskb;
-       } while (segs);
+       }
 
        return ret;
 }
@@ -422,7 +420,7 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 
 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-       struct net_device *dev = skb_dst(skb)->dev;
+       struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
 
        IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
 
@@ -430,7 +428,7 @@ int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
        skb->protocol = htons(ETH_P_IP);
 
        return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
-                           net, sk, skb, NULL, dev,
+                           net, sk, skb, indev, dev,
                            ip_finish_output,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
@@ -1258,15 +1256,18 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
                cork->addr = ipc->addr;
        }
 
-       /*
-        * We steal reference to this route, caller should not release it
-        */
-       *rtp = NULL;
        cork->fragsize = ip_sk_use_pmtu(sk) ?
-                        dst_mtu(&rt->dst) : rt->dst.dev->mtu;
+                        dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
+
+       if (!inetdev_valid_mtu(cork->fragsize))
+               return -ENETUNREACH;
 
        cork->gso_size = ipc->gso_size;
+
        cork->dst = &rt->dst;
+       /* We stole this route, caller should not release it. */
+       *rtp = NULL;
+
        cork->length = 0;
        cork->ttl = ipc->ttl;
        cork->tos = ipc->tos;