aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/input.c6
-rw-r--r--net/dccp/ipv4.c8
-rw-r--r--net/dccp/ipv6.c8
-rw-r--r--net/dccp/options.c34
4 files changed, 34 insertions, 22 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index dacd4fd3c63c..08392ed86c25 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -369,7 +369,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
369 if (dccp_check_seqno(sk, skb)) 369 if (dccp_check_seqno(sk, skb))
370 goto discard; 370 goto discard;
371 371
372 if (dccp_parse_options(sk, skb)) 372 if (dccp_parse_options(sk, NULL, skb))
373 goto discard; 373 goto discard;
374 374
375 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 375 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
@@ -427,7 +427,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
427 goto out_invalid_packet; 427 goto out_invalid_packet;
428 } 428 }
429 429
430 if (dccp_parse_options(sk, skb)) 430 if (dccp_parse_options(sk, NULL, skb))
431 goto out_invalid_packet; 431 goto out_invalid_packet;
432 432
433 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */ 433 /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */
@@ -609,7 +609,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
609 /* 609 /*
610 * Step 8: Process options and mark acknowledgeable 610 * Step 8: Process options and mark acknowledgeable
611 */ 611 */
612 if (dccp_parse_options(sk, skb)) 612 if (dccp_parse_options(sk, NULL, skb))
613 goto discard; 613 goto discard;
614 614
615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index db17b83e8d3e..02fc91ce2505 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -600,11 +600,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
600 if (req == NULL) 600 if (req == NULL)
601 goto drop; 601 goto drop;
602 602
603 if (dccp_parse_options(sk, skb))
604 goto drop_and_free;
605
606 dccp_reqsk_init(req, skb); 603 dccp_reqsk_init(req, skb);
607 604
605 dreq = dccp_rsk(req);
606 if (dccp_parse_options(sk, dreq, skb))
607 goto drop_and_free;
608
608 if (security_inet_conn_request(sk, skb, req)) 609 if (security_inet_conn_request(sk, skb, req))
609 goto drop_and_free; 610 goto drop_and_free;
610 611
@@ -621,7 +622,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
621 * In fact we defer setting S.GSR, S.SWL, S.SWH to 622 * In fact we defer setting S.GSR, S.SWL, S.SWH to
622 * dccp_create_openreq_child. 623 * dccp_create_openreq_child.
623 */ 624 */
624 dreq = dccp_rsk(req);
625 dreq->dreq_isr = dcb->dccpd_seq; 625 dreq->dreq_isr = dcb->dccpd_seq;
626 dreq->dreq_iss = dccp_v4_init_sequence(skb); 626 dreq->dreq_iss = dccp_v4_init_sequence(skb);
627 dreq->dreq_service = service; 627 dreq->dreq_service = service;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index a08e2cb11915..f42b75ce7f5c 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -415,11 +415,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
415 if (req == NULL) 415 if (req == NULL)
416 goto drop; 416 goto drop;
417 417
418 if (dccp_parse_options(sk, skb))
419 goto drop_and_free;
420
421 dccp_reqsk_init(req, skb); 418 dccp_reqsk_init(req, skb);
422 419
420 dreq = dccp_rsk(req);
421 if (dccp_parse_options(sk, dreq, skb))
422 goto drop_and_free;
423
423 if (security_inet_conn_request(sk, skb, req)) 424 if (security_inet_conn_request(sk, skb, req))
424 goto drop_and_free; 425 goto drop_and_free;
425 426
@@ -449,7 +450,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
449 * In fact we defer setting S.GSR, S.SWL, S.SWH to 450 * In fact we defer setting S.GSR, S.SWL, S.SWH to
450 * dccp_create_openreq_child. 451 * dccp_create_openreq_child.
451 */ 452 */
452 dreq = dccp_rsk(req);
453 dreq->dreq_isr = dcb->dccpd_seq; 453 dreq->dreq_isr = dcb->dccpd_seq;
454 dreq->dreq_iss = dccp_v6_init_sequence(skb); 454 dreq->dreq_iss = dccp_v6_init_sequence(skb);
455 dreq->dreq_service = service; 455 dreq->dreq_service = service;
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 523250b45ea5..f496d4dc7efc 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -46,7 +46,13 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
46 return value; 46 return value;
47} 47}
48 48
49int dccp_parse_options(struct sock *sk, struct sk_buff *skb) 49/**
50 * dccp_parse_options - Parse DCCP options present in @skb
51 * @sk: client|server|listening dccp socket (when @dreq != NULL)
52 * @dreq: request socket to use during connection setup, or NULL
53 */
54int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
55 struct sk_buff *skb)
50{ 56{
51 struct dccp_sock *dp = dccp_sk(sk); 57 struct dccp_sock *dp = dccp_sk(sk);
52 const struct dccp_hdr *dh = dccp_hdr(skb); 58 const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -92,6 +98,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
92 goto out_invalid_option; 98 goto out_invalid_option;
93 } 99 }
94 100
101 /*
102 * CCID-Specific Options (from RFC 4340, sec. 10.3):
103 *
104 * Option numbers 128 through 191 are for options sent from the
105 * HC-Sender to the HC-Receiver; option numbers 192 through 255
106 * are for options sent from the HC-Receiver to the HC-Sender.
107 *
108 * CCID-specific options are ignored during connection setup, as
109 * negotiation may still be in progress (see RFC 4340, 10.3).
110 *
111 */
112 if (dreq != NULL && opt >= 128)
113 goto ignore_option;
114
95 switch (opt) { 115 switch (opt) {
96 case DCCPO_PADDING: 116 case DCCPO_PADDING:
97 break; 117 break;
@@ -150,6 +170,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
150 opt_val = get_unaligned((__be32 *)value); 170 opt_val = get_unaligned((__be32 *)value);
151 opt_recv->dccpor_timestamp = ntohl(opt_val); 171 opt_recv->dccpor_timestamp = ntohl(opt_val);
152 172
173 /* FIXME: if dreq != NULL, don't store this on listening socket */
153 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; 174 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
154 dp->dccps_timestamp_time = ktime_get_real(); 175 dp->dccps_timestamp_time = ktime_get_real();
155 176
@@ -213,15 +234,6 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
213 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", 234 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
214 dccp_role(sk), elapsed_time); 235 dccp_role(sk), elapsed_time);
215 break; 236 break;
216 /*
217 * From RFC 4340, sec. 10.3:
218 *
219 * Option numbers 128 through 191 are for
220 * options sent from the HC-Sender to the
221 * HC-Receiver; option numbers 192 through 255
222 * are for options sent from the HC-Receiver to
223 * the HC-Sender.
224 */
225 case 128 ... 191: { 237 case 128 ... 191: {
226 const u16 idx = value - options; 238 const u16 idx = value - options;
227 239
@@ -245,7 +257,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
245 "implemented, ignoring", sk, opt, len); 257 "implemented, ignoring", sk, opt, len);
246 break; 258 break;
247 } 259 }
248 260ignore_option:
249 if (opt != DCCPO_MANDATORY) 261 if (opt != DCCPO_MANDATORY)
250 mandatory = 0; 262 mandatory = 0;
251 } 263 }