|
@@ -111,6 +111,10 @@ struct l2tp_net {
|
|
|
spinlock_t l2tp_session_hlist_lock;
|
|
|
};
|
|
|
|
|
|
+static void l2tp_session_set_header_len(struct l2tp_session *session, int version);
|
|
|
+static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
|
|
|
+static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
|
|
|
+
|
|
|
static inline struct l2tp_net *l2tp_pernet(struct net *net)
|
|
|
{
|
|
|
BUG_ON(!net);
|
|
@@ -118,6 +122,34 @@ static inline struct l2tp_net *l2tp_pernet(struct net *net)
|
|
|
return net_generic(net, l2tp_net_id);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/* Tunnel reference counts. Incremented per session that is added to
|
|
|
+ * the tunnel.
|
|
|
+ */
|
|
|
+static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel)
|
|
|
+{
|
|
|
+ atomic_inc(&tunnel->ref_count);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel)
|
|
|
+{
|
|
|
+ if (atomic_dec_and_test(&tunnel->ref_count))
|
|
|
+ l2tp_tunnel_free(tunnel);
|
|
|
+}
|
|
|
+#ifdef L2TP_REFCNT_DEBUG
|
|
|
+#define l2tp_tunnel_inc_refcount(_t) do { \
|
|
|
+ printk(KERN_DEBUG "l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \
|
|
|
+ l2tp_tunnel_inc_refcount_1(_t); \
|
|
|
+ } while (0)
|
|
|
+#define l2tp_tunnel_dec_refcount(_t) do { \
|
|
|
+ printk(KERN_DEBUG "l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \
|
|
|
+ l2tp_tunnel_dec_refcount_1(_t); \
|
|
|
+ } while (0)
|
|
|
+#else
|
|
|
+#define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t)
|
|
|
+#define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t)
|
|
|
+#endif
|
|
|
+
|
|
|
/* Session hash global list for L2TPv3.
|
|
|
* The session_id SHOULD be random according to RFC3931, but several
|
|
|
* L2TP implementations use incrementing session_ids. So we do a real
|
|
@@ -699,8 +731,8 @@ EXPORT_SYMBOL(l2tp_recv_common);
|
|
|
* Returns 1 if the packet was not a good data packet and could not be
|
|
|
* forwarded. All such packets are passed up to userspace to deal with.
|
|
|
*/
|
|
|
-int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
|
|
|
- int (*payload_hook)(struct sk_buff *skb))
|
|
|
+static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
|
|
|
+ int (*payload_hook)(struct sk_buff *skb))
|
|
|
{
|
|
|
struct l2tp_session *session = NULL;
|
|
|
unsigned char *ptr, *optr;
|
|
@@ -922,7 +954,8 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
|
|
|
return bufp - optr;
|
|
|
}
|
|
|
|
|
|
-int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, size_t data_len)
|
|
|
+static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
|
|
|
+ size_t data_len)
|
|
|
{
|
|
|
struct l2tp_tunnel *tunnel = session->tunnel;
|
|
|
unsigned int len = skb->len;
|
|
@@ -1089,7 +1122,7 @@ EXPORT_SYMBOL_GPL(l2tp_xmit_skb);
|
|
|
* The tunnel context is deleted only when all session sockets have been
|
|
|
* closed.
|
|
|
*/
|
|
|
-void l2tp_tunnel_destruct(struct sock *sk)
|
|
|
+static void l2tp_tunnel_destruct(struct sock *sk)
|
|
|
{
|
|
|
struct l2tp_tunnel *tunnel;
|
|
|
|
|
@@ -1128,11 +1161,10 @@ void l2tp_tunnel_destruct(struct sock *sk)
|
|
|
end:
|
|
|
return;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(l2tp_tunnel_destruct);
|
|
|
|
|
|
/* When the tunnel is closed, all the attached sessions need to go too.
|
|
|
*/
|
|
|
-void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
|
|
|
+static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
|
|
|
{
|
|
|
int hash;
|
|
|
struct hlist_node *walk;
|
|
@@ -1198,7 +1230,7 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_closeall);
|
|
|
/* Really kill the tunnel.
|
|
|
* Come here only when all sessions have been cleared from the tunnel.
|
|
|
*/
|
|
|
-void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
|
|
|
+static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
|
|
|
{
|
|
|
struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
|
|
|
|
|
@@ -1217,7 +1249,6 @@ void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
|
|
|
atomic_dec(&l2tp_tunnel_count);
|
|
|
kfree(tunnel);
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(l2tp_tunnel_free);
|
|
|
|
|
|
/* Create a socket for the tunnel, if one isn't set up by
|
|
|
* userspace. This is used for static tunnels where there is no
|
|
@@ -1512,7 +1543,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete);
|
|
|
/* We come here whenever a session's send_seq, cookie_len or
|
|
|
* l2specific_len parameters are set.
|
|
|
*/
|
|
|
-void l2tp_session_set_header_len(struct l2tp_session *session, int version)
|
|
|
+static void l2tp_session_set_header_len(struct l2tp_session *session, int version)
|
|
|
{
|
|
|
if (version == L2TP_HDR_VER_2) {
|
|
|
session->hdr_len = 6;
|
|
@@ -1525,7 +1556,6 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(l2tp_session_set_header_len);
|
|
|
|
|
|
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)
|
|
|
{
|