diff options
Diffstat (limited to 'net/ipv6/sit.c')
| -rw-r--r-- | net/ipv6/sit.c | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 976e68244b99..4699cd3c3118 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
| 29 | #include <linux/if_arp.h> | 29 | #include <linux/if_arp.h> |
| 30 | #include <linux/icmp.h> | 30 | #include <linux/icmp.h> |
| 31 | #include <linux/slab.h> | ||
| 31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
| 33 | #include <linux/netfilter_ipv4.h> | 34 | #include <linux/netfilter_ipv4.h> |
| @@ -62,7 +63,6 @@ | |||
| 62 | #define HASH_SIZE 16 | 63 | #define HASH_SIZE 16 |
| 63 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) | 64 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
| 64 | 65 | ||
| 65 | static void ipip6_fb_tunnel_init(struct net_device *dev); | ||
| 66 | static void ipip6_tunnel_init(struct net_device *dev); | 66 | static void ipip6_tunnel_init(struct net_device *dev); |
| 67 | static void ipip6_tunnel_setup(struct net_device *dev); | 67 | static void ipip6_tunnel_setup(struct net_device *dev); |
| 68 | 68 | ||
| @@ -249,8 +249,6 @@ failed: | |||
| 249 | return NULL; | 249 | return NULL; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | static DEFINE_SPINLOCK(ipip6_prl_lock); | ||
| 253 | |||
| 254 | #define for_each_prl_rcu(start) \ | 252 | #define for_each_prl_rcu(start) \ |
| 255 | for (prl = rcu_dereference(start); \ | 253 | for (prl = rcu_dereference(start); \ |
| 256 | prl; \ | 254 | prl; \ |
| @@ -340,7 +338,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) | |||
| 340 | if (a->addr == htonl(INADDR_ANY)) | 338 | if (a->addr == htonl(INADDR_ANY)) |
| 341 | return -EINVAL; | 339 | return -EINVAL; |
| 342 | 340 | ||
| 343 | spin_lock(&ipip6_prl_lock); | 341 | ASSERT_RTNL(); |
| 344 | 342 | ||
| 345 | for (p = t->prl; p; p = p->next) { | 343 | for (p = t->prl; p; p = p->next) { |
| 346 | if (p->addr == a->addr) { | 344 | if (p->addr == a->addr) { |
| @@ -364,14 +362,12 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) | |||
| 364 | goto out; | 362 | goto out; |
| 365 | } | 363 | } |
| 366 | 364 | ||
| 367 | INIT_RCU_HEAD(&p->rcu_head); | ||
| 368 | p->next = t->prl; | 365 | p->next = t->prl; |
| 369 | p->addr = a->addr; | 366 | p->addr = a->addr; |
| 370 | p->flags = a->flags; | 367 | p->flags = a->flags; |
| 371 | t->prl_count++; | 368 | t->prl_count++; |
| 372 | rcu_assign_pointer(t->prl, p); | 369 | rcu_assign_pointer(t->prl, p); |
| 373 | out: | 370 | out: |
| 374 | spin_unlock(&ipip6_prl_lock); | ||
| 375 | return err; | 371 | return err; |
| 376 | } | 372 | } |
| 377 | 373 | ||
| @@ -398,7 +394,7 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | |||
| 398 | struct ip_tunnel_prl_entry *x, **p; | 394 | struct ip_tunnel_prl_entry *x, **p; |
| 399 | int err = 0; | 395 | int err = 0; |
| 400 | 396 | ||
| 401 | spin_lock(&ipip6_prl_lock); | 397 | ASSERT_RTNL(); |
| 402 | 398 | ||
| 403 | if (a && a->addr != htonl(INADDR_ANY)) { | 399 | if (a && a->addr != htonl(INADDR_ANY)) { |
| 404 | for (p = &t->prl; *p; p = &(*p)->next) { | 400 | for (p = &t->prl; *p; p = &(*p)->next) { |
| @@ -420,7 +416,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | |||
| 420 | } | 416 | } |
| 421 | } | 417 | } |
| 422 | out: | 418 | out: |
| 423 | spin_unlock(&ipip6_prl_lock); | ||
| 424 | return err; | 419 | return err; |
| 425 | } | 420 | } |
| 426 | 421 | ||
| @@ -567,11 +562,9 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
| 567 | kfree_skb(skb); | 562 | kfree_skb(skb); |
| 568 | return 0; | 563 | return 0; |
| 569 | } | 564 | } |
| 570 | tunnel->dev->stats.rx_packets++; | 565 | |
| 571 | tunnel->dev->stats.rx_bytes += skb->len; | 566 | skb_tunnel_rx(skb, tunnel->dev); |
| 572 | skb->dev = tunnel->dev; | 567 | |
| 573 | skb_dst_drop(skb); | ||
| 574 | nf_reset(skb); | ||
| 575 | ipip6_ecn_decapsulate(iph, skb); | 568 | ipip6_ecn_decapsulate(iph, skb); |
| 576 | netif_rx(skb); | 569 | netif_rx(skb); |
| 577 | rcu_read_unlock(); | 570 | rcu_read_unlock(); |
| @@ -719,7 +712,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 719 | stats->tx_carrier_errors++; | 712 | stats->tx_carrier_errors++; |
| 720 | goto tx_error_icmp; | 713 | goto tx_error_icmp; |
| 721 | } | 714 | } |
| 722 | tdev = rt->u.dst.dev; | 715 | tdev = rt->dst.dev; |
| 723 | 716 | ||
| 724 | if (tdev == dev) { | 717 | if (tdev == dev) { |
| 725 | ip_rt_put(rt); | 718 | ip_rt_put(rt); |
| @@ -728,7 +721,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 728 | } | 721 | } |
| 729 | 722 | ||
| 730 | if (df) { | 723 | if (df) { |
| 731 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 724 | mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); |
| 732 | 725 | ||
| 733 | if (mtu < 68) { | 726 | if (mtu < 68) { |
| 734 | stats->collisions++; | 727 | stats->collisions++; |
| @@ -745,7 +738,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 745 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | 738 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); |
| 746 | 739 | ||
| 747 | if (skb->len > mtu) { | 740 | if (skb->len > mtu) { |
| 748 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); | 741 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
| 749 | ip_rt_put(rt); | 742 | ip_rt_put(rt); |
| 750 | goto tx_error; | 743 | goto tx_error; |
| 751 | } | 744 | } |
| @@ -787,7 +780,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 787 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 780 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
| 788 | IPCB(skb)->flags = 0; | 781 | IPCB(skb)->flags = 0; |
| 789 | skb_dst_drop(skb); | 782 | skb_dst_drop(skb); |
| 790 | skb_dst_set(skb, &rt->u.dst); | 783 | skb_dst_set(skb, &rt->dst); |
| 791 | 784 | ||
| 792 | /* | 785 | /* |
| 793 | * Push down and install the IPIP header. | 786 | * Push down and install the IPIP header. |
| @@ -836,7 +829,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) | |||
| 836 | .proto = IPPROTO_IPV6 }; | 829 | .proto = IPPROTO_IPV6 }; |
| 837 | struct rtable *rt; | 830 | struct rtable *rt; |
| 838 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { | 831 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { |
| 839 | tdev = rt->u.dst.dev; | 832 | tdev = rt->dst.dev; |
| 840 | ip_rt_put(rt); | 833 | ip_rt_put(rt); |
| 841 | } | 834 | } |
| 842 | dev->flags |= IFF_POINTOPOINT; | 835 | dev->flags |= IFF_POINTOPOINT; |
| @@ -1120,7 +1113,7 @@ static void ipip6_tunnel_init(struct net_device *dev) | |||
| 1120 | ipip6_tunnel_bind_dev(dev); | 1113 | ipip6_tunnel_bind_dev(dev); |
| 1121 | } | 1114 | } |
| 1122 | 1115 | ||
| 1123 | static void ipip6_fb_tunnel_init(struct net_device *dev) | 1116 | static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) |
| 1124 | { | 1117 | { |
| 1125 | struct ip_tunnel *tunnel = netdev_priv(dev); | 1118 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 1126 | struct iphdr *iph = &tunnel->parms.iph; | 1119 | struct iphdr *iph = &tunnel->parms.iph; |
| @@ -1145,7 +1138,7 @@ static struct xfrm_tunnel sit_handler = { | |||
| 1145 | .priority = 1, | 1138 | .priority = 1, |
| 1146 | }; | 1139 | }; |
| 1147 | 1140 | ||
| 1148 | static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) | 1141 | static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) |
| 1149 | { | 1142 | { |
| 1150 | int prio; | 1143 | int prio; |
| 1151 | 1144 | ||
| @@ -1162,7 +1155,7 @@ static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) | |||
| 1162 | } | 1155 | } |
| 1163 | } | 1156 | } |
| 1164 | 1157 | ||
| 1165 | static int sit_init_net(struct net *net) | 1158 | static int __net_init sit_init_net(struct net *net) |
| 1166 | { | 1159 | { |
| 1167 | struct sit_net *sitn = net_generic(net, sit_net_id); | 1160 | struct sit_net *sitn = net_generic(net, sit_net_id); |
| 1168 | int err; | 1161 | int err; |
| @@ -1195,7 +1188,7 @@ err_alloc_dev: | |||
| 1195 | return err; | 1188 | return err; |
| 1196 | } | 1189 | } |
| 1197 | 1190 | ||
| 1198 | static void sit_exit_net(struct net *net) | 1191 | static void __net_exit sit_exit_net(struct net *net) |
| 1199 | { | 1192 | { |
| 1200 | struct sit_net *sitn = net_generic(net, sit_net_id); | 1193 | struct sit_net *sitn = net_generic(net, sit_net_id); |
| 1201 | LIST_HEAD(list); | 1194 | LIST_HEAD(list); |
| @@ -1228,15 +1221,14 @@ static int __init sit_init(void) | |||
| 1228 | 1221 | ||
| 1229 | printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); | 1222 | printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); |
| 1230 | 1223 | ||
| 1231 | if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) { | ||
| 1232 | printk(KERN_INFO "sit init: Can't add protocol\n"); | ||
| 1233 | return -EAGAIN; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | err = register_pernet_device(&sit_net_ops); | 1224 | err = register_pernet_device(&sit_net_ops); |
| 1237 | if (err < 0) | 1225 | if (err < 0) |
| 1238 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1226 | return err; |
| 1239 | 1227 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); | |
| 1228 | if (err < 0) { | ||
| 1229 | unregister_pernet_device(&sit_net_ops); | ||
| 1230 | printk(KERN_INFO "sit init: Can't add protocol\n"); | ||
| 1231 | } | ||
| 1240 | return err; | 1232 | return err; |
| 1241 | } | 1233 | } |
| 1242 | 1234 | ||
