|
@@ -97,6 +97,7 @@
|
|
|
#include <net/ip.h>
|
|
|
#include <net/udp.h>
|
|
|
#include <net/xfrm.h>
|
|
|
+#include <net/inet_common.h>
|
|
|
|
|
|
#include <asm/byteorder.h>
|
|
|
#include <linux/atomic.h>
|
|
@@ -447,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session)
|
|
|
{
|
|
|
struct pppol2tp_session *ps = l2tp_session_priv(session);
|
|
|
struct sock *sk = ps->sock;
|
|
|
- struct sk_buff *skb;
|
|
|
+ struct socket *sock = sk->sk_socket;
|
|
|
|
|
|
BUG_ON(session->magic != L2TP_SESSION_MAGIC);
|
|
|
|
|
|
- if (session->session_id == 0)
|
|
|
- goto out;
|
|
|
-
|
|
|
- if (sk != NULL) {
|
|
|
- lock_sock(sk);
|
|
|
-
|
|
|
- if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
|
|
|
- pppox_unbind_sock(sk);
|
|
|
- sk->sk_state = PPPOX_DEAD;
|
|
|
- sk->sk_state_change(sk);
|
|
|
- }
|
|
|
-
|
|
|
- /* Purge any queued data */
|
|
|
- skb_queue_purge(&sk->sk_receive_queue);
|
|
|
- skb_queue_purge(&sk->sk_write_queue);
|
|
|
- while ((skb = skb_dequeue(&session->reorder_q))) {
|
|
|
- kfree_skb(skb);
|
|
|
- sock_put(sk);
|
|
|
- }
|
|
|
|
|
|
- release_sock(sk);
|
|
|
+ if (sock) {
|
|
|
+ inet_shutdown(sock, 2);
|
|
|
+ /* Don't let the session go away before our socket does */
|
|
|
+ l2tp_session_inc_refcount(session);
|
|
|
}
|
|
|
-
|
|
|
-out:
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -525,16 +508,12 @@ static int pppol2tp_release(struct socket *sock)
|
|
|
session = pppol2tp_sock_to_session(sk);
|
|
|
|
|
|
/* Purge any queued data */
|
|
|
- skb_queue_purge(&sk->sk_receive_queue);
|
|
|
- skb_queue_purge(&sk->sk_write_queue);
|
|
|
if (session != NULL) {
|
|
|
- struct sk_buff *skb;
|
|
|
- while ((skb = skb_dequeue(&session->reorder_q))) {
|
|
|
- kfree_skb(skb);
|
|
|
- sock_put(sk);
|
|
|
- }
|
|
|
+ l2tp_session_queue_purge(session);
|
|
|
sock_put(sk);
|
|
|
}
|
|
|
+ skb_queue_purge(&sk->sk_receive_queue);
|
|
|
+ skb_queue_purge(&sk->sk_write_queue);
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
|
@@ -880,18 +859,6 @@ out:
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
-/* Called when deleting sessions via the netlink interface.
|
|
|
- */
|
|
|
-static int pppol2tp_session_delete(struct l2tp_session *session)
|
|
|
-{
|
|
|
- struct pppol2tp_session *ps = l2tp_session_priv(session);
|
|
|
-
|
|
|
- if (ps->sock == NULL)
|
|
|
- l2tp_session_dec_refcount(session);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
#endif /* CONFIG_L2TP_V3 */
|
|
|
|
|
|
/* getname() support.
|
|
@@ -1839,7 +1806,7 @@ static const struct pppox_proto pppol2tp_proto = {
|
|
|
|
|
|
static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
|
|
|
.session_create = pppol2tp_session_create,
|
|
|
- .session_delete = pppol2tp_session_delete,
|
|
|
+ .session_delete = l2tp_session_delete,
|
|
|
};
|
|
|
|
|
|
#endif /* CONFIG_L2TP_V3 */
|