Commit 30f60bae authored by Geliang Tang's avatar Geliang Tang Committed by David S. Miller
Browse files

mptcp: use mptcp_addr_info in mptcp_out_options



This patch moved the mptcp_addr_info struct from protocol.h to mptcp.h,
added a new struct mptcp_addr_info member addr in struct mptcp_out_options,
and dropped the original addr, addr6, addr_id and port fields in it. Then
we can use opts->addr to get the adding address from PM directly using
mptcp_pm_add_addr_signal.

Since the port number became big-endian now, use ntohs to convert it
before sending it out with the ADD_ADDR suboption. Also convert it
when passing it to add_addr_generate_hmac or printing it out.

Co-developed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarGeliang Tang <geliangtang@gmail.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent daa83ab0
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -41,20 +41,25 @@ struct mptcp_rm_list {
	u8 nr;
};

struct mptcp_out_options {
#if IS_ENABLED(CONFIG_MPTCP)
	u16 suboptions;
	u64 sndr_key;
	u64 rcvr_key;
struct mptcp_addr_info {
	u8			id;
	sa_family_t		family;
	__be16			port;
	union {
		struct in_addr	addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
		struct in6_addr	addr6;
#endif
	};
	u8 addr_id;
	u16 port;
};

struct mptcp_out_options {
#if IS_ENABLED(CONFIG_MPTCP)
	u16 suboptions;
	u64 sndr_key;
	u64 rcvr_key;
	u64 ahmac;
	struct mptcp_addr_info addr;
	struct mptcp_rm_list rm_list;
	u8 join_id;
	u8 backup;
+20 −24
Original line number Diff line number Diff line
@@ -626,7 +626,6 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
	bool drop_other_suboptions = false;
	unsigned int opt_size = *size;
	struct mptcp_addr_info saddr;
	bool echo;
	bool port;
	int len;
@@ -643,45 +642,40 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
	}

	if (!mptcp_pm_should_add_signal(msk) ||
	    !(mptcp_pm_add_addr_signal(msk, remaining, &saddr, &echo, &port)))
	    !(mptcp_pm_add_addr_signal(msk, remaining, &opts->addr, &echo, &port)))
		return false;

	len = mptcp_add_addr_len(saddr.family, echo, port);
	len = mptcp_add_addr_len(opts->addr.family, echo, port);
	if (remaining < len)
		return false;

	*size = len;
	if (drop_other_suboptions)
		*size -= opt_size;
	opts->addr_id = saddr.id;
	if (port)
		opts->port = ntohs(saddr.port);
	if (saddr.family == AF_INET) {
	if (opts->addr.family == AF_INET) {
		opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
		opts->addr = saddr.addr;
		if (!echo) {
			opts->ahmac = add_addr_generate_hmac(msk->local_key,
							     msk->remote_key,
							     opts->addr_id,
							     &opts->addr,
							     opts->port);
							     opts->addr.id,
							     &opts->addr.addr,
							     ntohs(opts->addr.port));
		}
	}
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	else if (saddr.family == AF_INET6) {
	else if (opts->addr.family == AF_INET6) {
		opts->suboptions |= OPTION_MPTCP_ADD_ADDR6;
		opts->addr6 = saddr.addr6;
		if (!echo) {
			opts->ahmac = add_addr6_generate_hmac(msk->local_key,
							      msk->remote_key,
							      opts->addr_id,
							      &opts->addr6,
							      opts->port);
							      opts->addr.id,
							      &opts->addr.addr6,
							      ntohs(opts->addr.port));
		}
	}
#endif
	pr_debug("addr_id=%d, ahmac=%llu, echo=%d, port=%d",
		 opts->addr_id, opts->ahmac, echo, opts->port);
		 opts->addr.id, opts->ahmac, echo, ntohs(opts->addr.port));

	return true;
}
@@ -1217,7 +1211,7 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
			len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
#endif

		if (opts->port)
		if (opts->addr.port)
			len += TCPOLEN_MPTCP_PORT_LEN;

		if (opts->ahmac) {
@@ -1226,28 +1220,30 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
		}

		*ptr++ = mptcp_option(MPTCPOPT_ADD_ADDR,
				      len, echo, opts->addr_id);
				      len, echo, opts->addr.id);
		if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
			memcpy((u8 *)ptr, (u8 *)&opts->addr.s_addr, 4);
			memcpy((u8 *)ptr, (u8 *)&opts->addr.addr.s_addr, 4);
			ptr += 1;
		}
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
		else if (OPTION_MPTCP_ADD_ADDR6 & opts->suboptions) {
			memcpy((u8 *)ptr, opts->addr6.s6_addr, 16);
			memcpy((u8 *)ptr, opts->addr.addr6.s6_addr, 16);
			ptr += 4;
		}
#endif

		if (!opts->port) {
		if (!opts->addr.port) {
			if (opts->ahmac) {
				put_unaligned_be64(opts->ahmac, ptr);
				ptr += 2;
			}
		} else {
			u16 port = ntohs(opts->addr.port);

			if (opts->ahmac) {
				u8 *bptr = (u8 *)ptr;

				put_unaligned_be16(opts->port, bptr);
				put_unaligned_be16(port, bptr);
				bptr += 2;
				put_unaligned_be64(opts->ahmac, bptr);
				bptr += 8;
@@ -1256,7 +1252,7 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,

				ptr += 3;
			} else {
				put_unaligned_be32(opts->port << 16 |
				put_unaligned_be32(port << 16 |
						   TCPOPT_NOP << 8 |
						   TCPOPT_NOP, ptr);
				ptr += 1;
+0 −12
Original line number Diff line number Diff line
@@ -169,18 +169,6 @@ static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
		     ((nib & 0xF) << 8) | field);
}

struct mptcp_addr_info {
	sa_family_t		family;
	__be16			port;
	u8			id;
	union {
		struct in_addr addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
		struct in6_addr addr6;
#endif
	};
};

enum mptcp_pm_status {
	MPTCP_PM_ADD_ADDR_RECEIVED,
	MPTCP_PM_ADD_ADDR_SEND_ACK,