diff options
-rw-r--r-- | net/dccp/dccp.h | 1 | ||||
-rw-r--r-- | net/dccp/options.c | 32 | ||||
-rw-r--r-- | net/dccp/output.c | 2 |
3 files changed, 24 insertions, 11 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 3af3320194f0..b138e2019d78 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -428,6 +428,7 @@ static inline int dccp_ack_pending(const struct sock *sk) | |||
428 | } | 428 | } |
429 | 429 | ||
430 | extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb); | 430 | extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb); |
431 | extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*); | ||
431 | extern int dccp_insert_option_elapsed_time(struct sock *sk, | 432 | extern int dccp_insert_option_elapsed_time(struct sock *sk, |
432 | struct sk_buff *skb, | 433 | struct sk_buff *skb, |
433 | u32 elapsed_time); | 434 | u32 elapsed_time); |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 0c996d8c79a3..bedb5daaa3c5 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -537,6 +537,18 @@ static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb) | |||
537 | return 0; | 537 | return 0; |
538 | } | 538 | } |
539 | 539 | ||
540 | /* The length of all options needs to be a multiple of 4 (5.8) */ | ||
541 | static void dccp_insert_option_padding(struct sk_buff *skb) | ||
542 | { | ||
543 | int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4; | ||
544 | |||
545 | if (padding != 0) { | ||
546 | padding = 4 - padding; | ||
547 | memset(skb_push(skb, padding), 0, padding); | ||
548 | DCCP_SKB_CB(skb)->dccpd_opt_len += padding; | ||
549 | } | ||
550 | } | ||
551 | |||
540 | int dccp_insert_options(struct sock *sk, struct sk_buff *skb) | 552 | int dccp_insert_options(struct sock *sk, struct sk_buff *skb) |
541 | { | 553 | { |
542 | struct dccp_sock *dp = dccp_sk(sk); | 554 | struct dccp_sock *dp = dccp_sk(sk); |
@@ -580,18 +592,18 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb) | |||
580 | dccp_insert_option_timestamp_echo(dp, NULL, skb)) | 592 | dccp_insert_option_timestamp_echo(dp, NULL, skb)) |
581 | return -1; | 593 | return -1; |
582 | 594 | ||
583 | /* XXX: insert other options when appropriate */ | 595 | dccp_insert_option_padding(skb); |
596 | return 0; | ||
597 | } | ||
584 | 598 | ||
585 | if (DCCP_SKB_CB(skb)->dccpd_opt_len != 0) { | 599 | int dccp_insert_options_rsk(struct dccp_request_sock *dreq, struct sk_buff *skb) |
586 | /* The length of all options has to be a multiple of 4 */ | 600 | { |
587 | int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4; | 601 | DCCP_SKB_CB(skb)->dccpd_opt_len = 0; |
588 | 602 | ||
589 | if (padding != 0) { | 603 | if (dreq->dreq_timestamp_echo != 0 && |
590 | padding = 4 - padding; | 604 | dccp_insert_option_timestamp_echo(NULL, dreq, skb)) |
591 | memset(skb_push(skb, padding), 0, padding); | 605 | return -1; |
592 | DCCP_SKB_CB(skb)->dccpd_opt_len += padding; | ||
593 | } | ||
594 | } | ||
595 | 606 | ||
607 | dccp_insert_option_padding(skb); | ||
596 | return 0; | 608 | return 0; |
597 | } | 609 | } |
diff --git a/net/dccp/output.c b/net/dccp/output.c index b2e17910930d..5589a5e581f4 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -303,7 +303,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
303 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; | 303 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; |
304 | DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; | 304 | DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; |
305 | 305 | ||
306 | if (dccp_insert_options(sk, skb)) { | 306 | if (dccp_insert_options_rsk(dreq, skb)) { |
307 | kfree_skb(skb); | 307 | kfree_skb(skb); |
308 | return NULL; | 308 | return NULL; |
309 | } | 309 | } |