diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-09 16:42:20 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-10 23:47:22 -0700 |
commit | fc038410b4b1643766f8033f4940bcdb1dace633 (patch) | |
tree | 3ee59190ecaa77061a9b64cdc09fcce6b6efc389 /net/ipv6 | |
parent | a2af421f1819946556c6f467b1efdd0dc84af4d5 (diff) |
[UDP]: Fix AF-specific references in AF-agnostic code.
__udp_lib_port_inuse() cannot make direct references to
inet_sk(sk)->rcv_saddr as that is ipv4 specific state and
this code is used by ipv6 too.
Use an operations vector to solve this, and this also paves
the way for ipv6 support for non-wild saddr hashing in UDP.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/udp.c | 21 | ||||
-rw-r--r-- | net/ipv6/udp_impl.h | 2 | ||||
-rw-r--r-- | net/ipv6/udplite.c | 2 |
3 files changed, 23 insertions, 2 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b083c09e3d2..a7ae59c954d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -52,9 +52,28 @@ DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; +static int ipv6_rcv_saddr_any(const struct sock *sk) +{ + struct ipv6_pinfo *np = inet6_sk(sk); + + return ipv6_addr_any(&np->rcv_saddr); +} + +static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port, + const struct sock *sk) +{ + return port; +} + +const struct udp_get_port_ops udp_ipv6_ops = { + .saddr_cmp = ipv6_rcv_saddr_equal, + .saddr_any = ipv6_rcv_saddr_any, + .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr, +}; + static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) { - return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); + return udp_get_port(sk, snum, &udp_ipv6_ops); } static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 6e252f318f7..36b0c11a28a 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h @@ -6,6 +6,8 @@ #include <net/addrconf.h> #include <net/inet_common.h> +extern const struct udp_get_port_ops udp_ipv6_ops; + extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, int , int , int , __be32 , struct hlist_head []); diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index f54016a5500..c40a51362f8 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = { static int udplite_v6_get_port(struct sock *sk, unsigned short snum) { - return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal); + return udplite_get_port(sk, snum, &udp_ipv6_ops); } struct proto udplitev6_prot = { |