options.c 16.4 KB
Newer Older
1 2 3 4
/*
 *  net/dccp/options.c
 *
 *  An implementation of the DCCP protocol
I
Ian McDonald 已提交
5 6
 *  Copyright (c) 2005 Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
 *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
7
 *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
8 9 10 11 12 13 14 15 16
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */
#include <linux/dccp.h>
#include <linux/module.h>
#include <linux/types.h>
G
Gerrit Renker 已提交
17
#include <asm/unaligned.h>
18 19 20
#include <linux/kernel.h>
#include <linux/skbuff.h>

21
#include "ackvec.h"
22 23
#include "ccid.h"
#include "dccp.h"
24
#include "feat.h"
25

26
u64 dccp_decode_value_var(const u8 *bf, const u8 len)
27
{
28
	u64 value = 0;
29

30 31 32 33
	if (len >= DCCP_OPTVAL_MAXLEN)
		value += ((u64)*bf++) << 40;
	if (len > 4)
		value += ((u64)*bf++) << 32;
34
	if (len > 3)
35
		value += ((u64)*bf++) << 24;
36
	if (len > 2)
37
		value += ((u64)*bf++) << 16;
38
	if (len > 1)
39
		value += ((u64)*bf++) << 8;
40 41 42 43 44 45
	if (len > 0)
		value += *bf;

	return value;
}

46 47 48 49 50 51 52
/**
 * dccp_parse_options  -  Parse DCCP options present in @skb
 * @sk: client|server|listening dccp socket (when @dreq != NULL)
 * @dreq: request socket to use during connection setup, or NULL
 */
int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
		       struct sk_buff *skb)
53 54 55 56
{
	struct dccp_sock *dp = dccp_sk(sk);
	const struct dccp_hdr *dh = dccp_hdr(skb);
	const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
57
	u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
58 59
	unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
	unsigned char *opt_ptr = options;
60 61
	const unsigned char *opt_end = (unsigned char *)dh +
					(dh->dccph_doff * 4);
62 63 64
	struct dccp_options_received *opt_recv = &dp->dccps_options_received;
	unsigned char opt, len;
	unsigned char *value;
65
	u32 elapsed_time;
G
Gerrit Renker 已提交
66
	__be32 opt_val;
67 68
	int rc;
	int mandatory = 0;
69 70 71

	memset(opt_recv, 0, sizeof(*opt_recv));

72
	opt = len = 0;
73 74 75 76 77 78 79 80
	while (opt_ptr != opt_end) {
		opt   = *opt_ptr++;
		len   = 0;
		value = NULL;

		/* Check if this isn't a single byte option */
		if (opt > DCCPO_MAX_RESERVED) {
			if (opt_ptr == opt_end)
81
				goto out_nonsensical_length;
82 83

			len = *opt_ptr++;
84 85
			if (len < 2)
				goto out_nonsensical_length;
86 87 88 89 90 91 92 93 94
			/*
			 * Remove the type and len fields, leaving
			 * just the value size
			 */
			len	-= 2;
			value	= opt_ptr;
			opt_ptr += len;

			if (opt_ptr > opt_end)
95
				goto out_nonsensical_length;
96 97
		}

98 99 100
		/*
		 * CCID-specific options are ignored during connection setup, as
		 * negotiation may still be in progress (see RFC 4340, 10.3).
101
		 * The same applies to Ack Vectors, as these depend on the CCID.
102
		 */
103
		if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC ||
104
		    opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
105 106
			goto ignore_option;

107 108 109
		switch (opt) {
		case DCCPO_PADDING:
			break;
110 111 112
		case DCCPO_MANDATORY:
			if (mandatory)
				goto out_invalid_option;
113 114
			if (pkt_type != DCCP_PKT_DATA)
				mandatory = 1;
115
			break;
116
		case DCCPO_NDP_COUNT:
117
			if (len > 6)
118 119 120
				goto out_invalid_option;

			opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
121 122
			dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk),
				      (unsigned long long)opt_recv->dccpor_ndp);
123
			break;
G
Gerrit Renker 已提交
124 125
		case DCCPO_CHANGE_L ... DCCPO_CONFIRM_R:
			if (pkt_type == DCCP_PKT_DATA)      /* RFC 4340, 6 */
126
				break;
127 128 129 130
			rc = dccp_feat_parse_options(sk, dreq, mandatory, opt,
						    *value, value + 1, len - 1);
			if (rc)
				goto out_featneg_failed;
131
			break;
132
		case DCCPO_ACK_VECTOR_0:
133
		case DCCPO_ACK_VECTOR_1:
134
			if (dccp_packet_without_ack(skb))   /* RFC 4340, 11.4 */
135
				break;
136
			if (dp->dccps_hc_rx_ackvec != NULL &&
137
			    dccp_ackvec_parse(sk, skb, &ackno, opt, value, len))
138
				goto out_invalid_option;
139 140 141 142
			break;
		case DCCPO_TIMESTAMP:
			if (len != 4)
				goto out_invalid_option;
143 144 145 146 147
			/*
			 * RFC 4340 13.1: "The precise time corresponding to
			 * Timestamp Value zero is not specified". We use
			 * zero to indicate absence of a meaningful timestamp.
			 */
G
Gerrit Renker 已提交
148
			opt_val = get_unaligned((__be32 *)value);
149 150 151 152
			if (unlikely(opt_val == 0)) {
				DCCP_WARN("Timestamp with zero value\n");
				break;
			}
153

154 155 156 157 158 159 160 161
			if (dreq != NULL) {
				dreq->dreq_timestamp_echo = ntohl(opt_val);
				dreq->dreq_timestamp_time = dccp_timestamp();
			} else {
				opt_recv->dccpor_timestamp =
					dp->dccps_timestamp_echo = ntohl(opt_val);
				dp->dccps_timestamp_time = dccp_timestamp();
			}
162
			dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
163
				      dccp_role(sk), ntohl(opt_val),
164
				      (unsigned long long)
165
				      DCCP_SKB_CB(skb)->dccpd_ack_seq);
166 167
			/* schedule an Ack in case this sender is quiescent */
			inet_csk_schedule_ack(sk);
168 169
			break;
		case DCCPO_TIMESTAMP_ECHO:
I
Ian McDonald 已提交
170
			if (len != 4 && len != 6 && len != 8)
171 172
				goto out_invalid_option;

G
Gerrit Renker 已提交
173 174
			opt_val = get_unaligned((__be32 *)value);
			opt_recv->dccpor_timestamp_echo = ntohl(opt_val);
175

176
			dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
177
				      "ackno=%llu", dccp_role(sk),
178
				      opt_recv->dccpor_timestamp_echo,
179 180
				      len + 2,
				      (unsigned long long)
I
Ian McDonald 已提交
181 182
				      DCCP_SKB_CB(skb)->dccpd_ack_seq);

G
Gerrit Renker 已提交
183
			value += 4;
I
Ian McDonald 已提交
184

G
Gerrit Renker 已提交
185
			if (len == 4) {		/* no elapsed time included */
186
				dccp_pr_debug_cat("\n");
187
				break;
188
			}
189

G
Gerrit Renker 已提交
190 191 192 193 194 195 196
			if (len == 6) {		/* 2-byte elapsed time */
				__be16 opt_val2 = get_unaligned((__be16 *)value);
				elapsed_time = ntohs(opt_val2);
			} else {		/* 4-byte elapsed time */
				opt_val = get_unaligned((__be32 *)value);
				elapsed_time = ntohl(opt_val);
			}
197

G
Gerrit Renker 已提交
198
			dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
199

200 201 202
			/* Give precedence to the biggest ELAPSED_TIME */
			if (elapsed_time > opt_recv->dccpor_elapsed_time)
				opt_recv->dccpor_elapsed_time = elapsed_time;
203 204
			break;
		case DCCPO_ELAPSED_TIME:
205 206
			if (dccp_packet_without_ack(skb))   /* RFC 4340, 13.2 */
				break;
I
Ian McDonald 已提交
207

G
Gerrit Renker 已提交
208 209 210
			if (len == 2) {
				__be16 opt_val2 = get_unaligned((__be16 *)value);
				elapsed_time = ntohs(opt_val2);
211
			} else if (len == 4) {
G
Gerrit Renker 已提交
212 213
				opt_val = get_unaligned((__be32 *)value);
				elapsed_time = ntohl(opt_val);
214 215
			} else {
				goto out_invalid_option;
G
Gerrit Renker 已提交
216
			}
217 218 219

			if (elapsed_time > opt_recv->dccpor_elapsed_time)
				opt_recv->dccpor_elapsed_time = elapsed_time;
I
Ian McDonald 已提交
220

221 222
			dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
				      dccp_role(sk), elapsed_time);
223
			break;
224
		case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC:
225
			if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
226
						     pkt_type, opt, value, len))
227 228
				goto out_invalid_option;
			break;
229
		case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
230
			if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
231
						     pkt_type, opt, value, len))
232 233 234
				goto out_invalid_option;
			break;
		default:
235 236
			DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
				  "implemented, ignoring", sk, opt, len);
237
			break;
238
		}
239
ignore_option:
240 241
		if (opt != DCCPO_MANDATORY)
			mandatory = 0;
242 243
	}

244 245 246 247
	/* mandatory was the last byte in option list -> reset connection */
	if (mandatory)
		goto out_invalid_option;

248 249
out_nonsensical_length:
	/* RFC 4340, 5.8: ignore option and all remaining option space */
250 251 252 253
	return 0;

out_invalid_option:
	DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
254 255 256 257
	rc = DCCP_RESET_CODE_OPTION_ERROR;
out_featneg_failed:
	DCCP_WARN("DCCP(%p): Option %d (len=%d) error=%u\n", sk, opt, len, rc);
	DCCP_SKB_CB(skb)->dccpd_reset_code = rc;
258 259 260
	DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt;
	DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0;
	DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0;
261 262 263
	return -1;
}

264 265
EXPORT_SYMBOL_GPL(dccp_parse_options);

266
void dccp_encode_value_var(const u64 value, u8 *to, const u8 len)
267
{
268 269 270 271
	if (len >= DCCP_OPTVAL_MAXLEN)
		*to++ = (value & 0xFF0000000000ull) >> 40;
	if (len > 4)
		*to++ = (value & 0xFF00000000ull) >> 32;
272 273 274 275 276 277 278 279 280 281
	if (len > 3)
		*to++ = (value & 0xFF000000) >> 24;
	if (len > 2)
		*to++ = (value & 0xFF0000) >> 16;
	if (len > 1)
		*to++ = (value & 0xFF00) >> 8;
	if (len > 0)
		*to++ = (value & 0xFF);
}

282
static inline u8 dccp_ndp_len(const u64 ndp)
283
{
284 285 286
	if (likely(ndp <= 0xFF))
		return 1;
	return likely(ndp <= USHORT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6);
287 288
}

289
int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
290 291 292 293 294
			const unsigned char option,
			const void *value, const unsigned char len)
{
	unsigned char *to;

295 296
	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
		return -1;
297 298 299 300 301 302 303 304

	DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;

	to    = skb_push(skb, len + 2);
	*to++ = option;
	*to++ = len + 2;

	memcpy(to, value, len);
305
	return 0;
306 307 308 309
}

EXPORT_SYMBOL_GPL(dccp_insert_option);

310
static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
311 312
{
	struct dccp_sock *dp = dccp_sk(sk);
313
	u64 ndp = dp->dccps_ndp_count;
314 315 316 317 318 319 320 321 322 323 324 325

	if (dccp_non_data_packet(skb))
		++dp->dccps_ndp_count;
	else
		dp->dccps_ndp_count = 0;

	if (ndp > 0) {
		unsigned char *ptr;
		const int ndp_len = dccp_ndp_len(ndp);
		const int len = ndp_len + 2;

		if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
326
			return -1;
327 328 329 330 331 332 333 334

		DCCP_SKB_CB(skb)->dccpd_opt_len += len;

		ptr = skb_push(skb, len);
		*ptr++ = DCCPO_NDP_COUNT;
		*ptr++ = len;
		dccp_encode_value_var(ndp, ptr, ndp_len);
	}
335 336

	return 0;
337 338 339 340
}

static inline int dccp_elapsed_time_len(const u32 elapsed_time)
{
341
	return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
342 343
}

344 345
int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb,
				    u32 elapsed_time)
346 347 348 349 350
{
	const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
	const int len = 2 + elapsed_time_len;
	unsigned char *to;

I
Ian McDonald 已提交
351
	if (elapsed_time_len == 0)
352
		return 0;
353

354 355
	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
		return -1;
356 357 358 359 360 361 362

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to    = skb_push(skb, len);
	*to++ = DCCPO_ELAPSED_TIME;
	*to++ = len;

I
Ian McDonald 已提交
363
	if (elapsed_time_len == 2) {
364
		const __be16 var16 = htons((u16)elapsed_time);
I
Ian McDonald 已提交
365 366
		memcpy(to, &var16, 2);
	} else {
367
		const __be32 var32 = htonl(elapsed_time);
I
Ian McDonald 已提交
368 369
		memcpy(to, &var32, 4);
	}
370

371
	return 0;
372 373
}

374
EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
375

376
int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
377
{
378
	__be32 now = htonl(dccp_timestamp());
I
Ian McDonald 已提交
379 380 381
	/* yes this will overflow but that is the point as we want a
	 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */

382
	return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
383 384
}

385 386
EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);

387 388
static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
					     struct dccp_request_sock *dreq,
389
					     struct sk_buff *skb)
390
{
391
	__be32 tstamp_echo;
392
	unsigned char *to;
393 394 395 396 397 398 399 400 401 402 403 404
	u32 elapsed_time, elapsed_time_len, len;

	if (dreq != NULL) {
		elapsed_time = dccp_timestamp() - dreq->dreq_timestamp_time;
		tstamp_echo  = htonl(dreq->dreq_timestamp_echo);
		dreq->dreq_timestamp_echo = 0;
	} else {
		elapsed_time = dccp_timestamp() - dp->dccps_timestamp_time;
		tstamp_echo  = htonl(dp->dccps_timestamp_echo);
		dp->dccps_timestamp_echo = 0;
	}

405 406 407
	elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
	len = 6 + elapsed_time_len;

408 409
	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
		return -1;
410 411 412 413 414 415 416 417 418

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to    = skb_push(skb, len);
	*to++ = DCCPO_TIMESTAMP_ECHO;
	*to++ = len;

	memcpy(to, &tstamp_echo, 4);
	to += 4;
419

I
Ian McDonald 已提交
420
	if (elapsed_time_len == 2) {
421
		const __be16 var16 = htons((u16)elapsed_time);
I
Ian McDonald 已提交
422 423
		memcpy(to, &var16, 2);
	} else if (elapsed_time_len == 4) {
424
		const __be32 var32 = htonl(elapsed_time);
I
Ian McDonald 已提交
425 426
		memcpy(to, &var32, 4);
	}
427

428
	return 0;
429 430
}

431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
	/* Figure out how many options do we need to represent the ackvec */
	const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN);
	u16 len = av->av_vec_len + 2 * nr_opts;
	u8 i, nonce = 0;
	const unsigned char *tail, *from;
	unsigned char *to;

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
		return -1;

	DCCP_SKB_CB(skb)->dccpd_opt_len += len;

	to   = skb_push(skb, len);
	len  = av->av_vec_len;
	from = av->av_buf + av->av_buf_head;
	tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN;

	for (i = 0; i < nr_opts; ++i) {
		int copylen = len;

		if (len > DCCP_SINGLE_OPT_MAXLEN)
			copylen = DCCP_SINGLE_OPT_MAXLEN;

		/*
		 * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via
		 * its type; ack_nonce is the sum of all individual buf_nonce's.
		 */
		nonce ^= av->av_buf_nonce[i];

		*to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i];
		*to++ = copylen + 2;

		/* Check if buf_head wraps */
		if (from + copylen > tail) {
			const u16 tailsize = tail - from;

			memcpy(to, from, tailsize);
			to	+= tailsize;
			len	-= tailsize;
			copylen	-= tailsize;
			from	= av->av_buf;
		}

		memcpy(to, from, copylen);
		from += copylen;
		to   += copylen;
		len  -= copylen;
	}
	/*
	 * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340.
	 */
	if (dccp_ackvec_update_records(av, DCCP_SKB_CB(skb)->dccpd_seq, nonce))
		return -ENOBUFS;
	return 0;
}

491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
/**
 * dccp_insert_option_mandatory  -  Mandatory option (5.8.2)
 * Note that since we are using skb_push, this function needs to be called
 * _after_ inserting the option it is supposed to influence (stack order).
 */
int dccp_insert_option_mandatory(struct sk_buff *skb)
{
	if (DCCP_SKB_CB(skb)->dccpd_opt_len >= DCCP_MAX_OPT_LEN)
		return -1;

	DCCP_SKB_CB(skb)->dccpd_opt_len++;
	*skb_push(skb, 1) = DCCPO_MANDATORY;
	return 0;
}

506 507 508 509 510 511 512 513 514 515 516 517 518 519
/**
 * dccp_insert_fn_opt  -  Insert single Feature-Negotiation option into @skb
 * @type: %DCCPO_CHANGE_L, %DCCPO_CHANGE_R, %DCCPO_CONFIRM_L, %DCCPO_CONFIRM_R
 * @feat: one out of %dccp_feature_numbers
 * @val: NN value or SP array (preferred element first) to copy
 * @len: true length of @val in bytes (excluding first element repetition)
 * @repeat_first: whether to copy the first element of @val twice
 * The last argument is used to construct Confirm options, where the preferred
 * value and the preference list appear separately (RFC 4340, 6.3.1). Preference
 * lists are kept such that the preferred entry is always first, so we only need
 * to copy twice, and avoid the overhead of cloning into a bigger array.
 */
int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat,
		       u8 *val, u8 len, bool repeat_first)
520
{
521
	u8 tot_len, *to;
522

523 524 525
	/* take the `Feature' field and possible repetition into account */
	if (len > (DCCP_SINGLE_OPT_MAXLEN - 2)) {
		DCCP_WARN("length %u for feature %u too large\n", len, feat);
526 527 528
		return -1;
	}

529 530 531 532 533 534 535 536 537
	if (unlikely(val == NULL || len == 0))
		len = repeat_first = 0;
	tot_len = 3 + repeat_first + len;

	if (DCCP_SKB_CB(skb)->dccpd_opt_len + tot_len > DCCP_MAX_OPT_LEN) {
		DCCP_WARN("packet too small for feature %d option!\n", feat);
		return -1;
	}
	DCCP_SKB_CB(skb)->dccpd_opt_len += tot_len;
538

539
	to    = skb_push(skb, tot_len);
540
	*to++ = type;
541
	*to++ = tot_len;
542 543
	*to++ = feat;

544 545
	if (repeat_first)
		*to++ = *val;
546 547 548 549 550
	if (len)
		memcpy(to, val, len);
	return 0;
}

551 552 553 554 555 556 557 558 559 560 561 562
/* The length of all options needs to be a multiple of 4 (5.8) */
static void dccp_insert_option_padding(struct sk_buff *skb)
{
	int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;

	if (padding != 0) {
		padding = 4 - padding;
		memset(skb_push(skb, padding), 0, padding);
		DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
	}
}

563
int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
564 565 566 567 568
{
	struct dccp_sock *dp = dccp_sk(sk);

	DCCP_SKB_CB(skb)->dccpd_opt_len = 0;

569
	if (dp->dccps_send_ndp_count && dccp_insert_option_ndp(sk, skb))
570
		return -1;
571

572 573 574 575
	if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {

		/* Feature Negotiation */
		if (dccp_feat_insert_opts(dp, NULL, skb))
576
			return -1;
577 578 579 580 581 582 583 584 585

		if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_REQUEST) {
			/*
			 * Obtain RTT sample from Request/Response exchange.
			 * This is currently used in CCID 3 initialisation.
			 */
			if (dccp_insert_option_timestamp(sk, skb))
				return -1;

586
		} else if (dp->dccps_hc_rx_ackvec != NULL &&
587 588 589 590
			   dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
			   dccp_insert_option_ackvec(sk, skb)) {
				return -1;
		}
591 592
	}

593
	if (dp->dccps_hc_rx_insert_options) {
594 595
		if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
			return -1;
596 597
		dp->dccps_hc_rx_insert_options = 0;
	}
598

599 600 601 602
	if (dp->dccps_timestamp_echo != 0 &&
	    dccp_insert_option_timestamp_echo(dp, NULL, skb))
		return -1;

603 604 605
	dccp_insert_option_padding(skb);
	return 0;
}
606

607 608 609
int dccp_insert_options_rsk(struct dccp_request_sock *dreq, struct sk_buff *skb)
{
	DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
610

611 612 613
	if (dccp_feat_insert_opts(NULL, dreq, skb))
		return -1;

614 615 616
	if (dreq->dreq_timestamp_echo != 0 &&
	    dccp_insert_option_timestamp_echo(NULL, dreq, skb))
		return -1;
617

618
	dccp_insert_option_padding(skb);
619
	return 0;
620
}