diff mbox series

[net-next] dccp: add getsockopt option for CCID2: DCCP_SOCKOPT_CCID_TX_INFO

Message ID 20210425173219.175324-1-richard_siegfried@systemli.org (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next] dccp: add getsockopt option for CCID2: DCCP_SOCKOPT_CCID_TX_INFO | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 4 maintainers not CCed: linux-doc@vger.kernel.org kuba@kernel.org corbet@lwn.net andrew@lunn.ch
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff fail Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit fail Errors and warnings before: 32 this patch: 34
netdev/kdoc success Errors and warnings before: 22 this patch: 22
netdev/verify_fixes success Link
netdev/checkpatch fail ERROR: code indent should use tabs where possible WARNING: please, no spaces at the start of a line
netdev/build_allmodconfig_warn fail Errors and warnings before: 31 this patch: 33
netdev/header_inline success Link

Commit Message

Richard Sailer April 25, 2021, 5:32 p.m. UTC
CCID 3 already has the getsockopt() option DCCP_SOCKOPT_CCID_TX_INFO,
this commit also adds it for CCID2. It returns tx and congestion control
information in struct ccid_tx_info.

This also adds doc in Documentation/networking/dccp.rst and defines
the struct in include/uapi/linux/dccp.h to make it accessible to userspace.
---
 Documentation/networking/dccp.rst | 22 +++++++++++----------
 include/uapi/linux/dccp.h         | 16 ++++++++++++++++
 net/dccp/ccids/ccid2.c            | 32 +++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/networking/dccp.rst b/Documentation/networking/dccp.rst
index 91e5c33ba3ff..8f2852817773 100644
--- a/Documentation/networking/dccp.rst
+++ b/Documentation/networking/dccp.rst
@@ -126,16 +126,18 @@  DCCP_SOCKOPT_RECV_CSCOV is for the receiver and has a different meaning: it
 	restrictive this setting (see [RFC 4340, sec. 9.2.1]). Partial coverage
 	settings are inherited to the child socket after accept().
 
-The following two options apply to CCID 3 exclusively and are getsockopt()-only.
-In either case, a TFRC info struct (defined in <linux/tfrc.h>) is returned.
-
-DCCP_SOCKOPT_CCID_RX_INFO
-	Returns a ``struct tfrc_rx_info`` in optval; the buffer for optval and
-	optlen must be set to at least sizeof(struct tfrc_rx_info).
-
-DCCP_SOCKOPT_CCID_TX_INFO
-	Returns a ``struct tfrc_tx_info`` in optval; the buffer for optval and
-	optlen must be set to at least sizeof(struct tfrc_tx_info).
+DCCP_SOCKOPT_CCID_RX_INFO (CCID3 only, getsockopt() only)
+	Returns a ``struct tfrc_rx_info`` (defined in <linux/tfrc.h>) in optval;
+	the buffer for optval and optlen must be at least sizeof(struct tfrc_rx_info).
+
+DCCP_SOCKOPT_CCID_TX_INFO (getsockopt() only)
+	CCID 3:
+	Returns a ``struct tfrc_tx_info`` (defined in <linux/tfrc.h>) in optval;
+	the buffer for optval and optlen must be at least sizeof(struct tfrc_tx_info).
+
+	CCID 2:
+	Returns a ``struct ccid2_tx_info`` (defined in <uapi/linux/dccp.h>) in optval;
+	the buffer for optval and optlen must be at least sizeof(struct ccid2_tx_info).
 
 On unidirectional connections it is useful to close the unused half-connection
 via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs.
diff --git a/include/uapi/linux/dccp.h b/include/uapi/linux/dccp.h
index 6e1978dbcf7c..5d5290b8788a 100644
--- a/include/uapi/linux/dccp.h
+++ b/include/uapi/linux/dccp.h
@@ -47,6 +47,22 @@  struct dccp_hdr {
 	__be16	dccph_seq;
 };
 
+/**  struct ccid2_tx_info (Congestion Control Infos)
+ *
+ * @tx_cwnd:                 max number of packets the path can handle
+ * @tx_srtt:                 smoothed RTT estimate, scaled by 2^3
+ * @tx_pipe:                 estimate of "in flight" packets
+ * @buffer_fill              number of bytes in send buffer
+ * @cur_mss                  current MSS (in bytes) (pMTU - header_sizes)
+ */
+struct ccid2_tx_info {
+	__u32	tx_cwnd;
+	__u32	tx_srtt;
+	__u32	tx_pipe;
+	int	buffer_fill;
+	__u32	cur_mss;
+};
+
 /**
  * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
  *
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 4d9823d6dced..3f40265552c5 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -22,6 +22,37 @@  static bool ccid2_debug;
 #define ccid2_pr_debug(format, a...)
 #endif
 
+int ccid2_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
+                           u32 __user *optval, int __user *optlen)
+{
+	const struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+	struct dccp_sock *dp = dccp_sk(sk);
+	struct ccid2_tx_info ccid2_info;
+	const void *val;
+
+	switch (optname) {
+	case DCCP_SOCKOPT_CCID_TX_INFO:
+		if (len < sizeof(ccid2_info))
+			return -EINVAL;
+		memset(&ccid2_info, 0, sizeof(ccid2_info));
+		ccid2_info.tx_cwnd	   = hc->tx_cwnd;
+		ccid2_info.tx_srtt         = hc->tx_srtt;
+		ccid2_info.tx_pipe         = hc->tx_pipe;
+		ccid2_info.buffer_fill     = sk_wmem_alloc_get(sk);
+		ccid2_info.cur_mss         = dp->dccps_mss_cache;
+		len = sizeof(ccid2_info);
+		val = &ccid2_info;
+		break;
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (put_user(len, optlen) || copy_to_user(optval, val, len))
+		return -EFAULT;
+
+	return 0;
+}
+
 static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc)
 {
 	struct ccid2_seq *seqp;
@@ -785,6 +816,7 @@  struct ccid_operations ccid2_ops = {
 	.ccid_hc_tx_packet_recv	  = ccid2_hc_tx_packet_recv,
 	.ccid_hc_rx_obj_size	  = sizeof(struct ccid2_hc_rx_sock),
 	.ccid_hc_rx_packet_recv	  = ccid2_hc_rx_packet_recv,
+	.ccid_hc_tx_getsockopt    = ccid2_hc_tx_getsockopt,
 };
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG