diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_trie.c | 8 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 1 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 31 |
3 files changed, 33 insertions, 7 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d07fc076bea0..febca0f1008c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -2452,9 +2452,7 @@ struct fib_route_iter { | |||
2452 | static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, | 2452 | static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, |
2453 | loff_t pos) | 2453 | loff_t pos) |
2454 | { | 2454 | { |
2455 | struct fib_table *tb = iter->main_tb; | ||
2456 | struct key_vector *l, **tp = &iter->tnode; | 2455 | struct key_vector *l, **tp = &iter->tnode; |
2457 | struct trie *t; | ||
2458 | t_key key; | 2456 | t_key key; |
2459 | 2457 | ||
2460 | /* use cache location of next-to-find key */ | 2458 | /* use cache location of next-to-find key */ |
@@ -2462,8 +2460,6 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, | |||
2462 | pos -= iter->pos; | 2460 | pos -= iter->pos; |
2463 | key = iter->key; | 2461 | key = iter->key; |
2464 | } else { | 2462 | } else { |
2465 | t = (struct trie *)tb->tb_data; | ||
2466 | iter->tnode = t->kv; | ||
2467 | iter->pos = 0; | 2463 | iter->pos = 0; |
2468 | key = 0; | 2464 | key = 0; |
2469 | } | 2465 | } |
@@ -2504,12 +2500,12 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) | |||
2504 | return NULL; | 2500 | return NULL; |
2505 | 2501 | ||
2506 | iter->main_tb = tb; | 2502 | iter->main_tb = tb; |
2503 | t = (struct trie *)tb->tb_data; | ||
2504 | iter->tnode = t->kv; | ||
2507 | 2505 | ||
2508 | if (*pos != 0) | 2506 | if (*pos != 0) |
2509 | return fib_route_get_idx(iter, *pos); | 2507 | return fib_route_get_idx(iter, *pos); |
2510 | 2508 | ||
2511 | t = (struct trie *)tb->tb_data; | ||
2512 | iter->tnode = t->kv; | ||
2513 | iter->pos = 0; | 2509 | iter->pos = 0; |
2514 | iter->key = 0; | 2510 | iter->key = 0; |
2515 | 2511 | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5b1481be0282..113cc43df789 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -370,7 +370,6 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, | |||
370 | tunnel->parms.o_flags, proto, tunnel->parms.o_key, | 370 | tunnel->parms.o_flags, proto, tunnel->parms.o_key, |
371 | htonl(tunnel->o_seqno)); | 371 | htonl(tunnel->o_seqno)); |
372 | 372 | ||
373 | skb_set_inner_protocol(skb, proto); | ||
374 | ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol); | 373 | ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol); |
375 | } | 374 | } |
376 | 375 | ||
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index a917903d5e97..cc701fa70b12 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -557,6 +557,33 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = { | |||
557 | .get_link_net = ip_tunnel_get_link_net, | 557 | .get_link_net = ip_tunnel_get_link_net, |
558 | }; | 558 | }; |
559 | 559 | ||
560 | static bool is_vti_tunnel(const struct net_device *dev) | ||
561 | { | ||
562 | return dev->netdev_ops == &vti_netdev_ops; | ||
563 | } | ||
564 | |||
565 | static int vti_device_event(struct notifier_block *unused, | ||
566 | unsigned long event, void *ptr) | ||
567 | { | ||
568 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||
569 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
570 | |||
571 | if (!is_vti_tunnel(dev)) | ||
572 | return NOTIFY_DONE; | ||
573 | |||
574 | switch (event) { | ||
575 | case NETDEV_DOWN: | ||
576 | if (!net_eq(tunnel->net, dev_net(dev))) | ||
577 | xfrm_garbage_collect(tunnel->net); | ||
578 | break; | ||
579 | } | ||
580 | return NOTIFY_DONE; | ||
581 | } | ||
582 | |||
583 | static struct notifier_block vti_notifier_block __read_mostly = { | ||
584 | .notifier_call = vti_device_event, | ||
585 | }; | ||
586 | |||
560 | static int __init vti_init(void) | 587 | static int __init vti_init(void) |
561 | { | 588 | { |
562 | const char *msg; | 589 | const char *msg; |
@@ -564,6 +591,8 @@ static int __init vti_init(void) | |||
564 | 591 | ||
565 | pr_info("IPv4 over IPsec tunneling driver\n"); | 592 | pr_info("IPv4 over IPsec tunneling driver\n"); |
566 | 593 | ||
594 | register_netdevice_notifier(&vti_notifier_block); | ||
595 | |||
567 | msg = "tunnel device"; | 596 | msg = "tunnel device"; |
568 | err = register_pernet_device(&vti_net_ops); | 597 | err = register_pernet_device(&vti_net_ops); |
569 | if (err < 0) | 598 | if (err < 0) |
@@ -596,6 +625,7 @@ xfrm_proto_ah_failed: | |||
596 | xfrm_proto_esp_failed: | 625 | xfrm_proto_esp_failed: |
597 | unregister_pernet_device(&vti_net_ops); | 626 | unregister_pernet_device(&vti_net_ops); |
598 | pernet_dev_failed: | 627 | pernet_dev_failed: |
628 | unregister_netdevice_notifier(&vti_notifier_block); | ||
599 | pr_err("vti init: failed to register %s\n", msg); | 629 | pr_err("vti init: failed to register %s\n", msg); |
600 | return err; | 630 | return err; |
601 | } | 631 | } |
@@ -607,6 +637,7 @@ static void __exit vti_fini(void) | |||
607 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); | 637 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); |
608 | xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); | 638 | xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); |
609 | unregister_pernet_device(&vti_net_ops); | 639 | unregister_pernet_device(&vti_net_ops); |
640 | unregister_netdevice_notifier(&vti_notifier_block); | ||
610 | } | 641 | } |
611 | 642 | ||
612 | module_init(vti_init); | 643 | module_init(vti_init); |