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/options.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  An implementation of the DCCP protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (c) 2005 Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/dccp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "ackvec.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "ccid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "dccp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "feat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) u64 dccp_decode_value_var(const u8 *bf, const u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	u64 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	if (len >= DCCP_OPTVAL_MAXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		value += ((u64)*bf++) << 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		value += ((u64)*bf++) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	if (len > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		value += ((u64)*bf++) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	if (len > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		value += ((u64)*bf++) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (len > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		value += ((u64)*bf++) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		value += *bf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * dccp_parse_options  -  Parse DCCP options present in @skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * @sk: client|server|listening dccp socket (when @dreq != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * @dreq: request socket to use during connection setup, or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * @skb: frame to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		       struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	const struct dccp_hdr *dh = dccp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	unsigned char *opt_ptr = options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	const unsigned char *opt_end = (unsigned char *)dh +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 					(dh->dccph_doff * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct dccp_options_received *opt_recv = &dp->dccps_options_received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned char opt, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned char *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u32 elapsed_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	__be32 opt_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	int mandatory = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	memset(opt_recv, 0, sizeof(*opt_recv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	opt = len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	while (opt_ptr != opt_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		opt   = *opt_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		len   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		/* Check if this isn't a single byte option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		if (opt > DCCPO_MAX_RESERVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			if (opt_ptr == opt_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				goto out_nonsensical_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			len = *opt_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			if (len < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				goto out_nonsensical_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			 * Remove the type and len fields, leaving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			 * just the value size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			len	-= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			value	= opt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			opt_ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			if (opt_ptr > opt_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 				goto out_nonsensical_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		 * CCID-specific options are ignored during connection setup, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		 * negotiation may still be in progress (see RFC 4340, 10.3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		 * The same applies to Ack Vectors, as these depend on the CCID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		    opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			goto ignore_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		case DCCPO_PADDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		case DCCPO_MANDATORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			if (mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			if (pkt_type != DCCP_PKT_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				mandatory = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		case DCCPO_NDP_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			if (len > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				      (unsigned long long)opt_recv->dccpor_ndp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		case DCCPO_CHANGE_L ... DCCPO_CONFIRM_R:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			if (pkt_type == DCCP_PKT_DATA)      /* RFC 4340, 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			rc = dccp_feat_parse_options(sk, dreq, mandatory, opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 						    *value, value + 1, len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 				goto out_featneg_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		case DCCPO_TIMESTAMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			if (len != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			 * RFC 4340 13.1: "The precise time corresponding to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			 * Timestamp Value zero is not specified". We use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			 * zero to indicate absence of a meaningful timestamp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			opt_val = get_unaligned((__be32 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			if (unlikely(opt_val == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				DCCP_WARN("Timestamp with zero value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			if (dreq != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				dreq->dreq_timestamp_echo = ntohl(opt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				dreq->dreq_timestamp_time = dccp_timestamp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				opt_recv->dccpor_timestamp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 					dp->dccps_timestamp_echo = ntohl(opt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				dp->dccps_timestamp_time = dccp_timestamp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				      dccp_role(sk), ntohl(opt_val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 				      (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				      DCCP_SKB_CB(skb)->dccpd_ack_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			/* schedule an Ack in case this sender is quiescent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			inet_csk_schedule_ack(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		case DCCPO_TIMESTAMP_ECHO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			if (len != 4 && len != 6 && len != 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			opt_val = get_unaligned((__be32 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			opt_recv->dccpor_timestamp_echo = ntohl(opt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				      "ackno=%llu", dccp_role(sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				      opt_recv->dccpor_timestamp_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				      len + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 				      (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				      DCCP_SKB_CB(skb)->dccpd_ack_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			value += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			if (len == 4) {		/* no elapsed time included */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				dccp_pr_debug_cat("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			if (len == 6) {		/* 2-byte elapsed time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 				__be16 opt_val2 = get_unaligned((__be16 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				elapsed_time = ntohs(opt_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			} else {		/* 4-byte elapsed time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				opt_val = get_unaligned((__be32 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 				elapsed_time = ntohl(opt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			/* Give precedence to the biggest ELAPSED_TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			if (elapsed_time > opt_recv->dccpor_elapsed_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				opt_recv->dccpor_elapsed_time = elapsed_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		case DCCPO_ELAPSED_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			if (dccp_packet_without_ack(skb))   /* RFC 4340, 13.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			if (len == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				__be16 opt_val2 = get_unaligned((__be16 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				elapsed_time = ntohs(opt_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			} else if (len == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				opt_val = get_unaligned((__be32 *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				elapsed_time = ntohl(opt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			if (elapsed_time > opt_recv->dccpor_elapsed_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				opt_recv->dccpor_elapsed_time = elapsed_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				      dccp_role(sk), elapsed_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 						     pkt_type, opt, value, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		case DCCPO_ACK_VECTOR_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		case DCCPO_ACK_VECTOR_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			if (dccp_packet_without_ack(skb))   /* RFC 4340, 11.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			 * Ack vectors are processed by the TX CCID if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			 * interested. The RX CCID need not parse Ack Vectors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			 * since it is only interested in clearing old state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 						     pkt_type, opt, value, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				  "implemented, ignoring", sk, opt, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ignore_option:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		if (opt != DCCPO_MANDATORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			mandatory = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	/* mandatory was the last byte in option list -> reset connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		goto out_invalid_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) out_nonsensical_length:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/* RFC 4340, 5.8: ignore option and all remaining option space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) out_invalid_option:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	DCCP_INC_STATS(DCCP_MIB_INVALIDOPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	rc = DCCP_RESET_CODE_OPTION_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) out_featneg_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	DCCP_WARN("DCCP(%p): Option %d (len=%d) error=%u\n", sk, opt, len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	DCCP_SKB_CB(skb)->dccpd_reset_code = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) EXPORT_SYMBOL_GPL(dccp_parse_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void dccp_encode_value_var(const u64 value, u8 *to, const u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (len >= DCCP_OPTVAL_MAXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		*to++ = (value & 0xFF0000000000ull) >> 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		*to++ = (value & 0xFF00000000ull) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (len > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		*to++ = (value & 0xFF000000) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (len > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		*to++ = (value & 0xFF0000) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (len > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		*to++ = (value & 0xFF00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		*to++ = (value & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static inline u8 dccp_ndp_len(const u64 ndp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (likely(ndp <= 0xFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	return likely(ndp <= USHRT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int dccp_insert_option(struct sk_buff *skb, const unsigned char option,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		       const void *value, const unsigned char len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	unsigned char *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	to    = skb_push(skb, len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	*to++ = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	*to++ = len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	memcpy(to, value, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) EXPORT_SYMBOL_GPL(dccp_insert_option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	u64 ndp = dp->dccps_ndp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (dccp_non_data_packet(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		++dp->dccps_ndp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		dp->dccps_ndp_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (ndp > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		const int ndp_len = dccp_ndp_len(ndp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		const int len = ndp_len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		DCCP_SKB_CB(skb)->dccpd_opt_len += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		ptr = skb_push(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		*ptr++ = DCCPO_NDP_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		*ptr++ = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		dccp_encode_value_var(ndp, ptr, ndp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static inline int dccp_elapsed_time_len(const u32 elapsed_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int dccp_insert_option_timestamp(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	__be32 now = htonl(dccp_timestamp());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	/* yes this will overflow but that is the point as we want a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	return dccp_insert_option(skb, DCCPO_TIMESTAMP, &now, sizeof(now));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 					     struct dccp_request_sock *dreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 					     struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	__be32 tstamp_echo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	unsigned char *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	u32 elapsed_time, elapsed_time_len, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (dreq != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		elapsed_time = dccp_timestamp() - dreq->dreq_timestamp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		tstamp_echo  = htonl(dreq->dreq_timestamp_echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		dreq->dreq_timestamp_echo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		elapsed_time = dccp_timestamp() - dp->dccps_timestamp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		tstamp_echo  = htonl(dp->dccps_timestamp_echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		dp->dccps_timestamp_echo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	len = 6 + elapsed_time_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	DCCP_SKB_CB(skb)->dccpd_opt_len += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	to    = skb_push(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	*to++ = DCCPO_TIMESTAMP_ECHO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	*to++ = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	memcpy(to, &tstamp_echo, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	to += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (elapsed_time_len == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		const __be16 var16 = htons((u16)elapsed_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		memcpy(to, &var16, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	} else if (elapsed_time_len == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		const __be32 var32 = htonl(elapsed_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		memcpy(to, &var32, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	const u16 buflen = dccp_ackvec_buflen(av);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	/* Figure out how many options do we need to represent the ackvec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	u16 len = buflen + 2 * nr_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	u8 i, nonce = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	const unsigned char *tail, *from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	unsigned char *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (dcb->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		DCCP_WARN("Lacking space for %u bytes on %s packet\n", len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			  dccp_packet_name(dcb->dccpd_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	 * Since Ack Vectors are variable-length, we can not always predict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	 * their size. To catch exception cases where the space is running out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	 * on the skb, a separate Sync is scheduled to carry the Ack Vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	if (len > DCCPAV_MIN_OPTLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	    len + dcb->dccpd_opt_len + skb->len > dp->dccps_mss_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		DCCP_WARN("No space left for Ack Vector (%u) on skb (%u+%u), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			  "MPS=%u ==> reduce payload size?\n", len, skb->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			  dcb->dccpd_opt_len, dp->dccps_mss_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		dp->dccps_sync_scheduled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	dcb->dccpd_opt_len += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	to   = skb_push(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	len  = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	from = av->av_buf + av->av_buf_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	for (i = 0; i < nr_opts; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		int copylen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		if (len > DCCP_SINGLE_OPT_MAXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			copylen = DCCP_SINGLE_OPT_MAXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		 * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		 * its type; ack_nonce is the sum of all individual buf_nonce's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		nonce ^= av->av_buf_nonce[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		*to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		*to++ = copylen + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		/* Check if buf_head wraps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		if (from + copylen > tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			const u16 tailsize = tail - from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			memcpy(to, from, tailsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			to	+= tailsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			len	-= tailsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			copylen	-= tailsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			from	= av->av_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		memcpy(to, from, copylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		from += copylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		to   += copylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		len  -= copylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	 * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (dccp_ackvec_update_records(av, dcb->dccpd_seq, nonce))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	return 0;
^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_insert_option_mandatory  -  Mandatory option (5.8.2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  * @skb: frame into which to insert option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  * Note that since we are using skb_push, this function needs to be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  * _after_ inserting the option it is supposed to influence (stack order).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int dccp_insert_option_mandatory(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (DCCP_SKB_CB(skb)->dccpd_opt_len >= DCCP_MAX_OPT_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	DCCP_SKB_CB(skb)->dccpd_opt_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	*(u8 *)skb_push(skb, 1) = DCCPO_MANDATORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  * dccp_insert_fn_opt  -  Insert single Feature-Negotiation option into @skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)  * @skb: frame to insert feature negotiation option into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  * @type: %DCCPO_CHANGE_L, %DCCPO_CHANGE_R, %DCCPO_CONFIRM_L, %DCCPO_CONFIRM_R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  * @feat: one out of %dccp_feature_numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  * @val: NN value or SP array (preferred element first) to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  * @len: true length of @val in bytes (excluding first element repetition)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  * @repeat_first: whether to copy the first element of @val twice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  * The last argument is used to construct Confirm options, where the preferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)  * value and the preference list appear separately (RFC 4340, 6.3.1). Preference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)  * lists are kept such that the preferred entry is always first, so we only need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)  * to copy twice, and avoid the overhead of cloning into a bigger array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		       u8 *val, u8 len, bool repeat_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	u8 tot_len, *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	/* take the `Feature' field and possible repetition into account */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (len > (DCCP_SINGLE_OPT_MAXLEN - 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		DCCP_WARN("length %u for feature %u too large\n", len, feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	if (unlikely(val == NULL || len == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		len = repeat_first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	tot_len = 3 + repeat_first + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	if (DCCP_SKB_CB(skb)->dccpd_opt_len + tot_len > DCCP_MAX_OPT_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		DCCP_WARN("packet too small for feature %d option!\n", feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	DCCP_SKB_CB(skb)->dccpd_opt_len += tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	to    = skb_push(skb, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	*to++ = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	*to++ = tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	*to++ = feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (repeat_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		*to++ = *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		memcpy(to, val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* The length of all options needs to be a multiple of 4 (5.8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static void dccp_insert_option_padding(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (padding != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		padding = 4 - padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		memset(skb_push(skb, padding), 0, padding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	struct dccp_sock *dp = dccp_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (dp->dccps_send_ndp_count && dccp_insert_option_ndp(sk, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		/* Feature Negotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		if (dccp_feat_insert_opts(dp, NULL, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			 * Obtain RTT sample from Request/Response exchange.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			 * This is currently used for TFRC initialisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			if (dccp_insert_option_timestamp(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		} else if (dccp_ackvec_pending(sk) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			   dccp_insert_option_ackvec(sk, skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (dp->dccps_hc_rx_insert_options) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		dp->dccps_hc_rx_insert_options = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	if (dp->dccps_timestamp_echo != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	    dccp_insert_option_timestamp_echo(dp, NULL, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	dccp_insert_option_padding(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int dccp_insert_options_rsk(struct dccp_request_sock *dreq, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (dccp_feat_insert_opts(NULL, dreq, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	/* Obtain RTT sample from Response/Ack exchange (used by TFRC). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	if (dccp_insert_option_timestamp(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	if (dreq->dreq_timestamp_echo != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	    dccp_insert_option_timestamp_echo(NULL, dreq, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	dccp_insert_option_padding(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }