1 // SPDX-License-Identifier: GPL-2.0
2 /* MPTCP socket monitoring support
4 * Copyright (c) 2019 Red Hat
6 * Author: Davide Caratti <dcaratti@redhat.com>
9 #include <linux/kernel.h>
10 #include <linux/net.h>
11 #include <linux/inet_diag.h>
12 #include <net/netlink.h>
13 #include <uapi/linux/mptcp.h>
16 static int subflow_get_info(const struct sock
*sk
, struct sk_buff
*skb
)
18 struct mptcp_subflow_context
*sf
;
23 start
= nla_nest_start_noflag(skb
, INET_ULP_INFO_MPTCP
);
28 sf
= rcu_dereference(inet_csk(sk
)->icsk_ulp_data
);
35 flags
|= MPTCP_SUBFLOW_FLAG_MCAP_REM
;
36 if (sf
->request_mptcp
)
37 flags
|= MPTCP_SUBFLOW_FLAG_MCAP_LOC
;
39 flags
|= MPTCP_SUBFLOW_FLAG_JOIN_REM
;
41 flags
|= MPTCP_SUBFLOW_FLAG_JOIN_LOC
;
43 flags
|= MPTCP_SUBFLOW_FLAG_BKUP_REM
;
45 flags
|= MPTCP_SUBFLOW_FLAG_BKUP_LOC
;
46 if (sf
->fully_established
)
47 flags
|= MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED
;
48 if (sf
->conn_finished
)
49 flags
|= MPTCP_SUBFLOW_FLAG_CONNECTED
;
51 flags
|= MPTCP_SUBFLOW_FLAG_MAPVALID
;
53 if (nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_TOKEN_REM
, sf
->remote_token
) ||
54 nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_TOKEN_LOC
, sf
->token
) ||
55 nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ
,
57 nla_put_u64_64bit(skb
, MPTCP_SUBFLOW_ATTR_MAP_SEQ
, sf
->map_seq
,
58 MPTCP_SUBFLOW_ATTR_PAD
) ||
59 nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_MAP_SFSEQ
,
60 sf
->map_subflow_seq
) ||
61 nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_SSN_OFFSET
, sf
->ssn_offset
) ||
62 nla_put_u16(skb
, MPTCP_SUBFLOW_ATTR_MAP_DATALEN
,
64 nla_put_u32(skb
, MPTCP_SUBFLOW_ATTR_FLAGS
, flags
) ||
65 nla_put_u8(skb
, MPTCP_SUBFLOW_ATTR_ID_REM
, sf
->remote_id
) ||
66 nla_put_u8(skb
, MPTCP_SUBFLOW_ATTR_ID_LOC
, sf
->local_id
)) {
72 nla_nest_end(skb
, start
);
77 nla_nest_cancel(skb
, start
);
81 static size_t subflow_get_info_size(const struct sock
*sk
)
85 size
+= nla_total_size(0) + /* INET_ULP_INFO_MPTCP */
86 nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_TOKEN_REM */
87 nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_TOKEN_LOC */
88 nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */
89 nla_total_size_64bit(8) + /* MPTCP_SUBFLOW_ATTR_MAP_SEQ */
90 nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_MAP_SFSEQ */
91 nla_total_size(2) + /* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */
92 nla_total_size(2) + /* MPTCP_SUBFLOW_ATTR_MAP_DATALEN */
93 nla_total_size(4) + /* MPTCP_SUBFLOW_ATTR_FLAGS */
94 nla_total_size(1) + /* MPTCP_SUBFLOW_ATTR_ID_REM */
95 nla_total_size(1) + /* MPTCP_SUBFLOW_ATTR_ID_LOC */
100 void mptcp_diag_subflow_init(struct tcp_ulp_ops
*ops
)
102 ops
->get_info
= subflow_get_info
;
103 ops
->get_info_size
= subflow_get_info_size
;