delay deletion from internal tables when cur router deletes
[unix-history] / usr / src / sbin / routed / input.c
index 035ecf6..d9bc288 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)input.c    5.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)input.c    5.7 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -27,6 +27,7 @@ rip_input(from, size)
        struct interface *if_ifwithdstaddr();
        int newsize;
        register struct afswitch *afp;
        struct interface *if_ifwithdstaddr();
        int newsize;
        register struct afswitch *afp;
+       static struct sockaddr badfrom;
 
        ifp = 0;
        TRACE_INPUT(ifp, from, size);
 
        ifp = 0;
        TRACE_INPUT(ifp, from, size);
@@ -63,7 +64,7 @@ rip_input(from, size)
                        if (n->rip_dst.sa_family == AF_UNSPEC &&
                            n->rip_metric == HOPCNT_INFINITY && size == 0) {
                                if (supplier || (*afp->af_portmatch)(from) == 0)
                        if (n->rip_dst.sa_family == AF_UNSPEC &&
                            n->rip_metric == HOPCNT_INFINITY && size == 0) {
                                if (supplier || (*afp->af_portmatch)(from) == 0)
-                                       supply(from, 0, ifp);
+                                       supply(from, 0, 0);
                                return;
                        }
                        if (n->rip_dst.sa_family < af_max &&
                                return;
                        }
                        if (n->rip_dst.sa_family < af_max &&
@@ -92,6 +93,11 @@ rip_input(from, size)
                /* verify message came from a privileged port */
                if ((*afp->af_portcheck)(from) == 0)
                        return;
                /* verify message came from a privileged port */
                if ((*afp->af_portcheck)(from) == 0)
                        return;
+               if (if_iflookup(from) == 0) {
+                       syslog(LOG_ERR, "trace command from unknown router, %s",
+                           (*afswitch[from->sa_family].af_format)(from));
+                       return;
+               }
                packet[size] = '\0';
                if (msg->rip_cmd == RIPCMD_TRACEON)
                        traceon(msg->rip_tracefile);
                packet[size] = '\0';
                if (msg->rip_cmd == RIPCMD_TRACEON)
                        traceon(msg->rip_tracefile);
@@ -119,10 +125,21 @@ rip_input(from, size)
                 * If from other end of a point-to-point link that isn't
                 * in the routing tables, (re-)add the route.
                 */
                 * If from other end of a point-to-point link that isn't
                 * in the routing tables, (re-)add the route.
                 */
-               if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE))
+               if ((rt = rtfind(from)) &&
+                   (rt->rt_state & (RTS_INTERFACE | RTS_REMOTE)))
                        rt->rt_timer = 0;
                else if (ifp = if_ifwithdstaddr(from))
                        addrouteforif(ifp);
                        rt->rt_timer = 0;
                else if (ifp = if_ifwithdstaddr(from))
                        addrouteforif(ifp);
+               else if (if_iflookup(from) == 0) {
+                       if (bcmp((char *)from, (char *)&badfrom,
+                           sizeof(badfrom)) != 0) {
+                               syslog(LOG_ERR,
+                                 "packet from unknown router, %s",
+                                 (*afswitch[from->sa_family].af_format)(from));
+                               badfrom = *from;
+                       }
+                       return;
+               }
                size -= 4 * sizeof (char);
                n = msg->rip_nets;
                for (; size > 0; size -= sizeof (struct netinfo), n++) {
                size -= 4 * sizeof (char);
                n = msg->rip_nets;
                for (; size > 0; size -= sizeof (struct netinfo), n++) {
@@ -153,7 +170,13 @@ rip_input(from, size)
                                continue;
                        }
                        rt = rtlookup(&n->rip_dst);
                                continue;
                        }
                        rt = rtlookup(&n->rip_dst);
-                       if (rt == 0) {
+                       if (rt == 0 ||
+                           (rt->rt_state & (RTS_INTERNAL|RTS_INTERFACE)) ==
+                           (RTS_INTERNAL|RTS_INTERFACE)) {
+                               rt = rtfind(&n->rip_dst);
+                               if (rt && equal(from, &rt->rt_router) &&
+                                   rt->rt_metric == n->rip_metric)
+                                       continue;
                                if (n->rip_metric < HOPCNT_INFINITY)
                                    rtadd(&n->rip_dst, from, n->rip_metric, 0);
                                continue;
                                if (n->rip_metric < HOPCNT_INFINITY)
                                    rtadd(&n->rip_dst, from, n->rip_metric, 0);
                                continue;
@@ -164,10 +187,6 @@ rip_input(from, size)
                         * shorter, or getting stale and equivalent.
                         */
                        if (equal(from, &rt->rt_router)) {
                         * shorter, or getting stale and equivalent.
                         */
                        if (equal(from, &rt->rt_router)) {
-                               if (n->rip_metric == HOPCNT_INFINITY) {
-                                       rtdelete(rt);
-                                       continue;
-                               }
                                if (n->rip_metric != rt->rt_metric)
                                        rtchange(rt, from, n->rip_metric);
                                rt->rt_timer = 0;
                                if (n->rip_metric != rt->rt_metric)
                                        rtchange(rt, from, n->rip_metric);
                                rt->rt_timer = 0;