Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 remove IPv6 router renumbering prefix informati...



details:   https://anonhg.NetBSD.org/src/rev/9d81bdb7b4b9
branches:  trunk
changeset: 481821:9d81bdb7b4b9
user:      itojun <itojun%NetBSD.org@localhost>
date:      Mon Feb 07 05:48:11 2000 +0000

description:
remove IPv6 router renumbering prefix information in the kernel
when all the interface addresses are gone.
this should remove dangling structure when:
# ifconfig lo0 inet6 3ffe::1 prefixlen 64 alias
# ifconfig lo0 inet6 3ffe::1 -alias
is performed.

diffstat:

 sys/netinet6/in6_prefix.c |  53 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 49 insertions(+), 4 deletions(-)

diffs (108 lines):

diff -r 2d86e7ca5180 -r 9d81bdb7b4b9 sys/netinet6/in6_prefix.c
--- a/sys/netinet6/in6_prefix.c Mon Feb 07 05:42:59 2000 +0000
+++ b/sys/netinet6/in6_prefix.c Mon Feb 07 05:48:11 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_prefix.c,v 1.8 2000/02/06 12:49:44 itojun Exp $    */
+/*     $NetBSD: in6_prefix.c,v 1.9 2000/02/07 05:48:11 itojun Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -87,10 +87,13 @@
 
 #include <net/net_osdep.h>
 
+static void    add_each_addr __P((struct socket *so, struct rr_prefix *rpp,
+                                  struct rp_addr *rap));
 static int create_ra_entry __P((struct rp_addr **rapp));
 static int add_each_prefix __P((struct socket *so, struct rr_prefix *rpp));
 static void free_rp_entries __P((struct rr_prefix *rpp));
 static int link_stray_ia6s __P((struct rr_prefix *rpp));
+static void    rp_remove __P((struct rr_prefix *rpp));
 
 /*
  * Copy bits from src to tgt, from off bit for len bits.
@@ -393,6 +396,34 @@
        return 0;
 }
 
+static int
+in6_prefix_add_llifid(int iilen, struct in6_ifaddr *ia)
+{
+       struct rr_prefix *rpp;
+       struct rp_addr *rap;
+       struct socket so;
+       int error, s;
+
+       if ((error = create_ra_entry(&rap)) != 0)
+               return(error);
+       /* copy interface id part */
+       bit_copy((caddr_t)&rap->ra_ifid, sizeof(rap->ra_ifid) << 3,
+                (caddr_t)IA6_IN6(ia), sizeof(*IA6_IN6(ia)) << 3,
+                64, (sizeof(rap->ra_ifid) << 3) - 64);
+       /* XXX: init dummy so */
+       bzero(&so, sizeof(so));
+       /* insert into list */
+       for (rpp = LIST_FIRST(&rr_prefix); rpp; rpp = LIST_NEXT(rpp, rp_entry))
+       {
+               s = splnet();
+               LIST_INSERT_HEAD(&rpp->rp_addrhead, rap, ra_entry);
+               splx(s);
+               add_each_addr(&so, rpp, rap);
+       }
+       return 0;
+}
+
+
 int
 in6_prefix_add_ifid(int iilen, struct in6_ifaddr *ia)
 {
@@ -401,6 +432,8 @@
        struct rp_addr *rap;
        int error = 0;
 
+       if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
+               return(in6_prefix_add_llifid(iilen, ia));
        ifpr = in6_prefixwithifp(ia->ia_ifp, plen, IA6_IN6(ia));
        if (ifpr == NULL) {
                struct rr_prefix rp;
@@ -486,6 +519,8 @@
                splx(s);
                free(rap, M_RR_ADDR);
        }
+       if (LIST_FIRST(&ifpr2rp(ia->ia6_ifpr)->rp_addrhead) == NULL)
+               rp_remove(ifpr2rp(ia->ia6_ifpr));
 }
 
 void
@@ -1030,11 +1065,20 @@
                        free_rp_entries(&rp_tmp);
                        break;
                }
-               ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp);
-               if (ifa != NULL) {
+               for (ifa = ifp->if_addrlist.tqh_first;
+                    ifa;
+                    ifa = ifa->ifa_list.tqe_next)
+               {
+                       if (ifa->ifa_addr == NULL)
+                               continue;       /* just for safety */
+                       if (ifa->ifa_addr->sa_family != AF_INET6)
+                               continue;
+                       if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa)) == 0)
+                               continue;
+
                        if ((error = create_ra_entry(&rap)) != 0) {
                                free_rp_entries(&rp_tmp);
-                               break;
+                               goto bad;
                        }
                        /* copy interface id part */
                        bit_copy((caddr_t)&rap->ra_ifid,
@@ -1061,6 +1105,7 @@
                error = delete_each_prefix(rpp, ipr->ipr_origin);
                break;
        }
+ bad:
        return error;
 }
 



Home | Main Index | Thread Index | Old Index