Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3305f9a9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'l2tp-rework-pppol2tp-ioctl-handling'



Guillaume Nault says:

====================
l2tp: rework pppol2tp ioctl handling

The current ioctl() handling code can be simplified. It tests for
non-relevant conditions and uselessly holds sockets. Once useless
code is removed, it becomes even simpler to let pppol2tp_ioctl() handle
commands directly, rather than dispatch them to pppol2tp_tunnel_ioctl()
or pppol2tp_session_ioctl(). That is the approach taken by this series.

Patch #1 and #2 define helper functions aimed at simplifying the rest
of the patch set.

Patch #3 drops useless tests in pppol2p_ioctl() and avoid holding a
refcount on the socket.

Patches #4, #5 and #6 are the core of the series. They let
pppol2tp_ioctl() handle all ioctls and drop the tunnel and session
specific functions.

Then patch #6 brings a little bit of consolidation.

Finally, patch #7 takes advantage of the simplified code to make
pppol2tp sockets compatible with dev_ioctl(). Certainly not a killer
feature, but it is trivial and it is always nice to see l2tp getting
better integration with the rest of the stack.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8a8982d1 4f5f85e9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ struct ppp_option_data {
struct pppol2tp_ioc_stats {
	__u16		tunnel_id;	/* redundant */
	__u16		session_id;	/* if zero, get tunnel stats */
	__u32		using_ipsec:1;	/* valid only for session_id == 0 */
	__u32		using_ipsec:1;
	__aligned_u64	tx_packets;
	__aligned_u64	tx_bytes;
	__aligned_u64	tx_errors;
+25 −25
Original line number Diff line number Diff line
@@ -203,44 +203,44 @@ struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
}
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_session *l2tp_tunnel_get_session(struct l2tp_tunnel *tunnel,
					     u32 session_id)
{
	struct hlist_head *session_list;
	struct l2tp_session *session;

	if (!tunnel) {
		struct l2tp_net *pn = l2tp_pernet(net);

		session_list = l2tp_session_id_hash_2(pn, session_id);
	session_list = l2tp_session_id_hash(tunnel, session_id);

		rcu_read_lock_bh();
		hlist_for_each_entry_rcu(session, session_list, global_hlist) {
	read_lock_bh(&tunnel->hlist_lock);
	hlist_for_each_entry(session, session_list, hlist)
		if (session->session_id == session_id) {
			l2tp_session_inc_refcount(session);
				rcu_read_unlock_bh();
			read_unlock_bh(&tunnel->hlist_lock);

			return session;
		}
		}
		rcu_read_unlock_bh();
	read_unlock_bh(&tunnel->hlist_lock);

	return NULL;
}
EXPORT_SYMBOL_GPL(l2tp_tunnel_get_session);

	session_list = l2tp_session_id_hash(tunnel, session_id);
	read_lock_bh(&tunnel->hlist_lock);
	hlist_for_each_entry(session, session_list, hlist) {
struct l2tp_session *l2tp_session_get(const struct net *net, u32 session_id)
{
	struct hlist_head *session_list;
	struct l2tp_session *session;

	session_list = l2tp_session_id_hash_2(l2tp_pernet(net), session_id);

	rcu_read_lock_bh();
	hlist_for_each_entry_rcu(session, session_list, global_hlist)
		if (session->session_id == session_id) {
			l2tp_session_inc_refcount(session);
			read_unlock_bh(&tunnel->hlist_lock);
			rcu_read_unlock_bh();

			return session;
		}
	}
	read_unlock_bh(&tunnel->hlist_lock);
	rcu_read_unlock_bh();

	return NULL;
}
@@ -872,7 +872,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
	}

	/* Find the session context */
	session = l2tp_session_get(tunnel->l2tp_net, tunnel, session_id);
	session = l2tp_tunnel_get_session(tunnel, session_id);
	if (!session || !session->recv_skb) {
		if (session)
			l2tp_session_dec_refcount(session);
+22 −3
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@
#include <net/dst.h>
#include <net/sock.h>

#ifdef CONFIG_XFRM
#include <net/xfrm.h>
#endif

/* Just some random numbers */
#define L2TP_TUNNEL_MAGIC	0x42114DDA
#define L2TP_SESSION_MAGIC	0x0C04EB7D
@@ -192,12 +196,12 @@ static inline void *l2tp_session_priv(struct l2tp_session *session)

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);
struct l2tp_session *l2tp_tunnel_get_session(struct l2tp_tunnel *tunnel,
					     u32 session_id);

void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);

struct l2tp_session *l2tp_session_get(const struct net *net,
				      struct l2tp_tunnel *tunnel,
				      u32 session_id);
struct l2tp_session *l2tp_session_get(const struct net *net, u32 session_id);
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
						const char *ifname);
@@ -284,6 +288,21 @@ static inline u32 l2tp_tunnel_dst_mtu(const struct l2tp_tunnel *tunnel)
	return mtu;
}

#ifdef CONFIG_XFRM
static inline bool l2tp_tunnel_uses_xfrm(const struct l2tp_tunnel *tunnel)
{
	struct sock *sk = tunnel->sock;

	return sk && (rcu_access_pointer(sk->sk_policy[0]) ||
		      rcu_access_pointer(sk->sk_policy[1]));
}
#else
static inline bool l2tp_tunnel_uses_xfrm(const struct l2tp_tunnel *tunnel)
{
	return false;
}
#endif

#define l2tp_printk(ptr, type, func, fmt, ...)				\
do {									\
	if (((ptr)->debug) & (type))					\
+1 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ static int l2tp_ip_recv(struct sk_buff *skb)
	}

	/* Ok, this is a data packet. Lookup the session. */
	session = l2tp_session_get(net, NULL, session_id);
	session = l2tp_session_get(net, session_id);
	if (!session)
		goto discard;

+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
	}

	/* Ok, this is a data packet. Lookup the session. */
	session = l2tp_session_get(net, NULL, session_id);
	session = l2tp_session_get(net, session_id);
	if (!session)
		goto discard;

Loading