forked from mirrors/linux
		
	net: dccp: Add handling of IPV6_PKTOPTIONS to dccp_v6_do_rcv()
Add handling of IPV6_PKTOPTIONS to dccp_v6_do_rcv() in net/dccp/ipv6.c, similar to the handling in net/ipv6/tcp_ipv6.c Signed-off-by: Andrii Vladyka <tulup@mail.ru> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									e3cfddd577
								
							
						
					
					
						commit
						323fbd0edf
					
				
					 1 changed files with 35 additions and 12 deletions
				
			
		|  | @ -16,6 +16,7 @@ | |||
| #include <linux/random.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/xfrm.h> | ||||
| #include <linux/string.h> | ||||
| 
 | ||||
| #include <net/addrconf.h> | ||||
| #include <net/inet_common.h> | ||||
|  | @ -30,6 +31,7 @@ | |||
| #include <net/ip6_checksum.h> | ||||
| #include <net/xfrm.h> | ||||
| #include <net/secure_seq.h> | ||||
| #include <net/sock.h> | ||||
| 
 | ||||
| #include "dccp.h" | ||||
| #include "ipv6.h" | ||||
|  | @ -597,19 +599,13 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 					       --ANK (980728) | ||||
| 	 */ | ||||
| 	if (np->rxopt.all) | ||||
| 	/*
 | ||||
| 	 * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below | ||||
| 	 *        (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example. | ||||
| 	 */ | ||||
| 		opt_skb = skb_clone(skb, GFP_ATOMIC); | ||||
| 
 | ||||
| 	if (sk->sk_state == DCCP_OPEN) { /* Fast path */ | ||||
| 		if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) | ||||
| 			goto reset; | ||||
| 		if (opt_skb) { | ||||
| 			/* XXX This is where we would goto ipv6_pktoptions. */ | ||||
| 			__kfree_skb(opt_skb); | ||||
| 		} | ||||
| 		if (opt_skb) | ||||
| 			goto ipv6_pktoptions; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -640,10 +636,8 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 
 | ||||
| 	if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) | ||||
| 		goto reset; | ||||
| 	if (opt_skb) { | ||||
| 		/* XXX This is where we would goto ipv6_pktoptions. */ | ||||
| 		__kfree_skb(opt_skb); | ||||
| 	} | ||||
| 	if (opt_skb) | ||||
| 		goto ipv6_pktoptions; | ||||
| 	return 0; | ||||
| 
 | ||||
| reset: | ||||
|  | @ -653,6 +647,35 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 		__kfree_skb(opt_skb); | ||||
| 	kfree_skb(skb); | ||||
| 	return 0; | ||||
| 
 | ||||
| /* Handling IPV6_PKTOPTIONS skb the similar
 | ||||
|  * way it's done for net/ipv6/tcp_ipv6.c | ||||
|  */ | ||||
| ipv6_pktoptions: | ||||
| 	if (!((1 << sk->sk_state) & (DCCPF_CLOSED | DCCPF_LISTEN))) { | ||||
| 		if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) | ||||
| 			np->mcast_oif = inet6_iif(opt_skb); | ||||
| 		if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) | ||||
| 			np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; | ||||
| 		if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) | ||||
| 			np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); | ||||
| 		if (np->repflow) | ||||
| 			np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); | ||||
| 		if (ipv6_opt_accepted(sk, opt_skb, | ||||
| 				      &DCCP_SKB_CB(opt_skb)->header.h6)) { | ||||
| 			skb_set_owner_r(opt_skb, sk); | ||||
| 			memmove(IP6CB(opt_skb), | ||||
| 				&DCCP_SKB_CB(opt_skb)->header.h6, | ||||
| 				sizeof(struct inet6_skb_parm)); | ||||
| 			opt_skb = xchg(&np->pktoptions, opt_skb); | ||||
| 		} else { | ||||
| 			__kfree_skb(opt_skb); | ||||
| 			opt_skb = xchg(&np->pktoptions, NULL); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	kfree_skb(opt_skb); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dccp_v6_rcv(struct sk_buff *skb) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Andrii
						Andrii