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

Commit bb5016ea authored by Guillaume Nault's avatar Guillaume Nault Committed by David S. Miller
Browse files

l2tp: fix manual sequencing (de)activation in L2TPv2



Commit e0d4435f "l2tp: Update PPP-over-L2TP driver to work over L2TPv3"
broke the PPPOL2TP_SO_SENDSEQ setsockopt. The L2TP header length was
previously computed by pppol2tp_l2t_header_len() before each call to
l2tp_xmit_skb(). Now that header length is retrieved from the hdr_len
session field, this field must be updated every time the L2TP header
format is modified, or l2tp_xmit_skb() won't push the right amount of
data for the L2TP header.

This patch uses l2tp_session_set_header_len() to adjust hdr_len every
time sequencing is (de)activated from userspace (either by the
PPPOL2TP_SO_SENDSEQ setsockopt or the L2TP_ATTR_SEND_SEQ netlink
attribute).

Signed-off-by: default avatarGuillaume Nault <g.nault@alphalink.fr>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1b07da51
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -112,7 +112,6 @@ struct l2tp_net {
	spinlock_t l2tp_session_hlist_lock;
	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_free(struct l2tp_tunnel *tunnel);


static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
@@ -1863,7 +1862,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete);
/* We come here whenever a session's send_seq, cookie_len or
/* We come here whenever a session's send_seq, cookie_len or
 * l2specific_len parameters are set.
 * l2specific_len parameters are set.
 */
 */
static void l2tp_session_set_header_len(struct l2tp_session *session, int version)
void l2tp_session_set_header_len(struct l2tp_session *session, int version)
{
{
	if (version == L2TP_HDR_VER_2) {
	if (version == L2TP_HDR_VER_2) {
		session->hdr_len = 6;
		session->hdr_len = 6;
@@ -1876,6 +1875,7 @@ static void l2tp_session_set_header_len(struct l2tp_session *session, int versio
	}
	}


}
}
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)
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)
{
{
+1 −0
Original line number Original line Diff line number Diff line
@@ -263,6 +263,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
		      int length, int (*payload_hook)(struct sk_buff *skb));
		      int length, int (*payload_hook)(struct sk_buff *skb));
int l2tp_session_queue_purge(struct l2tp_session *session);
int l2tp_session_queue_purge(struct l2tp_session *session);
int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
void l2tp_session_set_header_len(struct l2tp_session *session, int version);


int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb,
int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb,
		  int hdr_len);
		  int hdr_len);
+3 −1
Original line number Original line Diff line number Diff line
@@ -578,8 +578,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf
	if (info->attrs[L2TP_ATTR_RECV_SEQ])
	if (info->attrs[L2TP_ATTR_RECV_SEQ])
		session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
		session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);


	if (info->attrs[L2TP_ATTR_SEND_SEQ])
	if (info->attrs[L2TP_ATTR_SEND_SEQ]) {
		session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
		session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
		l2tp_session_set_header_len(session, session->tunnel->version);
	}


	if (info->attrs[L2TP_ATTR_LNS_MODE])
	if (info->attrs[L2TP_ATTR_LNS_MODE])
		session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
		session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
+1 −0
Original line number Original line Diff line number Diff line
@@ -1312,6 +1312,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
			po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
			po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
				PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
				PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
		}
		}
		l2tp_session_set_header_len(session, session->tunnel->version);
		l2tp_info(session, PPPOL2TP_MSG_CONTROL,
		l2tp_info(session, PPPOL2TP_MSG_CONTROL,
			  "%s: set send_seq=%d\n",
			  "%s: set send_seq=%d\n",
			  session->name, session->send_seq);
			  session->name, session->send_seq);