diff options
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b4d74c86586c..6163f851dc01 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -101,19 +101,19 @@ static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net, | |||
101 | for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) { | 101 | for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) { |
102 | if (local == t->parms.iph.saddr && | 102 | if (local == t->parms.iph.saddr && |
103 | remote == t->parms.iph.daddr && | 103 | remote == t->parms.iph.daddr && |
104 | (!dev || !t->parms.link || dev->iflink == t->parms.link) && | 104 | (!dev || !t->parms.link || dev->ifindex == t->parms.link) && |
105 | (t->dev->flags & IFF_UP)) | 105 | (t->dev->flags & IFF_UP)) |
106 | return t; | 106 | return t; |
107 | } | 107 | } |
108 | for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) { | 108 | for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) { |
109 | if (remote == t->parms.iph.daddr && | 109 | if (remote == t->parms.iph.daddr && |
110 | (!dev || !t->parms.link || dev->iflink == t->parms.link) && | 110 | (!dev || !t->parms.link || dev->ifindex == t->parms.link) && |
111 | (t->dev->flags & IFF_UP)) | 111 | (t->dev->flags & IFF_UP)) |
112 | return t; | 112 | return t; |
113 | } | 113 | } |
114 | for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) { | 114 | for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) { |
115 | if (local == t->parms.iph.saddr && | 115 | if (local == t->parms.iph.saddr && |
116 | (!dev || !t->parms.link || dev->iflink == t->parms.link) && | 116 | (!dev || !t->parms.link || dev->ifindex == t->parms.link) && |
117 | (t->dev->flags & IFF_UP)) | 117 | (t->dev->flags & IFF_UP)) |
118 | return t; | 118 | return t; |
119 | } | 119 | } |
@@ -250,7 +250,8 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, | |||
250 | else | 250 | else |
251 | strcpy(name, "sit%d"); | 251 | strcpy(name, "sit%d"); |
252 | 252 | ||
253 | dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); | 253 | dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, |
254 | ipip6_tunnel_setup); | ||
254 | if (dev == NULL) | 255 | if (dev == NULL) |
255 | return NULL; | 256 | return NULL; |
256 | 257 | ||
@@ -560,12 +561,12 @@ static int ipip6_err(struct sk_buff *skb, u32 info) | |||
560 | 561 | ||
561 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { | 562 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { |
562 | ipv4_update_pmtu(skb, dev_net(skb->dev), info, | 563 | ipv4_update_pmtu(skb, dev_net(skb->dev), info, |
563 | t->dev->ifindex, 0, IPPROTO_IPV6, 0); | 564 | t->parms.link, 0, IPPROTO_IPV6, 0); |
564 | err = 0; | 565 | err = 0; |
565 | goto out; | 566 | goto out; |
566 | } | 567 | } |
567 | if (type == ICMP_REDIRECT) { | 568 | if (type == ICMP_REDIRECT) { |
568 | ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0, | 569 | ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, |
569 | IPPROTO_IPV6, 0); | 570 | IPPROTO_IPV6, 0); |
570 | err = 0; | 571 | err = 0; |
571 | goto out; | 572 | goto out; |
@@ -974,8 +975,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
974 | goto out; | 975 | goto out; |
975 | } | 976 | } |
976 | 977 | ||
977 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, | 978 | err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, |
978 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 979 | IPPROTO_IPV6, tos, ttl, df, |
980 | !net_eq(tunnel->net, dev_net(dev))); | ||
979 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 981 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
980 | return NETDEV_TX_OK; | 982 | return NETDEV_TX_OK; |
981 | 983 | ||
@@ -1126,8 +1128,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1126 | int err = 0; | 1128 | int err = 0; |
1127 | struct ip_tunnel_parm p; | 1129 | struct ip_tunnel_parm p; |
1128 | struct ip_tunnel_prl prl; | 1130 | struct ip_tunnel_prl prl; |
1129 | struct ip_tunnel *t; | 1131 | struct ip_tunnel *t = netdev_priv(dev); |
1130 | struct net *net = dev_net(dev); | 1132 | struct net *net = t->net; |
1131 | struct sit_net *sitn = net_generic(net, sit_net_id); | 1133 | struct sit_net *sitn = net_generic(net, sit_net_id); |
1132 | #ifdef CONFIG_IPV6_SIT_6RD | 1134 | #ifdef CONFIG_IPV6_SIT_6RD |
1133 | struct ip_tunnel_6rd ip6rd; | 1135 | struct ip_tunnel_6rd ip6rd; |
@@ -1138,16 +1140,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1138 | #ifdef CONFIG_IPV6_SIT_6RD | 1140 | #ifdef CONFIG_IPV6_SIT_6RD |
1139 | case SIOCGET6RD: | 1141 | case SIOCGET6RD: |
1140 | #endif | 1142 | #endif |
1141 | t = NULL; | ||
1142 | if (dev == sitn->fb_tunnel_dev) { | 1143 | if (dev == sitn->fb_tunnel_dev) { |
1143 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { | 1144 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { |
1144 | err = -EFAULT; | 1145 | err = -EFAULT; |
1145 | break; | 1146 | break; |
1146 | } | 1147 | } |
1147 | t = ipip6_tunnel_locate(net, &p, 0); | 1148 | t = ipip6_tunnel_locate(net, &p, 0); |
1149 | if (t == NULL) | ||
1150 | t = netdev_priv(dev); | ||
1148 | } | 1151 | } |
1149 | if (t == NULL) | ||
1150 | t = netdev_priv(dev); | ||
1151 | 1152 | ||
1152 | err = -EFAULT; | 1153 | err = -EFAULT; |
1153 | if (cmd == SIOCGETTUNNEL) { | 1154 | if (cmd == SIOCGETTUNNEL) { |
@@ -1243,9 +1244,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1243 | err = -EINVAL; | 1244 | err = -EINVAL; |
1244 | if (dev == sitn->fb_tunnel_dev) | 1245 | if (dev == sitn->fb_tunnel_dev) |
1245 | goto done; | 1246 | goto done; |
1246 | err = -ENOENT; | ||
1247 | if (!(t = netdev_priv(dev))) | ||
1248 | goto done; | ||
1249 | err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); | 1247 | err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); |
1250 | break; | 1248 | break; |
1251 | 1249 | ||
@@ -1261,9 +1259,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1261 | err = -EFAULT; | 1259 | err = -EFAULT; |
1262 | if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) | 1260 | if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) |
1263 | goto done; | 1261 | goto done; |
1264 | err = -ENOENT; | ||
1265 | if (!(t = netdev_priv(dev))) | ||
1266 | goto done; | ||
1267 | 1262 | ||
1268 | switch (cmd) { | 1263 | switch (cmd) { |
1269 | case SIOCDELPRL: | 1264 | case SIOCDELPRL: |
@@ -1291,8 +1286,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1291 | sizeof(ip6rd))) | 1286 | sizeof(ip6rd))) |
1292 | goto done; | 1287 | goto done; |
1293 | 1288 | ||
1294 | t = netdev_priv(dev); | ||
1295 | |||
1296 | if (cmd != SIOCDEL6RD) { | 1289 | if (cmd != SIOCDEL6RD) { |
1297 | err = ipip6_tunnel_update_6rd(t, &ip6rd); | 1290 | err = ipip6_tunnel_update_6rd(t, &ip6rd); |
1298 | if (err < 0) | 1291 | if (err < 0) |
@@ -1363,7 +1356,6 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
1363 | static int ipip6_tunnel_init(struct net_device *dev) | 1356 | static int ipip6_tunnel_init(struct net_device *dev) |
1364 | { | 1357 | { |
1365 | struct ip_tunnel *tunnel = netdev_priv(dev); | 1358 | struct ip_tunnel *tunnel = netdev_priv(dev); |
1366 | int i; | ||
1367 | 1359 | ||
1368 | tunnel->dev = dev; | 1360 | tunnel->dev = dev; |
1369 | tunnel->net = dev_net(dev); | 1361 | tunnel->net = dev_net(dev); |
@@ -1372,16 +1364,10 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
1372 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); | 1364 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
1373 | 1365 | ||
1374 | ipip6_tunnel_bind_dev(dev); | 1366 | ipip6_tunnel_bind_dev(dev); |
1375 | dev->tstats = alloc_percpu(struct pcpu_sw_netstats); | 1367 | dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
1376 | if (!dev->tstats) | 1368 | if (!dev->tstats) |
1377 | return -ENOMEM; | 1369 | return -ENOMEM; |
1378 | 1370 | ||
1379 | for_each_possible_cpu(i) { | ||
1380 | struct pcpu_sw_netstats *ipip6_tunnel_stats; | ||
1381 | ipip6_tunnel_stats = per_cpu_ptr(dev->tstats, i); | ||
1382 | u64_stats_init(&ipip6_tunnel_stats->syncp); | ||
1383 | } | ||
1384 | |||
1385 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | 1371 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); |
1386 | if (!tunnel->dst_cache) { | 1372 | if (!tunnel->dst_cache) { |
1387 | free_percpu(dev->tstats); | 1373 | free_percpu(dev->tstats); |
@@ -1397,7 +1383,6 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1397 | struct iphdr *iph = &tunnel->parms.iph; | 1383 | struct iphdr *iph = &tunnel->parms.iph; |
1398 | struct net *net = dev_net(dev); | 1384 | struct net *net = dev_net(dev); |
1399 | struct sit_net *sitn = net_generic(net, sit_net_id); | 1385 | struct sit_net *sitn = net_generic(net, sit_net_id); |
1400 | int i; | ||
1401 | 1386 | ||
1402 | tunnel->dev = dev; | 1387 | tunnel->dev = dev; |
1403 | tunnel->net = dev_net(dev); | 1388 | tunnel->net = dev_net(dev); |
@@ -1408,16 +1393,10 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1408 | iph->ihl = 5; | 1393 | iph->ihl = 5; |
1409 | iph->ttl = 64; | 1394 | iph->ttl = 64; |
1410 | 1395 | ||
1411 | dev->tstats = alloc_percpu(struct pcpu_sw_netstats); | 1396 | dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
1412 | if (!dev->tstats) | 1397 | if (!dev->tstats) |
1413 | return -ENOMEM; | 1398 | return -ENOMEM; |
1414 | 1399 | ||
1415 | for_each_possible_cpu(i) { | ||
1416 | struct pcpu_sw_netstats *ipip6_fb_stats; | ||
1417 | ipip6_fb_stats = per_cpu_ptr(dev->tstats, i); | ||
1418 | u64_stats_init(&ipip6_fb_stats->syncp); | ||
1419 | } | ||
1420 | |||
1421 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | 1400 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); |
1422 | if (!tunnel->dst_cache) { | 1401 | if (!tunnel->dst_cache) { |
1423 | free_percpu(dev->tstats); | 1402 | free_percpu(dev->tstats); |
@@ -1751,6 +1730,7 @@ static int __net_init sit_init_net(struct net *net) | |||
1751 | sitn->tunnels[3] = sitn->tunnels_r_l; | 1730 | sitn->tunnels[3] = sitn->tunnels_r_l; |
1752 | 1731 | ||
1753 | sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", | 1732 | sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", |
1733 | NET_NAME_UNKNOWN, | ||
1754 | ipip6_tunnel_setup); | 1734 | ipip6_tunnel_setup); |
1755 | if (!sitn->fb_tunnel_dev) { | 1735 | if (!sitn->fb_tunnel_dev) { |
1756 | err = -ENOMEM; | 1736 | err = -ENOMEM; |
@@ -1850,4 +1830,5 @@ xfrm_tunnel_failed: | |||
1850 | module_init(sit_init); | 1830 | module_init(sit_init); |
1851 | module_exit(sit_cleanup); | 1831 | module_exit(sit_cleanup); |
1852 | MODULE_LICENSE("GPL"); | 1832 | MODULE_LICENSE("GPL"); |
1833 | MODULE_ALIAS_RTNL_LINK("sit"); | ||
1853 | MODULE_ALIAS_NETDEV("sit0"); | 1834 | MODULE_ALIAS_NETDEV("sit0"); |