// SPDX-License-Identifier: GPL-2.0
/* MPTCP socket monitoring support
 *
 * Copyright (c) 2019 Red Hat
 *
 * Author: Davide Caratti <dcaratti@redhat.com>
 */

#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/inet_diag.h>
#include <net/netlink.h>
#include <uapi/linux/mptcp.h>
#include "protocol.h"

static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
{
	struct mptcp_subflow_context *sf;
	struct nlattr *start;
	u32 flags = 0;
	bool slow;
	int err;

	start = nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP);
	if (!start)
		return -EMSGSIZE;

	slow = lock_sock_fast(sk);
	rcu_read_lock();
	sf = rcu_dereference(inet_csk(sk)->icsk_ulp_data);
	if (!sf) {
		err = 0;
		goto nla_failure;
	}

	if (sf->mp_capable)
		flags |= MPTCP_SUBFLOW_FLAG_MCAP_REM;
	if (sf->request_mptcp)
		flags |= MPTCP_SUBFLOW_FLAG_MCAP_LOC;
	if (sf->mp_join)
		flags |= MPTCP_SUBFLOW_FLAG_JOIN_REM;
	if (sf->request_join)
		flags |= MPTCP_SUBFLOW_FLAG_JOIN_LOC;
	if (sf->backup)
		flags |= MPTCP_SUBFLOW_FLAG_BKUP_REM;
	if (sf->request_bkup)
		flags |= MPTCP_SUBFLOW_FLAG_BKUP_LOC;
	if (sf->fully_established)
		flags |= MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED;
	if (sf->conn_finished)
		flags |= MPTCP_SUBFLOW_FLAG_CONNECTED;
	if (sf->map_valid)
		flags |= MPTCP_SUBFLOW_FLAG_MAPVALID;

	if (nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_TOKEN_REM, sf->remote_token) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_TOKEN_LOC, sf->token) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
			sf->rel_write_seq) ||
	    nla_put_u64_64bit(skb, MPTCP_SUBFLOW_ATTR_MAP_SEQ, sf->map_seq,
			      MPTCP_SUBFLOW_ATTR_PAD) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_MAP_SFSEQ,
			sf->map_subflow_seq) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_SSN_OFFSET, sf->ssn_offset) ||
	    nla_put_u16(skb, MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
			sf->map_data_len) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf))) {
		err = -EMSGSIZE;
		goto nla_failure;
	}

	rcu_read_unlock();
	unlock_sock_fast(sk, slow);
	nla_nest_end(skb, start);
	return 0;

nla_failure:
	rcu_read_unlock();
	unlock_sock_fast(sk, slow);
	nla_nest_cancel(skb, start);
	return err;
}

static size_t subflow_get_info_size(const struct sock *sk)
{
	size_t size = 0;

	size += nla_total_size(0) +	/* INET_ULP_INFO_MPTCP */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_TOKEN_REM */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_TOKEN_LOC */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */
		nla_total_size_64bit(8) +	/* MPTCP_SUBFLOW_ATTR_MAP_SEQ */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_MAP_SFSEQ */
		nla_total_size(2) +	/* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */
		nla_total_size(2) +	/* MPTCP_SUBFLOW_ATTR_MAP_DATALEN */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_FLAGS */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_REM */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_LOC */
		0;
	return size;
}

void mptcp_diag_subflow_init(struct tcp_ulp_ops *ops)
{
	ops->get_info = subflow_get_info;
	ops->get_info_size = subflow_get_info_size;
}
