diff options
Diffstat (limited to 'net/dccp/ipv6.c')
| -rw-r--r-- | net/dccp/ipv6.c | 95 | 
1 files changed, 48 insertions, 47 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6cf9f7782ad..4db3c2a1679 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -67,7 +67,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb)  	struct dccp_hdr *dh = dccp_hdr(skb);  	dccp_csum_outgoing(skb); -	dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); +	dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &sk->sk_v6_daddr);  }  static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) @@ -141,6 +141,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  	if (type == ICMPV6_PKT_TOOBIG) {  		struct dst_entry *dst = NULL; +		if (!ip6_sk_accept_pmtu(sk)) +			goto out; +  		if (sock_owned_by_user(sk))  			goto out;  		if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED)) @@ -216,7 +219,7 @@ out:  static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)  { -	struct inet6_request_sock *ireq6 = inet6_rsk(req); +	struct inet_request_sock *ireq = inet_rsk(req);  	struct ipv6_pinfo *np = inet6_sk(sk);  	struct sk_buff *skb;  	struct in6_addr *final_p, final; @@ -226,18 +229,18 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)  	memset(&fl6, 0, sizeof(fl6));  	fl6.flowi6_proto = IPPROTO_DCCP; -	fl6.daddr = ireq6->rmt_addr; -	fl6.saddr = ireq6->loc_addr; +	fl6.daddr = ireq->ir_v6_rmt_addr; +	fl6.saddr = ireq->ir_v6_loc_addr;  	fl6.flowlabel = 0; -	fl6.flowi6_oif = ireq6->iif; -	fl6.fl6_dport = inet_rsk(req)->rmt_port; -	fl6.fl6_sport = inet_rsk(req)->loc_port; +	fl6.flowi6_oif = ireq->ir_iif; +	fl6.fl6_dport = ireq->ir_rmt_port; +	fl6.fl6_sport = htons(ireq->ir_num);  	security_req_classify_flow(req, flowi6_to_flowi(&fl6));  	final_p = fl6_update_dst(&fl6, np->opt, &final); -	dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); +	dst = ip6_dst_lookup_flow(sk, &fl6, final_p);  	if (IS_ERR(dst)) {  		err = PTR_ERR(dst);  		dst = NULL; @@ -249,9 +252,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)  		struct dccp_hdr *dh = dccp_hdr(skb);  		dh->dccph_checksum = dccp_v6_csum_finish(skb, -							 &ireq6->loc_addr, -							 &ireq6->rmt_addr); -		fl6.daddr = ireq6->rmt_addr; +							 &ireq->ir_v6_loc_addr, +							 &ireq->ir_v6_rmt_addr); +		fl6.daddr = ireq->ir_v6_rmt_addr;  		err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);  		err = net_xmit_eval(err);  	} @@ -264,8 +267,7 @@ done:  static void dccp_v6_reqsk_destructor(struct request_sock *req)  {  	dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); -	if (inet6_rsk(req)->pktopts != NULL) -		kfree_skb(inet6_rsk(req)->pktopts); +	kfree_skb(inet_rsk(req)->pktopts);  }  static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) @@ -302,7 +304,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)  	security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));  	/* sk = NULL, but it is safe for now. RST socket required. */ -	dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false); +	dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL);  	if (!IS_ERR(dst)) {  		skb_dst_set(skb, dst);  		ip6_xmit(ctl_sk, skb, &fl6, NULL, 0); @@ -359,7 +361,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)  {  	struct request_sock *req;  	struct dccp_request_sock *dreq; -	struct inet6_request_sock *ireq6; +	struct inet_request_sock *ireq;  	struct ipv6_pinfo *np = inet6_sk(sk);  	const __be32 service = dccp_hdr_request(skb)->dccph_req_service;  	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); @@ -398,22 +400,22 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)  	if (security_inet_conn_request(sk, skb, req))  		goto drop_and_free; -	ireq6 = inet6_rsk(req); -	ireq6->rmt_addr = ipv6_hdr(skb)->saddr; -	ireq6->loc_addr = ipv6_hdr(skb)->daddr; +	ireq = inet_rsk(req); +	ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; +	ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;  	if (ipv6_opt_accepted(sk, skb) ||  	    np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||  	    np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {  		atomic_inc(&skb->users); -		ireq6->pktopts = skb; +		ireq->pktopts = skb;  	} -	ireq6->iif = sk->sk_bound_dev_if; +	ireq->ir_iif = sk->sk_bound_dev_if;  	/* So that link locals have meaning */  	if (!sk->sk_bound_dev_if && -	    ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL) -		ireq6->iif = inet6_iif(skb); +	    ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) +		ireq->ir_iif = inet6_iif(skb);  	/*  	 * Step 3: Process LISTEN state @@ -446,7 +448,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,  					      struct request_sock *req,  					      struct dst_entry *dst)  { -	struct inet6_request_sock *ireq6 = inet6_rsk(req); +	struct inet_request_sock *ireq = inet_rsk(req);  	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);  	struct inet_sock *newinet;  	struct dccp6_sock *newdp6; @@ -467,11 +469,11 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,  		memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -		ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr); +		ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);  		ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); -		newnp->rcv_saddr = newnp->saddr; +		newsk->sk_v6_rcv_saddr = newnp->saddr;  		inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;  		newsk->sk_backlog_rcv = dccp_v4_do_rcv; @@ -505,15 +507,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,  		memset(&fl6, 0, sizeof(fl6));  		fl6.flowi6_proto = IPPROTO_DCCP; -		fl6.daddr = ireq6->rmt_addr; +		fl6.daddr = ireq->ir_v6_rmt_addr;  		final_p = fl6_update_dst(&fl6, np->opt, &final); -		fl6.saddr = ireq6->loc_addr; +		fl6.saddr = ireq->ir_v6_loc_addr;  		fl6.flowi6_oif = sk->sk_bound_dev_if; -		fl6.fl6_dport = inet_rsk(req)->rmt_port; -		fl6.fl6_sport = inet_rsk(req)->loc_port; +		fl6.fl6_dport = ireq->ir_rmt_port; +		fl6.fl6_sport = htons(ireq->ir_num);  		security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); -		dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); +		dst = ip6_dst_lookup_flow(sk, &fl6, final_p);  		if (IS_ERR(dst))  			goto out;  	} @@ -538,10 +540,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,  	memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -	newnp->daddr = ireq6->rmt_addr; -	newnp->saddr = ireq6->loc_addr; -	newnp->rcv_saddr = ireq6->loc_addr; -	newsk->sk_bound_dev_if = ireq6->iif; +	newsk->sk_v6_daddr	= ireq->ir_v6_rmt_addr; +	newnp->saddr		= ireq->ir_v6_loc_addr; +	newsk->sk_v6_rcv_saddr	= ireq->ir_v6_loc_addr; +	newsk->sk_bound_dev_if	= ireq->ir_iif;  	/* Now IPv6 options... @@ -554,10 +556,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,  	/* Clone pktoptions received with SYN */  	newnp->pktoptions = NULL; -	if (ireq6->pktopts != NULL) { -		newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC); -		consume_skb(ireq6->pktopts); -		ireq6->pktopts = NULL; +	if (ireq->pktopts != NULL) { +		newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); +		consume_skb(ireq->pktopts); +		ireq->pktopts = NULL;  		if (newnp->pktoptions)  			skb_set_owner_r(newnp->pktoptions, newsk);  	} @@ -852,7 +854,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  			flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);  			if (flowlabel == NULL)  				return -EINVAL; -			usin->sin6_addr = flowlabel->dst;  			fl6_sock_release(flowlabel);  		}  	} @@ -885,7 +886,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  			return -EINVAL;  	} -	np->daddr = usin->sin6_addr; +	sk->sk_v6_daddr = usin->sin6_addr;  	np->flow_label = fl6.flowlabel;  	/* @@ -915,16 +916,16 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  			goto failure;  		}  		ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); -		ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr); +		ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &sk->sk_v6_rcv_saddr);  		return err;  	} -	if (!ipv6_addr_any(&np->rcv_saddr)) -		saddr = &np->rcv_saddr; +	if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) +		saddr = &sk->sk_v6_rcv_saddr;  	fl6.flowi6_proto = IPPROTO_DCCP; -	fl6.daddr = np->daddr; +	fl6.daddr = sk->sk_v6_daddr;  	fl6.saddr = saddr ? *saddr : np->saddr;  	fl6.flowi6_oif = sk->sk_bound_dev_if;  	fl6.fl6_dport = usin->sin6_port; @@ -933,7 +934,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  	final_p = fl6_update_dst(&fl6, np->opt, &final); -	dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); +	dst = ip6_dst_lookup_flow(sk, &fl6, final_p);  	if (IS_ERR(dst)) {  		err = PTR_ERR(dst);  		goto failure; @@ -941,7 +942,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  	if (saddr == NULL) {  		saddr = &fl6.saddr; -		np->rcv_saddr = *saddr; +		sk->sk_v6_rcv_saddr = *saddr;  	}  	/* set the source address */ @@ -963,7 +964,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  		goto late_failure;  	dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32, -						      np->daddr.s6_addr32, +						      sk->sk_v6_daddr.s6_addr32,  						      inet->inet_sport,  						      inet->inet_dport);  	err = dccp_connect(sk);  | 
