aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_tunnel.c')
-rw-r--r--net/ipv4/ip_tunnel.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 2acc2337d38b..097b3e7c1e8f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -268,6 +268,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
268 __be32 remote = parms->iph.daddr; 268 __be32 remote = parms->iph.daddr;
269 __be32 local = parms->iph.saddr; 269 __be32 local = parms->iph.saddr;
270 __be32 key = parms->i_key; 270 __be32 key = parms->i_key;
271 __be16 flags = parms->i_flags;
271 int link = parms->link; 272 int link = parms->link;
272 struct ip_tunnel *t = NULL; 273 struct ip_tunnel *t = NULL;
273 struct hlist_head *head = ip_bucket(itn, parms); 274 struct hlist_head *head = ip_bucket(itn, parms);
@@ -275,9 +276,9 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
275 hlist_for_each_entry_rcu(t, head, hash_node) { 276 hlist_for_each_entry_rcu(t, head, hash_node) {
276 if (local == t->parms.iph.saddr && 277 if (local == t->parms.iph.saddr &&
277 remote == t->parms.iph.daddr && 278 remote == t->parms.iph.daddr &&
278 key == t->parms.i_key &&
279 link == t->parms.link && 279 link == t->parms.link &&
280 type == t->dev->type) 280 type == t->dev->type &&
281 ip_tunnel_key_match(&t->parms, flags, key))
281 break; 282 break;
282 } 283 }
283 return t; 284 return t;
@@ -395,11 +396,10 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
395 struct ip_tunnel_net *itn, 396 struct ip_tunnel_net *itn,
396 struct ip_tunnel_parm *parms) 397 struct ip_tunnel_parm *parms)
397{ 398{
398 struct ip_tunnel *nt, *fbt; 399 struct ip_tunnel *nt;
399 struct net_device *dev; 400 struct net_device *dev;
400 401
401 BUG_ON(!itn->fb_tunnel_dev); 402 BUG_ON(!itn->fb_tunnel_dev);
402 fbt = netdev_priv(itn->fb_tunnel_dev);
403 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms); 403 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
404 if (IS_ERR(dev)) 404 if (IS_ERR(dev))
405 return ERR_CAST(dev); 405 return ERR_CAST(dev);
@@ -668,6 +668,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
668 dev->needed_headroom = max_headroom; 668 dev->needed_headroom = max_headroom;
669 669
670 if (skb_cow_head(skb, dev->needed_headroom)) { 670 if (skb_cow_head(skb, dev->needed_headroom)) {
671 ip_rt_put(rt);
671 dev->stats.tx_dropped++; 672 dev->stats.tx_dropped++;
672 kfree_skb(skb); 673 kfree_skb(skb);
673 return; 674 return;
@@ -747,19 +748,19 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
747 goto done; 748 goto done;
748 if (p->iph.ttl) 749 if (p->iph.ttl)
749 p->iph.frag_off |= htons(IP_DF); 750 p->iph.frag_off |= htons(IP_DF);
750 if (!(p->i_flags&TUNNEL_KEY)) 751 if (!(p->i_flags & VTI_ISVTI)) {
751 p->i_key = 0; 752 if (!(p->i_flags & TUNNEL_KEY))
752 if (!(p->o_flags&TUNNEL_KEY)) 753 p->i_key = 0;
753 p->o_key = 0; 754 if (!(p->o_flags & TUNNEL_KEY))
755 p->o_key = 0;
756 }
754 757
755 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 758 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
756 759
757 if (!t && (cmd == SIOCADDTUNNEL)) { 760 if (!t && (cmd == SIOCADDTUNNEL)) {
758 t = ip_tunnel_create(net, itn, p); 761 t = ip_tunnel_create(net, itn, p);
759 if (IS_ERR(t)) { 762 err = PTR_ERR_OR_ZERO(t);
760 err = PTR_ERR(t); 763 break;
761 break;
762 }
763 } 764 }
764 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { 765 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
765 if (t != NULL) { 766 if (t != NULL) {