Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 when chasing nd6_llinfo chain, make sure we do ...



details:   https://anonhg.NetBSD.org/src/rev/3c79a4c12ea7
branches:  trunk
changeset: 503537:3c79a4c12ea7
user:      itojun <itojun%NetBSD.org@localhost>
date:      Thu Feb 08 12:57:54 2001 +0000

description:
when chasing nd6_llinfo chain, make sure we do not touch dangling
pointer (due to RTM_DELETE during default router list management).
from kame

diffstat:

 sys/netinet6/nd6.c |  38 ++++++++++++++++++++++++++------------
 sys/netinet6/nd6.h |   6 +++---
 2 files changed, 29 insertions(+), 15 deletions(-)

diffs (116 lines):

diff -r f820d61c6ccb -r 3c79a4c12ea7 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Thu Feb 08 12:36:06 2001 +0000
+++ b/sys/netinet6/nd6.c        Thu Feb 08 12:57:54 2001 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: nd6.c,v 1.36 2001/02/07 08:59:48 itojun Exp $  */
-/*     $KAME: nd6.c,v 1.110 2001/02/06 09:14:38 jinmei Exp $   */
+/*     $NetBSD: nd6.c,v 1.37 2001/02/08 12:57:54 itojun Exp $  */
+/*     $KAME: nd6.c,v 1.118 2001/02/08 12:14:33 itojun Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -458,7 +458,7 @@
                                                    ICMP6_DST_UNREACH_ADDR, 0);
                                        ln->ln_hold = NULL;
                                }
-                               nd6_free(rt);
+                               next = nd6_free(rt);
                        }
                        break;
                case ND6_LLINFO_REACHABLE:
@@ -489,12 +489,11 @@
                                        nd_ifinfo[ifp->if_index].retrans / 1000;
                                nd6_ns_output(ifp, &dst->sin6_addr,
                                               &dst->sin6_addr, ln, 0);
-                       } else {
-                               nd6_free(rt);
-                       }
+                       } else
+                               next = nd6_free(rt);
                        break;
                case ND6_LLINFO_WAITDELETE:
-                       nd6_free(rt);
+                       next = nd6_free(rt);
                        break;
                }
                ln = next;
@@ -626,7 +625,7 @@
                    rt->rt_gateway->sa_family == AF_LINK) {
                        sdl = (struct sockaddr_dl *)rt->rt_gateway;
                        if (sdl->sdl_index == ifp->if_index)
-                               nd6_free(rt);
+                               nln = nd6_free(rt);
                }
                ln = nln;
        }
@@ -804,11 +803,11 @@
 /*
  * Free an nd6 llinfo entry.
  */
-void
+struct llinfo_nd6 *
 nd6_free(rt)
        struct rtentry *rt;
 {
-       struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
+       struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo, *next;
        struct sockaddr_dl *sdl;
        struct in6_addr in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
        struct nd_defrouter *dr;
@@ -873,11 +872,26 @@
                ln->ln_state = ND6_LLINFO_WAITDELETE;
                ln->ln_asked = 0;
                rt->rt_flags &= ~RTF_REJECT;
-               return;
+               return ln->ln_next;
        }
 
+       /*
+        * Before deleting the entry, remember the next entry as the
+        * return value.  We need this because pfxlist_onlink_check() above
+        * might have freed other entries (particularly the old next entry) as
+        * a side effect (XXX). 
+        */
+       next = ln->ln_next;
+
+       /*
+        * Detach the route from the routing tree and the list of neighbor
+        * caches, and disable the route entry not to be used in already
+        * cached routes.
+        */
        rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
                  rt_mask(rt), 0, (struct rtentry **)0);
+
+       return next;
 }
 
 /*
@@ -1585,7 +1599,7 @@
                return NULL;
        if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
 fail:
-               nd6_free(rt);
+               (void)nd6_free(rt);
                return NULL;
        }
        ln = (struct llinfo_nd6 *)rt->rt_llinfo;
diff -r f820d61c6ccb -r 3c79a4c12ea7 sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Thu Feb 08 12:36:06 2001 +0000
+++ b/sys/netinet6/nd6.h        Thu Feb 08 12:57:54 2001 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: nd6.h,v 1.17 2001/02/07 08:59:48 itojun Exp $  */
-/*     $KAME: nd6.h,v 1.42 2001/02/06 09:14:39 jinmei Exp $    */
+/*     $NetBSD: nd6.h,v 1.18 2001/02/08 12:57:55 itojun Exp $  */
+/*     $KAME: nd6.h,v 1.46 2001/02/08 10:57:00 itojun Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -283,7 +283,7 @@
 void nd6_setmtu __P((struct ifnet *));
 void nd6_timer __P((void *));
 void nd6_purge __P((struct ifnet *));
-void nd6_free __P((struct rtentry *));
+struct llinfo_nd6 *nd6_free __P((struct rtentry *));
 void nd6_nud_hint __P((struct rtentry *, struct in6_addr *, int));
 int nd6_resolve __P((struct ifnet *, struct rtentry *,
                     struct mbuf *, struct sockaddr *, u_char *));



Home | Main Index | Thread Index | Old Index