Commit bfd072df authored by David S. Miller's avatar David S. Miller

Merge branch 'l2tp-set-l2specific_len-based-on-l2specific_type'

Lorenzo Bianconi says:

====================
l2tp: set l2specific_len based on l2specific_type

Do not rely on l2specific_len value provided by userspace but set sublayer
length according to l2specific_type.
Mark L2TP_ATTR_L2SPEC_LEN attribute as not used

Changes since v2:
- drop the patch related to a fix in the switch default case in
  l2tp_nl_cmd_session_create()
- use L2SPECTYPE_NONE as default case in l2tp_get_l2specific_len()

Changes since v1:
- remove l2specific_len parameter
- add sanity check on l2specific_type provided by userspace
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e0e8a149 4db5a802
...@@ -97,7 +97,7 @@ enum { ...@@ -97,7 +97,7 @@ enum {
L2TP_ATTR_OFFSET, /* u16 (not used) */ L2TP_ATTR_OFFSET, /* u16 (not used) */
L2TP_ATTR_DATA_SEQ, /* u16 */ L2TP_ATTR_DATA_SEQ, /* u16 */
L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */
L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */ L2TP_ATTR_L2SPEC_LEN, /* u8 (not used) */
L2TP_ATTR_PROTO_VERSION, /* u8 */ L2TP_ATTR_PROTO_VERSION, /* u8 */
L2TP_ATTR_IFNAME, /* string */ L2TP_ATTR_IFNAME, /* string */
L2TP_ATTR_CONN_ID, /* u32 */ L2TP_ATTR_CONN_ID, /* u32 */
......
...@@ -730,11 +730,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, ...@@ -730,11 +730,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
"%s: recv data ns=%u, session nr=%u\n", "%s: recv data ns=%u, session nr=%u\n",
session->name, ns, session->nr); session->name, ns, session->nr);
} }
ptr += 4;
} }
/* Advance past L2-specific header, if present */
ptr += session->l2specific_len;
if (L2TP_SKB_CB(skb)->has_seq) { if (L2TP_SKB_CB(skb)->has_seq) {
/* Received a packet with sequence numbers. If we're the LNS, /* Received a packet with sequence numbers. If we're the LNS,
* check if we sre sending sequence numbers and if not, * check if we sre sending sequence numbers and if not,
...@@ -1048,21 +1046,20 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) ...@@ -1048,21 +1046,20 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
memcpy(bufp, &session->cookie[0], session->cookie_len); memcpy(bufp, &session->cookie[0], session->cookie_len);
bufp += session->cookie_len; bufp += session->cookie_len;
} }
if (session->l2specific_len) { if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { u32 l2h = 0;
u32 l2h = 0;
if (session->send_seq) {
l2h = 0x40000000 | session->ns;
session->ns++;
session->ns &= 0xffffff;
l2tp_dbg(session, L2TP_MSG_SEQ,
"%s: updated ns to %u\n",
session->name, session->ns);
}
*((__be32 *) bufp) = htonl(l2h); if (session->send_seq) {
l2h = 0x40000000 | session->ns;
session->ns++;
session->ns &= 0xffffff;
l2tp_dbg(session, L2TP_MSG_SEQ,
"%s: updated ns to %u\n",
session->name, session->ns);
} }
bufp += session->l2specific_len;
*((__be32 *)bufp) = htonl(l2h);
bufp += 4;
} }
return bufp - optr; return bufp - optr;
...@@ -1719,7 +1716,7 @@ int l2tp_session_delete(struct l2tp_session *session) ...@@ -1719,7 +1716,7 @@ int l2tp_session_delete(struct l2tp_session *session)
EXPORT_SYMBOL_GPL(l2tp_session_delete); 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_type parameters are set.
*/ */
void l2tp_session_set_header_len(struct l2tp_session *session, int version) void l2tp_session_set_header_len(struct l2tp_session *session, int version)
{ {
...@@ -1728,7 +1725,8 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version) ...@@ -1728,7 +1725,8 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
if (session->send_seq) if (session->send_seq)
session->hdr_len += 4; session->hdr_len += 4;
} else { } else {
session->hdr_len = 4 + session->cookie_len + session->l2specific_len; session->hdr_len = 4 + session->cookie_len;
session->hdr_len += l2tp_get_l2specific_len(session);
if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP) if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP)
session->hdr_len += 4; session->hdr_len += 4;
} }
...@@ -1779,7 +1777,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn ...@@ -1779,7 +1777,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
session->lns_mode = cfg->lns_mode; session->lns_mode = cfg->lns_mode;
session->reorder_timeout = cfg->reorder_timeout; session->reorder_timeout = cfg->reorder_timeout;
session->l2specific_type = cfg->l2specific_type; session->l2specific_type = cfg->l2specific_type;
session->l2specific_len = cfg->l2specific_len;
session->cookie_len = cfg->cookie_len; session->cookie_len = cfg->cookie_len;
memcpy(&session->cookie[0], &cfg->cookie[0], cfg->cookie_len); memcpy(&session->cookie[0], &cfg->cookie[0], cfg->cookie_len);
session->peer_cookie_len = cfg->peer_cookie_len; session->peer_cookie_len = cfg->peer_cookie_len;
......
...@@ -59,7 +59,6 @@ struct l2tp_session_cfg { ...@@ -59,7 +59,6 @@ struct l2tp_session_cfg {
int debug; /* bitmask of debug message int debug; /* bitmask of debug message
* categories */ * categories */
u16 vlan_id; /* VLAN pseudowire only */ u16 vlan_id; /* VLAN pseudowire only */
u16 l2specific_len; /* Layer 2 specific length */
u16 l2specific_type; /* Layer 2 specific type */ u16 l2specific_type; /* Layer 2 specific type */
u8 cookie[8]; /* optional cookie */ u8 cookie[8]; /* optional cookie */
int cookie_len; /* 0, 4 or 8 bytes */ int cookie_len; /* 0, 4 or 8 bytes */
...@@ -85,7 +84,6 @@ struct l2tp_session { ...@@ -85,7 +84,6 @@ struct l2tp_session {
int cookie_len; int cookie_len;
u8 peer_cookie[8]; u8 peer_cookie[8];
int peer_cookie_len; int peer_cookie_len;
u16 l2specific_len;
u16 l2specific_type; u16 l2specific_type;
u16 hdr_len; u16 hdr_len;
u32 nr; /* session NR state (receive) */ u32 nr; /* session NR state (receive) */
...@@ -302,6 +300,17 @@ static inline void l2tp_session_dec_refcount(struct l2tp_session *session) ...@@ -302,6 +300,17 @@ static inline void l2tp_session_dec_refcount(struct l2tp_session *session)
l2tp_session_free(session); l2tp_session_free(session);
} }
static inline int l2tp_get_l2specific_len(struct l2tp_session *session)
{
switch (session->l2specific_type) {
case L2TP_L2SPECTYPE_DEFAULT:
return 4;
case L2TP_L2SPECTYPE_NONE:
default:
return 0;
}
}
#define l2tp_printk(ptr, type, func, fmt, ...) \ #define l2tp_printk(ptr, type, func, fmt, ...) \
do { \ do { \
if (((ptr)->debug) & (type)) \ if (((ptr)->debug) & (type)) \
......
...@@ -181,7 +181,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v) ...@@ -181,7 +181,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
session->debug, session->debug,
jiffies_to_msecs(session->reorder_timeout)); jiffies_to_msecs(session->reorder_timeout));
seq_printf(m, " offset 0 l2specific %hu/%hu\n", seq_printf(m, " offset 0 l2specific %hu/%hu\n",
session->l2specific_type, session->l2specific_len); session->l2specific_type, l2tp_get_l2specific_len(session));
if (session->cookie_len) { if (session->cookie_len) {
seq_printf(m, " cookie %02x%02x%02x%02x", seq_printf(m, " cookie %02x%02x%02x%02x",
session->cookie[0], session->cookie[1], session->cookie[0], session->cookie[1],
......
...@@ -550,13 +550,16 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ...@@ -550,13 +550,16 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
if (info->attrs[L2TP_ATTR_DATA_SEQ]) if (info->attrs[L2TP_ATTR_DATA_SEQ])
cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT; if (info->attrs[L2TP_ATTR_L2SPEC_TYPE]) {
if (info->attrs[L2TP_ATTR_L2SPEC_TYPE])
cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]); cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]);
if (cfg.l2specific_type != L2TP_L2SPECTYPE_DEFAULT &&
cfg.l2specific_len = 4; cfg.l2specific_type != L2TP_L2SPECTYPE_NONE) {
if (info->attrs[L2TP_ATTR_L2SPEC_LEN]) ret = -EINVAL;
cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]); goto out_tunnel;
}
} else {
cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT;
}
if (info->attrs[L2TP_ATTR_COOKIE]) { if (info->attrs[L2TP_ATTR_COOKIE]) {
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]); u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment