]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - net/ipv6/ip6_tunnel.c
net: Put flowi_* prefix on AF independent members of struct flowi
[linux-3.10.git] / net / ipv6 / ip6_tunnel.c
index c2c0f89397b1164bacefdb449cd2b97dbe41d66c..c3fc824c24d9b745a9bac8bf2f22694db7f5d251 100644 (file)
@@ -57,8 +57,7 @@
 MODULE_AUTHOR("Ville Nuorvala");
 MODULE_DESCRIPTION("IPv6 tunneling device");
 MODULE_LICENSE("GPL");
-
-#define IPV6_TLV_TEL_DST_SIZE 8
+MODULE_ALIAS_NETDEV("ip6tnl0");
 
 #ifdef IP6_TNL_DEBUG
 #define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__)
@@ -537,7 +536,6 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        int err;
        struct sk_buff *skb2;
        struct iphdr *eiph;
-       struct flowi fl;
        struct rtable *rt;
 
        err = ip6_tnl_err(skb, IPPROTO_IPIP, opt, &rel_type, &rel_code,
@@ -579,11 +577,11 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        eiph = ip_hdr(skb2);
 
        /* Try to guess incoming interface */
-       memset(&fl, 0, sizeof(fl));
-       fl.fl4_dst = eiph->saddr;
-       fl.fl4_tos = RT_TOS(eiph->tos);
-       fl.proto = IPPROTO_IPIP;
-       if (ip_route_output_key(dev_net(skb->dev), &rt, &fl))
+       rt = ip_route_output_ports(dev_net(skb->dev), NULL,
+                                  eiph->saddr, 0,
+                                  0, 0,
+                                  IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
+       if (IS_ERR(rt))
                goto out;
 
        skb2->dev = rt->dst.dev;
@@ -592,15 +590,18 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (rt->rt_flags & RTCF_LOCAL) {
                ip_rt_put(rt);
                rt = NULL;
-               fl.fl4_dst = eiph->daddr;
-               fl.fl4_src = eiph->saddr;
-               fl.fl4_tos = eiph->tos;
-               if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) ||
+               rt = ip_route_output_ports(dev_net(skb->dev), NULL,
+                                          eiph->daddr, eiph->saddr,
+                                          0, 0,
+                                          IPPROTO_IPIP,
+                                          RT_TOS(eiph->tos), 0);
+               if (IS_ERR(rt) ||
                    rt->dst.dev->type != ARPHRD_TUNNEL) {
-                       ip_rt_put(rt);
+                       if (!IS_ERR(rt))
+                               ip_rt_put(rt);
                        goto out;
                }
-               skb_dst_set(skb2, (struct dst_entry *)rt);
+               skb_dst_set(skb2, &rt->dst);
        } else {
                ip_rt_put(rt);
                if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
@@ -905,8 +906,14 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        else {
                dst = ip6_route_output(net, NULL, fl);
 
-               if (dst->error || xfrm_lookup(net, &dst, fl, NULL, 0) < 0)
+               if (dst->error)
                        goto tx_err_link_failure;
+               dst = xfrm_lookup(net, dst, fl, NULL, 0);
+               if (IS_ERR(dst)) {
+                       err = PTR_ERR(dst);
+                       dst = NULL;
+                       goto tx_err_link_failure;
+               }
        }
 
        tdev = dst->dev;
@@ -956,7 +963,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 
        skb->transport_header = skb->network_header;
 
-       proto = fl->proto;
+       proto = fl->flowi_proto;
        if (encap_limit >= 0) {
                init_tel_txopt(&opt, encap_limit);
                ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
@@ -1013,7 +1020,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
                encap_limit = t->parms.encap_limit;
 
        memcpy(&fl, &t->fl, sizeof (fl));
-       fl.proto = IPPROTO_IPIP;
+       fl.flowi_proto = IPPROTO_IPIP;
 
        dsfield = ipv4_get_dsfield(iph);
 
@@ -1063,7 +1070,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
                encap_limit = t->parms.encap_limit;
 
        memcpy(&fl, &t->fl, sizeof (fl));
-       fl.proto = IPPROTO_IPV6;
+       fl.flowi_proto = IPPROTO_IPV6;
 
        dsfield = ipv6_get_dsfield(ipv6h);
        if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
@@ -1142,7 +1149,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
        /* Set up flowi template */
        ipv6_addr_copy(&fl->fl6_src, &p->laddr);
        ipv6_addr_copy(&fl->fl6_dst, &p->raddr);
-       fl->oif = p->link;
+       fl->flowi_oif = p->link;
        fl->fl6_flowlabel = 0;
 
        if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
@@ -1175,6 +1182,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
                                sizeof (struct ipv6hdr);
 
                        dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+                       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+                               dev->mtu-=8;
 
                        if (dev->mtu < IPV6_MIN_MTU)
                                dev->mtu = IPV6_MIN_MTU;
@@ -1284,6 +1293,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                                t = netdev_priv(dev);
 
                        ip6_tnl_unlink(ip6n, t);
+                       synchronize_net();
                        err = ip6_tnl_change(t, &p);
                        ip6_tnl_link(ip6n, t);
                        netdev_state_change(dev);
@@ -1362,15 +1372,21 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
 
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
+       struct ip6_tnl *t;
+
        dev->netdev_ops = &ip6_tnl_netdev_ops;
        dev->destructor = ip6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
        dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+       t = netdev_priv(dev);
+       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+               dev->mtu-=8;
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
        dev->features |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }