aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r--net/dccp/ipv6.c613
1 files changed, 292 insertions, 321 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index fc4242c0767c..c7aaa2574f52 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -36,13 +36,6 @@
36/* Socket used for sending RSTs and ACKs */ 36/* Socket used for sending RSTs and ACKs */
37static struct socket *dccp_v6_ctl_socket; 37static struct socket *dccp_v6_ctl_socket;
38 38
39static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
40static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
41 struct request_sock *req);
42static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
43
44static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
45
46static struct inet_connection_sock_af_ops dccp_ipv6_mapped; 39static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
47static struct inet_connection_sock_af_ops dccp_ipv6_af_ops; 40static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
48 41
@@ -65,205 +58,37 @@ static void dccp_v6_hash(struct sock *sk)
65 } 58 }
66} 59}
67 60
68static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len, 61/* add pseudo-header to DCCP checksum stored in skb->csum */
69 struct in6_addr *saddr, 62static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
70 struct in6_addr *daddr, 63 struct in6_addr *saddr,
71 unsigned long base) 64 struct in6_addr *daddr)
72{ 65{
73 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base); 66 return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
74} 67}
75 68
76static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) 69static inline void dccp_v6_send_check(struct sock *sk, int unused_value,
70 struct sk_buff *skb)
77{ 71{
78 const struct dccp_hdr *dh = dccp_hdr(skb); 72 struct ipv6_pinfo *np = inet6_sk(sk);
79 73 struct dccp_hdr *dh = dccp_hdr(skb);
80 if (skb->protocol == htons(ETH_P_IPV6))
81 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
82 skb->nh.ipv6h->saddr.s6_addr32,
83 dh->dccph_dport,
84 dh->dccph_sport);
85 74
86 return secure_dccp_sequence_number(skb->nh.iph->daddr, 75 dccp_csum_outgoing(skb);
87 skb->nh.iph->saddr, 76 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr);
88 dh->dccph_dport,
89 dh->dccph_sport);
90} 77}
91 78
92static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 79static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
93 int addr_len) 80 __be16 sport, __be16 dport )
94{ 81{
95 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr; 82 return secure_tcpv6_sequence_number(saddr, daddr, sport, dport);
96 struct inet_connection_sock *icsk = inet_csk(sk); 83}
97 struct inet_sock *inet = inet_sk(sk);
98 struct ipv6_pinfo *np = inet6_sk(sk);
99 struct dccp_sock *dp = dccp_sk(sk);
100 struct in6_addr *saddr = NULL, *final_p = NULL, final;
101 struct flowi fl;
102 struct dst_entry *dst;
103 int addr_type;
104 int err;
105
106 dp->dccps_role = DCCP_ROLE_CLIENT;
107
108 if (addr_len < SIN6_LEN_RFC2133)
109 return -EINVAL;
110
111 if (usin->sin6_family != AF_INET6)
112 return -EAFNOSUPPORT;
113
114 memset(&fl, 0, sizeof(fl));
115
116 if (np->sndflow) {
117 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
118 IP6_ECN_flow_init(fl.fl6_flowlabel);
119 if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
120 struct ip6_flowlabel *flowlabel;
121 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
122 if (flowlabel == NULL)
123 return -EINVAL;
124 ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
125 fl6_sock_release(flowlabel);
126 }
127 }
128 /*
129 * connect() to INADDR_ANY means loopback (BSD'ism).
130 */
131 if (ipv6_addr_any(&usin->sin6_addr))
132 usin->sin6_addr.s6_addr[15] = 1;
133
134 addr_type = ipv6_addr_type(&usin->sin6_addr);
135
136 if (addr_type & IPV6_ADDR_MULTICAST)
137 return -ENETUNREACH;
138
139 if (addr_type & IPV6_ADDR_LINKLOCAL) {
140 if (addr_len >= sizeof(struct sockaddr_in6) &&
141 usin->sin6_scope_id) {
142 /* If interface is set while binding, indices
143 * must coincide.
144 */
145 if (sk->sk_bound_dev_if &&
146 sk->sk_bound_dev_if != usin->sin6_scope_id)
147 return -EINVAL;
148
149 sk->sk_bound_dev_if = usin->sin6_scope_id;
150 }
151
152 /* Connect to link-local address requires an interface */
153 if (!sk->sk_bound_dev_if)
154 return -EINVAL;
155 }
156
157 ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
158 np->flow_label = fl.fl6_flowlabel;
159
160 /*
161 * DCCP over IPv4
162 */
163 if (addr_type == IPV6_ADDR_MAPPED) {
164 u32 exthdrlen = icsk->icsk_ext_hdr_len;
165 struct sockaddr_in sin;
166
167 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
168
169 if (__ipv6_only_sock(sk))
170 return -ENETUNREACH;
171
172 sin.sin_family = AF_INET;
173 sin.sin_port = usin->sin6_port;
174 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
175
176 icsk->icsk_af_ops = &dccp_ipv6_mapped;
177 sk->sk_backlog_rcv = dccp_v4_do_rcv;
178
179 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
180 if (err) {
181 icsk->icsk_ext_hdr_len = exthdrlen;
182 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
183 sk->sk_backlog_rcv = dccp_v6_do_rcv;
184 goto failure;
185 } else {
186 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
187 inet->saddr);
188 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
189 inet->rcv_saddr);
190 }
191
192 return err;
193 }
194
195 if (!ipv6_addr_any(&np->rcv_saddr))
196 saddr = &np->rcv_saddr;
197
198 fl.proto = IPPROTO_DCCP;
199 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
200 ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
201 fl.oif = sk->sk_bound_dev_if;
202 fl.fl_ip_dport = usin->sin6_port;
203 fl.fl_ip_sport = inet->sport;
204 security_sk_classify_flow(sk, &fl);
205
206 if (np->opt != NULL && np->opt->srcrt != NULL) {
207 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
208
209 ipv6_addr_copy(&final, &fl.fl6_dst);
210 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
211 final_p = &final;
212 }
213
214 err = ip6_dst_lookup(sk, &dst, &fl);
215 if (err)
216 goto failure;
217
218 if (final_p)
219 ipv6_addr_copy(&fl.fl6_dst, final_p);
220
221 err = xfrm_lookup(&dst, &fl, sk, 0);
222 if (err < 0)
223 goto failure;
224
225 if (saddr == NULL) {
226 saddr = &fl.fl6_src;
227 ipv6_addr_copy(&np->rcv_saddr, saddr);
228 }
229
230 /* set the source address */
231 ipv6_addr_copy(&np->saddr, saddr);
232 inet->rcv_saddr = LOOPBACK4_IPV6;
233
234 __ip6_dst_store(sk, dst, NULL, NULL);
235
236 icsk->icsk_ext_hdr_len = 0;
237 if (np->opt != NULL)
238 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
239 np->opt->opt_nflen);
240
241 inet->dport = usin->sin6_port;
242
243 dccp_set_state(sk, DCCP_REQUESTING);
244 err = inet6_hash_connect(&dccp_death_row, sk);
245 if (err)
246 goto late_failure;
247 /* FIXME */
248#if 0
249 dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
250 np->daddr.s6_addr32,
251 inet->sport,
252 inet->dport);
253#endif
254 err = dccp_connect(sk);
255 if (err)
256 goto late_failure;
257 84
258 return 0; 85static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
86{
87 return secure_dccpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
88 skb->nh.ipv6h->saddr.s6_addr32,
89 dccp_hdr(skb)->dccph_dport,
90 dccp_hdr(skb)->dccph_sport );
259 91
260late_failure:
261 dccp_set_state(sk, DCCP_CLOSED);
262 __sk_dst_reset(sk);
263failure:
264 inet->dport = 0;
265 sk->sk_route_caps = 0;
266 return err;
267} 92}
268 93
269static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 94static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
@@ -464,16 +289,12 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
464 if (skb != NULL) { 289 if (skb != NULL) {
465 struct dccp_hdr *dh = dccp_hdr(skb); 290 struct dccp_hdr *dh = dccp_hdr(skb);
466 291
467 dh->dccph_checksum = dccp_v6_check(dh, skb->len, 292 dh->dccph_checksum = dccp_v6_csum_finish(skb,
468 &ireq6->loc_addr, 293 &ireq6->loc_addr,
469 &ireq6->rmt_addr, 294 &ireq6->rmt_addr);
470 csum_partial((char *)dh,
471 skb->len,
472 skb->csum));
473 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); 295 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
474 err = ip6_xmit(sk, skb, &fl, opt, 0); 296 err = ip6_xmit(sk, skb, &fl, opt, 0);
475 if (err == NET_XMIT_CN) 297 err = net_xmit_eval(err);
476 err = 0;
477 } 298 }
478 299
479done: 300done:
@@ -489,32 +310,7 @@ static void dccp_v6_reqsk_destructor(struct request_sock *req)
489 kfree_skb(inet6_rsk(req)->pktopts); 310 kfree_skb(inet6_rsk(req)->pktopts);
490} 311}
491 312
492static struct request_sock_ops dccp6_request_sock_ops = { 313static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
493 .family = AF_INET6,
494 .obj_size = sizeof(struct dccp6_request_sock),
495 .rtx_syn_ack = dccp_v6_send_response,
496 .send_ack = dccp_v6_reqsk_send_ack,
497 .destructor = dccp_v6_reqsk_destructor,
498 .send_reset = dccp_v6_ctl_send_reset,
499};
500
501static struct timewait_sock_ops dccp6_timewait_sock_ops = {
502 .twsk_obj_size = sizeof(struct dccp6_timewait_sock),
503};
504
505static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
506{
507 struct ipv6_pinfo *np = inet6_sk(sk);
508 struct dccp_hdr *dh = dccp_hdr(skb);
509
510 dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
511 len, IPPROTO_DCCP,
512 csum_partial((char *)dh,
513 dh->dccph_doff << 2,
514 skb->csum));
515}
516
517static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
518{ 314{
519 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 315 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
520 const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) + 316 const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
@@ -522,7 +318,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
522 sizeof(struct dccp_hdr_reset); 318 sizeof(struct dccp_hdr_reset);
523 struct sk_buff *skb; 319 struct sk_buff *skb;
524 struct flowi fl; 320 struct flowi fl;
525 u64 seqno; 321 u64 seqno = 0;
526 322
527 if (rxdh->dccph_type == DCCP_PKT_RESET) 323 if (rxdh->dccph_type == DCCP_PKT_RESET)
528 return; 324 return;
@@ -537,9 +333,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
537 333
538 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header); 334 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
539 335
540 skb->h.raw = skb_push(skb, dccp_hdr_reset_len); 336 dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
541 dh = dccp_hdr(skb);
542 memset(dh, 0, dccp_hdr_reset_len);
543 337
544 /* Swap the send and the receive. */ 338 /* Swap the send and the receive. */
545 dh->dccph_type = DCCP_PKT_RESET; 339 dh->dccph_type = DCCP_PKT_RESET;
@@ -551,20 +345,20 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
551 DCCP_SKB_CB(rxskb)->dccpd_reset_code; 345 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
552 346
553 /* See "8.3.1. Abnormal Termination" in RFC 4340 */ 347 /* See "8.3.1. Abnormal Termination" in RFC 4340 */
554 seqno = 0;
555 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 348 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
556 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); 349 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
557 350
558 dccp_hdr_set_seq(dh, seqno); 351 dccp_hdr_set_seq(dh, seqno);
559 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 352 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
560 DCCP_SKB_CB(rxskb)->dccpd_seq); 353
354 dccp_csum_outgoing(skb);
355 dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxskb->nh.ipv6h->saddr,
356 &rxskb->nh.ipv6h->daddr);
561 357
562 memset(&fl, 0, sizeof(fl)); 358 memset(&fl, 0, sizeof(fl));
563 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr); 359 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
564 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr); 360 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
565 dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, 361
566 sizeof(*dh), IPPROTO_DCCP,
567 skb->csum);
568 fl.proto = IPPROTO_DCCP; 362 fl.proto = IPPROTO_DCCP;
569 fl.oif = inet6_iif(rxskb); 363 fl.oif = inet6_iif(rxskb);
570 fl.fl_ip_dport = dh->dccph_dport; 364 fl.fl_ip_dport = dh->dccph_dport;
@@ -584,60 +378,14 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
584 kfree_skb(skb); 378 kfree_skb(skb);
585} 379}
586 380
587static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb, 381static struct request_sock_ops dccp6_request_sock_ops = {
588 struct request_sock *req) 382 .family = AF_INET6,
589{ 383 .obj_size = sizeof(struct dccp6_request_sock),
590 struct flowi fl; 384 .rtx_syn_ack = dccp_v6_send_response,
591 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 385 .send_ack = dccp_reqsk_send_ack,
592 const u32 dccp_hdr_ack_len = sizeof(struct dccp_hdr) + 386 .destructor = dccp_v6_reqsk_destructor,
593 sizeof(struct dccp_hdr_ext) + 387 .send_reset = dccp_v6_ctl_send_reset,
594 sizeof(struct dccp_hdr_ack_bits); 388};
595 struct sk_buff *skb;
596
597 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
598 GFP_ATOMIC);
599 if (skb == NULL)
600 return;
601
602 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
603
604 skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
605 dh = dccp_hdr(skb);
606 memset(dh, 0, dccp_hdr_ack_len);
607
608 /* Build DCCP header and checksum it. */
609 dh->dccph_type = DCCP_PKT_ACK;
610 dh->dccph_sport = rxdh->dccph_dport;
611 dh->dccph_dport = rxdh->dccph_sport;
612 dh->dccph_doff = dccp_hdr_ack_len / 4;
613 dh->dccph_x = 1;
614
615 dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
616 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
617 DCCP_SKB_CB(rxskb)->dccpd_seq);
618
619 memset(&fl, 0, sizeof(fl));
620 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
621 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
622
623 /* FIXME: calculate checksum, IPv4 also should... */
624
625 fl.proto = IPPROTO_DCCP;
626 fl.oif = inet6_iif(rxskb);
627 fl.fl_ip_dport = dh->dccph_dport;
628 fl.fl_ip_sport = dh->dccph_sport;
629 security_req_classify_flow(req, &fl);
630
631 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
632 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
633 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
634 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
635 return;
636 }
637 }
638
639 kfree_skb(skb);
640}
641 389
642static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) 390static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
643{ 391{
@@ -672,7 +420,6 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
672 420
673static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 421static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
674{ 422{
675 struct dccp_sock dp;
676 struct request_sock *req; 423 struct request_sock *req;
677 struct dccp_request_sock *dreq; 424 struct dccp_request_sock *dreq;
678 struct inet6_request_sock *ireq6; 425 struct inet6_request_sock *ireq6;
@@ -704,9 +451,10 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
704 if (req == NULL) 451 if (req == NULL)
705 goto drop; 452 goto drop;
706 453
707 /* FIXME: process options */ 454 if (dccp_parse_options(sk, skb))
455 goto drop_and_free;
708 456
709 dccp_openreq_init(req, &dp, skb); 457 dccp_reqsk_init(req, skb);
710 458
711 if (security_inet_conn_request(sk, skb, req)) 459 if (security_inet_conn_request(sk, skb, req))
712 goto drop_and_free; 460 goto drop_and_free;
@@ -714,7 +462,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
714 ireq6 = inet6_rsk(req); 462 ireq6 = inet6_rsk(req);
715 ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); 463 ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
716 ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); 464 ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
717 req->rcv_wnd = dccp_feat_default_sequence_window;
718 ireq6->pktopts = NULL; 465 ireq6->pktopts = NULL;
719 466
720 if (ipv6_opt_accepted(sk, skb) || 467 if (ipv6_opt_accepted(sk, skb) ||
@@ -733,14 +480,14 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
733 /* 480 /*
734 * Step 3: Process LISTEN state 481 * Step 3: Process LISTEN state
735 * 482 *
736 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 483 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
737 * 484 *
738 * In fact we defer setting S.GSR, S.SWL, S.SWH to 485 * In fact we defer setting S.GSR, S.SWL, S.SWH to
739 * dccp_create_openreq_child. 486 * dccp_create_openreq_child.
740 */ 487 */
741 dreq = dccp_rsk(req); 488 dreq = dccp_rsk(req);
742 dreq->dreq_isr = dcb->dccpd_seq; 489 dreq->dreq_isr = dcb->dccpd_seq;
743 dreq->dreq_iss = dccp_v6_init_sequence(sk, skb); 490 dreq->dreq_iss = dccp_v6_init_sequence(skb);
744 dreq->dreq_service = service; 491 dreq->dreq_service = service;
745 492
746 if (dccp_v6_send_response(sk, req, NULL)) 493 if (dccp_v6_send_response(sk, req, NULL))
@@ -990,18 +737,46 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
990 --ANK (980728) 737 --ANK (980728)
991 */ 738 */
992 if (np->rxopt.all) 739 if (np->rxopt.all)
740 /*
741 * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below
742 * (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example.
743 */
993 opt_skb = skb_clone(skb, GFP_ATOMIC); 744 opt_skb = skb_clone(skb, GFP_ATOMIC);
994 745
995 if (sk->sk_state == DCCP_OPEN) { /* Fast path */ 746 if (sk->sk_state == DCCP_OPEN) { /* Fast path */
996 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) 747 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
997 goto reset; 748 goto reset;
998 if (opt_skb) { 749 if (opt_skb) {
999 /* This is where we would goto ipv6_pktoptions. */ 750 /* XXX This is where we would goto ipv6_pktoptions. */
1000 __kfree_skb(opt_skb); 751 __kfree_skb(opt_skb);
1001 } 752 }
1002 return 0; 753 return 0;
1003 } 754 }
1004 755
756 /*
757 * Step 3: Process LISTEN state
758 * If S.state == LISTEN,
759 * If P.type == Request or P contains a valid Init Cookie option,
760 * (* Must scan the packet's options to check for Init
761 * Cookies. Only Init Cookies are processed here,
762 * however; other options are processed in Step 8. This
763 * scan need only be performed if the endpoint uses Init
764 * Cookies *)
765 * (* Generate a new socket and switch to that socket *)
766 * Set S := new socket for this port pair
767 * S.state = RESPOND
768 * Choose S.ISS (initial seqno) or set from Init Cookies
769 * Initialize S.GAR := S.ISS
770 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
771 * Continue with S.state == RESPOND
772 * (* A Response packet will be generated in Step 11 *)
773 * Otherwise,
774 * Generate Reset(No Connection) unless P.type == Reset
775 * Drop packet and return
776 *
777 * NOTE: the check for the packet types is done in
778 * dccp_rcv_state_process
779 */
1005 if (sk->sk_state == DCCP_LISTEN) { 780 if (sk->sk_state == DCCP_LISTEN) {
1006 struct sock *nsk = dccp_v6_hnd_req(sk, skb); 781 struct sock *nsk = dccp_v6_hnd_req(sk, skb);
1007 782
@@ -1024,13 +799,13 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1024 if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) 799 if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
1025 goto reset; 800 goto reset;
1026 if (opt_skb) { 801 if (opt_skb) {
1027 /* This is where we would goto ipv6_pktoptions. */ 802 /* XXX This is where we would goto ipv6_pktoptions. */
1028 __kfree_skb(opt_skb); 803 __kfree_skb(opt_skb);
1029 } 804 }
1030 return 0; 805 return 0;
1031 806
1032reset: 807reset:
1033 dccp_v6_ctl_send_reset(skb); 808 dccp_v6_ctl_send_reset(sk, skb);
1034discard: 809discard:
1035 if (opt_skb != NULL) 810 if (opt_skb != NULL)
1036 __kfree_skb(opt_skb); 811 __kfree_skb(opt_skb);
@@ -1043,12 +818,20 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1043 const struct dccp_hdr *dh; 818 const struct dccp_hdr *dh;
1044 struct sk_buff *skb = *pskb; 819 struct sk_buff *skb = *pskb;
1045 struct sock *sk; 820 struct sock *sk;
821 int min_cov;
1046 822
1047 /* Step 1: Check header basics: */ 823 /* Step 1: Check header basics */
1048 824
1049 if (dccp_invalid_packet(skb)) 825 if (dccp_invalid_packet(skb))
1050 goto discard_it; 826 goto discard_it;
1051 827
828 /* Step 1: If header checksum is incorrect, drop packet and return. */
829 if (dccp_v6_csum_finish(skb, &skb->nh.ipv6h->saddr,
830 &skb->nh.ipv6h->daddr)) {
831 DCCP_WARN("dropped packet with invalid checksum\n");
832 goto discard_it;
833 }
834
1052 dh = dccp_hdr(skb); 835 dh = dccp_hdr(skb);
1053 836
1054 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); 837 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb);
@@ -1068,11 +851,12 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1068 /* 851 /*
1069 * Step 2: 852 * Step 2:
1070 * If no socket ... 853 * If no socket ...
1071 * Generate Reset(No Connection) unless P.type == Reset
1072 * Drop packet and return
1073 */ 854 */
1074 if (sk == NULL) 855 if (sk == NULL) {
856 dccp_pr_debug("failed to look up flow ID in table and "
857 "get corresponding socket\n");
1075 goto no_dccp_socket; 858 goto no_dccp_socket;
859 }
1076 860
1077 /* 861 /*
1078 * Step 2: 862 * Step 2:
@@ -1080,43 +864,226 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1080 * Generate Reset(No Connection) unless P.type == Reset 864 * Generate Reset(No Connection) unless P.type == Reset
1081 * Drop packet and return 865 * Drop packet and return
1082 */ 866 */
1083 if (sk->sk_state == DCCP_TIME_WAIT) 867 if (sk->sk_state == DCCP_TIME_WAIT) {
1084 goto do_time_wait; 868 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
869 inet_twsk_put(inet_twsk(sk));
870 goto no_dccp_socket;
871 }
872
873 /*
874 * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
875 * o if MinCsCov = 0, only packets with CsCov = 0 are accepted
876 * o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
877 */
878 min_cov = dccp_sk(sk)->dccps_pcrlen;
879 if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov)) {
880 dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
881 dh->dccph_cscov, min_cov);
882 /* FIXME: send Data Dropped option (see also dccp_v4_rcv) */
883 goto discard_and_relse;
884 }
1085 885
1086 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 886 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1087 goto discard_and_relse; 887 goto discard_and_relse;
1088 888
1089 return sk_receive_skb(sk, skb) ? -1 : 0; 889 return sk_receive_skb(sk, skb, 1) ? -1 : 0;
1090 890
1091no_dccp_socket: 891no_dccp_socket:
1092 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 892 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1093 goto discard_it; 893 goto discard_it;
1094 /* 894 /*
1095 * Step 2: 895 * Step 2:
896 * If no socket ...
1096 * Generate Reset(No Connection) unless P.type == Reset 897 * Generate Reset(No Connection) unless P.type == Reset
1097 * Drop packet and return 898 * Drop packet and return
1098 */ 899 */
1099 if (dh->dccph_type != DCCP_PKT_RESET) { 900 if (dh->dccph_type != DCCP_PKT_RESET) {
1100 DCCP_SKB_CB(skb)->dccpd_reset_code = 901 DCCP_SKB_CB(skb)->dccpd_reset_code =
1101 DCCP_RESET_CODE_NO_CONNECTION; 902 DCCP_RESET_CODE_NO_CONNECTION;
1102 dccp_v6_ctl_send_reset(skb); 903 dccp_v6_ctl_send_reset(sk, skb);
1103 } 904 }
1104discard_it:
1105
1106 /*
1107 * Discard frame
1108 */
1109 905
906discard_it:
1110 kfree_skb(skb); 907 kfree_skb(skb);
1111 return 0; 908 return 0;
1112 909
1113discard_and_relse: 910discard_and_relse:
1114 sock_put(sk); 911 sock_put(sk);
1115 goto discard_it; 912 goto discard_it;
913}
1116 914
1117do_time_wait: 915static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
1118 inet_twsk_put(inet_twsk(sk)); 916 int addr_len)
1119 goto no_dccp_socket; 917{
918 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
919 struct inet_connection_sock *icsk = inet_csk(sk);
920 struct inet_sock *inet = inet_sk(sk);
921 struct ipv6_pinfo *np = inet6_sk(sk);
922 struct dccp_sock *dp = dccp_sk(sk);
923 struct in6_addr *saddr = NULL, *final_p = NULL, final;
924 struct flowi fl;
925 struct dst_entry *dst;
926 int addr_type;
927 int err;
928
929 dp->dccps_role = DCCP_ROLE_CLIENT;
930
931 if (addr_len < SIN6_LEN_RFC2133)
932 return -EINVAL;
933
934 if (usin->sin6_family != AF_INET6)
935 return -EAFNOSUPPORT;
936
937 memset(&fl, 0, sizeof(fl));
938
939 if (np->sndflow) {
940 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
941 IP6_ECN_flow_init(fl.fl6_flowlabel);
942 if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
943 struct ip6_flowlabel *flowlabel;
944 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
945 if (flowlabel == NULL)
946 return -EINVAL;
947 ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
948 fl6_sock_release(flowlabel);
949 }
950 }
951 /*
952 * connect() to INADDR_ANY means loopback (BSD'ism).
953 */
954 if (ipv6_addr_any(&usin->sin6_addr))
955 usin->sin6_addr.s6_addr[15] = 1;
956
957 addr_type = ipv6_addr_type(&usin->sin6_addr);
958
959 if (addr_type & IPV6_ADDR_MULTICAST)
960 return -ENETUNREACH;
961
962 if (addr_type & IPV6_ADDR_LINKLOCAL) {
963 if (addr_len >= sizeof(struct sockaddr_in6) &&
964 usin->sin6_scope_id) {
965 /* If interface is set while binding, indices
966 * must coincide.
967 */
968 if (sk->sk_bound_dev_if &&
969 sk->sk_bound_dev_if != usin->sin6_scope_id)
970 return -EINVAL;
971
972 sk->sk_bound_dev_if = usin->sin6_scope_id;
973 }
974
975 /* Connect to link-local address requires an interface */
976 if (!sk->sk_bound_dev_if)
977 return -EINVAL;
978 }
979
980 ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
981 np->flow_label = fl.fl6_flowlabel;
982
983 /*
984 * DCCP over IPv4
985 */
986 if (addr_type == IPV6_ADDR_MAPPED) {
987 u32 exthdrlen = icsk->icsk_ext_hdr_len;
988 struct sockaddr_in sin;
989
990 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
991
992 if (__ipv6_only_sock(sk))
993 return -ENETUNREACH;
994
995 sin.sin_family = AF_INET;
996 sin.sin_port = usin->sin6_port;
997 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
998
999 icsk->icsk_af_ops = &dccp_ipv6_mapped;
1000 sk->sk_backlog_rcv = dccp_v4_do_rcv;
1001
1002 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
1003 if (err) {
1004 icsk->icsk_ext_hdr_len = exthdrlen;
1005 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
1006 sk->sk_backlog_rcv = dccp_v6_do_rcv;
1007 goto failure;
1008 } else {
1009 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
1010 inet->saddr);
1011 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
1012 inet->rcv_saddr);
1013 }
1014
1015 return err;
1016 }
1017
1018 if (!ipv6_addr_any(&np->rcv_saddr))
1019 saddr = &np->rcv_saddr;
1020
1021 fl.proto = IPPROTO_DCCP;
1022 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
1023 ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
1024 fl.oif = sk->sk_bound_dev_if;
1025 fl.fl_ip_dport = usin->sin6_port;
1026 fl.fl_ip_sport = inet->sport;
1027 security_sk_classify_flow(sk, &fl);
1028
1029 if (np->opt != NULL && np->opt->srcrt != NULL) {
1030 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
1031
1032 ipv6_addr_copy(&final, &fl.fl6_dst);
1033 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
1034 final_p = &final;
1035 }
1036
1037 err = ip6_dst_lookup(sk, &dst, &fl);
1038 if (err)
1039 goto failure;
1040
1041 if (final_p)
1042 ipv6_addr_copy(&fl.fl6_dst, final_p);
1043
1044 err = xfrm_lookup(&dst, &fl, sk, 0);
1045 if (err < 0)
1046 goto failure;
1047
1048 if (saddr == NULL) {
1049 saddr = &fl.fl6_src;
1050 ipv6_addr_copy(&np->rcv_saddr, saddr);
1051 }
1052
1053 /* set the source address */
1054 ipv6_addr_copy(&np->saddr, saddr);
1055 inet->rcv_saddr = LOOPBACK4_IPV6;
1056
1057 __ip6_dst_store(sk, dst, NULL, NULL);
1058
1059 icsk->icsk_ext_hdr_len = 0;
1060 if (np->opt != NULL)
1061 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
1062 np->opt->opt_nflen);
1063
1064 inet->dport = usin->sin6_port;
1065
1066 dccp_set_state(sk, DCCP_REQUESTING);
1067 err = inet6_hash_connect(&dccp_death_row, sk);
1068 if (err)
1069 goto late_failure;
1070
1071 dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
1072 np->daddr.s6_addr32,
1073 inet->sport, inet->dport);
1074 err = dccp_connect(sk);
1075 if (err)
1076 goto late_failure;
1077
1078 return 0;
1079
1080late_failure:
1081 dccp_set_state(sk, DCCP_CLOSED);
1082 __sk_dst_reset(sk);
1083failure:
1084 inet->dport = 0;
1085 sk->sk_route_caps = 0;
1086 return err;
1120} 1087}
1121 1088
1122static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = { 1089static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
@@ -1179,6 +1146,10 @@ static int dccp_v6_destroy_sock(struct sock *sk)
1179 return inet6_destroy_sock(sk); 1146 return inet6_destroy_sock(sk);
1180} 1147}
1181 1148
1149static struct timewait_sock_ops dccp6_timewait_sock_ops = {
1150 .twsk_obj_size = sizeof(struct dccp6_timewait_sock),
1151};
1152
1182static struct proto dccp_v6_prot = { 1153static struct proto dccp_v6_prot = {
1183 .name = "DCCPv6", 1154 .name = "DCCPv6",
1184 .owner = THIS_MODULE, 1155 .owner = THIS_MODULE,