Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/route6d correct p2p interface address handling.



details:   https://anonhg.NetBSD.org/src/rev/a6f819dbef31
branches:  trunk
changeset: 486236:a6f819dbef31
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue May 16 14:04:32 2000 +0000

description:
correct p2p interface address handling.
avoid memory leak.
bzero() after malloc().
(sync from kame)

diffstat:

 usr.sbin/route6d/route6d.8 |    8 +-
 usr.sbin/route6d/route6d.c |  196 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 168 insertions(+), 36 deletions(-)

diffs (truncated from 379 to 300 lines):

diff -r 42e13c3a0afc -r a6f819dbef31 usr.sbin/route6d/route6d.8
--- a/usr.sbin/route6d/route6d.8        Tue May 16 13:45:25 2000 +0000
+++ b/usr.sbin/route6d/route6d.8        Tue May 16 14:04:32 2000 +0000
@@ -1,5 +1,5 @@
-.\"    $NetBSD: route6d.8,v 1.5 2000/02/25 06:22:05 itojun Exp $
-.\"    $KAME: route6d.8,v 1.5 2000/02/25 06:15:05 itojun Exp $
+.\"    $NetBSD: route6d.8,v 1.6 2000/05/16 14:04:32 itojun Exp $
+.\"    $KAME: route6d.8,v 1.6 2000/05/13 01:29:47 itojun Exp $
 .\"
 .\" Copyright (c) 1996 WIDE Project. All rights reserved.
 .\"
@@ -14,7 +14,6 @@
 .\" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
 .\" LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 .\" A PARTICULAR PURPOSE.
-.\"
 .Dd January 31, 1997
 .Dt ROUTE6D 8
 .Os
@@ -93,7 +92,8 @@
 By default,
 .Nm
 will not exchange site local routes for safety reasons.
-This is because semantics of site local address space is rather vague,
+This is because semantics of site local address space is rather vague
+.Pq specification is still in being worked ,
 and there is no good way to define site local boundary.
 With
 .Fl l
diff -r 42e13c3a0afc -r a6f819dbef31 usr.sbin/route6d/route6d.c
--- a/usr.sbin/route6d/route6d.c        Tue May 16 13:45:25 2000 +0000
+++ b/usr.sbin/route6d/route6d.c        Tue May 16 14:04:32 2000 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: route6d.c,v 1.11 2000/04/11 11:57:15 itojun Exp $      */
-/*     $KAME: route6d.c,v 1.16 2000/03/22 17:33:43 itojun Exp $        */
+/*     $NetBSD: route6d.c,v 1.12 2000/05/16 14:04:32 itojun Exp $      */
+/*     $KAME: route6d.c,v 1.19 2000/05/16 13:10:39 itojun Exp $        */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef        lint
-__RCSID("$NetBSD: route6d.c,v 1.11 2000/04/11 11:57:15 itojun Exp $");
+__RCSID("$NetBSD: route6d.c,v 1.12 2000/05/16 14:04:32 itojun Exp $");
 #endif
 
 #include <stdio.h>
@@ -229,6 +229,7 @@
 const char *rtflags __P((struct rt_msghdr *rtm));
 const char *ifflags __P((int flags));
 void ifrt __P((struct ifc *, int));
+void ifrt_p2p __P((struct ifc *, int));
 void applymask __P((struct in6_addr *, struct in6_addr *));
 void applyplen __P((struct in6_addr *, int));
 void ifrtdump __P((int));
@@ -275,8 +276,6 @@
        struct  ifc *ifcp;
        sigset_t mask, omask;
        FILE    *pidfile;
-       extern char *optarg;
-       extern int optind;
        char *progname;
 
        progname = strrchr(*argv, '/');
@@ -376,6 +375,7 @@
 
        if ((ripbuf = (struct rip6 *)malloc(RIP6_MAXMTU)) == NULL)
                fatal("malloc");
+       memset(ripbuf, 0, RIP6_MAXMTU);
        ripbuf->rip6_cmd = RIP6_RESPONSE;
        ripbuf->rip6_vers = RIP6_VERSION;
        ripbuf->rip6_res1[0] = 0;
@@ -1112,6 +1112,7 @@
                        /* Got a new valid route */
                        if ((rrt = MALLOC(struct riprt)) == NULL)
                                fatal("malloc: struct riprt");
+                       memset(rrt, 0, sizeof(*rrt));
                        nq = &rrt->rrt_info;
 
                        rrt->rrt_same = NULL;
@@ -1238,7 +1239,8 @@
                        continue;
                if (!ifcp) {
                        /* new interface */
-                       ifcp = (struct ifc *)malloc(sizeof(*ifcp));
+                       if ((ifcp = MALLOC(struct ifc)) == NULL)
+                               fatal("malloc: struct ifc");
                        memset(ifcp, 0, sizeof(*ifcp));
                        ifcp->ifc_index = -1;
                        ifcp->ifc_next = ifc;
@@ -1332,7 +1334,8 @@
                        goto skip;
                if (!ifcp) {
                        /* new interface */
-                       ifcp = (struct ifc *)malloc(sizeof(*ifcp));
+                       if ((ifcp = MALLOC(struct ifc)) == NULL)
+                               fatal("malloc: struct ifc");
                        memset(ifcp, 0, sizeof(*ifcp));
                        ifcp->ifc_index = -1;
                        ifcp->ifc_next = ifc;
@@ -1408,6 +1411,7 @@
         */
        if ((ifa = MALLOC(struct ifac)) == NULL)
                fatal("malloc: struct ifac");
+       memset(ifa, 0, sizeof(*ifa));
        ifa->ifa_conf = ifcp;
        ifa->ifa_next = ifcp->ifc_addr;
        ifcp->ifc_addr = ifa;
@@ -1857,20 +1861,39 @@
  */
 void
 ifrt(ifcp, again)
-       struct  ifc *ifcp;
+       struct ifc *ifcp;
        int again;
 {
-       struct  ifac *ifa;
-       struct  riprt *rrt;
-       struct  netinfo6 *np;
+       struct ifac *ifa;
+       struct riprt *rrt;
+       struct netinfo6 *np;
 
        if (ifcp->ifc_flags & IFF_LOOPBACK)
                return;                 /* ignore loopback */
+       if (ifcp->ifc_flags & IFF_POINTOPOINT) {
+               ifrt_p2p(ifcp, again);
+               return;
+       }
+
        for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
-               if (IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr))
-                       continue;       /* don't advertise link local addr */
+               if (IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr)) {
+#if 0
+                       trace(1, "route: %s on %s: "
+                           "skip linklocal interface address\n",
+                           inet6_n2p(&ifa->ifa_addr), ifcp->ifc_name);
+#endif
+                       continue;
+               }
+               if (IN6_IS_ADDR_UNSPECIFIED(&ifa->ifa_addr)) {
+#if 0
+                       trace(1, "route: %s: skip unspec interface address\n",
+                           ifcp->ifc_name);
+#endif
+                       continue;
+               }
                if ((rrt = MALLOC(struct riprt)) == NULL)
                        fatal("malloc: struct riprt");
+               memset(rrt, 0, sizeof(*rrt));
                rrt->rrt_same = NULL;
                rrt->rrt_index = ifcp->ifc_index;
                rrt->rrt_t = 0; /* don't age */
@@ -1883,46 +1906,153 @@
                np = &rrt->rrt_info;
                if (rtsearch(np) == NULL) {
                        /* Attach the route to the list */
+                       trace(1, "route: %s/%d: register route (%s)\n",
+                           inet6_n2p(&np->rip6_dest), np->rip6_plen,
+                           ifcp->ifc_name);
                        rrt->rrt_next = riprt;
                        riprt = rrt;
                } else {
                        /* Already found */
                        if (!again) {
-                               trace(1, "route: %s/%d: already registered\n",
-                                       inet6_n2p(&np->rip6_dest),
-                                       np->rip6_plen);
+                               trace(1, "route: %s/%d: "
+                                   "already registered (%s)\n",
+                                   inet6_n2p(&np->rip6_dest), np->rip6_plen,
+                                   ifcp->ifc_name);
                        }
                        free(rrt);
                }
+       }
+}
 
-               if (ifcp->ifc_flags & IFF_POINTOPOINT) {
+/*
+ * there are couple of p2p interface routing models.  "behavior" lets
+ * you pick one.
+ */
+void
+ifrt_p2p(ifcp, again)
+       struct ifc *ifcp;
+       int again;
+{
+       struct ifac *ifa;
+       struct riprt *rrt;
+       struct netinfo6 *np;
+       struct in6_addr addr, dest;
+       int advert, i;
+#define P2PADVERT_NETWORK      1
+#define P2PADVERT_ADDR         2
+#define P2PADVERT_DEST         4
+#define P2PADVERT_MAX          4
+       const enum { CISCO, GATED, ROUTE6D } behavior = GATED;
+       const char *category;
+       const char *noadv;
+
+       for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
+               addr = ifa->ifa_addr;
+               dest = ifa->ifa_raddr;
+               applyplen(&addr, ifa->ifa_plen);
+               applyplen(&dest, ifa->ifa_plen);
+               switch (behavior) {
+               case CISCO:
+                       /*
+                        * advertise addr/plen, treating p2p interface
+                        * just like shared medium interface.
+                        * this may cause trouble if you reuse addr/plen
+                        * in other places.
+                        */
+                       advert |= P2PADVERT_NETWORK;
+                       break;
+               case GATED:
+                       /*
+                        * advertise dest/128.  since addr/128 is not
+                        * advertised, addr/128 is not reachable from other
+                        * interfaces (if p2p interface is A, addr/128 is not
+                        * reachable from other interfaces).  not sure why it
+                        * is not advertised.
+                        */
+                       advert |= P2PADVERT_DEST;
+                       break;
+               case ROUTE6D:
+                       /*
+                        * just for testing...
+                        */
+                       if (IN6_ARE_ADDR_EQUAL(&addr, &dest))
+                               advert |= P2PADVERT_NETWORK;
+                       else {
+                               advert |= P2PADVERT_ADDR;
+                               advert |= P2PADVERT_DEST;
+                       }
+                       break;
+               }
+
+               for (i = 1; i <= P2PADVERT_MAX; i *= 2) {
                        if ((rrt = MALLOC(struct riprt)) == NULL)
                                fatal("malloc: struct riprt");
+                       memset(rrt, 0, sizeof(*rrt));
                        rrt->rrt_same = NULL;
                        rrt->rrt_index = ifcp->ifc_index;
-                       rrt->rrt_t = 0; /* Don't age */
-                       rrt->rrt_info.rip6_dest = ifa->ifa_raddr;
+                       rrt->rrt_t = 0; /* don't age */
+                       switch (i) {
+                       case P2PADVERT_NETWORK:
+                               rrt->rrt_info.rip6_dest = ifa->ifa_addr;
+                               rrt->rrt_info.rip6_plen = ifa->ifa_plen;
+                               applyplen(&rrt->rrt_info.rip6_dest,
+                                   ifa->ifa_plen);
+                               category = "network";
+                               break;
+                       case P2PADVERT_ADDR:
+                               rrt->rrt_info.rip6_dest = ifa->ifa_addr;
+                               rrt->rrt_info.rip6_plen = 128;
+                               category = "addr";
+                               break;
+                       case P2PADVERT_DEST:
+                               rrt->rrt_info.rip6_dest = ifa->ifa_raddr;
+                               rrt->rrt_info.rip6_plen = 128;
+                               category = "dest";
+                               break;
+                       }
+                       if (IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_info.rip6_dest) ||
+                           IN6_IS_ADDR_LINKLOCAL(&rrt->rrt_info.rip6_dest)) {
+#if 0
+                               trace(1, "route: %s: skip unspec/linklocal "
+                                   "(%s on %s)\n", category, ifcp->ifc_name);
+#endif
+                               free(rrt);
+                               continue;
+                       }
+                       if ((advert & i) == 0) {
+                               rrt->rrt_flags |= RTF_NOADVERTISE;
+                               noadv = ", NO-ADV";
+                       } else
+                               noadv = "";
                        rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
-                       rrt->rrt_info.rip6_metric = 1;
-                       rrt->rrt_info.rip6_plen = 128;
-                       rrt->rrt_gw = ifa->ifa_addr;
-                       rrt->rrt_flags |= RTF_NOADVERTISE;
+                       rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric;
+                       memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr));
                        np = &rrt->rrt_info;
                        if (rtsearch(np) == NULL) {
                                /* Attach the route to the list */
+                               trace(1, "route: %s/%d: register route "
+                                   "(%s on %s%s)\n",
+                                   inet6_n2p(&np->rip6_dest), np->rip6_plen,
+                                   category, ifcp->ifc_name, noadv);
                                rrt->rrt_next = riprt;
                                riprt = rrt;



Home | Main Index | Thread Index | Old Index