|
@@ -137,11 +137,7 @@ EXPORT_SYMBOL(udp_memory_allocated);
|
|
|
static int udp_lib_lport_inuse(struct net *net, __u16 num,
|
|
|
const struct udp_hslot *hslot,
|
|
|
unsigned long *bitmap,
|
|
|
- struct sock *sk,
|
|
|
- int (*saddr_comp)(const struct sock *sk1,
|
|
|
- const struct sock *sk2,
|
|
|
- bool match_wildcard),
|
|
|
- unsigned int log)
|
|
|
+ struct sock *sk, unsigned int log)
|
|
|
{
|
|
|
struct sock *sk2;
|
|
|
kuid_t uid = sock_i_uid(sk);
|
|
@@ -153,7 +149,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
|
|
|
(!sk2->sk_reuse || !sk->sk_reuse) &&
|
|
|
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
|
|
|
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
|
|
|
- saddr_comp(sk, sk2, true)) {
|
|
|
+ inet_rcv_saddr_equal(sk, sk2, true)) {
|
|
|
if (sk2->sk_reuseport && sk->sk_reuseport &&
|
|
|
!rcu_access_pointer(sk->sk_reuseport_cb) &&
|
|
|
uid_eq(uid, sock_i_uid(sk2))) {
|
|
@@ -176,10 +172,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
|
|
|
*/
|
|
|
static int udp_lib_lport_inuse2(struct net *net, __u16 num,
|
|
|
struct udp_hslot *hslot2,
|
|
|
- struct sock *sk,
|
|
|
- int (*saddr_comp)(const struct sock *sk1,
|
|
|
- const struct sock *sk2,
|
|
|
- bool match_wildcard))
|
|
|
+ struct sock *sk)
|
|
|
{
|
|
|
struct sock *sk2;
|
|
|
kuid_t uid = sock_i_uid(sk);
|
|
@@ -193,7 +186,7 @@ static int udp_lib_lport_inuse2(struct net *net, __u16 num,
|
|
|
(!sk2->sk_reuse || !sk->sk_reuse) &&
|
|
|
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
|
|
|
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
|
|
|
- saddr_comp(sk, sk2, true)) {
|
|
|
+ inet_rcv_saddr_equal(sk, sk2, true)) {
|
|
|
if (sk2->sk_reuseport && sk->sk_reuseport &&
|
|
|
!rcu_access_pointer(sk->sk_reuseport_cb) &&
|
|
|
uid_eq(uid, sock_i_uid(sk2))) {
|
|
@@ -208,10 +201,7 @@ static int udp_lib_lport_inuse2(struct net *net, __u16 num,
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot,
|
|
|
- int (*saddr_same)(const struct sock *sk1,
|
|
|
- const struct sock *sk2,
|
|
|
- bool match_wildcard))
|
|
|
+static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
|
|
|
{
|
|
|
struct net *net = sock_net(sk);
|
|
|
kuid_t uid = sock_i_uid(sk);
|
|
@@ -225,7 +215,7 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot,
|
|
|
(udp_sk(sk2)->udp_port_hash == udp_sk(sk)->udp_port_hash) &&
|
|
|
(sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
|
|
|
sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) &&
|
|
|
- (*saddr_same)(sk, sk2, false)) {
|
|
|
+ inet_rcv_saddr_equal(sk, sk2, false)) {
|
|
|
return reuseport_add_sock(sk, sk2);
|
|
|
}
|
|
|
}
|
|
@@ -241,14 +231,10 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot,
|
|
|
*
|
|
|
* @sk: socket struct in question
|
|
|
* @snum: port number to look up
|
|
|
- * @saddr_comp: AF-dependent comparison of bound local IP addresses
|
|
|
* @hash2_nulladdr: AF-dependent hash value in secondary hash chains,
|
|
|
* with NULL address
|
|
|
*/
|
|
|
int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|
|
- int (*saddr_comp)(const struct sock *sk1,
|
|
|
- const struct sock *sk2,
|
|
|
- bool match_wildcard),
|
|
|
unsigned int hash2_nulladdr)
|
|
|
{
|
|
|
struct udp_hslot *hslot, *hslot2;
|
|
@@ -277,7 +263,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|
|
bitmap_zero(bitmap, PORTS_PER_CHAIN);
|
|
|
spin_lock_bh(&hslot->lock);
|
|
|
udp_lib_lport_inuse(net, snum, hslot, bitmap, sk,
|
|
|
- saddr_comp, udptable->log);
|
|
|
+ udptable->log);
|
|
|
|
|
|
snum = first;
|
|
|
/*
|
|
@@ -310,12 +296,11 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|
|
if (hslot->count < hslot2->count)
|
|
|
goto scan_primary_hash;
|
|
|
|
|
|
- exist = udp_lib_lport_inuse2(net, snum, hslot2,
|
|
|
- sk, saddr_comp);
|
|
|
+ exist = udp_lib_lport_inuse2(net, snum, hslot2, sk);
|
|
|
if (!exist && (hash2_nulladdr != slot2)) {
|
|
|
hslot2 = udp_hashslot2(udptable, hash2_nulladdr);
|
|
|
exist = udp_lib_lport_inuse2(net, snum, hslot2,
|
|
|
- sk, saddr_comp);
|
|
|
+ sk);
|
|
|
}
|
|
|
if (exist)
|
|
|
goto fail_unlock;
|
|
@@ -323,8 +308,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|
|
goto found;
|
|
|
}
|
|
|
scan_primary_hash:
|
|
|
- if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk,
|
|
|
- saddr_comp, 0))
|
|
|
+ if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk, 0))
|
|
|
goto fail_unlock;
|
|
|
}
|
|
|
found:
|
|
@@ -333,7 +317,7 @@ found:
|
|
|
udp_sk(sk)->udp_portaddr_hash ^= snum;
|
|
|
if (sk_unhashed(sk)) {
|
|
|
if (sk->sk_reuseport &&
|
|
|
- udp_reuseport_add_sock(sk, hslot, saddr_comp)) {
|
|
|
+ udp_reuseport_add_sock(sk, hslot)) {
|
|
|
inet_sk(sk)->inet_num = 0;
|
|
|
udp_sk(sk)->udp_port_hash = 0;
|
|
|
udp_sk(sk)->udp_portaddr_hash ^= snum;
|
|
@@ -365,24 +349,6 @@ fail:
|
|
|
}
|
|
|
EXPORT_SYMBOL(udp_lib_get_port);
|
|
|
|
|
|
-/* match_wildcard == true: 0.0.0.0 equals to any IPv4 addresses
|
|
|
- * match_wildcard == false: addresses must be exactly the same, i.e.
|
|
|
- * 0.0.0.0 only equals to 0.0.0.0
|
|
|
- */
|
|
|
-int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2,
|
|
|
- bool match_wildcard)
|
|
|
-{
|
|
|
- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
|
|
|
-
|
|
|
- if (!ipv6_only_sock(sk2)) {
|
|
|
- if (inet1->inet_rcv_saddr == inet2->inet_rcv_saddr)
|
|
|
- return 1;
|
|
|
- if (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr)
|
|
|
- return match_wildcard;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static u32 udp4_portaddr_hash(const struct net *net, __be32 saddr,
|
|
|
unsigned int port)
|
|
|
{
|
|
@@ -398,7 +364,7 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum)
|
|
|
|
|
|
/* precompute partial secondary hash */
|
|
|
udp_sk(sk)->udp_portaddr_hash = hash2_partial;
|
|
|
- return udp_lib_get_port(sk, snum, ipv4_rcv_saddr_equal, hash2_nulladdr);
|
|
|
+ return udp_lib_get_port(sk, snum, hash2_nulladdr);
|
|
|
}
|
|
|
|
|
|
static int compute_score(struct sock *sk, struct net *net,
|