aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/sit.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r--net/ipv6/sit.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d3005b34476a..b4d74c86586c 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -475,6 +475,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
475 ipip6_tunnel_unlink(sitn, tunnel); 475 ipip6_tunnel_unlink(sitn, tunnel);
476 ipip6_tunnel_del_prl(tunnel, NULL); 476 ipip6_tunnel_del_prl(tunnel, NULL);
477 } 477 }
478 ip_tunnel_dst_reset_all(tunnel);
478 dev_put(dev); 479 dev_put(dev);
479} 480}
480 481
@@ -671,7 +672,7 @@ static int ipip6_rcv(struct sk_buff *skb)
671 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, 672 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
672 iph->saddr, iph->daddr); 673 iph->saddr, iph->daddr);
673 if (tunnel != NULL) { 674 if (tunnel != NULL) {
674 struct pcpu_tstats *tstats; 675 struct pcpu_sw_netstats *tstats;
675 676
676 if (tunnel->parms.iph.protocol != IPPROTO_IPV6 && 677 if (tunnel->parms.iph.protocol != IPPROTO_IPV6 &&
677 tunnel->parms.iph.protocol != 0) 678 tunnel->parms.iph.protocol != 0)
@@ -1082,6 +1083,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
1082 t->parms.link = p->link; 1083 t->parms.link = p->link;
1083 ipip6_tunnel_bind_dev(t->dev); 1084 ipip6_tunnel_bind_dev(t->dev);
1084 } 1085 }
1086 ip_tunnel_dst_reset_all(t);
1085 netdev_state_change(t->dev); 1087 netdev_state_change(t->dev);
1086} 1088}
1087 1089
@@ -1112,6 +1114,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
1112 t->ip6rd.relay_prefix = relay_prefix; 1114 t->ip6rd.relay_prefix = relay_prefix;
1113 t->ip6rd.prefixlen = ip6rd->prefixlen; 1115 t->ip6rd.prefixlen = ip6rd->prefixlen;
1114 t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; 1116 t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen;
1117 ip_tunnel_dst_reset_all(t);
1115 netdev_state_change(t->dev); 1118 netdev_state_change(t->dev);
1116 return 0; 1119 return 0;
1117} 1120}
@@ -1271,6 +1274,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1271 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); 1274 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
1272 break; 1275 break;
1273 } 1276 }
1277 ip_tunnel_dst_reset_all(t);
1274 netdev_state_change(dev); 1278 netdev_state_change(dev);
1275 break; 1279 break;
1276 1280
@@ -1326,6 +1330,9 @@ static const struct net_device_ops ipip6_netdev_ops = {
1326 1330
1327static void ipip6_dev_free(struct net_device *dev) 1331static void ipip6_dev_free(struct net_device *dev)
1328{ 1332{
1333 struct ip_tunnel *tunnel = netdev_priv(dev);
1334
1335 free_percpu(tunnel->dst_cache);
1329 free_percpu(dev->tstats); 1336 free_percpu(dev->tstats);
1330 free_netdev(dev); 1337 free_netdev(dev);
1331} 1338}
@@ -1365,16 +1372,22 @@ static int ipip6_tunnel_init(struct net_device *dev)
1365 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); 1372 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
1366 1373
1367 ipip6_tunnel_bind_dev(dev); 1374 ipip6_tunnel_bind_dev(dev);
1368 dev->tstats = alloc_percpu(struct pcpu_tstats); 1375 dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
1369 if (!dev->tstats) 1376 if (!dev->tstats)
1370 return -ENOMEM; 1377 return -ENOMEM;
1371 1378
1372 for_each_possible_cpu(i) { 1379 for_each_possible_cpu(i) {
1373 struct pcpu_tstats *ipip6_tunnel_stats; 1380 struct pcpu_sw_netstats *ipip6_tunnel_stats;
1374 ipip6_tunnel_stats = per_cpu_ptr(dev->tstats, i); 1381 ipip6_tunnel_stats = per_cpu_ptr(dev->tstats, i);
1375 u64_stats_init(&ipip6_tunnel_stats->syncp); 1382 u64_stats_init(&ipip6_tunnel_stats->syncp);
1376 } 1383 }
1377 1384
1385 tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
1386 if (!tunnel->dst_cache) {
1387 free_percpu(dev->tstats);
1388 return -ENOMEM;
1389 }
1390
1378 return 0; 1391 return 0;
1379} 1392}
1380 1393
@@ -1395,16 +1408,22 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1395 iph->ihl = 5; 1408 iph->ihl = 5;
1396 iph->ttl = 64; 1409 iph->ttl = 64;
1397 1410
1398 dev->tstats = alloc_percpu(struct pcpu_tstats); 1411 dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
1399 if (!dev->tstats) 1412 if (!dev->tstats)
1400 return -ENOMEM; 1413 return -ENOMEM;
1401 1414
1402 for_each_possible_cpu(i) { 1415 for_each_possible_cpu(i) {
1403 struct pcpu_tstats *ipip6_fb_stats; 1416 struct pcpu_sw_netstats *ipip6_fb_stats;
1404 ipip6_fb_stats = per_cpu_ptr(dev->tstats, i); 1417 ipip6_fb_stats = per_cpu_ptr(dev->tstats, i);
1405 u64_stats_init(&ipip6_fb_stats->syncp); 1418 u64_stats_init(&ipip6_fb_stats->syncp);
1406 } 1419 }
1407 1420
1421 tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
1422 if (!tunnel->dst_cache) {
1423 free_percpu(dev->tstats);
1424 return -ENOMEM;
1425 }
1426
1408 dev_hold(dev); 1427 dev_hold(dev);
1409 rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); 1428 rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
1410 return 0; 1429 return 0;