]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/ipv6/ip6_gre.c
UBUNTU: [Config] CONFIG_SND_SOC_ES8316=m
[mirror_ubuntu-artful-kernel.git] / net / ipv6 / ip6_gre.c
index 67ff2aaf5dcbbe9f64482e2a251f061be8007770..1602b491b281123f691a4a7afc4ba5fe0a99ac55 100644 (file)
@@ -432,7 +432,9 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                }
                break;
        case ICMPV6_PKT_TOOBIG:
-               mtu = be32_to_cpu(info) - offset;
+               mtu = be32_to_cpu(info) - offset - t->tun_hlen;
+               if (t->dev->type == ARPHRD_ETHER)
+                       mtu -= ETH_HLEN;
                if (mtu < IPV6_MIN_MTU)
                        mtu = IPV6_MIN_MTU;
                t->dev->mtu = mtu;
@@ -938,24 +940,25 @@ done:
 }
 
 static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
-                       unsigned short type,
-                       const void *daddr, const void *saddr, unsigned int len)
+                        unsigned short type, const void *daddr,
+                        const void *saddr, unsigned int len)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct ipv6hdr *ipv6h = skb_push(skb, t->hlen);
-       __be16 *p = (__be16 *)(ipv6h+1);
+       struct ipv6hdr *ipv6h;
+       __be16 *p;
 
-       ip6_flow_hdr(ipv6h, 0,
-                    ip6_make_flowlabel(dev_net(dev), skb,
-                                       t->fl.u.ip6.flowlabel, true,
-                                       &t->fl.u.ip6));
+       ipv6h = skb_push(skb, t->hlen + sizeof(*ipv6h));
+       ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb,
+                                                 t->fl.u.ip6.flowlabel,
+                                                 true, &t->fl.u.ip6));
        ipv6h->hop_limit = t->parms.hop_limit;
        ipv6h->nexthdr = NEXTHDR_GRE;
        ipv6h->saddr = t->parms.laddr;
        ipv6h->daddr = t->parms.raddr;
 
-       p[0]            = t->parms.o_flags;
-       p[1]            = htons(type);
+       p = (__be16 *)(ipv6h + 1);
+       p[0] = t->parms.o_flags;
+       p[1] = htons(type);
 
        /*
         *      Set the source hardware address.
@@ -1308,6 +1311,7 @@ static void ip6gre_tap_setup(struct net_device *dev)
        dev->features |= NETIF_F_NETNS_LOCAL;
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+       netif_keep_dst(dev);
 }
 
 static bool ip6gre_netlink_encap_parms(struct nlattr *data[],