Source-Changes-HG archive

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

[src/trunk]: src perform neighbor unreachability detection on p2p links (spec...



details:   https://anonhg.NetBSD.org/src/rev/1e91f6e45275
branches:  trunk
changeset: 485000:1e91f6e45275
user:      itojun <itojun%NetBSD.org@localhost>
date:      Sun Apr 16 15:27:59 2000 +0000

description:
perform neighbor unreachability detection on p2p links (spec requires
it for bidir p2p links).
improve -i in ndp(8) to allow tweaking per-interface ND flag on.
fix ndp(8) infinite loop on certain routing table setup.

diffstat:

 sys/netinet6/in6.c          |   3 +-
 sys/netinet6/in6_ifattach.c |   8 +----
 sys/netinet6/in6_var.h      |   4 +-
 sys/netinet6/nd6.c          |  64 ++++++++++++++++++++++++++++++----------
 sys/netinet6/nd6.h          |   5 ++-
 usr.sbin/ndp/ndp.8          |  27 +++++++++++++---
 usr.sbin/ndp/ndp.c          |  71 ++++++++++++++++++++++++++++++++++++--------
 7 files changed, 138 insertions(+), 44 deletions(-)

diffs (truncated from 406 to 300 lines):

diff -r 5500e559a7fa -r 1e91f6e45275 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Sun Apr 16 15:00:56 2000 +0000
+++ b/sys/netinet6/in6.c        Sun Apr 16 15:27:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.30 2000/04/16 15:00:56 itojun Exp $  */
+/*     $NetBSD: in6.c,v 1.31 2000/04/16 15:27:59 itojun Exp $  */
 /*     $KAME: in6.c,v 1.75 2000/04/12 03:51:29 itojun Exp $    */
 
 /*
@@ -366,6 +366,7 @@
        case SIOCSPFXFLUSH_IN6:
        case SIOCSRTRFLUSH_IN6:
        case SIOCSDEFIFACE_IN6:
+       case SIOCSIFINFO_FLAGS:
                if (!privileged)
                        return(EPERM);
                /*fall through*/
diff -r 5500e559a7fa -r 1e91f6e45275 sys/netinet6/in6_ifattach.c
--- a/sys/netinet6/in6_ifattach.c       Sun Apr 16 15:00:56 2000 +0000
+++ b/sys/netinet6/in6_ifattach.c       Sun Apr 16 15:27:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_ifattach.c,v 1.27 2000/04/16 15:00:57 itojun Exp $ */
+/*     $NetBSD: in6_ifattach.c,v 1.28 2000/04/16 15:28:00 itojun Exp $ */
 /*     $KAME: in6_ifattach.c,v 1.53 2000/04/16 14:01:42 itojun Exp $   */
 
 /*
@@ -406,13 +406,7 @@
 #endif
                        rtflag = 0;
                        break;
-#if 1
-               case IFT_ARCNET:
-               case IFT_ETHER:
-               case IFT_FDDI:
-#else
                default:
-#endif
                        ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
                        ia->ia_ifa.ifa_flags |= RTF_CLONING;
                        rtflag = RTF_CLONING;
diff -r 5500e559a7fa -r 1e91f6e45275 sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h    Sun Apr 16 15:00:56 2000 +0000
+++ b/sys/netinet6/in6_var.h    Sun Apr 16 15:27:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_var.h,v 1.15 2000/04/16 15:00:57 itojun Exp $      */
+/*     $NetBSD: in6_var.h,v 1.16 2000/04/16 15:28:00 itojun Exp $      */
 /*     $KAME: in6_var.h,v 1.31 2000/03/25 07:23:46 sumikawa Exp $      */
 
 /*
@@ -395,6 +395,8 @@
 #define SIOCSDEFIFACE_IN6      _IOWR('i', 85, struct in6_ndifreq)
 #define SIOCGDEFIFACE_IN6      _IOWR('i', 86, struct in6_ndifreq)
 
+#define SIOCSIFINFO_FLAGS      _IOWR('i', 87, struct in6_ndireq) /* XXX */
+
 #define SIOCSIFPREFIX_IN6      _IOW('i', 100, struct in6_prefixreq) /* set */
 #define SIOCGIFPREFIX_IN6      _IOWR('i', 101, struct in6_prefixreq) /* get */
 #define SIOCDIFPREFIX_IN6      _IOW('i', 102, struct in6_prefixreq) /* del */
diff -r 5500e559a7fa -r 1e91f6e45275 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Sun Apr 16 15:00:56 2000 +0000
+++ b/sys/netinet6/nd6.c        Sun Apr 16 15:27:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.25 2000/04/16 15:00:57 itojun Exp $  */
+/*     $NetBSD: nd6.c,v 1.26 2000/04/16 15:28:00 itojun Exp $  */
 /*     $KAME: nd6.c,v 1.55 2000/04/16 14:08:30 itojun Exp $    */
 
 /*
@@ -173,6 +173,7 @@
        ND.reachable = ND_COMPUTE_RTIME(ND.basereachable);
        ND.retrans = RETRANS_TIMER;
        ND.receivedra = 0;
+       ND.flags = ND6_IFF_PERFORMNUD;
        nd6_setmtu(ifp);
 #undef ND
 }
@@ -392,6 +393,8 @@
                struct ifnet *ifp;
                struct sockaddr_in6 *dst;
                struct llinfo_nd6 *next = ln->ln_next;
+               /* XXX: used for the DELAY case only: */
+               struct nd_ifinfo *ndi = NULL;
 
                if ((rt = ln->ln_rt) == NULL) {
                        ln = next;
@@ -401,6 +404,7 @@
                        ln = next;
                        continue;
                }
+               ndi = &nd_ifinfo[ifp->if_index];
                dst = (struct sockaddr_in6 *)rt_key(rt);
 
                if (ln->ln_expire > time_second) {
@@ -454,14 +458,19 @@
                 * routine.
                 */
                case ND6_LLINFO_DELAY:
-                       ln->ln_asked = 1;
-                       ln->ln_state = ND6_LLINFO_PROBE;
-                       ln->ln_expire = time_second +
-                               nd_ifinfo[ifp->if_index].retrans / 1000;
-                       nd6_ns_output(ifp, &dst->sin6_addr, &dst->sin6_addr,
-                               ln, 0);
+                       if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) {
+                               /* We need NUD */
+                               ln->ln_asked = 1;
+                               ln->ln_state = ND6_LLINFO_PROBE;
+                               ln->ln_expire = time_second +
+                                       ndi->retrans / 1000;
+                               nd6_ns_output(ifp, &dst->sin6_addr,
+                                             &dst->sin6_addr,
+                                             ln, 0);
+                       }
+                       else
+                               ln->ln_state = ND6_LLINFO_STALE; /* XXX */
                        break;
-
                case ND6_LLINFO_PROBE:
                        if (ln->ln_asked < nd6_umaxtries) {
                                ln->ln_asked++;
@@ -1074,14 +1083,21 @@
 #endif
                /* FALLTHROUGH */
        case RTM_RESOLVE:
-               if (gate->sa_family != AF_LINK ||
-                   gate->sa_len < sizeof(null_sdl)) {
-                       log(LOG_DEBUG, "nd6_rtrequest: bad gateway value\n");
-                       break;
+               if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
+                       /*
+                        * Address resolution isn't necessary for a point to
+                        * point link, so we can skip this test for a p2p link.
+                        */
+                       if (gate->sa_family != AF_LINK ||
+                           gate->sa_len < sizeof(null_sdl)) {
+                               log(LOG_DEBUG,
+                                   "nd6_rtrequest: bad gateway value\n");
+                               break;
+                       }
+                       SDL(gate)->sdl_type = ifp->if_type;
+                       SDL(gate)->sdl_index = ifp->if_index;
                }
-               SDL(gate)->sdl_type = ifp->if_type;
-               SDL(gate)->sdl_index = ifp->if_index;
-               if (ln != 0)
+               if (ln != NULL)
                        break;  /* This happens on a route change */
                /*
                 * Case 2: This route may come from cloning, or a manual route
@@ -1380,6 +1396,10 @@
        case SIOCGIFINFO_IN6:
                ndi->ndi = nd_ifinfo[ifp->if_index];
                break;
+       case SIOCSIFINFO_FLAGS:
+               /* XXX: almost all other fields of ndi->ndi is unused */
+               nd_ifinfo[ifp->if_index].flags = ndi->ndi.flags;
+               break;
        case SIOCSNDFLUSH_IN6:  /* XXX: the ioctl name is confusing... */
                /* flush default router list */
                /*
@@ -1722,17 +1742,25 @@
 
        /*
         * XXX: we currently do not make neighbor cache on any interface
-        * other than ARCnet, Ethernet and FDDI.
+        * other than ARCnet, Ethernet, FDDI and GIF.
+        *
+        * draft-ietf-ngtrans-mech-04.txt says:
+        * - unidirectional tunnels needs no ND
         */
        switch (ifp->if_type) {
        case IFT_ARCNET:
        case IFT_ETHER:
        case IFT_FDDI:
+       case IFT_GIF:           /* XXX need more cases? */
                break;
        default:
                goto sendpkt;
        }
 
+       if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
+           (nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD) == 0)
+               goto sendpkt;
+
        /*
         * next hop determination. This routine is derived from ether_outpout.
         */
@@ -1782,6 +1810,10 @@
                senderr(EIO);   /* XXX: good error? */
        }
 
+       /* We don't have to do link-layer address resolution on a p2p link. */
+       if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
+           ln->ln_state < ND6_LLINFO_REACHABLE)
+               ln->ln_state = ND6_LLINFO_STALE;
 
        /*
         * The first time we send a packet to a neighbor whose entry is
diff -r 5500e559a7fa -r 1e91f6e45275 sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Sun Apr 16 15:00:56 2000 +0000
+++ b/sys/netinet6/nd6.h        Sun Apr 16 15:27:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.h,v 1.11 2000/04/16 15:00:57 itojun Exp $  */
+/*     $NetBSD: nd6.h,v 1.12 2000/04/16 15:28:00 itojun Exp $  */
 /*     $KAME: nd6.h,v 1.19 2000/03/25 07:23:57 sumikawa Exp $  */
 
 /*
@@ -68,11 +68,14 @@
        u_int32_t basereachable;        /* BaseReachableTime */
        u_int32_t reachable;            /* Reachable Time */
        u_int32_t retrans;              /* Retrans Timer */
+       u_int32_t flags;                /* Flags */
        int recalctm;                   /* BaseReacable re-calculation timer */
        u_int8_t chlim;                 /* CurHopLimit */
        u_int8_t receivedra;
 };
 
+#define ND6_IFF_PERFORMNUD     0x1
+
 struct in6_nbrinfo {
        char ifname[IFNAMSIZ];  /* if name, e.g. "en0" */
        struct in6_addr addr;   /* IPv6 address of the neighbor */
diff -r 5500e559a7fa -r 1e91f6e45275 usr.sbin/ndp/ndp.8
--- a/usr.sbin/ndp/ndp.8        Sun Apr 16 15:00:56 2000 +0000
+++ b/usr.sbin/ndp/ndp.8        Sun Apr 16 15:27:59 2000 +0000
@@ -25,8 +25,8 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $NetBSD: ndp.8,v 1.6 2000/03/07 19:40:54 kleink Exp $
-.\"    KAME Id: ndp.8,v 1.5 2000/02/17 05:35:56 itojun Exp
+.\"    $NetBSD: ndp.8,v 1.7 2000/04/16 15:28:01 itojun Exp $
+.\"     KAME Id: ndp.8,v 1.9 2000/04/16 15:17:33 itojun Exp
 .\"
 .Dd May 17, 1998
 .Dt NDP 8
@@ -62,6 +62,7 @@
 .Nm ndp
 .Fl i
 .Ar interface
+.Op Ar flags...
 .Nm ndp
 .Fl p
 .Nm ndp
@@ -112,9 +113,25 @@
 If a special keyword
 .Ic delete
 is specified, the current default interface will be deleted from the kernel.
-.It Fl i
-.Ar interface
-view ND information for specified interface.
+.It Fl i Ar interface Op Ar flags...
+View ND information for the specified interface.
+If additional arguments
+.Ar flags
+are given,
+.Nm
+sets or clears the specified flags for the interface.
+Possible flags are as follows. All of the flags can begin with the
+special character
+.Ql - ,
+which means the flag should be cleared.
+.\"
+.Bl -tag -width Ds -compact
+.It Xo
+.Ic nud
+.Xc
+turn on or off NUD (Neighbor Unreachability Detection) on the
+interface. NUD is usually turned on by default.
+.El
 .It Fl l
 Do not truncate numeric IPv6 address.
 .It Fl n
diff -r 5500e559a7fa -r 1e91f6e45275 usr.sbin/ndp/ndp.c
--- a/usr.sbin/ndp/ndp.c        Sun Apr 16 15:00:56 2000 +0000
+++ b/usr.sbin/ndp/ndp.c        Sun Apr 16 15:27:59 2000 +0000
@@ -148,7 +148,7 @@
 int ndp_ether_aton __P((char *, u_char *));
 void usage __P((void));
 int rtmsg __P((int));
-void ifinfo __P((char *));
+void ifinfo __P((int, char **));
 void rtrlist __P((void));
 void plist __P((void));
 void pfx_flush __P((void));
@@ -196,9 +196,11 @@
                        /*NOTREACHED*/
 #endif
                case 'i' :
-                       if (argc != 3)
+                       argc -= optind;
+                       argv += optind;
+                       if (argc < 1)
                                usage();
-                       ifinfo(argv[2]);
+                       ifinfo(argc, argv);
                        exit(0);
                case 'n':
                        nflag = 1;
@@ -480,12 +482,16 @@
        if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) {



Home | Main Index | Thread Index | Old Index