inet: move inet->freebind to inet->inet_flags
IP_FREEBIND socket option can now be set/read without locking the socket. Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8e8cfb114d
commit
3f7e753206
7 changed files with 22 additions and 22 deletions
|
@ -231,7 +231,6 @@ struct inet_sock {
|
|||
__u8 mc_ttl;
|
||||
__u8 pmtudisc;
|
||||
__u8 is_icsk:1,
|
||||
freebind:1,
|
||||
hdrincl:1,
|
||||
mc_loop:1,
|
||||
transparent:1,
|
||||
|
@ -271,6 +270,7 @@ enum {
|
|||
|
||||
INET_FLAGS_RECVERR = 9,
|
||||
INET_FLAGS_RECVERR_RFC4884 = 10,
|
||||
INET_FLAGS_FREEBIND = 11,
|
||||
};
|
||||
|
||||
/* cmsg flags for inet */
|
||||
|
@ -423,7 +423,8 @@ static inline bool inet_can_nonlocal_bind(struct net *net,
|
|||
struct inet_sock *inet)
|
||||
{
|
||||
return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
|
||||
inet->freebind || inet->transparent;
|
||||
test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) ||
|
||||
inet->transparent;
|
||||
}
|
||||
|
||||
static inline bool inet_addr_valid_or_nonlocal(struct net *net,
|
||||
|
|
|
@ -937,7 +937,8 @@ static inline bool ipv6_can_nonlocal_bind(struct net *net,
|
|||
struct inet_sock *inet)
|
||||
{
|
||||
return net->ipv6.sysctl.ip_nonlocal_bind ||
|
||||
inet->freebind || inet->transparent;
|
||||
test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) ||
|
||||
inet->transparent;
|
||||
}
|
||||
|
||||
/* Sysctl settings for net ipv6.auto_flowlabels */
|
||||
|
|
|
@ -184,7 +184,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
|
|||
memset(&inet_sockopt, 0, sizeof(inet_sockopt));
|
||||
inet_sockopt.recverr = inet_test_bit(RECVERR, sk);
|
||||
inet_sockopt.is_icsk = inet->is_icsk;
|
||||
inet_sockopt.freebind = inet->freebind;
|
||||
inet_sockopt.freebind = inet_test_bit(FREEBIND, sk);
|
||||
inet_sockopt.hdrincl = inet->hdrincl;
|
||||
inet_sockopt.mc_loop = inet->mc_loop;
|
||||
inet_sockopt.transparent = inet->transparent;
|
||||
|
|
|
@ -608,9 +608,7 @@ EXPORT_SYMBOL(ip_sock_set_tos);
|
|||
|
||||
void ip_sock_set_freebind(struct sock *sk)
|
||||
{
|
||||
lock_sock(sk);
|
||||
inet_sk(sk)->freebind = true;
|
||||
release_sock(sk);
|
||||
inet_set_bit(FREEBIND, sk);
|
||||
}
|
||||
EXPORT_SYMBOL(ip_sock_set_freebind);
|
||||
|
||||
|
@ -985,6 +983,11 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname,
|
|||
return -EINVAL;
|
||||
inet_assign_bit(RECVERR_RFC4884, sk, val);
|
||||
return 0;
|
||||
case IP_FREEBIND:
|
||||
if (optlen < 1)
|
||||
return -EINVAL;
|
||||
inet_assign_bit(FREEBIND, sk, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
@ -1310,12 +1313,6 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname,
|
|||
inet->mc_all = val;
|
||||
break;
|
||||
|
||||
case IP_FREEBIND:
|
||||
if (optlen < 1)
|
||||
goto e_inval;
|
||||
inet->freebind = !!val;
|
||||
break;
|
||||
|
||||
case IP_IPSEC_POLICY:
|
||||
case IP_XFRM_POLICY:
|
||||
err = -EPERM;
|
||||
|
@ -1578,6 +1575,9 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
case IP_RECVERR_RFC4884:
|
||||
val = inet_test_bit(RECVERR_RFC4884, sk);
|
||||
goto copyval;
|
||||
case IP_FREEBIND:
|
||||
val = inet_test_bit(FREEBIND, sk);
|
||||
goto copyval;
|
||||
}
|
||||
|
||||
if (needs_rtnl)
|
||||
|
@ -1737,9 +1737,6 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
len -= msg.msg_controllen;
|
||||
return copy_to_sockptr(optlen, &len, sizeof(int));
|
||||
}
|
||||
case IP_FREEBIND:
|
||||
val = inet->freebind;
|
||||
break;
|
||||
case IP_TRANSPARENT:
|
||||
val = inet->transparent;
|
||||
break;
|
||||
|
|
|
@ -641,7 +641,7 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
|||
if (optlen < sizeof(int))
|
||||
goto e_inval;
|
||||
/* we also don't have a separate freebind bit for IPV6 */
|
||||
inet_sk(sk)->freebind = valbool;
|
||||
inet_assign_bit(FREEBIND, sk, valbool);
|
||||
retv = 0;
|
||||
break;
|
||||
|
||||
|
@ -1334,7 +1334,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
|||
break;
|
||||
|
||||
case IPV6_FREEBIND:
|
||||
val = inet_sk(sk)->freebind;
|
||||
val = inet_test_bit(FREEBIND, sk);
|
||||
break;
|
||||
|
||||
case IPV6_RECVORIGDSTADDR:
|
||||
|
|
|
@ -419,7 +419,8 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
|
|||
inet_sk(sk)->transparent = inet_sk(ssk)->transparent;
|
||||
break;
|
||||
case IPV6_FREEBIND:
|
||||
inet_sk(sk)->freebind = inet_sk(ssk)->freebind;
|
||||
inet_assign_bit(FREEBIND, sk,
|
||||
inet_test_bit(FREEBIND, ssk));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -704,7 +705,7 @@ static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int o
|
|||
|
||||
switch (optname) {
|
||||
case IP_FREEBIND:
|
||||
issk->freebind = inet_sk(sk)->freebind;
|
||||
inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));
|
||||
break;
|
||||
case IP_TRANSPARENT:
|
||||
issk->transparent = inet_sk(sk)->transparent;
|
||||
|
@ -1441,7 +1442,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
|
|||
__tcp_sock_set_nodelay(ssk, !!msk->nodelay);
|
||||
|
||||
inet_sk(ssk)->transparent = inet_sk(sk)->transparent;
|
||||
inet_sk(ssk)->freebind = inet_sk(sk)->freebind;
|
||||
inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));
|
||||
}
|
||||
|
||||
static void __mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk)
|
||||
|
|
|
@ -360,7 +360,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
|
|||
ret = inet_addr_type_table(net, addr->v4.sin_addr.s_addr, tb_id);
|
||||
if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
|
||||
ret != RTN_LOCAL &&
|
||||
!sp->inet.freebind &&
|
||||
!inet_test_bit(FREEBIND, sk) &&
|
||||
!READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind))
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue