diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 39 | 
1 files changed, 30 insertions, 9 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5da069e91cac..e3d9f4559c99 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -512,7 +512,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,  		opt = ireq->ipv6_opt;  		if (!opt)  			opt = rcu_dereference(np->opt); -		err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, np->tclass); +		err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, np->tclass, +			       sk->sk_priority);  		rcu_read_unlock();  		err = net_xmit_eval(err);  	} @@ -803,7 +804,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {  static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq,  				 u32 ack, u32 win, u32 tsval, u32 tsecr,  				 int oif, struct tcp_md5sig_key *key, int rst, -				 u8 tclass, __be32 label) +				 u8 tclass, __be32 label, u32 priority)  {  	const struct tcphdr *th = tcp_hdr(skb);  	struct tcphdr *t1; @@ -907,7 +908,8 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32  	dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL);  	if (!IS_ERR(dst)) {  		skb_dst_set(buff, dst); -		ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass); +		ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass, +			 priority);  		TCP_INC_STATS(net, TCP_MIB_OUTSEGS);  		if (rst)  			TCP_INC_STATS(net, TCP_MIB_OUTRSTS); @@ -930,6 +932,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)  	struct sock *sk1 = NULL;  #endif  	__be32 label = 0; +	u32 priority = 0;  	struct net *net;  	int oif = 0; @@ -990,16 +993,19 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)  			trace_tcp_send_reset(sk, skb);  			if (np->repflow)  				label = ip6_flowlabel(ipv6h); +			priority = sk->sk_priority;  		} -		if (sk->sk_state == TCP_TIME_WAIT) +		if (sk->sk_state == TCP_TIME_WAIT) {  			label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); +			priority = inet_twsk(sk)->tw_priority; +		}  	} else {  		if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET)  			label = ip6_flowlabel(ipv6h);  	}  	tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, -			     label); +			     label, priority);  #ifdef CONFIG_TCP_MD5SIG  out: @@ -1010,10 +1016,10 @@ out:  static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq,  			    u32 ack, u32 win, u32 tsval, u32 tsecr, int oif,  			    struct tcp_md5sig_key *key, u8 tclass, -			    __be32 label) +			    __be32 label, u32 priority)  {  	tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, -			     tclass, label); +			     tclass, label, priority);  }  static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) @@ -1025,7 +1031,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)  			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,  			tcp_time_stamp_raw() + tcptw->tw_ts_offset,  			tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), -			tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); +			tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority);  	inet_twsk_put(tw);  } @@ -1048,7 +1054,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,  			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,  			req->ts_recent, sk->sk_bound_dev_if,  			tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), -			0, 0); +			0, 0, sk->sk_priority);  } @@ -1063,6 +1069,21 @@ static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb)  	return sk;  } +u16 tcp_v6_get_syncookie(struct sock *sk, struct ipv6hdr *iph, +			 struct tcphdr *th, u32 *cookie) +{ +	u16 mss = 0; +#ifdef CONFIG_SYN_COOKIES +	mss = tcp_get_syncookie_mss(&tcp6_request_sock_ops, +				    &tcp_request_sock_ipv6_ops, sk, th); +	if (mss) { +		*cookie = __cookie_v6_init_sequence(iph, th, &mss); +		tcp_synq_overflow(sk); +	} +#endif +	return mss; +} +  static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)  {  	if (skb->protocol == htons(ETH_P_IP))  |