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

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ enum {
	L2TP_ATTR_OFFSET,		/* u16 (not used) */
	L2TP_ATTR_DATA_SEQ,		/* u16 */
	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_IFNAME,		/* string */
	L2TP_ATTR_CONN_ID,		/* u32 */
+16 −19
Original line number Diff line number Diff line
@@ -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",
				 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) {
		/* Received a packet with sequence numbers. If we're the LNS,
		 * check if we sre sending sequence numbers and if not,
@@ -1048,9 +1046,9 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
		memcpy(bufp, &session->cookie[0], session->cookie_len);
		bufp += session->cookie_len;
	}
	if (session->l2specific_len) {
	if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
		u32 l2h = 0;

		if (session->send_seq) {
			l2h = 0x40000000 | session->ns;
			session->ns++;
@@ -1061,8 +1059,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
		}

		*((__be32 *)bufp) = htonl(l2h);
		}
		bufp += session->l2specific_len;
		bufp += 4;
	}

	return bufp - optr;
@@ -1719,7 +1716,7 @@ int l2tp_session_delete(struct l2tp_session *session)
EXPORT_SYMBOL_GPL(l2tp_session_delete);

/* 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)
{
@@ -1728,7 +1725,8 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
		if (session->send_seq)
			session->hdr_len += 4;
	} 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)
			session->hdr_len += 4;
	}
@@ -1779,7 +1777,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
			session->lns_mode = cfg->lns_mode;
			session->reorder_timeout = cfg->reorder_timeout;
			session->l2specific_type = cfg->l2specific_type;
			session->l2specific_len = cfg->l2specific_len;
			session->cookie_len = cfg->cookie_len;
			memcpy(&session->cookie[0], &cfg->cookie[0], cfg->cookie_len);
			session->peer_cookie_len = cfg->peer_cookie_len;
+11 −2
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ struct l2tp_session_cfg {
	int			debug;		/* bitmask of debug message
						 * categories */
	u16			vlan_id;	/* VLAN pseudowire only */
	u16			l2specific_len;	/* Layer 2 specific length */
	u16			l2specific_type; /* Layer 2 specific type */
	u8			cookie[8];	/* optional cookie */
	int			cookie_len;	/* 0, 4 or 8 bytes */
@@ -85,7 +84,6 @@ struct l2tp_session {
	int			cookie_len;
	u8			peer_cookie[8];
	int			peer_cookie_len;
	u16			l2specific_len;
	u16			l2specific_type;
	u16			hdr_len;
	u32			nr;		/* session NR state (receive) */
@@ -302,6 +300,17 @@ static inline void l2tp_session_dec_refcount(struct l2tp_session *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, ...)				\
do {									\
	if (((ptr)->debug) & (type))					\
+1 −1
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
		   session->debug,
		   jiffies_to_msecs(session->reorder_timeout));
	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) {
		seq_printf(m, "   cookie %02x%02x%02x%02x",
			   session->cookie[0], session->cookie[1],
+9 −6
Original line number Diff line number Diff line
@@ -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])
			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_len = 4;
		if (info->attrs[L2TP_ATTR_L2SPEC_LEN])
			cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]);
			if (cfg.l2specific_type != L2TP_L2SPECTYPE_DEFAULT &&
			    cfg.l2specific_type != L2TP_L2SPECTYPE_NONE) {
				ret = -EINVAL;
				goto out_tunnel;
			}
		} else {
			cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT;
		}

		if (info->attrs[L2TP_ATTR_COOKIE]) {
			u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);