/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1993-1998 Apple Computer, Inc.
#include <netat/debug.h>
#include <netat/at_pcb.h>
+#include <sys/kern_event.h>
+
extern void rtmp_router_input();
/****************************************************************/
unused = router;
}
if (unused) {
- router_added++;
+ router_added++;
+ if (ifID->ifARouter.s_net == 0) {
+ /* Send event that this interface just got a router. This does not
+ discriminate on whether this router is valid or not. If it is not
+ valid rtmp_input will send a KEV_ATALK_ROUTERUP_INVALID event. */
+ atalk_post_msg(ifID->aa_ifp, KEV_ATALK_ROUTERUP, 0, 0);
+ }
+
unused->ifID = ifID;
NET(unused) = net;
NODE(unused) = node;
+ ifID->ifRouterState = ROUTER_AROUND;
timeout(ddp_age_router, (caddr_t) unused, 50*SYS_HZ);
+
if (NET(ifID) == 0 && NODE(ifID) == 0) {
NET(ifID) = net;
NODE(ifID) = node;
- ifID->ifRouterState = ROUTER_AROUND;
}
}
}
void ddp_age_router(deadrouter)
register struct routerinfo *deadrouter;
{
- register at_ifaddr_t *ourrouter = deadrouter->ifID;
- boolean_t funnel_state;
+ register at_ifaddr_t *ourrouter;
- funnel_state = thread_funnel_set(network_flock, TRUE);
+ atalk_lock();
+
+ ourrouter = deadrouter->ifID;
+ if (ourrouter == NULL) {
+ atalk_unlock();
+ return;
+ }
dPrintf(D_M_RTMP, D_L_INFO,
("ddp_age_router called deadrouter=%d:%d\n", NODE(deadrouter), NET(deadrouter)));
newrouter = NULL;
}
if (newrouter) {
+ /* Set our router to another on the list and go on with life */
NET(ourrouter) = NET(newrouter);
NODE(ourrouter) = NODE(newrouter);
}
else {
/* from gorouterless() */
+ /* We have no other routers. */
ATTRACE(AT_MID_DDP, AT_SID_TIMERS, AT_LV_WARNING, FALSE,
"ddp_age_router entry : ARouter = 0x%x, RouterState = 0x%x",
ATALK_VALUE(ourrouter->ifARouter), ourrouter->ifRouterState, 0);
switch (ourrouter->ifRouterState) {
case ROUTER_AROUND :
+ /* This is where we lose our cable.
+ Reset router fields and state accordingly. */
ourrouter->ifARouter.s_net = 0;
ourrouter->ifARouter.s_node = 0;
- dPrintf(D_M_RTMP,D_L_INFO,
- ("rtmp.c Gorouterless!!!!!!!!\n"));
ourrouter->ifThisCableStart = DDP_MIN_NETWORK;
ourrouter->ifThisCableEnd = DDP_MAX_NETWORK;
ourrouter->ifRouterState = NO_ROUTER;
+
+ /* Send event to indicate that we've lost our seed router. */
+ atalk_post_msg(ourrouter->aa_ifp, KEV_ATALK_ROUTERDOWN, 0, 0);
+
zip_control(ourrouter, ZIP_NO_ROUTER);
break;
case ROUTER_WARNING :
} else
bzero((caddr_t) deadrouter, sizeof(struct routerinfo));
- (void) thread_funnel_set(network_flock, FALSE);
+ atalk_unlock();
} /* ddp_age_router */
* ignore the presence of router
*/
if (ifID->ifRouterState == NO_ROUTER) {
- dPrintf(D_M_RTMP, D_L_STARTUP,
- ("Warning: new router came up: invalid startup net/node\n"));
+ dPrintf(D_M_RTMP, D_L_INFO, ("rtmp_input: new router came up, INVALID: net \
+ in startup range.\n"));
+ /* trackrouter sends a KEV_ATALK_ROUTERUP event to note that
+ a new router has come up when we had none before. */
trackrouter(ifID,
NET_VALUE(rtmp->at_rtmp_this_net),
rtmp->at_rtmp_id[0]
);
ifID->ifRouterState = ROUTER_WARNING;
+
+ /* This router is invalid. Send event. */
+ atalk_post_msg(ifID->aa_ifp, KEV_ATALK_ROUTERUP_INVALID, 0, 0);
}
} else {
/* our address
*/
ifID->ifThisCableStart = range_start;
ifID->ifThisCableEnd = range_end;
+
+ /* A seed router that gives us back our cable range came up.
+ It's a valid router and gives us our network back. */
+ atalk_post_msg(ifID->aa_ifp, KEV_ATALK_ROUTERUP, 0, 0);
+
trackrouter(ifID,
NET_VALUE(rtmp->at_rtmp_this_net),
rtmp->at_rtmp_id[0]
* router
*/
if (ifID->ifRouterState == NO_ROUTER) {
- dPrintf(D_M_RTMP,D_L_ERROR,
- ("Warning: new router came up: invalid net/node\n"));
+ /* trackrouter sends a KEV_ATALK_ROUTERUP event to note that
+ a new router has come up when we had none before. */
trackrouter(ifID,
NET_VALUE(rtmp->at_rtmp_this_net),
rtmp->at_rtmp_id[0]
);
ifID->ifRouterState = ROUTER_WARNING;
+
+ /* A new seed router came up, but the cable range is different
+ than what we had before. */
+ atalk_post_msg(ifID->aa_ifp, KEV_ATALK_ROUTERUP_INVALID, 0, 0);
}
}
}