diff options
-rw-r--r-- | include/linux/ipv6.h | 3 | ||||
-rw-r--r-- | include/net/ip6_route.h | 9 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 7 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/udp.c | 7 |
9 files changed, 30 insertions, 11 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 297853c841b4..02d14a3ff2af 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -242,6 +242,9 @@ struct ipv6_pinfo { | |||
242 | struct in6_addr rcv_saddr; | 242 | struct in6_addr rcv_saddr; |
243 | struct in6_addr daddr; | 243 | struct in6_addr daddr; |
244 | struct in6_addr *daddr_cache; | 244 | struct in6_addr *daddr_cache; |
245 | #ifdef CONFIG_IPV6_SUBTREES | ||
246 | struct in6_addr *saddr_cache; | ||
247 | #endif | ||
245 | 248 | ||
246 | __u32 flow_label; | 249 | __u32 flow_label; |
247 | __u32 frag_size; | 250 | __u32 frag_size; |
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 249ce4545ef0..0d40f84df21b 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
@@ -144,21 +144,24 @@ extern rwlock_t rt6_lock; | |||
144 | * Store a destination cache entry in a socket | 144 | * Store a destination cache entry in a socket |
145 | */ | 145 | */ |
146 | static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst, | 146 | static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst, |
147 | struct in6_addr *daddr) | 147 | struct in6_addr *daddr, struct in6_addr *saddr) |
148 | { | 148 | { |
149 | struct ipv6_pinfo *np = inet6_sk(sk); | 149 | struct ipv6_pinfo *np = inet6_sk(sk); |
150 | struct rt6_info *rt = (struct rt6_info *) dst; | 150 | struct rt6_info *rt = (struct rt6_info *) dst; |
151 | 151 | ||
152 | sk_setup_caps(sk, dst); | 152 | sk_setup_caps(sk, dst); |
153 | np->daddr_cache = daddr; | 153 | np->daddr_cache = daddr; |
154 | #ifdef CONFIG_IPV6_SUBTREES | ||
155 | np->saddr_cache = saddr; | ||
156 | #endif | ||
154 | np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; | 157 | np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; |
155 | } | 158 | } |
156 | 159 | ||
157 | static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, | 160 | static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, |
158 | struct in6_addr *daddr) | 161 | struct in6_addr *daddr, struct in6_addr *saddr) |
159 | { | 162 | { |
160 | write_lock(&sk->sk_dst_lock); | 163 | write_lock(&sk->sk_dst_lock); |
161 | __ip6_dst_store(sk, dst, daddr); | 164 | __ip6_dst_store(sk, dst, daddr, saddr); |
162 | write_unlock(&sk->sk_dst_lock); | 165 | write_unlock(&sk->sk_dst_lock); |
163 | } | 166 | } |
164 | 167 | ||
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 231bc7c7e749..f9c5e12d7038 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -231,7 +231,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
231 | ipv6_addr_copy(&np->saddr, saddr); | 231 | ipv6_addr_copy(&np->saddr, saddr); |
232 | inet->rcv_saddr = LOOPBACK4_IPV6; | 232 | inet->rcv_saddr = LOOPBACK4_IPV6; |
233 | 233 | ||
234 | __ip6_dst_store(sk, dst, NULL); | 234 | __ip6_dst_store(sk, dst, NULL, NULL); |
235 | 235 | ||
236 | icsk->icsk_ext_hdr_len = 0; | 236 | icsk->icsk_ext_hdr_len = 0; |
237 | if (np->opt != NULL) | 237 | if (np->opt != NULL) |
@@ -872,7 +872,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
872 | * comment in that function for the gory details. -acme | 872 | * comment in that function for the gory details. -acme |
873 | */ | 873 | */ |
874 | 874 | ||
875 | __ip6_dst_store(newsk, dst, NULL); | 875 | __ip6_dst_store(newsk, dst, NULL, NULL); |
876 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | | 876 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | |
877 | NETIF_F_TSO); | 877 | NETIF_F_TSO); |
878 | newdp6 = (struct dccp6_sock *)newsk; | 878 | newdp6 = (struct dccp6_sock *)newsk; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 2ff600cfe3a4..57ee5ddea96f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -659,7 +659,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
659 | return err; | 659 | return err; |
660 | } | 660 | } |
661 | 661 | ||
662 | __ip6_dst_store(sk, dst, NULL); | 662 | __ip6_dst_store(sk, dst, NULL, NULL); |
663 | } | 663 | } |
664 | 664 | ||
665 | return 0; | 665 | return 0; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index c73508e090a6..8561b9da6db6 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -193,7 +193,12 @@ ipv4_connected: | |||
193 | 193 | ||
194 | ip6_dst_store(sk, dst, | 194 | ip6_dst_store(sk, dst, |
195 | ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? | 195 | ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? |
196 | &np->daddr : NULL); | 196 | &np->daddr : NULL, |
197 | #ifdef CONFIG_IPV6_SUBTREES | ||
198 | ipv6_addr_equal(&fl.fl6_src, &np->saddr) ? | ||
199 | &np->saddr : | ||
200 | #endif | ||
201 | NULL); | ||
197 | 202 | ||
198 | sk->sk_state = TCP_ESTABLISHED; | 203 | sk->sk_state = TCP_ESTABLISHED; |
199 | out: | 204 | out: |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 7a51a258615d..827f41d1478b 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -186,7 +186,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
186 | return err; | 186 | return err; |
187 | } | 187 | } |
188 | 188 | ||
189 | __ip6_dst_store(sk, dst, NULL); | 189 | __ip6_dst_store(sk, dst, NULL, NULL); |
190 | } | 190 | } |
191 | 191 | ||
192 | skb->dst = dst_clone(dst); | 192 | skb->dst = dst_clone(dst); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0a18cb6b1cbb..2a376b7d91b4 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -762,6 +762,9 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, | |||
762 | * 2. oif also should be the same. | 762 | * 2. oif also should be the same. |
763 | */ | 763 | */ |
764 | if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) || | 764 | if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) || |
765 | #ifdef CONFIG_IPV6_SUBTREES | ||
766 | ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) || | ||
767 | #endif | ||
765 | (fl->oif && fl->oif != dst->dev->ifindex)) { | 768 | (fl->oif && fl->oif != dst->dev->ifindex)) { |
766 | dst_release(dst); | 769 | dst_release(dst); |
767 | dst = NULL; | 770 | dst = NULL; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 7f1b660493b7..2b18918f3011 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -272,7 +272,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
272 | inet->rcv_saddr = LOOPBACK4_IPV6; | 272 | inet->rcv_saddr = LOOPBACK4_IPV6; |
273 | 273 | ||
274 | sk->sk_gso_type = SKB_GSO_TCPV6; | 274 | sk->sk_gso_type = SKB_GSO_TCPV6; |
275 | __ip6_dst_store(sk, dst, NULL); | 275 | __ip6_dst_store(sk, dst, NULL, NULL); |
276 | 276 | ||
277 | icsk->icsk_ext_hdr_len = 0; | 277 | icsk->icsk_ext_hdr_len = 0; |
278 | if (np->opt) | 278 | if (np->opt) |
@@ -954,7 +954,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
954 | */ | 954 | */ |
955 | 955 | ||
956 | newsk->sk_gso_type = SKB_GSO_TCPV6; | 956 | newsk->sk_gso_type = SKB_GSO_TCPV6; |
957 | __ip6_dst_store(newsk, dst, NULL); | 957 | __ip6_dst_store(newsk, dst, NULL, NULL); |
958 | 958 | ||
959 | newtcp6sk = (struct tcp6_sock *)newsk; | 959 | newtcp6sk = (struct tcp6_sock *)newsk; |
960 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; | 960 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index eb9e1b39c8f8..b9cc55ccb000 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -847,7 +847,12 @@ do_append_data: | |||
847 | if (connected) { | 847 | if (connected) { |
848 | ip6_dst_store(sk, dst, | 848 | ip6_dst_store(sk, dst, |
849 | ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ? | 849 | ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ? |
850 | &np->daddr : NULL); | 850 | &np->daddr : NULL, |
851 | #ifdef CONFIG_IPV6_SUBTREES | ||
852 | ipv6_addr_equal(&fl->fl6_src, &np->saddr) ? | ||
853 | &np->saddr : | ||
854 | #endif | ||
855 | NULL); | ||
851 | } else { | 856 | } else { |
852 | dst_release(dst); | 857 | dst_release(dst); |
853 | } | 858 | } |