aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c88
1 files changed, 44 insertions, 44 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 143333852624..f36ce156cac6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -125,7 +125,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev);
125 125
126#define HASH_SIZE 16 126#define HASH_SIZE 16
127 127
128static int ipgre_net_id; 128static int ipgre_net_id __read_mostly;
129struct ipgre_net { 129struct ipgre_net {
130 struct ip_tunnel *tunnels[4][HASH_SIZE]; 130 struct ip_tunnel *tunnels[4][HASH_SIZE];
131 131
@@ -156,8 +156,13 @@ struct ipgre_net {
156#define tunnels_r tunnels[2] 156#define tunnels_r tunnels[2]
157#define tunnels_l tunnels[1] 157#define tunnels_l tunnels[1]
158#define tunnels_wc tunnels[0] 158#define tunnels_wc tunnels[0]
159/*
160 * Locking : hash tables are protected by RCU and a spinlock
161 */
162static DEFINE_SPINLOCK(ipgre_lock);
159 163
160static DEFINE_RWLOCK(ipgre_lock); 164#define for_each_ip_tunnel_rcu(start) \
165 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
161 166
162/* Given src, dst and key, find appropriate for input tunnel. */ 167/* Given src, dst and key, find appropriate for input tunnel. */
163 168
@@ -175,7 +180,7 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
175 ARPHRD_ETHER : ARPHRD_IPGRE; 180 ARPHRD_ETHER : ARPHRD_IPGRE;
176 int score, cand_score = 4; 181 int score, cand_score = 4;
177 182
178 for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) { 183 for_each_ip_tunnel_rcu(ign->tunnels_r_l[h0 ^ h1]) {
179 if (local != t->parms.iph.saddr || 184 if (local != t->parms.iph.saddr ||
180 remote != t->parms.iph.daddr || 185 remote != t->parms.iph.daddr ||
181 key != t->parms.i_key || 186 key != t->parms.i_key ||
@@ -200,7 +205,7 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
200 } 205 }
201 } 206 }
202 207
203 for (t = ign->tunnels_r[h0^h1]; t; t = t->next) { 208 for_each_ip_tunnel_rcu(ign->tunnels_r[h0 ^ h1]) {
204 if (remote != t->parms.iph.daddr || 209 if (remote != t->parms.iph.daddr ||
205 key != t->parms.i_key || 210 key != t->parms.i_key ||
206 !(t->dev->flags & IFF_UP)) 211 !(t->dev->flags & IFF_UP))
@@ -224,7 +229,7 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
224 } 229 }
225 } 230 }
226 231
227 for (t = ign->tunnels_l[h1]; t; t = t->next) { 232 for_each_ip_tunnel_rcu(ign->tunnels_l[h1]) {
228 if ((local != t->parms.iph.saddr && 233 if ((local != t->parms.iph.saddr &&
229 (local != t->parms.iph.daddr || 234 (local != t->parms.iph.daddr ||
230 !ipv4_is_multicast(local))) || 235 !ipv4_is_multicast(local))) ||
@@ -250,7 +255,7 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
250 } 255 }
251 } 256 }
252 257
253 for (t = ign->tunnels_wc[h1]; t; t = t->next) { 258 for_each_ip_tunnel_rcu(ign->tunnels_wc[h1]) {
254 if (t->parms.i_key != key || 259 if (t->parms.i_key != key ||
255 !(t->dev->flags & IFF_UP)) 260 !(t->dev->flags & IFF_UP))
256 continue; 261 continue;
@@ -276,8 +281,9 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
276 if (cand != NULL) 281 if (cand != NULL)
277 return cand; 282 return cand;
278 283
279 if (ign->fb_tunnel_dev->flags & IFF_UP) 284 dev = ign->fb_tunnel_dev;
280 return netdev_priv(ign->fb_tunnel_dev); 285 if (dev->flags & IFF_UP)
286 return netdev_priv(dev);
281 287
282 return NULL; 288 return NULL;
283} 289}
@@ -311,10 +317,10 @@ static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t)
311{ 317{
312 struct ip_tunnel **tp = ipgre_bucket(ign, t); 318 struct ip_tunnel **tp = ipgre_bucket(ign, t);
313 319
320 spin_lock_bh(&ipgre_lock);
314 t->next = *tp; 321 t->next = *tp;
315 write_lock_bh(&ipgre_lock); 322 rcu_assign_pointer(*tp, t);
316 *tp = t; 323 spin_unlock_bh(&ipgre_lock);
317 write_unlock_bh(&ipgre_lock);
318} 324}
319 325
320static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t) 326static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
@@ -323,9 +329,9 @@ static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
323 329
324 for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) { 330 for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) {
325 if (t == *tp) { 331 if (t == *tp) {
326 write_lock_bh(&ipgre_lock); 332 spin_lock_bh(&ipgre_lock);
327 *tp = t->next; 333 *tp = t->next;
328 write_unlock_bh(&ipgre_lock); 334 spin_unlock_bh(&ipgre_lock);
329 break; 335 break;
330 } 336 }
331 } 337 }
@@ -476,7 +482,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
476 break; 482 break;
477 } 483 }
478 484
479 read_lock(&ipgre_lock); 485 rcu_read_lock();
480 t = ipgre_tunnel_lookup(skb->dev, iph->daddr, iph->saddr, 486 t = ipgre_tunnel_lookup(skb->dev, iph->daddr, iph->saddr,
481 flags & GRE_KEY ? 487 flags & GRE_KEY ?
482 *(((__be32 *)p) + (grehlen / 4) - 1) : 0, 488 *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
@@ -494,7 +500,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
494 t->err_count = 1; 500 t->err_count = 1;
495 t->err_time = jiffies; 501 t->err_time = jiffies;
496out: 502out:
497 read_unlock(&ipgre_lock); 503 rcu_read_unlock();
498 return; 504 return;
499} 505}
500 506
@@ -573,7 +579,7 @@ static int ipgre_rcv(struct sk_buff *skb)
573 579
574 gre_proto = *(__be16 *)(h + 2); 580 gre_proto = *(__be16 *)(h + 2);
575 581
576 read_lock(&ipgre_lock); 582 rcu_read_lock();
577 if ((tunnel = ipgre_tunnel_lookup(skb->dev, 583 if ((tunnel = ipgre_tunnel_lookup(skb->dev,
578 iph->saddr, iph->daddr, key, 584 iph->saddr, iph->daddr, key,
579 gre_proto))) { 585 gre_proto))) {
@@ -647,13 +653,13 @@ static int ipgre_rcv(struct sk_buff *skb)
647 ipgre_ecn_decapsulate(iph, skb); 653 ipgre_ecn_decapsulate(iph, skb);
648 654
649 netif_rx(skb); 655 netif_rx(skb);
650 read_unlock(&ipgre_lock); 656 rcu_read_unlock();
651 return(0); 657 return(0);
652 } 658 }
653 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 659 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
654 660
655drop: 661drop:
656 read_unlock(&ipgre_lock); 662 rcu_read_unlock();
657drop_nolock: 663drop_nolock:
658 kfree_skb(skb); 664 kfree_skb(skb);
659 return(0); 665 return(0);
@@ -662,7 +668,8 @@ drop_nolock:
662static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 668static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
663{ 669{
664 struct ip_tunnel *tunnel = netdev_priv(dev); 670 struct ip_tunnel *tunnel = netdev_priv(dev);
665 struct net_device_stats *stats = &tunnel->dev->stats; 671 struct net_device_stats *stats = &dev->stats;
672 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
666 struct iphdr *old_iph = ip_hdr(skb); 673 struct iphdr *old_iph = ip_hdr(skb);
667 struct iphdr *tiph; 674 struct iphdr *tiph;
668 u8 tos; 675 u8 tos;
@@ -810,7 +817,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
810 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 817 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
811 if (!new_skb) { 818 if (!new_skb) {
812 ip_rt_put(rt); 819 ip_rt_put(rt);
813 stats->tx_dropped++; 820 txq->tx_dropped++;
814 dev_kfree_skb(skb); 821 dev_kfree_skb(skb);
815 return NETDEV_TX_OK; 822 return NETDEV_TX_OK;
816 } 823 }
@@ -1283,33 +1290,27 @@ static const struct net_protocol ipgre_protocol = {
1283 .netns_ok = 1, 1290 .netns_ok = 1,
1284}; 1291};
1285 1292
1286static void ipgre_destroy_tunnels(struct ipgre_net *ign) 1293static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head)
1287{ 1294{
1288 int prio; 1295 int prio;
1289 1296
1290 for (prio = 0; prio < 4; prio++) { 1297 for (prio = 0; prio < 4; prio++) {
1291 int h; 1298 int h;
1292 for (h = 0; h < HASH_SIZE; h++) { 1299 for (h = 0; h < HASH_SIZE; h++) {
1293 struct ip_tunnel *t; 1300 struct ip_tunnel *t = ign->tunnels[prio][h];
1294 while ((t = ign->tunnels[prio][h]) != NULL) 1301
1295 unregister_netdevice(t->dev); 1302 while (t != NULL) {
1303 unregister_netdevice_queue(t->dev, head);
1304 t = t->next;
1305 }
1296 } 1306 }
1297 } 1307 }
1298} 1308}
1299 1309
1300static int ipgre_init_net(struct net *net) 1310static int ipgre_init_net(struct net *net)
1301{ 1311{
1312 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
1302 int err; 1313 int err;
1303 struct ipgre_net *ign;
1304
1305 err = -ENOMEM;
1306 ign = kzalloc(sizeof(struct ipgre_net), GFP_KERNEL);
1307 if (ign == NULL)
1308 goto err_alloc;
1309
1310 err = net_assign_generic(net, ipgre_net_id, ign);
1311 if (err < 0)
1312 goto err_assign;
1313 1314
1314 ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0", 1315 ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",
1315 ipgre_tunnel_setup); 1316 ipgre_tunnel_setup);
@@ -1330,27 +1331,26 @@ static int ipgre_init_net(struct net *net)
1330err_reg_dev: 1331err_reg_dev:
1331 free_netdev(ign->fb_tunnel_dev); 1332 free_netdev(ign->fb_tunnel_dev);
1332err_alloc_dev: 1333err_alloc_dev:
1333 /* nothing */
1334err_assign:
1335 kfree(ign);
1336err_alloc:
1337 return err; 1334 return err;
1338} 1335}
1339 1336
1340static void ipgre_exit_net(struct net *net) 1337static void ipgre_exit_net(struct net *net)
1341{ 1338{
1342 struct ipgre_net *ign; 1339 struct ipgre_net *ign;
1340 LIST_HEAD(list);
1343 1341
1344 ign = net_generic(net, ipgre_net_id); 1342 ign = net_generic(net, ipgre_net_id);
1345 rtnl_lock(); 1343 rtnl_lock();
1346 ipgre_destroy_tunnels(ign); 1344 ipgre_destroy_tunnels(ign, &list);
1345 unregister_netdevice_many(&list);
1347 rtnl_unlock(); 1346 rtnl_unlock();
1348 kfree(ign);
1349} 1347}
1350 1348
1351static struct pernet_operations ipgre_net_ops = { 1349static struct pernet_operations ipgre_net_ops = {
1352 .init = ipgre_init_net, 1350 .init = ipgre_init_net,
1353 .exit = ipgre_exit_net, 1351 .exit = ipgre_exit_net,
1352 .id = &ipgre_net_id,
1353 .size = sizeof(struct ipgre_net),
1354}; 1354};
1355 1355
1356static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) 1356static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -1471,7 +1471,7 @@ static void ipgre_tap_setup(struct net_device *dev)
1471 dev->features |= NETIF_F_NETNS_LOCAL; 1471 dev->features |= NETIF_F_NETNS_LOCAL;
1472} 1472}
1473 1473
1474static int ipgre_newlink(struct net_device *dev, struct nlattr *tb[], 1474static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[],
1475 struct nlattr *data[]) 1475 struct nlattr *data[])
1476{ 1476{
1477 struct ip_tunnel *nt; 1477 struct ip_tunnel *nt;
@@ -1670,7 +1670,7 @@ static int __init ipgre_init(void)
1670 return -EAGAIN; 1670 return -EAGAIN;
1671 } 1671 }
1672 1672
1673 err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); 1673 err = register_pernet_device(&ipgre_net_ops);
1674 if (err < 0) 1674 if (err < 0)
1675 goto gen_device_failed; 1675 goto gen_device_failed;
1676 1676
@@ -1688,7 +1688,7 @@ out:
1688tap_ops_failed: 1688tap_ops_failed:
1689 rtnl_link_unregister(&ipgre_link_ops); 1689 rtnl_link_unregister(&ipgre_link_ops);
1690rtnl_link_failed: 1690rtnl_link_failed:
1691 unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); 1691 unregister_pernet_device(&ipgre_net_ops);
1692gen_device_failed: 1692gen_device_failed:
1693 inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); 1693 inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
1694 goto out; 1694 goto out;
@@ -1698,7 +1698,7 @@ static void __exit ipgre_fini(void)
1698{ 1698{
1699 rtnl_link_unregister(&ipgre_tap_ops); 1699 rtnl_link_unregister(&ipgre_tap_ops);
1700 rtnl_link_unregister(&ipgre_link_ops); 1700 rtnl_link_unregister(&ipgre_link_ops);
1701 unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); 1701 unregister_pernet_device(&ipgre_net_ops);
1702 if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) 1702 if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
1703 printk(KERN_INFO "ipgre close: can't remove protocol\n"); 1703 printk(KERN_INFO "ipgre close: can't remove protocol\n");
1704} 1704}