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.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index aa6efc2ab55b..66cf0be4b679 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -82,7 +82,8 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne
82 82
83static DEFINE_RWLOCK(ipip6_lock); 83static DEFINE_RWLOCK(ipip6_lock);
84 84
85static struct ip_tunnel * ipip6_tunnel_lookup(__be32 remote, __be32 local) 85static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
86 __be32 remote, __be32 local)
86{ 87{
87 unsigned h0 = HASH(remote); 88 unsigned h0 = HASH(remote);
88 unsigned h1 = HASH(local); 89 unsigned h1 = HASH(local);
@@ -106,7 +107,8 @@ static struct ip_tunnel * ipip6_tunnel_lookup(__be32 remote, __be32 local)
106 return NULL; 107 return NULL;
107} 108}
108 109
109static struct ip_tunnel **__ipip6_bucket(struct ip_tunnel_parm *parms) 110static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn,
111 struct ip_tunnel_parm *parms)
110{ 112{
111 __be32 remote = parms->iph.daddr; 113 __be32 remote = parms->iph.daddr;
112 __be32 local = parms->iph.saddr; 114 __be32 local = parms->iph.saddr;
@@ -124,16 +126,17 @@ static struct ip_tunnel **__ipip6_bucket(struct ip_tunnel_parm *parms)
124 return &tunnels[prio][h]; 126 return &tunnels[prio][h];
125} 127}
126 128
127static inline struct ip_tunnel **ipip6_bucket(struct ip_tunnel *t) 129static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn,
130 struct ip_tunnel *t)
128{ 131{
129 return __ipip6_bucket(&t->parms); 132 return __ipip6_bucket(sitn, &t->parms);
130} 133}
131 134
132static void ipip6_tunnel_unlink(struct ip_tunnel *t) 135static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
133{ 136{
134 struct ip_tunnel **tp; 137 struct ip_tunnel **tp;
135 138
136 for (tp = ipip6_bucket(t); *tp; tp = &(*tp)->next) { 139 for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) {
137 if (t == *tp) { 140 if (t == *tp) {
138 write_lock_bh(&ipip6_lock); 141 write_lock_bh(&ipip6_lock);
139 *tp = t->next; 142 *tp = t->next;
@@ -143,9 +146,9 @@ static void ipip6_tunnel_unlink(struct ip_tunnel *t)
143 } 146 }
144} 147}
145 148
146static void ipip6_tunnel_link(struct ip_tunnel *t) 149static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
147{ 150{
148 struct ip_tunnel **tp = ipip6_bucket(t); 151 struct ip_tunnel **tp = ipip6_bucket(sitn, t);
149 152
150 t->next = *tp; 153 t->next = *tp;
151 write_lock_bh(&ipip6_lock); 154 write_lock_bh(&ipip6_lock);
@@ -153,15 +156,17 @@ static void ipip6_tunnel_link(struct ip_tunnel *t)
153 write_unlock_bh(&ipip6_lock); 156 write_unlock_bh(&ipip6_lock);
154} 157}
155 158
156static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) 159static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
160 struct ip_tunnel_parm *parms, int create)
157{ 161{
158 __be32 remote = parms->iph.daddr; 162 __be32 remote = parms->iph.daddr;
159 __be32 local = parms->iph.saddr; 163 __be32 local = parms->iph.saddr;
160 struct ip_tunnel *t, **tp, *nt; 164 struct ip_tunnel *t, **tp, *nt;
161 struct net_device *dev; 165 struct net_device *dev;
162 char name[IFNAMSIZ]; 166 char name[IFNAMSIZ];
167 struct sit_net *sitn = net_generic(net, sit_net_id);
163 168
164 for (tp = __ipip6_bucket(parms); (t = *tp) != NULL; tp = &t->next) { 169 for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) {
165 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) 170 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
166 return t; 171 return t;
167 } 172 }
@@ -194,7 +199,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
194 199
195 dev_hold(dev); 200 dev_hold(dev);
196 201
197 ipip6_tunnel_link(nt); 202 ipip6_tunnel_link(sitn, nt);
198 return nt; 203 return nt;
199 204
200failed_free: 205failed_free:
@@ -378,13 +383,16 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
378 383
379static void ipip6_tunnel_uninit(struct net_device *dev) 384static void ipip6_tunnel_uninit(struct net_device *dev)
380{ 385{
386 struct net *net = dev_net(dev);
387 struct sit_net *sitn = net_generic(net, sit_net_id);
388
381 if (dev == ipip6_fb_tunnel_dev) { 389 if (dev == ipip6_fb_tunnel_dev) {
382 write_lock_bh(&ipip6_lock); 390 write_lock_bh(&ipip6_lock);
383 tunnels_wc[0] = NULL; 391 tunnels_wc[0] = NULL;
384 write_unlock_bh(&ipip6_lock); 392 write_unlock_bh(&ipip6_lock);
385 dev_put(dev); 393 dev_put(dev);
386 } else { 394 } else {
387 ipip6_tunnel_unlink(netdev_priv(dev)); 395 ipip6_tunnel_unlink(sitn, netdev_priv(dev));
388 ipip6_tunnel_del_prl(netdev_priv(dev), NULL); 396 ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
389 dev_put(dev); 397 dev_put(dev);
390 } 398 }
@@ -436,7 +444,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
436 err = -ENOENT; 444 err = -ENOENT;
437 445
438 read_lock(&ipip6_lock); 446 read_lock(&ipip6_lock);
439 t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); 447 t = ipip6_tunnel_lookup(&init_net, iph->daddr, iph->saddr);
440 if (t == NULL || t->parms.iph.daddr == 0) 448 if (t == NULL || t->parms.iph.daddr == 0)
441 goto out; 449 goto out;
442 450
@@ -556,7 +564,8 @@ static int ipip6_rcv(struct sk_buff *skb)
556 iph = ip_hdr(skb); 564 iph = ip_hdr(skb);
557 565
558 read_lock(&ipip6_lock); 566 read_lock(&ipip6_lock);
559 if ((tunnel = ipip6_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) { 567 if ((tunnel = ipip6_tunnel_lookup(&init_net,
568 iph->saddr, iph->daddr)) != NULL) {
560 secpath_reset(skb); 569 secpath_reset(skb);
561 skb->mac_header = skb->network_header; 570 skb->mac_header = skb->network_header;
562 skb_reset_network_header(skb); 571 skb_reset_network_header(skb);
@@ -847,6 +856,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
847 struct ip_tunnel_parm p; 856 struct ip_tunnel_parm p;
848 struct ip_tunnel_prl prl; 857 struct ip_tunnel_prl prl;
849 struct ip_tunnel *t; 858 struct ip_tunnel *t;
859 struct net *net = dev_net(dev);
860 struct sit_net *sitn = net_generic(net, sit_net_id);
850 861
851 switch (cmd) { 862 switch (cmd) {
852 case SIOCGETTUNNEL: 863 case SIOCGETTUNNEL:
@@ -856,7 +867,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
856 err = -EFAULT; 867 err = -EFAULT;
857 break; 868 break;
858 } 869 }
859 t = ipip6_tunnel_locate(&p, 0); 870 t = ipip6_tunnel_locate(net, &p, 0);
860 } 871 }
861 if (t == NULL) 872 if (t == NULL)
862 t = netdev_priv(dev); 873 t = netdev_priv(dev);
@@ -882,7 +893,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
882 if (p.iph.ttl) 893 if (p.iph.ttl)
883 p.iph.frag_off |= htons(IP_DF); 894 p.iph.frag_off |= htons(IP_DF);
884 895
885 t = ipip6_tunnel_locate(&p, cmd == SIOCADDTUNNEL); 896 t = ipip6_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
886 897
887 if (dev != ipip6_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { 898 if (dev != ipip6_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
888 if (t != NULL) { 899 if (t != NULL) {
@@ -897,12 +908,12 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
897 break; 908 break;
898 } 909 }
899 t = netdev_priv(dev); 910 t = netdev_priv(dev);
900 ipip6_tunnel_unlink(t); 911 ipip6_tunnel_unlink(sitn, t);
901 t->parms.iph.saddr = p.iph.saddr; 912 t->parms.iph.saddr = p.iph.saddr;
902 t->parms.iph.daddr = p.iph.daddr; 913 t->parms.iph.daddr = p.iph.daddr;
903 memcpy(dev->dev_addr, &p.iph.saddr, 4); 914 memcpy(dev->dev_addr, &p.iph.saddr, 4);
904 memcpy(dev->broadcast, &p.iph.daddr, 4); 915 memcpy(dev->broadcast, &p.iph.daddr, 4);
905 ipip6_tunnel_link(t); 916 ipip6_tunnel_link(sitn, t);
906 netdev_state_change(dev); 917 netdev_state_change(dev);
907 } 918 }
908 } 919 }
@@ -934,7 +945,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
934 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 945 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
935 goto done; 946 goto done;
936 err = -ENOENT; 947 err = -ENOENT;
937 if ((t = ipip6_tunnel_locate(&p, 0)) == NULL) 948 if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL)
938 goto done; 949 goto done;
939 err = -EPERM; 950 err = -EPERM;
940 if (t == netdev_priv(ipip6_fb_tunnel_dev)) 951 if (t == netdev_priv(ipip6_fb_tunnel_dev))