aboutsummaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_output.c64
-rw-r--r--net/ipv6/tcp_ipv6.c1
2 files changed, 33 insertions, 32 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0e844c2736a..3df2c442d90 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -943,39 +943,39 @@ static int ip6_dst_lookup_tail(struct sock *sk,
}
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
- /*
- * Here if the dst entry we've looked up
- * has a neighbour entry that is in the INCOMPLETE
- * state and the src address from the flow is
- * marked as OPTIMISTIC, we release the found
- * dst entry and replace it instead with the
- * dst entry of the nexthop router
- */
- if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
- struct inet6_ifaddr *ifp;
- struct flowi fl_gw;
- int redirect;
-
- ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
- (*dst)->dev, 1);
-
- redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
- if (ifp)
- in6_ifa_put(ifp);
-
- if (redirect) {
- /*
- * We need to get the dst entry for the
- * default router instead
- */
- dst_release(*dst);
- memcpy(&fl_gw, fl, sizeof(struct flowi));
- memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
- *dst = ip6_route_output(net, sk, &fl_gw);
- if ((err = (*dst)->error))
- goto out_err_release;
- }
+ /*
+ * Here if the dst entry we've looked up
+ * has a neighbour entry that is in the INCOMPLETE
+ * state and the src address from the flow is
+ * marked as OPTIMISTIC, we release the found
+ * dst entry and replace it instead with the
+ * dst entry of the nexthop router
+ */
+ if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
+ struct inet6_ifaddr *ifp;
+ struct flowi fl_gw;
+ int redirect;
+
+ ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
+ (*dst)->dev, 1);
+
+ redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
+ if (ifp)
+ in6_ifa_put(ifp);
+
+ if (redirect) {
+ /*
+ * We need to get the dst entry for the
+ * default router instead
+ */
+ dst_release(*dst);
+ memcpy(&fl_gw, fl, sizeof(struct flowi));
+ memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
+ *dst = ip6_route_output(net, sk, &fl_gw);
+ if ((err = (*dst)->error))
+ goto out_err_release;
}
+ }
#endif
return 0;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5b90b369ccb..b585c850a89 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2148,6 +2148,7 @@ static int tcpv6_net_init(struct net *net)
static void tcpv6_net_exit(struct net *net)
{
inet_ctl_sock_destroy(net->ipv6.tcp_sk);
+ inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6);
}
static struct pernet_operations tcpv6_net_ops = {