Skip to content

Commit 8e1ef0a

Browse files
yoshfujiDavid S. Miller
authored andcommitted
[IPV6]: Cache source address as well in ipv6_pinfo{}.
Based on MIPL2 kernel patch. Signed-off-by: YOSHIFUJI Hideaki <[email protected]> Signed-off-by: Ville Nuorvala <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cf6b198 commit 8e1ef0a

File tree

9 files changed

+30
-11
lines changed

9 files changed

+30
-11
lines changed

include/linux/ipv6.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ struct ipv6_pinfo {
242242
struct in6_addr rcv_saddr;
243243
struct in6_addr daddr;
244244
struct in6_addr *daddr_cache;
245+
#ifdef CONFIG_IPV6_SUBTREES
246+
struct in6_addr *saddr_cache;
247+
#endif
245248

246249
__u32 flow_label;
247250
__u32 frag_size;

include/net/ip6_route.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,21 +144,24 @@ extern rwlock_t rt6_lock;
144144
* Store a destination cache entry in a socket
145145
*/
146146
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)
148148
{
149149
struct ipv6_pinfo *np = inet6_sk(sk);
150150
struct rt6_info *rt = (struct rt6_info *) dst;
151151

152152
sk_setup_caps(sk, dst);
153153
np->daddr_cache = daddr;
154+
#ifdef CONFIG_IPV6_SUBTREES
155+
np->saddr_cache = saddr;
156+
#endif
154157
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
155158
}
156159

157160
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)
159162
{
160163
write_lock(&sk->sk_dst_lock);
161-
__ip6_dst_store(sk, dst, daddr);
164+
__ip6_dst_store(sk, dst, daddr, saddr);
162165
write_unlock(&sk->sk_dst_lock);
163166
}
164167

net/dccp/ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
231231
ipv6_addr_copy(&np->saddr, saddr);
232232
inet->rcv_saddr = LOOPBACK4_IPV6;
233233

234-
__ip6_dst_store(sk, dst, NULL);
234+
__ip6_dst_store(sk, dst, NULL, NULL);
235235

236236
icsk->icsk_ext_hdr_len = 0;
237237
if (np->opt != NULL)
@@ -872,7 +872,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
872872
* comment in that function for the gory details. -acme
873873
*/
874874

875-
__ip6_dst_store(newsk, dst, NULL);
875+
__ip6_dst_store(newsk, dst, NULL, NULL);
876876
newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
877877
NETIF_F_TSO);
878878
newdp6 = (struct dccp6_sock *)newsk;

net/ipv6/af_inet6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
659659
return err;
660660
}
661661

662-
__ip6_dst_store(sk, dst, NULL);
662+
__ip6_dst_store(sk, dst, NULL, NULL);
663663
}
664664

665665
return 0;

net/ipv6/datagram.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,12 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
193193

194194
ip6_dst_store(sk, dst,
195195
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);
197202

198203
sk->sk_state = TCP_ESTABLISHED;
199204
out:

net/ipv6/inet6_connection_sock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
186186
return err;
187187
}
188188

189-
__ip6_dst_store(sk, dst, NULL);
189+
__ip6_dst_store(sk, dst, NULL, NULL);
190190
}
191191

192192
skb->dst = dst_clone(dst);

net/ipv6/ip6_output.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,9 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
762762
* 2. oif also should be the same.
763763
*/
764764
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
765768
(fl->oif && fl->oif != dst->dev->ifindex)) {
766769
dst_release(dst);
767770
dst = NULL;

net/ipv6/tcp_ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
272272
inet->rcv_saddr = LOOPBACK4_IPV6;
273273

274274
sk->sk_gso_type = SKB_GSO_TCPV6;
275-
__ip6_dst_store(sk, dst, NULL);
275+
__ip6_dst_store(sk, dst, NULL, NULL);
276276

277277
icsk->icsk_ext_hdr_len = 0;
278278
if (np->opt)
@@ -954,7 +954,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
954954
*/
955955

956956
newsk->sk_gso_type = SKB_GSO_TCPV6;
957-
__ip6_dst_store(newsk, dst, NULL);
957+
__ip6_dst_store(newsk, dst, NULL, NULL);
958958

959959
newtcp6sk = (struct tcp6_sock *)newsk;
960960
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;

net/ipv6/udp.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,12 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
847847
if (connected) {
848848
ip6_dst_store(sk, dst,
849849
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);
851856
} else {
852857
dst_release(dst);
853858
}

0 commit comments

Comments
 (0)