Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Guillaume Nault and committed by
David S. Miller
bb5016ea 1b07da51

+7 -3
+2 -2
net/l2tp/l2tp_core.c
··· 112 112 spinlock_t l2tp_session_hlist_lock; 113 113 }; 114 114 115 - static void l2tp_session_set_header_len(struct l2tp_session *session, int version); 116 115 static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); 117 116 118 117 static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) ··· 1862 1863 /* We come here whenever a session's send_seq, cookie_len or 1863 1864 * l2specific_len parameters are set. 1864 1865 */ 1865 - static void l2tp_session_set_header_len(struct l2tp_session *session, int version) 1866 + void l2tp_session_set_header_len(struct l2tp_session *session, int version) 1866 1867 { 1867 1868 if (version == L2TP_HDR_VER_2) { 1868 1869 session->hdr_len = 6; ··· 1875 1876 } 1876 1877 1877 1878 } 1879 + EXPORT_SYMBOL_GPL(l2tp_session_set_header_len); 1878 1880 1879 1881 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) 1880 1882 {
+1
net/l2tp/l2tp_core.h
··· 263 263 int length, int (*payload_hook)(struct sk_buff *skb)); 264 264 int l2tp_session_queue_purge(struct l2tp_session *session); 265 265 int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb); 266 + void l2tp_session_set_header_len(struct l2tp_session *session, int version); 266 267 267 268 int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, 268 269 int hdr_len);
+3 -1
net/l2tp/l2tp_netlink.c
··· 578 578 if (info->attrs[L2TP_ATTR_RECV_SEQ]) 579 579 session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); 580 580 581 - if (info->attrs[L2TP_ATTR_SEND_SEQ]) 581 + if (info->attrs[L2TP_ATTR_SEND_SEQ]) { 582 582 session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); 583 + l2tp_session_set_header_len(session, session->tunnel->version); 584 + } 583 585 584 586 if (info->attrs[L2TP_ATTR_LNS_MODE]) 585 587 session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
+1
net/l2tp/l2tp_ppp.c
··· 1312 1312 po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : 1313 1313 PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; 1314 1314 } 1315 + l2tp_session_set_header_len(session, session->tunnel->version); 1315 1316 l2tp_info(session, PPPOL2TP_MSG_CONTROL, 1316 1317 "%s: set send_seq=%d\n", 1317 1318 session->name, session->send_seq);