mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
xfrm: take care of request sockets
TCP SYNACK messages might now be attached to request sockets.
XFRM needs to get back to a listener socket.
Adds new helpers that might be used elsewhere :
sk_to_full_sk() and sk_const_to_full_sk()
Note: We also need to add RCU protection for xfrm lookups,
now TCP/DCCP have lockless listener processing. This will
be addressed in separate patches.
Fixes: ca6fb06518
("tcp: attach SYNACK messages to request sockets instead of listener")
Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
69ce6487dc
commit
bd5eb35f16
@ -210,18 +210,37 @@ struct inet_sock {
|
|||||||
#define IP_CMSG_ORIGDSTADDR BIT(6)
|
#define IP_CMSG_ORIGDSTADDR BIT(6)
|
||||||
#define IP_CMSG_CHECKSUM BIT(7)
|
#define IP_CMSG_CHECKSUM BIT(7)
|
||||||
|
|
||||||
/* SYNACK messages might be attached to request sockets.
|
/**
|
||||||
|
* sk_to_full_sk - Access to a full socket
|
||||||
|
* @sk: pointer to a socket
|
||||||
|
*
|
||||||
|
* SYNACK messages might be attached to request sockets.
|
||||||
* Some places want to reach the listener in this case.
|
* Some places want to reach the listener in this case.
|
||||||
*/
|
*/
|
||||||
static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
|
static inline struct sock *sk_to_full_sk(struct sock *sk)
|
||||||
{
|
{
|
||||||
struct sock *sk = skb->sk;
|
#ifdef CONFIG_INET
|
||||||
|
|
||||||
if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
|
if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||||
sk = inet_reqsk(sk)->rsk_listener;
|
sk = inet_reqsk(sk)->rsk_listener;
|
||||||
|
#endif
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sk_to_full_sk() variant with a const argument */
|
||||||
|
static inline const struct sock *sk_const_to_full_sk(const struct sock *sk)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_INET
|
||||||
|
if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||||
|
sk = ((const struct request_sock *)sk)->rsk_listener;
|
||||||
|
#endif
|
||||||
|
return sk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return sk_to_full_sk(skb->sk);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct inet_sock *inet_sk(const struct sock *sk)
|
static inline struct inet_sock *inet_sk(const struct sock *sk)
|
||||||
{
|
{
|
||||||
return (struct inet_sock *)sk;
|
return (struct inet_sock *)sk;
|
||||||
|
@ -2198,6 +2198,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
|
|||||||
xdst = NULL;
|
xdst = NULL;
|
||||||
route = NULL;
|
route = NULL;
|
||||||
|
|
||||||
|
sk = sk_const_to_full_sk(sk);
|
||||||
if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
|
if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
|
||||||
num_pols = 1;
|
num_pols = 1;
|
||||||
pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
|
pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
|
||||||
@ -2477,6 +2478,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pol = NULL;
|
pol = NULL;
|
||||||
|
sk = sk_to_full_sk(sk);
|
||||||
if (sk && sk->sk_policy[dir]) {
|
if (sk && sk->sk_policy[dir]) {
|
||||||
pol = xfrm_sk_policy_lookup(sk, dir, &fl);
|
pol = xfrm_sk_policy_lookup(sk, dir, &fl);
|
||||||
if (IS_ERR(pol)) {
|
if (IS_ERR(pol)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user