Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361800
b: refs/heads/master
c: f6e16b2
h: refs/heads/master
v: v3
  • Loading branch information
Tom Parkin authored and David S. Miller committed Mar 20, 2013
1 parent 5a04881 commit a90995a
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7b7c0719cd7afee725b920d75ec6a500b76107e6
refs/heads/master: f6e16b299bacaa71c6604a784f2d088a966f8c23
75 changes: 34 additions & 41 deletions trunk/net/l2tp/l2tp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1316,26 +1316,12 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)

hlist_del_init(&session->hlist);

/* Since we should hold the sock lock while
* doing any unbinding, we need to release the
* lock we're holding before taking that lock.
* Hold a reference to the sock so it doesn't
* disappear as we're jumping between locks.
*/
if (session->ref != NULL)
(*session->ref)(session);

write_unlock_bh(&tunnel->hlist_lock);

if (tunnel->version != L2TP_HDR_VER_2) {
struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);

spin_lock_bh(&pn->l2tp_session_hlist_lock);
hlist_del_init_rcu(&session->global_hlist);
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
synchronize_rcu();
}

__l2tp_session_unhash(session);
l2tp_session_queue_purge(session);

if (session->session_close != NULL)
Expand Down Expand Up @@ -1732,64 +1718,71 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
*/
void l2tp_session_free(struct l2tp_session *session)
{
struct l2tp_tunnel *tunnel;
struct l2tp_tunnel *tunnel = session->tunnel;

BUG_ON(atomic_read(&session->ref_count) != 0);

tunnel = session->tunnel;
if (tunnel != NULL) {
if (tunnel) {
BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
if (session->session_id != 0)
atomic_dec(&l2tp_session_count);
sock_put(tunnel->sock);
session->tunnel = NULL;
l2tp_tunnel_dec_refcount(tunnel);
}

kfree(session);

return;
}
EXPORT_SYMBOL_GPL(l2tp_session_free);

/* Remove an l2tp session from l2tp_core's hash lists.
* Provides a tidyup interface for pseudowire code which can't just route all
* shutdown via. l2tp_session_delete and a pseudowire-specific session_close
* callback.
*/
void __l2tp_session_unhash(struct l2tp_session *session)
{
struct l2tp_tunnel *tunnel = session->tunnel;

/* Delete the session from the hash */
/* Remove the session from core hashes */
if (tunnel) {
/* Remove from the per-tunnel hash */
write_lock_bh(&tunnel->hlist_lock);
hlist_del_init(&session->hlist);
write_unlock_bh(&tunnel->hlist_lock);

/* Unlink from the global hash if not L2TPv2 */
/* For L2TPv3 we have a per-net hash: remove from there, too */
if (tunnel->version != L2TP_HDR_VER_2) {
struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);

spin_lock_bh(&pn->l2tp_session_hlist_lock);
hlist_del_init_rcu(&session->global_hlist);
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
synchronize_rcu();
}

if (session->session_id != 0)
atomic_dec(&l2tp_session_count);

sock_put(tunnel->sock);

/* This will delete the tunnel context if this
* is the last session on the tunnel.
*/
session->tunnel = NULL;
l2tp_tunnel_dec_refcount(tunnel);
}

kfree(session);

return;
}
EXPORT_SYMBOL_GPL(l2tp_session_free);
EXPORT_SYMBOL_GPL(__l2tp_session_unhash);

/* This function is used by the netlink SESSION_DELETE command and by
pseudowire modules.
*/
int l2tp_session_delete(struct l2tp_session *session)
{
if (session->ref)
(*session->ref)(session);
__l2tp_session_unhash(session);
l2tp_session_queue_purge(session);

if (session->session_close != NULL)
(*session->session_close)(session);

if (session->deref)
(*session->ref)(session);
l2tp_session_dec_refcount(session);

return 0;
}
EXPORT_SYMBOL_GPL(l2tp_session_delete);


/* We come here whenever a session's send_seq, cookie_len or
* l2specific_len parameters are set.
*/
Expand Down
1 change: 1 addition & 0 deletions trunk/net/l2tp/l2tp_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_i
extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
extern void __l2tp_session_unhash(struct l2tp_session *session);
extern int l2tp_session_delete(struct l2tp_session *session);
extern void l2tp_session_free(struct l2tp_session *session);
extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb));
Expand Down
12 changes: 3 additions & 9 deletions trunk/net/l2tp/l2tp_ppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,19 +466,12 @@ static void pppol2tp_session_close(struct l2tp_session *session)
*/
static void pppol2tp_session_destruct(struct sock *sk)
{
struct l2tp_session *session;

if (sk->sk_user_data != NULL) {
session = sk->sk_user_data;
if (session == NULL)
goto out;

struct l2tp_session *session = sk->sk_user_data;
if (session) {
sk->sk_user_data = NULL;
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
l2tp_session_dec_refcount(session);
}

out:
return;
}

Expand Down Expand Up @@ -509,6 +502,7 @@ static int pppol2tp_release(struct socket *sock)

/* Purge any queued data */
if (session != NULL) {
__l2tp_session_unhash(session);
l2tp_session_queue_purge(session);
sock_put(sk);
}
Expand Down

0 comments on commit a90995a

Please sign in to comment.