Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  net/dccp/feat.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  Feature negotiation for the DCCP protocol (RFC 4340, section 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  Copyright (c) 2008 Gerrit Renker <gerrit@erg.abdn.ac.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *  Rewrote from scratch, some bits from earlier code by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *  ASSUMPTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *  -----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *  o Feature negotiation is coordinated with connection setup (as in TCP), wild
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *    changes of parameters of an established connection are not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *  o Changing non-negotiable (NN) values is supported in state OPEN/PARTOPEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *  o All currently known SP features have 1-byte quantities. If in the future
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *    extensions of RFCs 4340..42 define features with item lengths larger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *    one byte, a feature-specific extension of the code will be required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "ccid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "feat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) /* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) unsigned long	sysctl_dccp_sequence_window __read_mostly = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) int		sysctl_dccp_rx_ccid	    __read_mostly = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 		sysctl_dccp_tx_ccid	    __read_mostly = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * Feature activation handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * These all use an u64 argument, to provide enough room for NN/SP features. At
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * this stage the negotiated values have been checked to be within their range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	struct ccid *new_ccid = ccid_new(ccid, sk, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	if (new_ccid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	if (rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 		ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 		dp->dccps_hc_rx_ccid = new_ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		dp->dccps_hc_tx_ccid = new_ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	if (rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		dp->dccps_r_seq_win = seq_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 		/* propagate changes to update SWL/SWH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 		dccp_update_gsr(sk, dp->dccps_gsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 		dp->dccps_l_seq_win = seq_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		/* propagate changes to update AWL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 		dccp_update_gss(sk, dp->dccps_gss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static int dccp_hdlr_ack_ratio(struct sock *sk, u64 ratio, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	if (rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 		dccp_sk(sk)->dccps_r_ack_ratio = ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		dccp_sk(sk)->dccps_l_ack_ratio = ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) static int dccp_hdlr_ackvec(struct sock *sk, u64 enable, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	if (rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		if (enable && dp->dccps_hc_rx_ackvec == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 			dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 			if (dp->dccps_hc_rx_ackvec == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		} else if (!enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 			dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 			dp->dccps_hc_rx_ackvec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) static int dccp_hdlr_ndp(struct sock *sk, u64 enable, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	if (!rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		dccp_sk(sk)->dccps_send_ndp_count = (enable > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * Minimum Checksum Coverage is located at the RX side (9.2.1). This means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * `rx' holds when the sending peer informs about his partial coverage via a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * ChangeR() option. In the other case, we are the sender and the receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * announces its coverage via ChangeL() options. The policy here is to honour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * such communication by enabling the corresponding partial coverage - but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  * if it has not been set manually before; the warning here means that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  * packets will be dropped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static int dccp_hdlr_min_cscov(struct sock *sk, u64 cscov, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	if (rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		dp->dccps_pcrlen = cscov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		if (dp->dccps_pcslen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 			dp->dccps_pcslen = cscov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		else if (cscov > dp->dccps_pcslen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 			DCCP_WARN("CsCov %u too small, peer requires >= %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 				  dp->dccps_pcslen, (u8)cscov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	u8			feat_num;		/* DCCPF_xxx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	enum dccp_feat_type	rxtx;			/* RX or TX  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	enum dccp_feat_type	reconciliation;		/* SP or NN  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	u8			default_value;		/* as in 6.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	int (*activation_hdlr)(struct sock *sk, u64 val, bool rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)  *    Lookup table for location and type of features (from RFC 4340/4342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  *  +--------------------------+----+-----+----+----+---------+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  *  | Feature                  | Location | Reconc. | Initial |  Section  |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  *  |                          | RX | TX  | SP | NN |  Value  | Reference |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  *  +--------------------------+----+-----+----+----+---------+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)  *  | DCCPF_CCID               |    |  X  | X  |    |   2     | 10        |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)  *  | DCCPF_SHORT_SEQNOS       |    |  X  | X  |    |   0     |  7.6.1    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  *  | DCCPF_SEQUENCE_WINDOW    |    |  X  |    | X  | 100     |  7.5.2    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  *  | DCCPF_ECN_INCAPABLE      | X  |     | X  |    |   0     | 12.1      |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  *  | DCCPF_ACK_RATIO          |    |  X  |    | X  |   2     | 11.3      |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  *  | DCCPF_SEND_ACK_VECTOR    | X  |     | X  |    |   0     | 11.5      |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  *  | DCCPF_SEND_NDP_COUNT     |    |  X  | X  |    |   0     |  7.7.2    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  *  | DCCPF_MIN_CSUM_COVER     | X  |     | X  |    |   0     |  9.2.1    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  *  | DCCPF_DATA_CHECKSUM      | X  |     | X  |    |   0     |  9.3.1    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  *  | DCCPF_SEND_LEV_RATE      | X  |     | X  |    |   0     | 4342/8.4  |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  *  +--------------------------+----+-----+----+----+---------+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) } dccp_feat_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	{ DCCPF_CCID,		 FEAT_AT_TX, FEAT_SP, 2,   dccp_hdlr_ccid     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	{ DCCPF_SHORT_SEQNOS,	 FEAT_AT_TX, FEAT_SP, 0,   NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	{ DCCPF_SEQUENCE_WINDOW, FEAT_AT_TX, FEAT_NN, 100, dccp_hdlr_seq_win  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	{ DCCPF_ECN_INCAPABLE,	 FEAT_AT_RX, FEAT_SP, 0,   NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	{ DCCPF_ACK_RATIO,	 FEAT_AT_TX, FEAT_NN, 2,   dccp_hdlr_ack_ratio},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	{ DCCPF_SEND_ACK_VECTOR, FEAT_AT_RX, FEAT_SP, 0,   dccp_hdlr_ackvec   },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	{ DCCPF_SEND_NDP_COUNT,  FEAT_AT_TX, FEAT_SP, 0,   dccp_hdlr_ndp      },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	{ DCCPF_MIN_CSUM_COVER,  FEAT_AT_RX, FEAT_SP, 0,   dccp_hdlr_min_cscov},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	{ DCCPF_DATA_CHECKSUM,	 FEAT_AT_RX, FEAT_SP, 0,   NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	{ DCCPF_SEND_LEV_RATE,	 FEAT_AT_RX, FEAT_SP, 0,   NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #define DCCP_FEAT_SUPPORTED_MAX		ARRAY_SIZE(dccp_feat_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * dccp_feat_index  -  Hash function to map feature number into array position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * @feat_num: feature to hash, one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * Returns consecutive array index or -1 if the feature is not understood.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static int dccp_feat_index(u8 feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	/* The first 9 entries are occupied by the types from RFC 4340, 6.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	if (feat_num > DCCPF_RESERVED && feat_num <= DCCPF_DATA_CHECKSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		return feat_num - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	 * Other features: add cases for new feature types here after adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	 * them to the above table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	switch (feat_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	case DCCPF_SEND_LEV_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			return DCCP_FEAT_SUPPORTED_MAX - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) static u8 dccp_feat_type(u8 feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int idx = dccp_feat_index(feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		return FEAT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	return dccp_feat_table[idx].reconciliation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) static int dccp_feat_default_value(u8 feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	int idx = dccp_feat_index(feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	 * There are no default values for unknown features, so encountering a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	 * negative index here indicates a serious problem somewhere else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	DCCP_BUG_ON(idx < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211)  *	Debugging and verbose-printing section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static const char *dccp_feat_fname(const u8 feat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	static const char *const feature_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		[DCCPF_RESERVED]	= "Reserved",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		[DCCPF_CCID]		= "CCID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		[DCCPF_SEQUENCE_WINDOW]	= "Sequence Window",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		[DCCPF_ECN_INCAPABLE]	= "ECN Incapable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		[DCCPF_ACK_RATIO]	= "Ack Ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		[DCCPF_SEND_ACK_VECTOR]	= "Send ACK Vector",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		[DCCPF_SEND_NDP_COUNT]	= "Send NDP Count",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		[DCCPF_MIN_CSUM_COVER]	= "Min. Csum Coverage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		[DCCPF_DATA_CHECKSUM]	= "Send Data Checksum",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		return feature_names[DCCPF_RESERVED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (feat ==  DCCPF_SEND_LEV_RATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		return "Send Loss Event Rate";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (feat >= DCCPF_MIN_CCID_SPECIFIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		return "CCID-specific";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	return feature_names[feat];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) static const char *const dccp_feat_sname[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	"DEFAULT", "INITIALISING", "CHANGING", "UNSTABLE", "STABLE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) #ifdef CONFIG_IP_DCCP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) static const char *dccp_feat_oname(const u8 opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	case DCCPO_CHANGE_L:  return "Change_L";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	case DCCPO_CONFIRM_L: return "Confirm_L";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	case DCCPO_CHANGE_R:  return "Change_R";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	case DCCPO_CONFIRM_R: return "Confirm_R";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) static void dccp_feat_printval(u8 feat_num, dccp_feat_val const *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	u8 i, type = dccp_feat_type(feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (val == NULL || (type == FEAT_SP && val->sp.vec == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		dccp_pr_debug_cat("(NULL)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	else if (type == FEAT_SP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		for (i = 0; i < val->sp.len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			dccp_pr_debug_cat("%s%u", i ? " " : "", val->sp.vec[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	else if (type == FEAT_NN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		dccp_pr_debug_cat("%llu", (unsigned long long)val->nn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		dccp_pr_debug_cat("unknown type %u", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) static void dccp_feat_printvals(u8 feat_num, u8 *list, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	u8 type = dccp_feat_type(feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	dccp_feat_val fval = { .sp.vec = list, .sp.len = len };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (type == FEAT_NN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		fval.nn = dccp_decode_value_var(list, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	dccp_feat_printval(feat_num, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) static void dccp_feat_print_entry(struct dccp_feat_entry const *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	dccp_debug("   * %s %s = ", entry->is_local ? "local" : "remote",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 				    dccp_feat_fname(entry->feat_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	dccp_feat_printval(entry->feat_num, &entry->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	dccp_pr_debug_cat(", state=%s %s\n", dccp_feat_sname[entry->state],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			  entry->needs_confirm ? "(Confirm pending)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) #define dccp_feat_print_opt(opt, feat, val, len, mandatory)	do {	      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	dccp_pr_debug("%s(%s, ", dccp_feat_oname(opt), dccp_feat_fname(feat));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	dccp_feat_printvals(feat, val, len);				      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	dccp_pr_debug_cat(") %s\n", mandatory ? "!" : "");	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) #define dccp_feat_print_fnlist(fn_list)  {		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	const struct dccp_feat_entry *___entry;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	dccp_pr_debug("List Dump:\n");			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	list_for_each_entry(___entry, fn_list, node)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		dccp_feat_print_entry(___entry);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) #else	/* ! CONFIG_IP_DCCP_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) #define dccp_feat_print_opt(opt, feat, val, len, mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) #define dccp_feat_print_fnlist(fn_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) static int __dccp_feat_activate(struct sock *sk, const int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 				const bool is_local, dccp_feat_val const *fval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	bool rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	if (idx < 0 || idx >= DCCP_FEAT_SUPPORTED_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	if (dccp_feat_table[idx].activation_hdlr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (fval == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		val = dccp_feat_table[idx].default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	} else if (dccp_feat_table[idx].reconciliation == FEAT_SP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		if (fval->sp.vec == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 			 * This can happen when an empty Confirm is sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			 * for an SP (i.e. known) feature. In this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			 * we would be using the default anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			DCCP_CRIT("Feature #%d undefined: using default", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			val = dccp_feat_table[idx].default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			val = fval->sp.vec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		val = fval->nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	/* Location is RX if this is a local-RX or remote-TX feature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	rx = (is_local == (dccp_feat_table[idx].rxtx == FEAT_AT_RX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	dccp_debug("   -> activating %s %s, %sval=%llu\n", rx ? "RX" : "TX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		   dccp_feat_fname(dccp_feat_table[idx].feat_num),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		   fval ? "" : "default ",  (unsigned long long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	return dccp_feat_table[idx].activation_hdlr(sk, val, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345)  * dccp_feat_activate  -  Activate feature value on socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346)  * @sk: fully connected DCCP socket (after handshake is complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347)  * @feat_num: feature to activate, one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  * @local: whether local (1) or remote (0) @feat_num is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349)  * @fval: the value (SP or NN) to activate, or NULL to use the default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351)  * For general use this function is preferable over __dccp_feat_activate().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) static int dccp_feat_activate(struct sock *sk, u8 feat_num, bool local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			      dccp_feat_val const *fval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	return __dccp_feat_activate(sk, dccp_feat_index(feat_num), local, fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /* Test for "Req'd" feature (RFC 4340, 6.4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static inline int dccp_feat_must_be_understood(u8 feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	return	feat_num == DCCPF_CCID || feat_num == DCCPF_SHORT_SEQNOS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		feat_num == DCCPF_SEQUENCE_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) /* copy constructor, fval must not already contain allocated memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) static int dccp_feat_clone_sp_val(dccp_feat_val *fval, u8 const *val, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	fval->sp.len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	if (fval->sp.len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		fval->sp.vec = kmemdup(val, len, gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		if (fval->sp.vec == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			fval->sp.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) static void dccp_feat_val_destructor(u8 feat_num, dccp_feat_val *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (unlikely(val == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	if (dccp_feat_type(feat_num) == FEAT_SP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		kfree(val->sp.vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	memset(val, 0, sizeof(*val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) static struct dccp_feat_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	      dccp_feat_clone_entry(struct dccp_feat_entry const *original)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	struct dccp_feat_entry *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	u8 type = dccp_feat_type(original->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	if (type == FEAT_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	new = kmemdup(original, sizeof(struct dccp_feat_entry), gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	if (type == FEAT_SP && dccp_feat_clone_sp_val(&new->val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 						      original->val.sp.vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 						      original->val.sp.len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	if (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		dccp_feat_val_destructor(entry->feat_num, &entry->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420)  * List management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)  * Feature negotiation lists rely on and maintain the following invariants:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)  * - each feat_num in the list is known, i.e. we know its type and default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)  * - each feat_num/is_local combination is unique (old entries are overwritten)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  * - SP values are always freshly allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  * - list is sorted in increasing order of feature number (faster lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 						     u8 feat_num, bool is_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	list_for_each_entry(entry, fn_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		if (entry->feat_num == feat_num && entry->is_local == is_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		else if (entry->feat_num > feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  * dccp_feat_entry_new  -  Central list update routine (called by all others)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  * @head:  list to add to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)  * @feat:  feature number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  * @local: whether the local (1) or remote feature with number @feat is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448)  * This is the only constructor and serves to ensure the above invariants.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static struct dccp_feat_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	      dccp_feat_entry_new(struct list_head *head, u8 feat, bool local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	list_for_each_entry(entry, head, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		if (entry->feat_num == feat && entry->is_local == local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			dccp_feat_val_destructor(entry->feat_num, &entry->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		} else if (entry->feat_num > feat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			head = &entry->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	entry = kmalloc(sizeof(*entry), gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	if (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		entry->feat_num = feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		entry->is_local = local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		list_add_tail(&entry->node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * dccp_feat_push_change  -  Add/overwrite a Change option in the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * @fn_list: feature-negotiation list to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  * @local: whether local (1) or remote (0) @feat_num is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)  * @mandatory: whether to use Mandatory feature negotiation options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479)  * @fval: pointer to NN/SP value to be inserted (will be copied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				 u8 mandatory, dccp_feat_val *fval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	new->feat_num	     = feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	new->is_local	     = local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	new->state	     = FEAT_INITIALISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	new->needs_confirm   = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	new->empty_confirm   = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	new->val	     = *fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	new->needs_mandatory = mandatory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  * dccp_feat_push_confirm  -  Add a Confirm entry to the FN list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  * @fn_list: feature-negotiation list to add to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * @local: whether local (1) or remote (0) @feat_num is being confirmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  * @fval: pointer to NN/SP value to be inserted or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  * Returns 0 on success, a Reset code for further processing otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) static int dccp_feat_push_confirm(struct list_head *fn_list, u8 feat, u8 local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 				  dccp_feat_val *fval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		return DCCP_RESET_CODE_TOO_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	new->feat_num	     = feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	new->is_local	     = local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	new->state	     = FEAT_STABLE;	/* transition in 6.6.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	new->needs_confirm   = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	new->empty_confirm   = (fval == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	new->val.nn	     = 0;		/* zeroes the whole structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (!new->empty_confirm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		new->val     = *fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	new->needs_mandatory = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) static int dccp_push_empty_confirm(struct list_head *fn_list, u8 feat, u8 local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	return dccp_feat_push_confirm(fn_list, feat, local, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) static inline void dccp_feat_list_pop(struct dccp_feat_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	list_del(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	dccp_feat_entry_destructor(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) void dccp_feat_list_purge(struct list_head *fn_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	struct dccp_feat_entry *entry, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	list_for_each_entry_safe(entry, next, fn_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		dccp_feat_entry_destructor(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	INIT_LIST_HEAD(fn_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) EXPORT_SYMBOL_GPL(dccp_feat_list_purge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) /* generate @to as full clone of @from - @to must not contain any nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) int dccp_feat_clone_list(struct list_head const *from, struct list_head *to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	struct dccp_feat_entry *entry, *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	INIT_LIST_HEAD(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	list_for_each_entry(entry, from, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		new = dccp_feat_clone_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			goto cloning_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		list_add_tail(&new->node, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) cloning_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	dccp_feat_list_purge(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)  * dccp_feat_valid_nn_length  -  Enforce length constraints on NN options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  * @feat_num: feature to return length of, one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  * Length is between 0 and %DCCP_OPTVAL_MAXLEN. Used for outgoing packets only,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  * incoming options are accepted as long as their values are valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) static u8 dccp_feat_valid_nn_length(u8 feat_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (feat_num == DCCPF_ACK_RATIO)	/* RFC 4340, 11.3 and 6.6.8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (feat_num == DCCPF_SEQUENCE_WINDOW)	/* RFC 4340, 7.5.2 and 6.5  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		return 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) static u8 dccp_feat_is_valid_nn_val(u8 feat_num, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	switch (feat_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	case DCCPF_ACK_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		return val <= DCCPF_ACK_RATIO_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	case DCCPF_SEQUENCE_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		return val >= DCCPF_SEQ_WMIN && val <= DCCPF_SEQ_WMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return 0;	/* feature unknown - so we can't tell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) /* check that SP values are within the ranges defined in RFC 4340 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) static u8 dccp_feat_is_valid_sp_val(u8 feat_num, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	switch (feat_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	case DCCPF_CCID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		return val == DCCPC_CCID2 || val == DCCPC_CCID3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	/* Type-check Boolean feature values: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	case DCCPF_SHORT_SEQNOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	case DCCPF_ECN_INCAPABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	case DCCPF_SEND_ACK_VECTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	case DCCPF_SEND_NDP_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	case DCCPF_DATA_CHECKSUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	case DCCPF_SEND_LEV_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		return val < 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	case DCCPF_MIN_CSUM_COVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		return val < 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	return 0;			/* feature unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static u8 dccp_feat_sp_list_ok(u8 feat_num, u8 const *sp_list, u8 sp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (sp_list == NULL || sp_len < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	while (sp_len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		if (!dccp_feat_is_valid_sp_val(feat_num, *sp_list++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * dccp_feat_insert_opts  -  Generate FN options from current list state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  * @skb: next sk_buff to be sent to the peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)  * @dp: for client during handshake and general negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * @dreq: used by the server only (all Changes/Confirms in LISTEN/RESPOND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) int dccp_feat_insert_opts(struct dccp_sock *dp, struct dccp_request_sock *dreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			  struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	struct list_head *fn = dreq ? &dreq->dreq_featneg : &dp->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	struct dccp_feat_entry *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	u8 opt, type, len, *ptr, nn_in_nbo[DCCP_OPTVAL_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	bool rpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	/* put entries into @skb in the order they appear in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	list_for_each_entry_safe_reverse(pos, next, fn, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		opt  = dccp_feat_genopt(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		type = dccp_feat_type(pos->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		rpt  = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		if (pos->empty_confirm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			if (type == FEAT_SP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				len = pos->val.sp.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				ptr = pos->val.sp.vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				rpt = pos->needs_confirm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			} else if (type == FEAT_NN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 				len = dccp_feat_valid_nn_length(pos->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 				ptr = nn_in_nbo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				dccp_encode_value_var(pos->val.nn, ptr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 				DCCP_BUG("unknown feature %u", pos->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		dccp_feat_print_opt(opt, pos->feat_num, ptr, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		if (pos->needs_mandatory && dccp_insert_option_mandatory(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		if (skb->sk->sk_state == DCCP_OPEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		    (opt == DCCPO_CONFIRM_R || opt == DCCPO_CONFIRM_L)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			 * Confirms don't get retransmitted (6.6.3) once the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			 * connection is in state OPEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			dccp_feat_list_pop(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			 * Enter CHANGING after transmitting the Change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			 * option (6.6.2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 			if (pos->state == FEAT_INITIALISING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 				pos->state = FEAT_CHANGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  * __feat_register_nn  -  Register new NN value on socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  * @fn: feature-negotiation list to register with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)  * @feat: an NN feature from %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  * @mandatory: use Mandatory option if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  * @nn_val: value to register (restricted to 4 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)  * Note that NN features are local by definition (RFC 4340, 6.3.2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) static int __feat_register_nn(struct list_head *fn, u8 feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			      u8 mandatory, u64 nn_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	dccp_feat_val fval = { .nn = nn_val };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	if (dccp_feat_type(feat) != FEAT_NN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	    !dccp_feat_is_valid_nn_val(feat, nn_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	/* Don't bother with default values, they will be activated anyway. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	if (nn_val - (u64)dccp_feat_default_value(feat) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	return dccp_feat_push_change(fn, feat, 1, mandatory, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)  * __feat_register_sp  -  Register new SP value/list on socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  * @fn: feature-negotiation list to register with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)  * @feat: an SP feature from %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719)  * @is_local: whether the local (1) or the remote (0) @feat is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)  * @mandatory: use Mandatory option if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721)  * @sp_val: SP value followed by optional preference list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722)  * @sp_len: length of @sp_val in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) static int __feat_register_sp(struct list_head *fn, u8 feat, u8 is_local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			      u8 mandatory, u8 const *sp_val, u8 sp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	dccp_feat_val fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (dccp_feat_type(feat) != FEAT_SP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	    !dccp_feat_sp_list_ok(feat, sp_val, sp_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	/* Avoid negotiating alien CCIDs by only advertising supported ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (feat == DCCPF_CCID && !ccid_support_check(sp_val, sp_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	if (dccp_feat_clone_sp_val(&fval, sp_val, sp_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	if (dccp_feat_push_change(fn, feat, is_local, mandatory, &fval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		kfree(fval.sp.vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)  * dccp_feat_register_sp  -  Register requests to change SP feature values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750)  * @sk: client or listening socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752)  * @is_local: whether the local (1) or remote (0) @feat is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753)  * @list: array of preferred values, in descending order of preference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754)  * @len: length of @list in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			  u8 const *list, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) {	 /* any changes must be registered before establishing the connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	if (sk->sk_state != DCCP_CLOSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		return -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (dccp_feat_type(feat) != FEAT_SP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	return __feat_register_sp(&dccp_sk(sk)->dccps_featneg, feat, is_local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 				  0, list, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)  * dccp_feat_nn_get  -  Query current/pending value of NN feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769)  * @sk: DCCP socket of an established connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770)  * @feat: NN feature number from %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)  * For a known NN feature, returns value currently being negotiated, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773)  * current (confirmed) value if no negotiation is going on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) u64 dccp_feat_nn_get(struct sock *sk, u8 feat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	if (dccp_feat_type(feat) == FEAT_NN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		entry = dccp_feat_list_lookup(&dp->dccps_featneg, feat, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		if (entry != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			return entry->val.nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		switch (feat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		case DCCPF_ACK_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 			return dp->dccps_l_ack_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		case DCCPF_SEQUENCE_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			return dp->dccps_l_seq_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	DCCP_BUG("attempt to look up unsupported feature %u", feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) EXPORT_SYMBOL_GPL(dccp_feat_nn_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)  * dccp_feat_signal_nn_change  -  Update NN values for an established connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799)  * @sk: DCCP socket of an established connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800)  * @feat: NN feature number from %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801)  * @nn_val: the new value to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  * This function is used to communicate NN updates out-of-band.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	dccp_feat_val fval = { .nn = nn_val };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (sk->sk_state != DCCP_OPEN && sk->sk_state != DCCP_PARTOPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	if (dccp_feat_type(feat) != FEAT_NN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	    !dccp_feat_is_valid_nn_val(feat, nn_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (nn_val == dccp_feat_nn_get(sk, feat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		return 0;	/* already set or negotiation under way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	entry = dccp_feat_list_lookup(fn, feat, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	if (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		dccp_pr_debug("Clobbering existing NN entry %llu -> %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			      (unsigned long long)entry->val.nn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			      (unsigned long long)nn_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		dccp_feat_list_pop(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	inet_csk_schedule_ack(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	return dccp_feat_push_change(fn, feat, 1, 0, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) EXPORT_SYMBOL_GPL(dccp_feat_signal_nn_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  *	Tracking features whose value depend on the choice of CCID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  * This is designed with an extension in mind so that a list walk could be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  * before activating any features. However, the existing framework was found to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  * work satisfactorily up until now, the automatic verification is left open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  * When adding new CCIDs, add a corresponding dependency table here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) static const struct ccid_dependency *dccp_feat_ccid_deps(u8 ccid, bool is_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	static const struct ccid_dependency ccid2_dependencies[2][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		 * CCID2 mandates Ack Vectors (RFC 4341, 4.): as CCID is a TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		 * feature and Send Ack Vector is an RX feature, `is_local'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		 * needs to be reversed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		{	/* Dependencies of the receiver-side (remote) CCID2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				.dependent_feat	= DCCPF_SEND_ACK_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				.is_local	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 				.is_mandatory	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			{ 0, 0, 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		{	/* Dependencies of the sender-side (local) CCID2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				.dependent_feat	= DCCPF_SEND_ACK_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				.is_local	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 				.is_mandatory	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			{ 0, 0, 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	static const struct ccid_dependency ccid3_dependencies[2][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		{	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			 * Dependencies of the receiver-side CCID3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			{	/* locally disable Ack Vectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 				.dependent_feat	= DCCPF_SEND_ACK_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				.is_local	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 				.is_mandatory	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				.val		= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			{	/* see below why Send Loss Event Rate is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 				.dependent_feat	= DCCPF_SEND_LEV_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 				.is_local	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				.is_mandatory	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			{	/* NDP Count is needed as per RFC 4342, 6.1.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 				.dependent_feat	= DCCPF_SEND_NDP_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 				.is_local	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 				.is_mandatory	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			{ 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		{	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			 * CCID3 at the TX side: we request that the HC-receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			 * will not send Ack Vectors (they will be ignored, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			 * Mandatory is not set); we enable Send Loss Event Rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			 * (Mandatory since the implementation does not support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			 * the Loss Intervals option of RFC 4342, 8.6).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			 * The last two options are for peer's information only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 				.dependent_feat	= DCCPF_SEND_ACK_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 				.is_local	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 				.is_mandatory	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 				.val		= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 				.dependent_feat	= DCCPF_SEND_LEV_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 				.is_local	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 				.is_mandatory	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 			{	/* this CCID does not support Ack Ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 				.dependent_feat	= DCCPF_ACK_RATIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 				.is_local	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 				.is_mandatory	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 				.val		= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			{	/* tell receiver we are sending NDP counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 				.dependent_feat	= DCCPF_SEND_NDP_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				.is_local	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 				.is_mandatory	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 				.val		= 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			{ 0, 0, 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	switch (ccid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	case DCCPC_CCID2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		return ccid2_dependencies[is_local];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	case DCCPC_CCID3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		return ccid3_dependencies[is_local];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939)  * dccp_feat_propagate_ccid - Resolve dependencies of features on choice of CCID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940)  * @fn: feature-negotiation list to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941)  * @id: CCID number to track
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942)  * @is_local: whether TX CCID (1) or RX CCID (0) is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944)  * This function needs to be called after registering all other features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) static int dccp_feat_propagate_ccid(struct list_head *fn, u8 id, bool is_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	const struct ccid_dependency *table = dccp_feat_ccid_deps(id, is_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	int i, rc = (table == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	for (i = 0; rc == 0 && table[i].dependent_feat != DCCPF_RESERVED; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		if (dccp_feat_type(table[i].dependent_feat) == FEAT_SP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			rc = __feat_register_sp(fn, table[i].dependent_feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 						    table[i].is_local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 						    table[i].is_mandatory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 						    &table[i].val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 			rc = __feat_register_nn(fn, table[i].dependent_feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 						    table[i].is_mandatory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 						    table[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  * dccp_feat_finalise_settings  -  Finalise settings before starting negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  * @dp: client or listening socket (settings will be inherited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  * This is called after all registrations (socket initialisation, sysctls, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  * sockopt calls), and before sending the first packet containing Change options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)  * (ie. client-Request or server-Response), to ensure internal consistency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) int dccp_feat_finalise_settings(struct dccp_sock *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	struct list_head *fn = &dp->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	int i = 2, ccids[2] = { -1, -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	 * Propagating CCIDs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	 * 1) not useful to propagate CCID settings if this host advertises more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	 *    than one CCID: the choice of CCID  may still change - if this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	 *    the client, or if this is the server and the client sends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	 *    singleton CCID values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	 * 2) since is that propagate_ccid changes the list, we defer changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	 *    the sorted list until after the traversal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	list_for_each_entry(entry, fn, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		if (entry->feat_num == DCCPF_CCID && entry->val.sp.len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 			ccids[entry->is_local] = entry->val.sp.vec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	dccp_feat_print_fnlist(fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998)  * dccp_feat_server_ccid_dependencies  -  Resolve CCID-dependent features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999)  * It is the server which resolves the dependencies once the CCID has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)  * fully negotiated. If no CCID has been negotiated, it uses the default CCID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) int dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct list_head *fn = &dreq->dreq_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	u8 is_local, ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	for (is_local = 0; is_local <= 1; is_local++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		entry = dccp_feat_list_lookup(fn, DCCPF_CCID, is_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		if (entry != NULL && !entry->empty_confirm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			ccid = entry->val.sp.vec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			ccid = dccp_feat_default_value(DCCPF_CCID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		if (dccp_feat_propagate_ccid(fn, ccid, is_local))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* Select the first entry in @servlist that also occurs in @clilist (6.3.1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static int dccp_feat_preflist_match(u8 *servlist, u8 slen, u8 *clilist, u8 clen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	u8 c, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	for (s = 0; s < slen; s++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		for (c = 0; c < clen; c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			if (servlist[s] == clilist[c])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 				return servlist[s];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)  * dccp_feat_prefer  -  Move preferred entry to the start of array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)  * Reorder the @array_len elements in @array so that @preferred_value comes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)  * first. Returns >0 to indicate that @preferred_value does occur in @array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static u8 dccp_feat_prefer(u8 preferred_value, u8 *array, u8 array_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	u8 i, does_occur = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (array != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		for (i = 0; i < array_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			if (array[i] == preferred_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 				array[i] = array[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 				does_occur++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		if (does_occur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			array[0] = preferred_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	return does_occur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)  * dccp_feat_reconcile  -  Reconcile SP preference lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  *  @fv: SP list to reconcile into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  *  @arr: received SP preference list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  *  @len: length of @arr in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  *  @is_server: whether this side is the server (and @fv is the server's list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)  *  @reorder: whether to reorder the list in @fv after reconciling with @arr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)  * When successful, > 0 is returned and the reconciled list is in @fval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)  * A value of 0 means that negotiation failed (no shared entry).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static int dccp_feat_reconcile(dccp_feat_val *fv, u8 *arr, u8 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 			       bool is_server, bool reorder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (!fv->sp.vec || !arr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		DCCP_CRIT("NULL feature value or array");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if (is_server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		rc = dccp_feat_preflist_match(fv->sp.vec, fv->sp.len, arr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		rc = dccp_feat_preflist_match(arr, len, fv->sp.vec, fv->sp.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if (!reorder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	 * Reorder list: used for activating features and in dccp_insert_fn_opt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	return dccp_feat_prefer(rc, fv->sp.vec, fv->sp.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  * dccp_feat_change_recv  -  Process incoming ChangeL/R options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)  * @fn: feature-negotiation list to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)  * @is_mandatory: whether the Change was preceded by a Mandatory option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)  * @opt: %DCCPO_CHANGE_L or %DCCPO_CHANGE_R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)  * @val: NN value or SP value/preference list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)  * @len: length of @val in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)  * @server: whether this node is the server (1) or the client (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 				u8 feat, u8 *val, u8 len, const bool server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	u8 defval, type = dccp_feat_type(feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	const bool local = (opt == DCCPO_CHANGE_R);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	dccp_feat_val fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (len == 0 || type == FEAT_UNKNOWN)		/* 6.1 and 6.6.8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		goto unknown_feature_or_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	 *	Negotiation of NN features: Change R is invalid, so there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	 *	simultaneous negotiation; hence we do not look up in the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (type == FEAT_NN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		if (local || len > sizeof(fval.nn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			goto unknown_feature_or_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		/* 6.3.2: "The feature remote MUST accept any valid value..." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		fval.nn = dccp_decode_value_var(val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		if (!dccp_feat_is_valid_nn_val(feat, fval.nn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			goto unknown_feature_or_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		return dccp_feat_push_confirm(fn, feat, local, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	 *	Unidirectional/simultaneous negotiation of SP features (6.3.1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	entry = dccp_feat_list_lookup(fn, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		 * No particular preferences have been registered. We deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		 * this situation by assuming that all valid values are equally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		 * acceptable, and apply the following checks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		 * - if the peer's list is a singleton, we accept a valid value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		 * - if we are the server, we first try to see if the peer (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		 *   client) advertises the default value. If yes, we use it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		 *   otherwise we accept the preferred value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		 * - else if we are the client, we use the first list element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		if (dccp_feat_clone_sp_val(&fval, val, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			return DCCP_RESET_CODE_TOO_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		if (len > 1 && server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 			defval = dccp_feat_default_value(feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			if (dccp_feat_preflist_match(&defval, 1, val, len) > -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 				fval.sp.vec[0] = defval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		} else if (!dccp_feat_is_valid_sp_val(feat, fval.sp.vec[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			kfree(fval.sp.vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 			goto unknown_feature_or_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		/* Treat unsupported CCIDs like invalid values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		if (feat == DCCPF_CCID && !ccid_support_check(fval.sp.vec, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 			kfree(fval.sp.vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			goto not_valid_or_not_known;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		return dccp_feat_push_confirm(fn, feat, local, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	} else if (entry->state == FEAT_UNSTABLE) {	/* 6.6.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if (dccp_feat_reconcile(&entry->val, val, len, server, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		entry->empty_confirm = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	} else if (is_mandatory) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		return DCCP_RESET_CODE_MANDATORY_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	} else if (entry->state == FEAT_INITIALISING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		 * Failed simultaneous negotiation (server only): try to `save'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		 * the connection by checking whether entry contains the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		 * value for @feat. If yes, send an empty Confirm to signal that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		 * the received Change was not understood - which implies using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		 * the default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		 * If this also fails, we use Reset as the last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		WARN_ON(!server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		defval = dccp_feat_default_value(feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		if (!dccp_feat_reconcile(&entry->val, &defval, 1, server, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 			return DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		entry->empty_confirm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	entry->needs_confirm   = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	entry->needs_mandatory = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	entry->state	       = FEAT_STABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) unknown_feature_or_value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	if (!is_mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		return dccp_push_empty_confirm(fn, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) not_valid_or_not_known:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	return is_mandatory ? DCCP_RESET_CODE_MANDATORY_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			    : DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)  * dccp_feat_confirm_recv  -  Process received Confirm options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)  * @fn: feature-negotiation list to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)  * @is_mandatory: whether @opt was preceded by a Mandatory option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)  * @opt: %DCCPO_CONFIRM_L or %DCCPO_CONFIRM_R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)  * @val: NN value or SP value/preference list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)  * @len: length of @val in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)  * @server: whether this node is server (1) or client (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static u8 dccp_feat_confirm_recv(struct list_head *fn, u8 is_mandatory, u8 opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 				 u8 feat, u8 *val, u8 len, const bool server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	u8 *plist, plen, type = dccp_feat_type(feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	const bool local = (opt == DCCPO_CONFIRM_R);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	struct dccp_feat_entry *entry = dccp_feat_list_lookup(fn, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	dccp_feat_print_opt(opt, feat, val, len, is_mandatory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	if (entry == NULL) {	/* nothing queued: ignore or handle error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		if (is_mandatory && type == FEAT_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			return DCCP_RESET_CODE_MANDATORY_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		if (!local && type == FEAT_NN)		/* 6.3.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			goto confirmation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	if (entry->state != FEAT_CHANGING)		/* 6.6.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	if (len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		if (dccp_feat_must_be_understood(feat))	/* 6.6.7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			goto confirmation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		 * Empty Confirm during connection setup: this means reverting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		 * to the `old' value, which in this case is the default. Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		 * we handle default values automatically when no other values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		 * have been set, we revert to the old value by removing this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		 * entry from the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		dccp_feat_list_pop(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	if (type == FEAT_NN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		if (len > sizeof(entry->val.nn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 			goto confirmation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		if (entry->val.nn == dccp_decode_value_var(val, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 			goto confirmation_succeeded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		DCCP_WARN("Bogus Confirm for non-existing value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		goto confirmation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	 * Parsing SP Confirms: the first element of @val is the preferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	 * SP value which the peer confirms, the remainder depends on @len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	 * Note that only the confirmed value need to be a valid SP value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if (!dccp_feat_is_valid_sp_val(feat, *val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		goto confirmation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if (len == 1) {		/* peer didn't supply a preference list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		plist = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		plen  = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	} else {		/* preferred value + preference list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		plist = val + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		plen  = len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	/* Check whether the peer got the reconciliation right (6.6.8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if (dccp_feat_reconcile(&entry->val, plist, plen, server, 0) != *val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		DCCP_WARN("Confirm selected the wrong value %u\n", *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		return DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	entry->val.sp.vec[0] = *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) confirmation_succeeded:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	entry->state = FEAT_STABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) confirmation_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	DCCP_WARN("Confirmation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	return is_mandatory ? DCCP_RESET_CODE_MANDATORY_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 			    : DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)  * dccp_feat_handle_nn_established  -  Fast-path reception of NN options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)  * @sk:		socket of an established DCCP connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)  * @mandatory:	whether @opt was preceded by a Mandatory option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)  * @opt:	%DCCPO_CHANGE_L | %DCCPO_CONFIRM_R (NN only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)  * @feat:	NN number, one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)  * @val:	NN value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)  * @len:	length of @val in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)  * This function combines the functionality of change_recv/confirm_recv, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)  * the following differences (reset codes are the same):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)  *    - cleanup after receiving the Confirm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)  *    - values are directly activated after successful parsing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)  *    - deliberately restricted to NN features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  * The restriction to NN features is essential since SP features can have non-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)  * predictable outcomes (depending on the remote configuration), and are inter-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)  * dependent (CCIDs for instance cause further dependencies).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static u8 dccp_feat_handle_nn_established(struct sock *sk, u8 mandatory, u8 opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 					  u8 feat, u8 *val, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	const bool local = (opt == DCCPO_CONFIRM_R);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	struct dccp_feat_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	u8 type = dccp_feat_type(feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	dccp_feat_val fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	dccp_feat_print_opt(opt, feat, val, len, mandatory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	/* Ignore non-mandatory unknown and non-NN features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	if (type == FEAT_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		if (local && !mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		goto fast_path_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	} else if (type != FEAT_NN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	 * We don't accept empty Confirms, since in fast-path feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	 * negotiation the values are enabled immediately after sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	 * the Change option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	 * Empty Changes on the other hand are invalid (RFC 4340, 6.1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	if (len == 0 || len > sizeof(fval.nn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		goto fast_path_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	if (opt == DCCPO_CHANGE_L) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		fval.nn = dccp_decode_value_var(val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		if (!dccp_feat_is_valid_nn_val(feat, fval.nn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 			goto fast_path_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		if (dccp_feat_push_confirm(fn, feat, local, &fval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		    dccp_feat_activate(sk, feat, local, &fval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 			return DCCP_RESET_CODE_TOO_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		/* set the `Ack Pending' flag to piggyback a Confirm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		inet_csk_schedule_ack(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	} else if (opt == DCCPO_CONFIRM_R) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		entry = dccp_feat_list_lookup(fn, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		if (entry == NULL || entry->state != FEAT_CHANGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		fval.nn = dccp_decode_value_var(val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		 * Just ignore a value that doesn't match our current value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		 * If the option changes twice within two RTTs, then at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		 * one CONFIRM will be received for the old value after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		 * new CHANGE was sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		if (fval.nn != entry->val.nn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		/* Only activate after receiving the Confirm option (6.6.1). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		dccp_feat_activate(sk, feat, local, &fval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		/* It has been confirmed - so remove the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		dccp_feat_list_pop(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		DCCP_WARN("Received illegal option %u\n", opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		goto fast_path_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) fast_path_unknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	if (!mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		return dccp_push_empty_confirm(fn, feat, local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) fast_path_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	return mandatory ? DCCP_RESET_CODE_MANDATORY_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 			 : DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)  * dccp_feat_parse_options  -  Process Feature-Negotiation Options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)  * @sk: for general use and used by the client during connection setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)  * @dreq: used by the server during connection setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)  * @mandatory: whether @opt was preceded by a Mandatory option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)  * @opt: %DCCPO_CHANGE_L | %DCCPO_CHANGE_R | %DCCPO_CONFIRM_L | %DCCPO_CONFIRM_R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)  * @feat: one of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  * @val: value contents of @opt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)  * @len: length of @val in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)  * Returns 0 on success, a Reset code for ending the connection otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) int dccp_feat_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 			    u8 mandatory, u8 opt, u8 feat, u8 *val, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	struct list_head *fn = dreq ? &dreq->dreq_featneg : &dp->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	bool server = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	switch (sk->sk_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	 *	Negotiation during connection setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	case DCCP_LISTEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		server = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	case DCCP_REQUESTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		case DCCPO_CHANGE_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		case DCCPO_CHANGE_R:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			return dccp_feat_change_recv(fn, mandatory, opt, feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 						     val, len, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		case DCCPO_CONFIRM_R:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 		case DCCPO_CONFIRM_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 			return dccp_feat_confirm_recv(fn, mandatory, opt, feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 						      val, len, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 *	Support for exchanging NN options on an established connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	case DCCP_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	case DCCP_PARTOPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		return dccp_feat_handle_nn_established(sk, mandatory, opt, feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 						       val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	return 0;	/* ignore FN options in all other states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)  * dccp_feat_init  -  Seed feature negotiation with host-specific defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)  * @sk: Socket to initialize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)  * This initialises global defaults, depending on the value of the sysctls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)  * These can later be overridden by registering changes via setsockopt calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)  * The last link in the chain is finalise_settings, to make sure that between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)  * here and the start of actual feature negotiation no inconsistencies enter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)  * All features not appearing below use either defaults or are otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)  * later adjusted through dccp_feat_finalise_settings().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) int dccp_feat_init(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	u8 on = 1, off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		u8 *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	} tx, rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	/* Non-negotiable (NN) features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 				    sysctl_dccp_sequence_window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	/* Server-priority (SP) features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	/* Advertise that short seqnos are not supported (7.6.1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	rc = __feat_register_sp(fn, DCCPF_SHORT_SEQNOS, true, true, &off, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	/* RFC 4340 12.1: "If a DCCP is not ECN capable, ..." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	rc = __feat_register_sp(fn, DCCPF_ECN_INCAPABLE, true, true, &on, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	 * We advertise the available list of CCIDs and reorder according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	 * preferences, to avoid failure resulting from negotiating different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	 * singleton values (which always leads to failure).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	 * These settings can still (later) be overridden via sockopts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	if (ccid_get_builtin_ccids(&tx.val, &tx.len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	if (ccid_get_builtin_ccids(&rx.val, &rx.len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		kfree(tx.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	    !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		goto free_ccid_lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 		goto free_ccid_lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	rc = __feat_register_sp(fn, DCCPF_CCID, false, false, rx.val, rx.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) free_ccid_lists:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	kfree(tx.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	kfree(rx.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) int dccp_feat_activate_values(struct sock *sk, struct list_head *fn_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	struct dccp_feat_entry *cur, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	dccp_feat_val *fvals[DCCP_FEAT_SUPPORTED_MAX][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		 [0 ... DCCP_FEAT_SUPPORTED_MAX-1] = { NULL, NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	list_for_each_entry(cur, fn_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		 * An empty Confirm means that either an unknown feature type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		 * or an invalid value was present. In the first case there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		 * nothing to activate, in the other the default value is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		if (cur->empty_confirm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		idx = dccp_feat_index(cur->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		if (idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 			DCCP_BUG("Unknown feature %u", cur->feat_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 			goto activation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		if (cur->state != FEAT_STABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 			DCCP_CRIT("Negotiation of %s %s failed in state %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 				  cur->is_local ? "local" : "remote",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 				  dccp_feat_fname(cur->feat_num),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 				  dccp_feat_sname[cur->state]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 			goto activation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		fvals[idx][cur->is_local] = &cur->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	 * Activate in decreasing order of index, so that the CCIDs are always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	 * activated as the last feature. This avoids the case where a CCID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	 * relies on the initialisation of one or more features that it depends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	 * on (e.g. Send NDP Count, Send Ack Vector, and Ack Ratio features).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	for (idx = DCCP_FEAT_SUPPORTED_MAX; --idx >= 0;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		if (__dccp_feat_activate(sk, idx, 0, fvals[idx][0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		    __dccp_feat_activate(sk, idx, 1, fvals[idx][1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			DCCP_CRIT("Could not activate %d", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 			goto activation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	/* Clean up Change options which have been confirmed already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	list_for_each_entry_safe(cur, next, fn_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		if (!cur->needs_confirm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			dccp_feat_list_pop(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	dccp_pr_debug("Activation OK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) activation_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	 * We clean up everything that may have been allocated, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	 * it is difficult to track at which stage negotiation failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	 * This is ok, since all allocation functions below are robust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	 * against NULL arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	dp->dccps_hc_rx_ackvec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }