#include <linux/atomic.h>
 
 #include "l2tp_core.h"
+#include "trace.h"
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
 static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
 {
+       trace_free_tunnel(tunnel);
        sock_put(tunnel->sock);
        /* the tunnel is freed in the socket destructor */
 }
 {
        struct l2tp_tunnel *tunnel = session->tunnel;
 
+       trace_free_session(session);
+
        if (tunnel) {
                if (WARN_ON(tunnel->magic != L2TP_TUNNEL_MAGIC))
                        goto out;
        hlist_add_head(&session->hlist, head);
        write_unlock_bh(&tunnel->hlist_lock);
 
+       trace_register_session(session);
+
        return 0;
 
 err_tlock_pnlock:
        skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (L2TP_SKB_CB(skbp)->ns > ns) {
                        __skb_queue_before(&session->reorder_q, skbp, skb);
-                       l2tp_dbg(session, L2TP_MSG_SEQ,
-                                "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
-                                session->name, ns, L2TP_SKB_CB(skbp)->ns,
-                                skb_queue_len(&session->reorder_q));
                        atomic_long_inc(&session->stats.rx_oos_packets);
                        goto out;
                }
                /* Bump our Nr */
                session->nr++;
                session->nr &= session->nr_max;
-
-               l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated nr to %hu\n",
-                        session->name, session->nr);
+               trace_session_seqnum_update(session);
        }
 
        /* call private receive handler */
 start:
        spin_lock_bh(&session->reorder_q.lock);
        skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
-               if (time_after(jiffies, L2TP_SKB_CB(skb)->expires)) {
+               struct l2tp_skb_cb *cb = L2TP_SKB_CB(skb);
+
+               /* If the packet has been pending on the queue for too long, discard it */
+               if (time_after(jiffies, cb->expires)) {
                        atomic_long_inc(&session->stats.rx_seq_discards);
                        atomic_long_inc(&session->stats.rx_errors);
-                       l2tp_dbg(session, L2TP_MSG_SEQ,
-                                "%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n",
-                                session->name, L2TP_SKB_CB(skb)->ns,
-                                L2TP_SKB_CB(skb)->length, session->nr,
-                                skb_queue_len(&session->reorder_q));
+                       trace_session_pkt_expired(session, cb->ns);
                        session->reorder_skip = 1;
                        __skb_unlink(skb, &session->reorder_q);
                        kfree_skb(skb);
                        continue;
                }
 
-               if (L2TP_SKB_CB(skb)->has_seq) {
+               if (cb->has_seq) {
                        if (session->reorder_skip) {
-                               l2tp_dbg(session, L2TP_MSG_SEQ,
-                                        "%s: advancing nr to next pkt: %u -> %u",
-                                        session->name, session->nr,
-                                        L2TP_SKB_CB(skb)->ns);
                                session->reorder_skip = 0;
-                               session->nr = L2TP_SKB_CB(skb)->ns;
+                               session->nr = cb->ns;
+                               trace_session_seqnum_reset(session);
                        }
-                       if (L2TP_SKB_CB(skb)->ns != session->nr) {
-                               l2tp_dbg(session, L2TP_MSG_SEQ,
-                                        "%s: holding oos pkt %u len %d, waiting for %u, reorder_q_len=%d\n",
-                                        session->name, L2TP_SKB_CB(skb)->ns,
-                                        L2TP_SKB_CB(skb)->length, session->nr,
-                                        skb_queue_len(&session->reorder_q));
+                       if (cb->ns != session->nr)
                                goto out;
-                       }
                }
                __skb_unlink(skb, &session->reorder_q);
 
  */
 static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb)
 {
-       if (!l2tp_seq_check_rx_window(session, L2TP_SKB_CB(skb)->ns)) {
+       struct l2tp_skb_cb *cb = L2TP_SKB_CB(skb);
+
+       if (!l2tp_seq_check_rx_window(session, cb->ns)) {
                /* Packet sequence number is outside allowed window.
                 * Discard it.
                 */
-               l2tp_dbg(session, L2TP_MSG_SEQ,
-                        "%s: pkt %u len %d discarded, outside window, nr=%u\n",
-                        session->name, L2TP_SKB_CB(skb)->ns,
-                        L2TP_SKB_CB(skb)->length, session->nr);
+               trace_session_pkt_outside_rx_window(session, cb->ns);
                goto discard;
        }
 
         * is seen. After nr_oos_count_max in-sequence packets, reset the
         * sequence number to re-enable packet reception.
         */
-       if (L2TP_SKB_CB(skb)->ns == session->nr) {
+       if (cb->ns == session->nr) {
                skb_queue_tail(&session->reorder_q, skb);
        } else {
-               u32 nr_oos = L2TP_SKB_CB(skb)->ns;
+               u32 nr_oos = cb->ns;
                u32 nr_next = (session->nr_oos + 1) & session->nr_max;
 
                if (nr_oos == nr_next)
                session->nr_oos = nr_oos;
                if (session->nr_oos_count > session->nr_oos_count_max) {
                        session->reorder_skip = 1;
-                       l2tp_dbg(session, L2TP_MSG_SEQ,
-                                "%s: %d oos packets received. Resetting sequence numbers\n",
-                                session->name, session->nr_oos_count);
                }
                if (!session->reorder_skip) {
                        atomic_long_inc(&session->stats.rx_seq_discards);
-                       l2tp_dbg(session, L2TP_MSG_SEQ,
-                                "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n",
-                                session->name, L2TP_SKB_CB(skb)->ns,
-                                L2TP_SKB_CB(skb)->length, session->nr,
-                                skb_queue_len(&session->reorder_q));
+                       trace_session_pkt_oos(session, cb->ns);
                        goto discard;
                }
                skb_queue_tail(&session->reorder_q, skb);
                 * configure it so.
                 */
                if (!session->lns_mode && !session->send_seq) {
-                       l2tp_info(session, L2TP_MSG_SEQ,
-                                 "%s: requested to enable seq numbers by LNS\n",
-                                 session->name);
+                       trace_session_seqnum_lns_enable(session);
                        session->send_seq = 1;
                        l2tp_session_set_header_len(session, tunnel->version);
                }
                 * LAC is broken. Discard the frame.
                 */
                if (!session->lns_mode && session->send_seq) {
-                       l2tp_info(session, L2TP_MSG_SEQ,
-                                 "%s: requested to disable seq numbers by LNS\n",
-                                 session->name);
+                       trace_session_seqnum_lns_disable(session);
                        session->send_seq = 0;
                        l2tp_session_set_header_len(session, tunnel->version);
                } else if (session->send_seq) {
                *bufp++ = 0;
                session->ns++;
                session->ns &= 0xffff;
-               l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated ns to %u\n",
-                        session->name, session->ns);
+               trace_session_seqnum_update(session);
        }
 
        return bufp - optr;
                        l2h = 0x40000000 | session->ns;
                        session->ns++;
                        session->ns &= 0xffffff;
-                       l2tp_dbg(session, L2TP_MSG_SEQ,
-                                "%s: updated ns to %u\n",
-                                session->name, session->ns);
+                       trace_session_seqnum_update(session);
                }
 
                *((__be32 *)bufp) = htonl(l2h);
                                   "l2tp_sock");
        sk->sk_allocation = GFP_ATOMIC;
 
+       trace_register_tunnel(tunnel);
+
        if (tunnel->fd >= 0)
                sockfd_put(sock);
 
 void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
        if (!test_and_set_bit(0, &tunnel->dead)) {
+               trace_delete_tunnel(tunnel);
                l2tp_tunnel_inc_refcount(tunnel);
                queue_work(l2tp_wq, &tunnel->del_work);
        }
        if (test_and_set_bit(0, &session->dead))
                return;
 
+       trace_delete_session(session);
        l2tp_session_unhash(session);
        l2tp_session_queue_purge(session);
        if (session->session_close)