ipv6: gre: correct calculation of max_headroom
[deliverable/linux.git] / net / ipv6 / ip6_gre.c
index 90747f1973fe048abd6d8283235b2d80d038d691..7bb5446b9d73c16a7f4096f2705ce60f997c7c2a 100644 (file)
@@ -335,6 +335,7 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
        dev->rtnl_link_ops = &ip6gre_link_ops;
 
        nt->dev = dev;
+       nt->net = dev_net(dev);
        ip6gre_tnl_link_config(nt, 1);
 
        if (register_netdevice(dev) < 0)
@@ -508,8 +509,6 @@ static int ip6gre_rcv(struct sk_buff *skb)
                        goto drop;
                }
 
-               secpath_reset(skb);
-
                skb->protocol = gre_proto;
                /* WCCP version 1 and 2 protocol decoding.
                 * - Change protocol to IP
@@ -524,7 +523,6 @@ static int ip6gre_rcv(struct sk_buff *skb)
                skb->mac_header = skb->network_header;
                __pskb_pull(skb, offset);
                skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
-               skb->pkt_type = PACKET_HOST;
 
                if (((flags&GRE_CSUM) && csum) ||
                    (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
@@ -556,7 +554,7 @@ static int ip6gre_rcv(struct sk_buff *skb)
                        skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
                }
 
-               __skb_tunnel_rx(skb, tunnel->dev);
+               __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
 
                skb_reset_network_header(skb);
 
@@ -620,7 +618,7 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
        struct ip6_tnl *tunnel = netdev_priv(dev);
        struct net_device *tdev;    /* Device to other host */
        struct ipv6hdr  *ipv6h;     /* Our new IP header */
-       unsigned int max_headroom /* The extra header space needed */
+       unsigned int max_headroom = 0; /* The extra header space needed */
        int    gre_hlen;
        struct ipv6_tel_txoption opt;
        int    mtu;
@@ -693,7 +691,9 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
                        tunnel->err_count = 0;
        }
 
-       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len;
+       skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
+
+       max_headroom += LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len;
 
        if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
            (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
@@ -709,8 +709,6 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
                skb = new_skb;
        }
 
-       skb_dst_drop(skb);
-
        if (fl6->flowi6_mark) {
                skb_dst_set(skb, dst);
                ndst = NULL;
@@ -1260,6 +1258,7 @@ static int ip6gre_tunnel_init(struct net_device *dev)
        tunnel = netdev_priv(dev);
 
        tunnel->dev = dev;
+       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr));
@@ -1280,6 +1279,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
        struct ip6_tnl *tunnel = netdev_priv(dev);
 
        tunnel->dev = dev;
+       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        tunnel->hlen            = sizeof(struct ipv6hdr) + 4;
@@ -1455,6 +1455,7 @@ static int ip6gre_tap_init(struct net_device *dev)
        tunnel = netdev_priv(dev);
 
        tunnel->dev = dev;
+       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        ip6gre_tnl_link_config(tunnel, 1);
@@ -1506,6 +1507,7 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
                eth_hw_addr_random(dev);
 
        nt->dev = dev;
+       nt->net = dev_net(dev);
        ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
 
        /* Can use a lockless transmit, unless we generate output sequences */
This page took 0.026341 seconds and 5 git commands to generate.