}
 EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
 
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
+{
+       const struct l2tp_net *pn = l2tp_pernet(net);
+       struct l2tp_tunnel *tunnel;
+       int count = 0;
+
+       rcu_read_lock_bh();
+       list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+               if (++count > nth) {
+                       l2tp_tunnel_inc_refcount(tunnel);
+                       rcu_read_unlock_bh();
+                       return tunnel;
+               }
+       }
+       rcu_read_unlock_bh();
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_get_nth);
+
 /* Lookup a session. A new reference is held on the returned session. */
 struct l2tp_session *l2tp_session_get(const struct net *net,
                                      struct l2tp_tunnel *tunnel,
 
 }
 
 struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth);
+
 void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
 
 struct l2tp_session *l2tp_session_get(const struct net *net,
 
        struct net *net = sock_net(skb->sk);
 
        for (;;) {
-               tunnel = l2tp_tunnel_find_nth(net, ti);
+               tunnel = l2tp_tunnel_get_nth(net, ti);
                if (tunnel == NULL)
                        goto out;
 
                if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0)
+                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0) {
+                       l2tp_tunnel_dec_refcount(tunnel);
                        goto out;
+               }
+               l2tp_tunnel_dec_refcount(tunnel);
 
                ti++;
        }
 
        for (;;) {
                if (tunnel == NULL) {
-                       tunnel = l2tp_tunnel_find_nth(net, ti);
+                       tunnel = l2tp_tunnel_get_nth(net, ti);
                        if (tunnel == NULL)
                                goto out;
                }
                session = l2tp_session_get_nth(tunnel, si);
                if (session == NULL) {
                        ti++;
+                       l2tp_tunnel_dec_refcount(tunnel);
                        tunnel = NULL;
                        si = 0;
                        continue;
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         session, L2TP_CMD_SESSION_GET) < 0) {
                        l2tp_session_dec_refcount(session);
+                       l2tp_tunnel_dec_refcount(tunnel);
                        break;
                }
                l2tp_session_dec_refcount(session);