aboutsummaryrefslogtreecommitdiff
path: root/net/ipv6/inet6_connection_sock.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 19:40:14 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 19:40:14 -0700
commit038a5008b2f395c85e6e71d6ddf3c684e7c405b0 (patch)
tree4735eab577e97e5a22c3141e3f60071c8065585e /net/ipv6/inet6_connection_sock.c
parentdd6d1844af33acb4edd0a40b1770d091a22c94be (diff)
parent266918303226cceac7eca38ced30f15f277bd89c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (867 commits) [SKY2]: status polling loop (post merge) [NET]: Fix NAPI completion handling in some drivers. [TCP]: Limit processing lost_retrans loop to work-to-do cases [TCP]: Fix lost_retrans loop vs fastpath problems [TCP]: No need to re-count fackets_out/sacked_out at RTO [TCP]: Extract tcp_match_queue_to_sack from sacktag code [TCP]: Kill almost unused variable pcount from sacktag [TCP]: Fix mark_head_lost to ignore R-bit when trying to mark L [TCP]: Add bytes_acked (ABC) clearing to FRTO too [IPv6]: Update setsockopt(IPV6_MULTICAST_IF) to support RFC 3493, try2 [NETFILTER]: x_tables: add missing ip6t_modulename aliases [NETFILTER]: nf_conntrack_tcp: fix connection reopening [QETH]: fix qeth_main.c [NETLINK]: fib_frontend build fixes [IPv6]: Export userland ND options through netlink (RDNSS support) [9P]: build fix with !CONFIG_SYSCTL [NET]: Fix dev_put() and dev_hold() comments [NET]: make netlink user -> kernel interface synchronious [NET]: unify netlink kernel socket recognition [NET]: cleanup 3rd argument in netlink_sendskb ... Fix up conflicts manually in Documentation/feature-removal-schedule.txt and my new least favourite crap, the "mod_devicetable" support in the files include/linux/mod_devicetable.h and scripts/mod/file2alias.c. (The latter files seem to be explicitly _designed_ to get conflicts when different subsystems work with them - that have an absolutely horrid lack of subsystem separation!) Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'net/ipv6/inet6_connection_sock.c')
-rw-r--r--net/ipv6/inet6_connection_sock.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 116f94a4907..25b93170974 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -139,6 +139,41 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
+static inline
+void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
+ struct in6_addr *daddr, struct in6_addr *saddr)
+{
+ __ip6_dst_store(sk, dst, daddr, saddr);
+
+#ifdef CONFIG_XFRM
+ if (dst) {
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
+ }
+#endif
+}
+
+static inline
+struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
+{
+ struct dst_entry *dst;
+
+ dst = __sk_dst_check(sk, cookie);
+
+#ifdef CONFIG_XFRM
+ if (dst) {
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
+ sk->sk_dst_cache = NULL;
+ dst_release(dst);
+ dst = NULL;
+ }
+ }
+#endif
+
+ return dst;
+}
+
int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
{
struct sock *sk = skb->sk;
@@ -166,7 +201,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
final_p = &final;
}
- dst = __sk_dst_check(sk, np->dst_cookie);
+ dst = __inet6_csk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
int err = ip6_dst_lookup(sk, &dst, &fl);
@@ -186,7 +221,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
return err;
}
- __ip6_dst_store(sk, dst, NULL, NULL);
+ __inet6_csk_dst_store(sk, dst, NULL, NULL);
}
skb->dst = dst_clone(dst);