diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2014-03-06 05:14:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-06 14:25:39 -0500 |
commit | bb5016eac1656506df1a9d6057ce5bec342afbef (patch) | |
tree | c83f3e91c9e71915164e4212722f2415b5998f6a /net/l2tp | |
parent | 1b07da516ee25250f458c76c012ebe4cd677a84f (diff) |
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>
Diffstat (limited to 'net/l2tp')
-rw-r--r-- | net/l2tp/l2tp_core.c | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.h | 1 | ||||
-rw-r--r-- | net/l2tp/l2tp_netlink.c | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 1 |
4 files changed, 7 insertions, 3 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 735d0f60c83a..85d9d94c0a3c 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -112,7 +112,6 @@ struct l2tp_net { | |||
112 | spinlock_t l2tp_session_hlist_lock; | 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 | static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); | 115 | static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); |
117 | 116 | ||
118 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) | 117 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) |
@@ -1863,7 +1862,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete); | |||
1863 | /* We come here whenever a session's send_seq, cookie_len or | 1862 | /* We come here whenever a session's send_seq, cookie_len or |
1864 | * l2specific_len parameters are set. | 1863 | * l2specific_len parameters are set. |
1865 | */ | 1864 | */ |
1866 | static void l2tp_session_set_header_len(struct l2tp_session *session, int version) | 1865 | void l2tp_session_set_header_len(struct l2tp_session *session, int version) |
1867 | { | 1866 | { |
1868 | if (version == L2TP_HDR_VER_2) { | 1867 | if (version == L2TP_HDR_VER_2) { |
1869 | session->hdr_len = 6; | 1868 | session->hdr_len = 6; |
@@ -1876,6 +1875,7 @@ static void l2tp_session_set_header_len(struct l2tp_session *session, int versio | |||
1876 | } | 1875 | } |
1877 | 1876 | ||
1878 | } | 1877 | } |
1878 | EXPORT_SYMBOL_GPL(l2tp_session_set_header_len); | ||
1879 | 1879 | ||
1880 | 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 | 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) |
1881 | { | 1881 | { |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 1f01ba3435bc..3f93ccd6ba97 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
@@ -263,6 +263,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, | |||
263 | int length, int (*payload_hook)(struct sk_buff *skb)); | 263 | int length, int (*payload_hook)(struct sk_buff *skb)); |
264 | int l2tp_session_queue_purge(struct l2tp_session *session); | 264 | int l2tp_session_queue_purge(struct l2tp_session *session); |
265 | int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb); | 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 | int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, | 268 | int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, |
268 | int hdr_len); | 269 | int hdr_len); |
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 4cfd722e9153..bd7387adea9e 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c | |||
@@ -578,8 +578,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf | |||
578 | if (info->attrs[L2TP_ATTR_RECV_SEQ]) | 578 | if (info->attrs[L2TP_ATTR_RECV_SEQ]) |
579 | session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); | 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 | session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); | 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 | if (info->attrs[L2TP_ATTR_LNS_MODE]) | 586 | if (info->attrs[L2TP_ATTR_LNS_MODE]) |
585 | session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); | 587 | session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index be5fadf34739..6bfeaa777135 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -1312,6 +1312,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk, | |||
1312 | po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : | 1312 | po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : |
1313 | PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; | 1313 | PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; |
1314 | } | 1314 | } |
1315 | l2tp_session_set_header_len(session, session->tunnel->version); | ||
1315 | l2tp_info(session, PPPOL2TP_MSG_CONTROL, | 1316 | l2tp_info(session, PPPOL2TP_MSG_CONTROL, |
1316 | "%s: set send_seq=%d\n", | 1317 | "%s: set send_seq=%d\n", |
1317 | session->name, session->send_seq); | 1318 | session->name, session->send_seq); |