Commit f8c9dfbd authored by Geliang Tang's avatar Geliang Tang Committed by Jakub Kicinski
Browse files

mptcp: add pm listener events



This patch adds two new MPTCP netlink event types for PM listening
socket create and close, named MPTCP_EVENT_LISTENER_CREATED and
MPTCP_EVENT_LISTENER_CLOSED.

Add a new function mptcp_event_pm_listener() to push the new events
with family, port and addr to userspace.

Invoke mptcp_event_pm_listener() with MPTCP_EVENT_LISTENER_CREATED in
mptcp_listen() and mptcp_pm_nl_create_listen_socket(), invoke it with
MPTCP_EVENT_LISTENER_CLOSED in __mptcp_close_ssk().

Signed-off-by: default avatarGeliang Tang <geliang.tang@suse.com>
Reviewed-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5f17f8e3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -160,6 +160,12 @@ struct mptcp_info {
 *                           daddr4 | daddr6, sport, dport, backup, if_idx
 *                           [, error]
 * The priority of a subflow has changed. 'error' should not be set.
 *
 * MPTCP_EVENT_LISTENER_CREATED: family, sport, saddr4 | saddr6
 * A new PM listener is created.
 *
 * MPTCP_EVENT_LISTENER_CLOSED: family, sport, saddr4 | saddr6
 * A PM listener is closed.
 */
enum mptcp_event_type {
	MPTCP_EVENT_UNSPEC = 0,
@@ -174,6 +180,9 @@ enum mptcp_event_type {
	MPTCP_EVENT_SUB_CLOSED = 11,

	MPTCP_EVENT_SUB_PRIORITY = 13,

	MPTCP_EVENT_LISTENER_CREATED = 15,
	MPTCP_EVENT_LISTENER_CLOSED = 16,
};

enum mptcp_event_attr {
+57 −0
Original line number Diff line number Diff line
@@ -1029,6 +1029,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
	if (err)
		return err;

	mptcp_event_pm_listener(ssock->sk, MPTCP_EVENT_LISTENER_CREATED);

	return 0;
}

@@ -2152,6 +2154,58 @@ void mptcp_event_addr_announced(const struct sock *ssk,
	kfree_skb(skb);
}

void mptcp_event_pm_listener(const struct sock *ssk,
			     enum mptcp_event_type event)
{
	const struct inet_sock *issk = inet_sk(ssk);
	struct net *net = sock_net(ssk);
	struct nlmsghdr *nlh;
	struct sk_buff *skb;

	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
		return;

	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!skb)
		return;

	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
	if (!nlh)
		goto nla_put_failure;

	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
		goto nla_put_failure;

	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
		goto nla_put_failure;

	switch (ssk->sk_family) {
	case AF_INET:
		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
			goto nla_put_failure;
		break;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	case AF_INET6: {
		const struct ipv6_pinfo *np = inet6_sk(ssk);

		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
			goto nla_put_failure;
		break;
	}
#endif
	default:
		WARN_ON_ONCE(1);
		goto nla_put_failure;
	}

	genlmsg_end(skb, nlh);
	mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
	return;

nla_put_failure:
	kfree_skb(skb);
}

void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
		 const struct sock *ssk, gfp_t gfp)
{
@@ -2197,6 +2251,9 @@ void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
		if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
			goto nla_put_failure;
		break;
	case MPTCP_EVENT_LISTENER_CREATED:
	case MPTCP_EVENT_LISTENER_CLOSED:
		break;
	}

	genlmsg_end(skb, nlh);
+3 −0
Original line number Diff line number Diff line
@@ -2355,6 +2355,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
			tcp_set_state(ssk, TCP_CLOSE);
			mptcp_subflow_queue_clean(ssk);
			inet_csk_listen_stop(ssk);
			mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED);
		}
		__tcp_close(ssk, 0);

@@ -3647,6 +3648,8 @@ static int mptcp_listen(struct socket *sock, int backlog)
	if (!err)
		mptcp_copy_inaddrs(sock->sk, ssock->sk);

	mptcp_event_pm_listener(ssock->sk, MPTCP_EVENT_LISTENER_CREATED);

unlock:
	release_sock(sock->sk);
	return err;
+2 −0
Original line number Diff line number Diff line
@@ -839,6 +839,8 @@ void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
		 const struct sock *ssk, gfp_t gfp);
void mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_info *info);
void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
void mptcp_event_pm_listener(const struct sock *ssk,
			     enum mptcp_event_type event);
bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);

void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,