mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 06:34:11 +08:00
Merge branch 'l2tp-avoid-aliasing-tunnels-socket-pointer'
Guillaume Nault says: ==================== l2tp: avoid aliasing tunnels socket pointer We don't need to copy the tunnel's socket pointer in the pseudo-wire specific session structures. This uselessly complicates the code and hampers evolution. This series was part of an effort to protect tunnels socket pointer with RCU. But since it provides nice cleanup, I submit it separately. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
973573c499
@ -41,7 +41,6 @@
|
|||||||
|
|
||||||
/* via netdev_priv() */
|
/* via netdev_priv() */
|
||||||
struct l2tp_eth {
|
struct l2tp_eth {
|
||||||
struct sock *tunnel_sock;
|
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
atomic_long_t tx_bytes;
|
atomic_long_t tx_bytes;
|
||||||
atomic_long_t tx_packets;
|
atomic_long_t tx_packets;
|
||||||
@ -313,7 +312,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
|
|||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
priv->session = session;
|
priv->session = session;
|
||||||
|
|
||||||
priv->tunnel_sock = tunnel->sock;
|
|
||||||
session->recv_skb = l2tp_eth_dev_recv;
|
session->recv_skb = l2tp_eth_dev_recv;
|
||||||
session->session_close = l2tp_eth_delete;
|
session->session_close = l2tp_eth_delete;
|
||||||
#if IS_ENABLED(CONFIG_L2TP_DEBUGFS)
|
#if IS_ENABLED(CONFIG_L2TP_DEBUGFS)
|
||||||
|
@ -127,8 +127,6 @@ struct pppol2tp_session {
|
|||||||
* PPPoX socket */
|
* PPPoX socket */
|
||||||
struct sock *__sk; /* Copy of .sk, for cleanup */
|
struct sock *__sk; /* Copy of .sk, for cleanup */
|
||||||
struct rcu_head rcu; /* For asynchronous release */
|
struct rcu_head rcu; /* For asynchronous release */
|
||||||
struct sock *tunnel_sock; /* Pointer to the tunnel UDP
|
|
||||||
* socket */
|
|
||||||
int flags; /* accessed by PPPIOCGFLAGS.
|
int flags; /* accessed by PPPIOCGFLAGS.
|
||||||
* Unused. */
|
* Unused. */
|
||||||
};
|
};
|
||||||
@ -295,7 +293,6 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
|
|||||||
int error;
|
int error;
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel;
|
struct l2tp_tunnel *tunnel;
|
||||||
struct pppol2tp_session *ps;
|
|
||||||
int uhlen;
|
int uhlen;
|
||||||
|
|
||||||
error = -ENOTCONN;
|
error = -ENOTCONN;
|
||||||
@ -308,10 +305,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
|
|||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ps = l2tp_session_priv(session);
|
tunnel = session->tunnel;
|
||||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
|
||||||
if (tunnel == NULL)
|
|
||||||
goto error_put_sess;
|
|
||||||
|
|
||||||
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
||||||
|
|
||||||
@ -322,7 +316,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
|
|||||||
2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
|
2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
|
||||||
0, GFP_KERNEL);
|
0, GFP_KERNEL);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto error_put_sess_tun;
|
goto error_put_sess;
|
||||||
|
|
||||||
/* Reserve space for headers. */
|
/* Reserve space for headers. */
|
||||||
skb_reserve(skb, NET_SKB_PAD);
|
skb_reserve(skb, NET_SKB_PAD);
|
||||||
@ -340,20 +334,17 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
|
|||||||
error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
|
error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
goto error_put_sess_tun;
|
goto error_put_sess;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_bh_disable();
|
local_bh_disable();
|
||||||
l2tp_xmit_skb(session, skb, session->hdr_len);
|
l2tp_xmit_skb(session, skb, session->hdr_len);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
|
|
||||||
sock_put(ps->tunnel_sock);
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
||||||
return total_len;
|
return total_len;
|
||||||
|
|
||||||
error_put_sess_tun:
|
|
||||||
sock_put(ps->tunnel_sock);
|
|
||||||
error_put_sess:
|
error_put_sess:
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
error:
|
error:
|
||||||
@ -377,10 +368,8 @@ error:
|
|||||||
static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sock *sk = (struct sock *) chan->private;
|
struct sock *sk = (struct sock *) chan->private;
|
||||||
struct sock *sk_tun;
|
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel;
|
struct l2tp_tunnel *tunnel;
|
||||||
struct pppol2tp_session *ps;
|
|
||||||
int uhlen, headroom;
|
int uhlen, headroom;
|
||||||
|
|
||||||
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
|
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
|
||||||
@ -391,13 +380,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
ps = l2tp_session_priv(session);
|
tunnel = session->tunnel;
|
||||||
sk_tun = ps->tunnel_sock;
|
|
||||||
if (sk_tun == NULL)
|
|
||||||
goto abort_put_sess;
|
|
||||||
tunnel = l2tp_sock_to_tunnel(sk_tun);
|
|
||||||
if (tunnel == NULL)
|
|
||||||
goto abort_put_sess;
|
|
||||||
|
|
||||||
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
||||||
headroom = NET_SKB_PAD +
|
headroom = NET_SKB_PAD +
|
||||||
@ -406,7 +389,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||||||
session->hdr_len + /* L2TP header */
|
session->hdr_len + /* L2TP header */
|
||||||
2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
|
2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
|
||||||
if (skb_cow_head(skb, headroom))
|
if (skb_cow_head(skb, headroom))
|
||||||
goto abort_put_sess_tun;
|
goto abort_put_sess;
|
||||||
|
|
||||||
/* Setup PPP header */
|
/* Setup PPP header */
|
||||||
__skb_push(skb, 2);
|
__skb_push(skb, 2);
|
||||||
@ -417,12 +400,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||||||
l2tp_xmit_skb(session, skb, session->hdr_len);
|
l2tp_xmit_skb(session, skb, session->hdr_len);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
|
|
||||||
sock_put(sk_tun);
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
abort_put_sess_tun:
|
|
||||||
sock_put(sk_tun);
|
|
||||||
abort_put_sess:
|
abort_put_sess:
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
abort:
|
abort:
|
||||||
@ -609,7 +590,6 @@ static void pppol2tp_session_init(struct l2tp_session *session)
|
|||||||
|
|
||||||
ps = l2tp_session_priv(session);
|
ps = l2tp_session_priv(session);
|
||||||
mutex_init(&ps->sk_lock);
|
mutex_init(&ps->sk_lock);
|
||||||
ps->tunnel_sock = session->tunnel->sock;
|
|
||||||
ps->owner = current->pid;
|
ps->owner = current->pid;
|
||||||
|
|
||||||
/* If PMTU discovery was enabled, use the MTU that was discovered */
|
/* If PMTU discovery was enabled, use the MTU that was discovered */
|
||||||
@ -760,13 +740,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|||||||
error = -EEXIST;
|
error = -EEXIST;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* consistency checks */
|
|
||||||
if (ps->tunnel_sock != tunnel->sock) {
|
|
||||||
mutex_unlock(&ps->sk_lock);
|
|
||||||
error = -EEXIST;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Default MTU must allow space for UDP/L2TP/PPP headers */
|
/* Default MTU must allow space for UDP/L2TP/PPP headers */
|
||||||
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
|
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
|
||||||
@ -919,9 +892,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
pls = l2tp_session_priv(session);
|
pls = l2tp_session_priv(session);
|
||||||
tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock);
|
tunnel = session->tunnel;
|
||||||
if (tunnel == NULL)
|
|
||||||
goto end_put_sess;
|
|
||||||
|
|
||||||
inet = inet_sk(tunnel->sock);
|
inet = inet_sk(tunnel->sock);
|
||||||
if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) {
|
if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) {
|
||||||
@ -1001,8 +972,6 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
*usockaddr_len = len;
|
*usockaddr_len = len;
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
sock_put(pls->tunnel_sock);
|
|
||||||
end_put_sess:
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
end:
|
end:
|
||||||
return error;
|
return error;
|
||||||
@ -1241,7 +1210,6 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
|
|||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel;
|
struct l2tp_tunnel *tunnel;
|
||||||
struct pppol2tp_session *ps;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!sk)
|
if (!sk)
|
||||||
@ -1265,16 +1233,10 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
|
|||||||
/* Special case: if session's session_id is zero, treat ioctl as a
|
/* Special case: if session's session_id is zero, treat ioctl as a
|
||||||
* tunnel ioctl
|
* tunnel ioctl
|
||||||
*/
|
*/
|
||||||
ps = l2tp_session_priv(session);
|
|
||||||
if ((session->session_id == 0) &&
|
if ((session->session_id == 0) &&
|
||||||
(session->peer_session_id == 0)) {
|
(session->peer_session_id == 0)) {
|
||||||
err = -EBADF;
|
tunnel = session->tunnel;
|
||||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
|
||||||
if (tunnel == NULL)
|
|
||||||
goto end_put_sess;
|
|
||||||
|
|
||||||
err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
|
err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
|
||||||
sock_put(ps->tunnel_sock);
|
|
||||||
goto end_put_sess;
|
goto end_put_sess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1400,7 +1362,6 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct l2tp_session *session;
|
struct l2tp_session *session;
|
||||||
struct l2tp_tunnel *tunnel;
|
struct l2tp_tunnel *tunnel;
|
||||||
struct pppol2tp_session *ps;
|
|
||||||
int val;
|
int val;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -1425,20 +1386,14 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
|
|
||||||
/* Special case: if session_id == 0x0000, treat as operation on tunnel
|
/* Special case: if session_id == 0x0000, treat as operation on tunnel
|
||||||
*/
|
*/
|
||||||
ps = l2tp_session_priv(session);
|
|
||||||
if ((session->session_id == 0) &&
|
if ((session->session_id == 0) &&
|
||||||
(session->peer_session_id == 0)) {
|
(session->peer_session_id == 0)) {
|
||||||
err = -EBADF;
|
tunnel = session->tunnel;
|
||||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
|
||||||
if (tunnel == NULL)
|
|
||||||
goto end_put_sess;
|
|
||||||
|
|
||||||
err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
|
err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
|
||||||
sock_put(ps->tunnel_sock);
|
} else {
|
||||||
} else
|
|
||||||
err = pppol2tp_session_setsockopt(sk, session, optname, val);
|
err = pppol2tp_session_setsockopt(sk, session, optname, val);
|
||||||
|
}
|
||||||
|
|
||||||
end_put_sess:
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
end:
|
end:
|
||||||
return err;
|
return err;
|
||||||
@ -1526,7 +1481,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
|||||||
struct l2tp_tunnel *tunnel;
|
struct l2tp_tunnel *tunnel;
|
||||||
int val, len;
|
int val, len;
|
||||||
int err;
|
int err;
|
||||||
struct pppol2tp_session *ps;
|
|
||||||
|
|
||||||
if (level != SOL_PPPOL2TP)
|
if (level != SOL_PPPOL2TP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1550,16 +1504,10 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Special case: if session_id == 0x0000, treat as operation on tunnel */
|
/* Special case: if session_id == 0x0000, treat as operation on tunnel */
|
||||||
ps = l2tp_session_priv(session);
|
|
||||||
if ((session->session_id == 0) &&
|
if ((session->session_id == 0) &&
|
||||||
(session->peer_session_id == 0)) {
|
(session->peer_session_id == 0)) {
|
||||||
err = -EBADF;
|
tunnel = session->tunnel;
|
||||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
|
||||||
if (tunnel == NULL)
|
|
||||||
goto end_put_sess;
|
|
||||||
|
|
||||||
err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
|
err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
|
||||||
sock_put(ps->tunnel_sock);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto end_put_sess;
|
goto end_put_sess;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user