15 #include <linux/module.h>
16 #include <linux/random.h>
17 #include <linux/slab.h>
43 static void dccp_v6_hash(
struct sock *
sk)
46 if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
64 static inline void dccp_v6_send_check(
struct sock *sk,
struct sk_buff *
skb)
69 dccp_csum_outgoing(skb);
76 ipv6_hdr(skb)->
saddr.s6_addr32,
94 if (skb->
len < offset +
sizeof(*dh) ||
95 skb->
len < offset + __dccp_basic_hdr_len(dh)) {
102 &hdr->
daddr, dh->dccph_dport,
103 &hdr->
saddr, dh->dccph_sport, inet6_iif(skb));
124 seq = dccp_hdr_seq(dh);
137 dst->
ops->redirect(dst, sk, skb);
152 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst))
160 switch (sk->sk_state) {
178 if (!between48(seq, dccp_rsk(req)->dreq_iss,
179 dccp_rsk(req)->dreq_gss)) {
184 inet_csk_reqsk_queue_drop(sk, req, prev);
227 memset(&fl6, 0,
sizeof(fl6));
232 fl6.flowi6_oif = ireq6->
iif;
233 fl6.fl6_dport = inet_rsk(req)->rmt_port;
234 fl6.fl6_sport = inet_rsk(req)->loc_port;
235 security_req_classify_flow(req, flowi6_to_flowi(&fl6));
264 static void dccp_v6_reqsk_destructor(
struct request_sock *req)
267 if (inet6_rsk(req)->pktopts !=
NULL)
271 static void dccp_v6_ctl_send_reset(
struct sock *sk,
struct sk_buff *rxskb)
276 struct net *net = dev_net(skb_dst(rxskb)->
dev);
277 struct sock *ctl_sk = net->dccp.v6_ctl_sk;
283 if (!ipv6_unicast_destination(rxskb))
290 rxip6h = ipv6_hdr(rxskb);
294 memset(&fl6, 0,
sizeof(fl6));
295 fl6.daddr = rxip6h->
saddr;
296 fl6.saddr = rxip6h->
daddr;
299 fl6.flowi6_oif = inet6_iif(rxskb);
302 security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
307 skb_dst_set(skb, dst);
320 .rtx_syn_ack = dccp_v6_send_response,
322 .destructor = dccp_v6_reqsk_destructor,
323 .send_reset = dccp_v6_ctl_send_reset,
327 static struct sock *dccp_v6_hnd_req(
struct sock *sk,
struct sk_buff *skb)
330 const struct ipv6hdr *iph = ipv6_hdr(skb);
358 static int dccp_v6_conn_request(
struct sock *sk,
struct sk_buff *skb)
370 if (!ipv6_unicast_destination(skb))
373 if (dccp_bad_service_code(sk, service)) {
381 if (inet_csk_reqsk_queue_is_full(sk))
384 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
387 req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
394 dreq = dccp_rsk(req);
398 if (security_inet_conn_request(sk, skb, req))
401 ireq6 = inet6_rsk(req);
402 ireq6->
rmt_addr = ipv6_hdr(skb)->saddr;
403 ireq6->
loc_addr = ipv6_hdr(skb)->daddr;
411 ireq6->
iif = sk->sk_bound_dev_if;
414 if (!sk->sk_bound_dev_if &&
416 ireq6->
iif = inet6_iif(skb);
427 dreq->
dreq_iss = dccp_v6_init_sequence(skb);
431 if (dccp_v6_send_response(sk, req,
NULL))
444 static struct sock *dccp_v6_request_recv_sock(
struct sock *sk,
464 newinet = inet_sk(newsk);
465 newinet->pinet6 = &newdp6->
inet6;
466 newnp = inet6_sk(newsk);
470 ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->
daddr);
476 inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
499 if (sk_acceptq_is_full(sk))
506 memset(&fl6, 0,
sizeof(fl6));
511 fl6.flowi6_oif = sk->sk_bound_dev_if;
512 fl6.fl6_dport = inet_rsk(req)->rmt_port;
513 fl6.fl6_sport = inet_rsk(req)->loc_port;
514 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
531 __ip6_dst_store(newsk, dst,
NULL,
NULL);
535 newinet = inet_sk(newsk);
536 newinet->pinet6 = &newdp6->
inet6;
537 newnp = inet6_sk(newsk);
544 newsk->sk_bound_dev_if = ireq6->
iif;
577 inet_csk(newsk)->icsk_ext_hdr_len = 0;
579 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->
opt->opt_nflen +
580 newnp->
opt->opt_flen);
612 static int dccp_v6_do_rcv(
struct sock *sk,
struct sk_buff *skb)
691 struct sock *nsk = dccp_v6_hnd_req(sk, skb);
718 dccp_v6_ctl_send_reset(sk, skb);
726 static int dccp_v6_rcv(
struct sk_buff *skb)
738 if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->
saddr,
739 &ipv6_hdr(skb)->
daddr)) {
740 DCCP_WARN(
"dropped packet with invalid checksum\n");
749 if (dccp_packet_without_ack(skb))
752 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
756 sk = __inet6_lookup_skb(&dccp_hashinfo, skb,
764 "get corresponding socket\n");
775 dccp_pr_debug(
"sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
785 min_cov = dccp_sk(sk)->dccps_pcrlen;
786 if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov)) {
787 dccp_pr_debug(
"Packet CsCov %d does not satisfy MinCsCov %d\n",
788 dh->dccph_cscov, min_cov);
790 goto discard_and_relse;
794 goto discard_and_relse;
810 dccp_v6_ctl_send_reset(sk, skb);
844 memset(&fl6, 0,
sizeof(fl6));
852 if (flowlabel ==
NULL)
855 fl6_sock_release(flowlabel);
864 addr_type = ipv6_addr_type(&usin->
sin6_addr);
875 if (sk->sk_bound_dev_if &&
883 if (!sk->sk_bound_dev_if)
904 sin.sin_addr.s_addr = usin->
sin6_addr.s6_addr32[3];
917 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->
rcv_saddr);
926 fl6.daddr = np->
daddr;
927 fl6.saddr = saddr ? *saddr : np->
saddr;
928 fl6.flowi6_oif = sk->sk_bound_dev_if;
931 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
950 __ip6_dst_store(sk, dst,
NULL,
NULL);
985 .send_check = dccp_v6_send_check,
987 .conn_request = dccp_v6_conn_request,
988 .syn_recv_sock = dccp_v6_request_recv_sock,
989 .net_header_len =
sizeof(
struct ipv6hdr),
1008 .conn_request = dccp_v6_conn_request,
1009 .syn_recv_sock = dccp_v6_request_recv_sock,
1010 .net_header_len =
sizeof(
struct iphdr),
1015 #ifdef CONFIG_COMPAT
1024 static int dccp_v6_init_sock(
struct sock *sk)
1026 static __u8 dccp_v6_ctl_sock_initialized;
1030 if (
unlikely(!dccp_v6_ctl_sock_initialized))
1031 dccp_v6_ctl_sock_initialized = 1;
1032 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1038 static void dccp_v6_destroy_sock(
struct sock *sk)
1048 static struct proto dccp_v6_prot = {
1052 .connect = dccp_v6_connect,
1055 .init = dccp_v6_init_sock,
1060 .backlog_rcv = dccp_v6_do_rcv,
1061 .hash = dccp_v6_hash,
1066 .destroy = dccp_v6_destroy_sock,
1071 .rsk_prot = &dccp6_request_sock_ops,
1072 .twsk_prot = &dccp6_timewait_sock_ops,
1074 #ifdef CONFIG_COMPAT
1075 .compat_setsockopt = compat_dccp_setsockopt,
1076 .compat_getsockopt = compat_dccp_getsockopt,
1080 static const struct inet6_protocol dccp_v6_protocol = {
1081 .handler = dccp_v6_rcv,
1082 .err_handler = dccp_v6_err,
1083 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
1086 static const struct proto_ops inet6_dccp_ops = {
1105 #ifdef CONFIG_COMPAT
1114 .prot = &dccp_v6_prot,
1115 .ops = &inet6_dccp_ops,
1119 static int __net_init dccp_v6_init_net(
struct net *net)
1128 static void __net_exit dccp_v6_exit_net(
struct net *net)
1130 inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
1134 .init = dccp_v6_init_net,
1135 .exit = dccp_v6_exit_net,
1138 static int __init dccp_v6_init(
void)
1147 goto out_unregister_proto;
1153 goto out_destroy_ctl_sock;
1157 out_destroy_ctl_sock:
1160 out_unregister_proto:
1165 static void __exit dccp_v6_exit(
void)