diff options
author | David S. Miller <davem@davemloft.net> | 2016-10-30 12:42:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-30 12:42:58 -0400 |
commit | 27058af401e49d88a905df000dd26f443fcfa8ce (patch) | |
tree | 819f32113d3b8374b9fbf72e2202d4c4d4511a60 /drivers/net/geneve.c | |
parent | 357f4aae859b5d74554b0ccbb18556f1df4166c3 (diff) | |
parent | 2a26d99b251b8625d27aed14e97fc10707a3a81f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Mostly simple overlapping changes.
For example, David Ahern's adjacency list revamp in 'net-next'
conflicted with an adjacency list traversal bug fix in 'net'.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/geneve.c')
-rw-r--r-- | drivers/net/geneve.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 752bcaa852e4..85a423a66478 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c | |||
@@ -58,9 +58,9 @@ struct geneve_dev { | |||
58 | struct hlist_node hlist; /* vni hash table */ | 58 | struct hlist_node hlist; /* vni hash table */ |
59 | struct net *net; /* netns for packet i/o */ | 59 | struct net *net; /* netns for packet i/o */ |
60 | struct net_device *dev; /* netdev for geneve tunnel */ | 60 | struct net_device *dev; /* netdev for geneve tunnel */ |
61 | struct geneve_sock *sock4; /* IPv4 socket used for geneve tunnel */ | 61 | struct geneve_sock __rcu *sock4; /* IPv4 socket used for geneve tunnel */ |
62 | #if IS_ENABLED(CONFIG_IPV6) | 62 | #if IS_ENABLED(CONFIG_IPV6) |
63 | struct geneve_sock *sock6; /* IPv6 socket used for geneve tunnel */ | 63 | struct geneve_sock __rcu *sock6; /* IPv6 socket used for geneve tunnel */ |
64 | #endif | 64 | #endif |
65 | u8 vni[3]; /* virtual network ID for tunnel */ | 65 | u8 vni[3]; /* virtual network ID for tunnel */ |
66 | u8 ttl; /* TTL override */ | 66 | u8 ttl; /* TTL override */ |
@@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk, | |||
453 | 453 | ||
454 | skb_gro_pull(skb, gh_len); | 454 | skb_gro_pull(skb, gh_len); |
455 | skb_gro_postpull_rcsum(skb, gh, gh_len); | 455 | skb_gro_postpull_rcsum(skb, gh, gh_len); |
456 | pp = ptype->callbacks.gro_receive(head, skb); | 456 | pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); |
457 | flush = 0; | 457 | flush = 0; |
458 | 458 | ||
459 | out_unlock: | 459 | out_unlock: |
@@ -543,9 +543,19 @@ static void __geneve_sock_release(struct geneve_sock *gs) | |||
543 | 543 | ||
544 | static void geneve_sock_release(struct geneve_dev *geneve) | 544 | static void geneve_sock_release(struct geneve_dev *geneve) |
545 | { | 545 | { |
546 | __geneve_sock_release(geneve->sock4); | 546 | struct geneve_sock *gs4 = rtnl_dereference(geneve->sock4); |
547 | #if IS_ENABLED(CONFIG_IPV6) | 547 | #if IS_ENABLED(CONFIG_IPV6) |
548 | __geneve_sock_release(geneve->sock6); | 548 | struct geneve_sock *gs6 = rtnl_dereference(geneve->sock6); |
549 | |||
550 | rcu_assign_pointer(geneve->sock6, NULL); | ||
551 | #endif | ||
552 | |||
553 | rcu_assign_pointer(geneve->sock4, NULL); | ||
554 | synchronize_net(); | ||
555 | |||
556 | __geneve_sock_release(gs4); | ||
557 | #if IS_ENABLED(CONFIG_IPV6) | ||
558 | __geneve_sock_release(gs6); | ||
549 | #endif | 559 | #endif |
550 | } | 560 | } |
551 | 561 | ||
@@ -586,10 +596,10 @@ out: | |||
586 | gs->flags = geneve->flags; | 596 | gs->flags = geneve->flags; |
587 | #if IS_ENABLED(CONFIG_IPV6) | 597 | #if IS_ENABLED(CONFIG_IPV6) |
588 | if (ipv6) | 598 | if (ipv6) |
589 | geneve->sock6 = gs; | 599 | rcu_assign_pointer(geneve->sock6, gs); |
590 | else | 600 | else |
591 | #endif | 601 | #endif |
592 | geneve->sock4 = gs; | 602 | rcu_assign_pointer(geneve->sock4, gs); |
593 | 603 | ||
594 | hash = geneve_net_vni_hash(geneve->vni); | 604 | hash = geneve_net_vni_hash(geneve->vni); |
595 | hlist_add_head_rcu(&geneve->hlist, &gs->vni_list[hash]); | 605 | hlist_add_head_rcu(&geneve->hlist, &gs->vni_list[hash]); |
@@ -603,9 +613,7 @@ static int geneve_open(struct net_device *dev) | |||
603 | bool metadata = geneve->collect_md; | 613 | bool metadata = geneve->collect_md; |
604 | int ret = 0; | 614 | int ret = 0; |
605 | 615 | ||
606 | geneve->sock4 = NULL; | ||
607 | #if IS_ENABLED(CONFIG_IPV6) | 616 | #if IS_ENABLED(CONFIG_IPV6) |
608 | geneve->sock6 = NULL; | ||
609 | if (ipv6 || metadata) | 617 | if (ipv6 || metadata) |
610 | ret = geneve_sock_add(geneve, true); | 618 | ret = geneve_sock_add(geneve, true); |
611 | #endif | 619 | #endif |
@@ -720,6 +728,9 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb, | |||
720 | struct rtable *rt = NULL; | 728 | struct rtable *rt = NULL; |
721 | __u8 tos; | 729 | __u8 tos; |
722 | 730 | ||
731 | if (!rcu_dereference(geneve->sock4)) | ||
732 | return ERR_PTR(-EIO); | ||
733 | |||
723 | memset(fl4, 0, sizeof(*fl4)); | 734 | memset(fl4, 0, sizeof(*fl4)); |
724 | fl4->flowi4_mark = skb->mark; | 735 | fl4->flowi4_mark = skb->mark; |
725 | fl4->flowi4_proto = IPPROTO_UDP; | 736 | fl4->flowi4_proto = IPPROTO_UDP; |
@@ -772,11 +783,15 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, | |||
772 | { | 783 | { |
773 | bool use_cache = ip_tunnel_dst_cache_usable(skb, info); | 784 | bool use_cache = ip_tunnel_dst_cache_usable(skb, info); |
774 | struct geneve_dev *geneve = netdev_priv(dev); | 785 | struct geneve_dev *geneve = netdev_priv(dev); |
775 | struct geneve_sock *gs6 = geneve->sock6; | ||
776 | struct dst_entry *dst = NULL; | 786 | struct dst_entry *dst = NULL; |
777 | struct dst_cache *dst_cache; | 787 | struct dst_cache *dst_cache; |
788 | struct geneve_sock *gs6; | ||
778 | __u8 prio; | 789 | __u8 prio; |
779 | 790 | ||
791 | gs6 = rcu_dereference(geneve->sock6); | ||
792 | if (!gs6) | ||
793 | return ERR_PTR(-EIO); | ||
794 | |||
780 | memset(fl6, 0, sizeof(*fl6)); | 795 | memset(fl6, 0, sizeof(*fl6)); |
781 | fl6->flowi6_mark = skb->mark; | 796 | fl6->flowi6_mark = skb->mark; |
782 | fl6->flowi6_proto = IPPROTO_UDP; | 797 | fl6->flowi6_proto = IPPROTO_UDP; |
@@ -842,7 +857,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
842 | struct ip_tunnel_info *info) | 857 | struct ip_tunnel_info *info) |
843 | { | 858 | { |
844 | struct geneve_dev *geneve = netdev_priv(dev); | 859 | struct geneve_dev *geneve = netdev_priv(dev); |
845 | struct geneve_sock *gs4 = geneve->sock4; | 860 | struct geneve_sock *gs4; |
846 | struct rtable *rt = NULL; | 861 | struct rtable *rt = NULL; |
847 | const struct iphdr *iip; /* interior IP header */ | 862 | const struct iphdr *iip; /* interior IP header */ |
848 | int err = -EINVAL; | 863 | int err = -EINVAL; |
@@ -853,6 +868,10 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
853 | bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); | 868 | bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); |
854 | u32 flags = geneve->flags; | 869 | u32 flags = geneve->flags; |
855 | 870 | ||
871 | gs4 = rcu_dereference(geneve->sock4); | ||
872 | if (!gs4) | ||
873 | goto tx_error; | ||
874 | |||
856 | if (geneve->collect_md) { | 875 | if (geneve->collect_md) { |
857 | if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { | 876 | if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { |
858 | netdev_dbg(dev, "no tunnel metadata\n"); | 877 | netdev_dbg(dev, "no tunnel metadata\n"); |
@@ -932,9 +951,9 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
932 | struct ip_tunnel_info *info) | 951 | struct ip_tunnel_info *info) |
933 | { | 952 | { |
934 | struct geneve_dev *geneve = netdev_priv(dev); | 953 | struct geneve_dev *geneve = netdev_priv(dev); |
935 | struct geneve_sock *gs6 = geneve->sock6; | ||
936 | struct dst_entry *dst = NULL; | 954 | struct dst_entry *dst = NULL; |
937 | const struct iphdr *iip; /* interior IP header */ | 955 | const struct iphdr *iip; /* interior IP header */ |
956 | struct geneve_sock *gs6; | ||
938 | int err = -EINVAL; | 957 | int err = -EINVAL; |
939 | struct flowi6 fl6; | 958 | struct flowi6 fl6; |
940 | __u8 prio, ttl; | 959 | __u8 prio, ttl; |
@@ -943,6 +962,10 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
943 | bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); | 962 | bool xnet = !net_eq(geneve->net, dev_net(geneve->dev)); |
944 | u32 flags = geneve->flags; | 963 | u32 flags = geneve->flags; |
945 | 964 | ||
965 | gs6 = rcu_dereference(geneve->sock6); | ||
966 | if (!gs6) | ||
967 | goto tx_error; | ||
968 | |||
946 | if (geneve->collect_md) { | 969 | if (geneve->collect_md) { |
947 | if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { | 970 | if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { |
948 | netdev_dbg(dev, "no tunnel metadata\n"); | 971 | netdev_dbg(dev, "no tunnel metadata\n"); |