geneve: Check family when reusing sockets.
authorJesse Gross <jesse@nicira.com>
Sat, 3 Jan 2015 02:26:05 +0000 (18:26 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 5 Jan 2015 03:21:33 +0000 (22:21 -0500)
When searching for an existing socket to reuse, the address family
is not taken into account - only port number. This means that an
IPv4 socket could be used for IPv6 traffic and vice versa, which
is sure to cause problems when passing packets.

It is not possible to trigger this problem currently because the
only user of Geneve creates just IPv4 sockets. However, that is
likely to change in the near future.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/geneve.c

index 4fe5a592821cf94494d14e4852d95fb30ab72081..5b52046ec7a2e134de93ad39fa0dc4c1523fc9c0 100644 (file)
@@ -65,14 +65,15 @@ static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb)
        return (struct genevehdr *)(udp_hdr(skb) + 1);
 }
 
-/* Find geneve socket based on network namespace and UDP port */
-static struct geneve_sock *geneve_find_sock(struct net *net, __be16 port)
+static struct geneve_sock *geneve_find_sock(struct net *net,
+                                           sa_family_t family, __be16 port)
 {
        struct geneve_net *gn = net_generic(net, geneve_net_id);
        struct geneve_sock *gs;
 
        list_for_each_entry(gs, &gn->sock_list, list) {
-               if (inet_sk(gs->sock->sk)->inet_sport == port)
+               if (inet_sk(gs->sock->sk)->inet_sport == port &&
+                   inet_sk(gs->sock->sk)->sk.sk_family == family)
                        return gs;
        }
 
@@ -375,7 +376,7 @@ struct geneve_sock *geneve_sock_add(struct net *net, __be16 port,
 
        mutex_lock(&geneve_mutex);
 
-       gs = geneve_find_sock(net, port);
+       gs = geneve_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port);
        if (gs) {
                if (!no_share && gs->rcv == rcv)
                        gs->refcnt++;