aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/ackvec.c14
-rw-r--r--net/dccp/ccid.h18
-rw-r--r--net/dccp/ccids/ccid3.c37
-rw-r--r--net/dccp/dccp.h8
-rw-r--r--net/dccp/options.c109
-rw-r--r--net/dccp/output.c18
6 files changed, 102 insertions, 102 deletions
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index 5c76e81658cf..b5981e5f6b00 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -81,15 +81,16 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
81 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) 81 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
82 return -1; 82 return -1;
83 83
84 avr = dccp_ackvec_record_new();
85 if (avr == NULL)
86 return -1;
87
88 dccp_timestamp(sk, &now); 84 dccp_timestamp(sk, &now);
89 elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10; 85 elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10;
90 86
91 if (elapsed_time != 0) 87 if (elapsed_time != 0 &&
92 dccp_insert_option_elapsed_time(sk, skb, elapsed_time); 88 dccp_insert_option_elapsed_time(sk, skb, elapsed_time))
89 return -1;
90
91 avr = dccp_ackvec_record_new();
92 if (avr == NULL)
93 return -1;
93 94
94 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 95 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
95 96
@@ -310,7 +311,6 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
310 av->dccpav_buf_ackno = ackno; 311 av->dccpav_buf_ackno = ackno;
311 dccp_timestamp(sk, &av->dccpav_time); 312 dccp_timestamp(sk, &av->dccpav_time);
312out: 313out:
313 dccp_pr_debug("");
314 return 0; 314 return 0;
315 315
316out_duplicate: 316out_duplicate:
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 3dec50d49731..f7eb6c613414 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -41,9 +41,9 @@ struct ccid_operations {
41 unsigned char option, 41 unsigned char option,
42 unsigned char len, u16 idx, 42 unsigned char len, u16 idx,
43 unsigned char* value); 43 unsigned char* value);
44 void (*ccid_hc_rx_insert_options)(struct sock *sk, 44 int (*ccid_hc_rx_insert_options)(struct sock *sk,
45 struct sk_buff *skb); 45 struct sk_buff *skb);
46 void (*ccid_hc_tx_insert_options)(struct sock *sk, 46 int (*ccid_hc_tx_insert_options)(struct sock *sk,
47 struct sk_buff *skb); 47 struct sk_buff *skb);
48 void (*ccid_hc_tx_packet_recv)(struct sock *sk, 48 void (*ccid_hc_tx_packet_recv)(struct sock *sk,
49 struct sk_buff *skb); 49 struct sk_buff *skb);
@@ -146,18 +146,20 @@ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
146 return rc; 146 return rc;
147} 147}
148 148
149static inline void ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk, 149static inline int ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
150 struct sk_buff *skb) 150 struct sk_buff *skb)
151{ 151{
152 if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL) 152 if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
153 ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb); 153 return ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
154 return 0;
154} 155}
155 156
156static inline void ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, 157static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
157 struct sk_buff *skb) 158 struct sk_buff *skb)
158{ 159{
159 if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL) 160 if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
160 ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb); 161 return ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
162 return 0;
161} 163}
162 164
163static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk, 165static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index ff426a900999..b4a51d0355a5 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -574,16 +574,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
574 } 574 }
575} 575}
576 576
577static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) 577static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
578{ 578{
579 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 579 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
580 580
581 BUG_ON(hctx == NULL); 581 BUG_ON(hctx == NULL);
582 582
583 if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) 583 if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
584 return; 584 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
585 585 return 0;
586 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
587} 586}
588 587
589static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 588static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
@@ -774,7 +773,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
774 dccp_send_ack(sk); 773 dccp_send_ack(sk);
775} 774}
776 775
777static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) 776static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
778{ 777{
779 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 778 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
780 __be32 x_recv, pinv; 779 __be32 x_recv, pinv;
@@ -782,23 +781,27 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
782 BUG_ON(hcrx == NULL); 781 BUG_ON(hcrx == NULL);
783 782
784 if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) 783 if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
785 return; 784 return 0;
786 785
787 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; 786 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
788 787
789 if (dccp_packet_without_ack(skb)) 788 if (dccp_packet_without_ack(skb))
790 return; 789 return 0;
791 790
792 if (hcrx->ccid3hcrx_elapsed_time != 0)
793 dccp_insert_option_elapsed_time(sk, skb,
794 hcrx->ccid3hcrx_elapsed_time);
795 dccp_insert_option_timestamp(sk, skb);
796 x_recv = htonl(hcrx->ccid3hcrx_x_recv); 791 x_recv = htonl(hcrx->ccid3hcrx_x_recv);
797 pinv = htonl(hcrx->ccid3hcrx_pinv); 792 pinv = htonl(hcrx->ccid3hcrx_pinv);
798 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, 793
799 &pinv, sizeof(pinv)); 794 if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
800 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, 795 dccp_insert_option_elapsed_time(sk, skb,
801 &x_recv, sizeof(x_recv)); 796 hcrx->ccid3hcrx_elapsed_time)) ||
797 dccp_insert_option_timestamp(sk, skb) ||
798 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
799 &pinv, sizeof(pinv)) ||
800 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
801 &x_recv, sizeof(x_recv)))
802 return -1;
803
804 return 0;
802} 805}
803 806
804/* calculate first loss interval 807/* calculate first loss interval
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 7f5be0822f3a..34e70fb89d4a 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -326,13 +326,13 @@ static inline int dccp_ack_pending(const struct sock *sk)
326 inet_csk_ack_scheduled(sk); 326 inet_csk_ack_scheduled(sk);
327} 327}
328 328
329extern void dccp_insert_options(struct sock *sk, struct sk_buff *skb); 329extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb);
330extern void dccp_insert_option_elapsed_time(struct sock *sk, 330extern int dccp_insert_option_elapsed_time(struct sock *sk,
331 struct sk_buff *skb, 331 struct sk_buff *skb,
332 u32 elapsed_time); 332 u32 elapsed_time);
333extern void dccp_insert_option_timestamp(struct sock *sk, 333extern int dccp_insert_option_timestamp(struct sock *sk,
334 struct sk_buff *skb); 334 struct sk_buff *skb);
335extern void dccp_insert_option(struct sock *sk, struct sk_buff *skb, 335extern int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
336 unsigned char option, 336 unsigned char option,
337 const void *value, unsigned char len); 337 const void *value, unsigned char len);
338 338
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 0161a18e739a..da1676016484 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -283,17 +283,14 @@ static inline int dccp_ndp_len(const int ndp)
283 return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3; 283 return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
284} 284}
285 285
286void dccp_insert_option(struct sock *sk, struct sk_buff *skb, 286int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
287 const unsigned char option, 287 const unsigned char option,
288 const void *value, const unsigned char len) 288 const void *value, const unsigned char len)
289{ 289{
290 unsigned char *to; 290 unsigned char *to;
291 291
292 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) { 292 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
293 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " 293 return -1;
294 "%d option!\n", option);
295 return;
296 }
297 294
298 DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2; 295 DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
299 296
@@ -302,11 +299,12 @@ void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
302 *to++ = len + 2; 299 *to++ = len + 2;
303 300
304 memcpy(to, value, len); 301 memcpy(to, value, len);
302 return 0;
305} 303}
306 304
307EXPORT_SYMBOL_GPL(dccp_insert_option); 305EXPORT_SYMBOL_GPL(dccp_insert_option);
308 306
309static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb) 307static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
310{ 308{
311 struct dccp_sock *dp = dccp_sk(sk); 309 struct dccp_sock *dp = dccp_sk(sk);
312 int ndp = dp->dccps_ndp_count; 310 int ndp = dp->dccps_ndp_count;
@@ -322,7 +320,7 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
322 const int len = ndp_len + 2; 320 const int len = ndp_len + 2;
323 321
324 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) 322 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
325 return; 323 return -1;
326 324
327 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 325 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
328 326
@@ -331,6 +329,8 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
331 *ptr++ = len; 329 *ptr++ = len;
332 dccp_encode_value_var(ndp, ptr, ndp_len); 330 dccp_encode_value_var(ndp, ptr, ndp_len);
333 } 331 }
332
333 return 0;
334} 334}
335 335
336static inline int dccp_elapsed_time_len(const u32 elapsed_time) 336static inline int dccp_elapsed_time_len(const u32 elapsed_time)
@@ -338,27 +338,18 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time)
338 return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; 338 return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
339} 339}
340 340
341void dccp_insert_option_elapsed_time(struct sock *sk, 341int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb,
342 struct sk_buff *skb, 342 u32 elapsed_time)
343 u32 elapsed_time)
344{ 343{
345#ifdef CONFIG_IP_DCCP_DEBUG
346 struct dccp_sock *dp = dccp_sk(sk);
347 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
348 "CLIENT TX opt: " : "server TX opt: ";
349#endif
350 const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); 344 const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
351 const int len = 2 + elapsed_time_len; 345 const int len = 2 + elapsed_time_len;
352 unsigned char *to; 346 unsigned char *to;
353 347
354 if (elapsed_time_len == 0) 348 if (elapsed_time_len == 0)
355 return; 349 return 0;
356 350
357 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { 351 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
358 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to " 352 return -1;
359 "insert elapsed time!\n");
360 return;
361 }
362 353
363 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 354 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
364 355
@@ -374,10 +365,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk,
374 memcpy(to, &var32, 4); 365 memcpy(to, &var32, 4);
375 } 366 }
376 367
377 dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n", 368 return 0;
378 debug_prefix, elapsed_time,
379 len,
380 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
381} 369}
382 370
383EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); 371EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
@@ -398,7 +386,7 @@ void dccp_timestamp(const struct sock *sk, struct timeval *tv)
398 386
399EXPORT_SYMBOL_GPL(dccp_timestamp); 387EXPORT_SYMBOL_GPL(dccp_timestamp);
400 388
401void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) 389int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
402{ 390{
403 struct timeval tv; 391 struct timeval tv;
404 __be32 now; 392 __be32 now;
@@ -408,19 +396,15 @@ void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
408 /* yes this will overflow but that is the point as we want a 396 /* yes this will overflow but that is the point as we want a
409 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ 397 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
410 398
411 dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now)); 399 return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
412} 400}
413 401
414EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp); 402EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
415 403
416static void dccp_insert_option_timestamp_echo(struct sock *sk, 404static int dccp_insert_option_timestamp_echo(struct sock *sk,
417 struct sk_buff *skb) 405 struct sk_buff *skb)
418{ 406{
419 struct dccp_sock *dp = dccp_sk(sk); 407 struct dccp_sock *dp = dccp_sk(sk);
420#ifdef CONFIG_IP_DCCP_DEBUG
421 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
422 "CLIENT TX opt: " : "server TX opt: ";
423#endif
424 struct timeval now; 408 struct timeval now;
425 __be32 tstamp_echo; 409 __be32 tstamp_echo;
426 u32 elapsed_time; 410 u32 elapsed_time;
@@ -432,11 +416,8 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
432 elapsed_time_len = dccp_elapsed_time_len(elapsed_time); 416 elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
433 len = 6 + elapsed_time_len; 417 len = 6 + elapsed_time_len;
434 418
435 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { 419 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
436 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " 420 return -1;
437 "timestamp echo!\n");
438 return;
439 }
440 421
441 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 422 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
442 423
@@ -456,14 +437,10 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
456 memcpy(to, &var32, 4); 437 memcpy(to, &var32, 4);
457 } 438 }
458 439
459 dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n",
460 debug_prefix, dp->dccps_timestamp_echo,
461 len,
462 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
463
464 dp->dccps_timestamp_echo = 0; 440 dp->dccps_timestamp_echo = 0;
465 dp->dccps_timestamp_time.tv_sec = 0; 441 dp->dccps_timestamp_time.tv_sec = 0;
466 dp->dccps_timestamp_time.tv_usec = 0; 442 dp->dccps_timestamp_time.tv_usec = 0;
443 return 0;
467} 444}
468 445
469static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat, 446static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
@@ -491,7 +468,7 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
491 return 0; 468 return 0;
492} 469}
493 470
494static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb) 471static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
495{ 472{
496 struct dccp_sock *dp = dccp_sk(sk); 473 struct dccp_sock *dp = dccp_sk(sk);
497 struct dccp_opt_pend *opt, *next; 474 struct dccp_opt_pend *opt, *next;
@@ -551,44 +528,48 @@ static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb)
551 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 528 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
552 inet_csk(sk)->icsk_rto, DCCP_RTO_MAX); 529 inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
553 } 530 }
531
532 return 0;
554} 533}
555 534
556void dccp_insert_options(struct sock *sk, struct sk_buff *skb) 535int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
557{ 536{
558 struct dccp_sock *dp = dccp_sk(sk); 537 struct dccp_sock *dp = dccp_sk(sk);
559 538
560 DCCP_SKB_CB(skb)->dccpd_opt_len = 0; 539 DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
561 540
562 if (dp->dccps_options.dccpo_send_ndp_count) 541 if (dp->dccps_options.dccpo_send_ndp_count &&
563 dccp_insert_option_ndp(sk, skb); 542 dccp_insert_option_ndp(sk, skb))
543 return -1;
564 544
565 if (!dccp_packet_without_ack(skb)) { 545 if (!dccp_packet_without_ack(skb)) {
566 if (dp->dccps_options.dccpo_send_ack_vector && 546 if (dp->dccps_options.dccpo_send_ack_vector &&
567 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) 547 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
568 dccp_insert_option_ackvec(sk, skb); 548 dccp_insert_option_ackvec(sk, skb))
569 if (dp->dccps_timestamp_echo != 0) 549 return -1;
570 dccp_insert_option_timestamp_echo(sk, skb); 550
551 if (dp->dccps_timestamp_echo != 0 &&
552 dccp_insert_option_timestamp_echo(sk, skb))
553 return -1;
571 } 554 }
572 555
573 if (dp->dccps_hc_rx_insert_options) { 556 if (dp->dccps_hc_rx_insert_options) {
574 ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb); 557 if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
558 return -1;
575 dp->dccps_hc_rx_insert_options = 0; 559 dp->dccps_hc_rx_insert_options = 0;
576 } 560 }
577 if (dp->dccps_hc_tx_insert_options) { 561 if (dp->dccps_hc_tx_insert_options) {
578 ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb); 562 if (ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb))
563 return -1;
579 dp->dccps_hc_tx_insert_options = 0; 564 dp->dccps_hc_tx_insert_options = 0;
580 } 565 }
581 566
582 /* Feature negotiation */ 567 /* Feature negotiation */
583 switch(DCCP_SKB_CB(skb)->dccpd_type) { 568 /* Data packets can't do feat negotiation */
584 /* Data packets can't do feat negotiation */ 569 if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA &&
585 case DCCP_PKT_DATA: 570 DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATAACK &&
586 case DCCP_PKT_DATAACK: 571 dccp_insert_options_feat(sk, skb))
587 break; 572 return -1;
588 default:
589 dccp_insert_feat(sk, skb);
590 break;
591 }
592 573
593 /* XXX: insert other options when appropriate */ 574 /* XXX: insert other options when appropriate */
594 575
@@ -602,4 +583,6 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
602 DCCP_SKB_CB(skb)->dccpd_opt_len += padding; 583 DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
603 } 584 }
604 } 585 }
586
587 return 0;
605} 588}
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 2975e3d7a48c..7409e4a3abdf 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -83,7 +83,11 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
83 } 83 }
84 84
85 dcb->dccpd_seq = dp->dccps_gss; 85 dcb->dccpd_seq = dp->dccps_gss;
86 dccp_insert_options(sk, skb); 86
87 if (dccp_insert_options(sk, skb)) {
88 kfree_skb(skb);
89 return -EPROTO;
90 }
87 91
88 skb->h.raw = skb_push(skb, dccp_header_size); 92 skb->h.raw = skb_push(skb, dccp_header_size);
89 dh = dccp_hdr(skb); 93 dh = dccp_hdr(skb);
@@ -296,7 +300,11 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
296 dreq = dccp_rsk(req); 300 dreq = dccp_rsk(req);
297 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; 301 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
298 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; 302 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
299 dccp_insert_options(sk, skb); 303
304 if (dccp_insert_options(sk, skb)) {
305 kfree_skb(skb);
306 return NULL;
307 }
300 308
301 skb->h.raw = skb_push(skb, dccp_header_size); 309 skb->h.raw = skb_push(skb, dccp_header_size);
302 310
@@ -344,7 +352,11 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
344 DCCP_SKB_CB(skb)->dccpd_reset_code = code; 352 DCCP_SKB_CB(skb)->dccpd_reset_code = code;
345 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET; 353 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET;
346 DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss; 354 DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss;
347 dccp_insert_options(sk, skb); 355
356 if (dccp_insert_options(sk, skb)) {
357 kfree_skb(skb);
358 return NULL;
359 }
348 360
349 skb->h.raw = skb_push(skb, dccp_header_size); 361 skb->h.raw = skb_push(skb, dccp_header_size);
350 362