void add_ptopt_localrt(struct interface *ifp) { struct rt_entry *rt; struct sockaddr *dst; struct sockaddr_in net; int state; state = RTS_INTERFACE | RTS_PASSIVE; /* look for route to logical network */ memset(&net, 0, sizeof (net)); net.sin_family = AF_INET; net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); dst = (struct sockaddr *)&net; rt = rtfind(dst); if (rt && rt->rt_state & RTS_INTERNAL) state |= RTS_SUBNET; dst = &ifp->int_addr; if ((rt = rtfind(dst))!=NULL) { if (rt && rt->rt_state & RTS_INTERFACE) return; rtdelete(rt); } rtadd(dst, &loopaddr, 1, state); }
void addrouteforif(struct interface *ifp) { struct sockaddr_in net; struct sockaddr *dst; int state; struct rt_entry *rt; if (ifp->int_flags & IFF_POINTOPOINT) dst = &ifp->int_dstaddr; else { memset(&net, 0, sizeof (net)); net.sin_family = AF_INET; net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY); dst = (struct sockaddr *)&net; } rt = rtfind(dst); if (rt && (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE) return; if (rt) rtdelete(rt); /* * If interface on subnetted network, * install route to network as well. * This is meant for external viewers. */ if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) { struct in_addr subnet; subnet = net.sin_addr; net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); rt = rtfind(dst); if (rt == 0) rtadd(dst, &ifp->int_addr, ifp->int_metric, ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET)); else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == (RTS_INTERNAL|RTS_SUBNET) && ifp->int_metric < rt->rt_metric) rtchange(rt, &rt->rt_router, ifp->int_metric); net.sin_addr = subnet; } if (ifp->int_transitions++ > 0) syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); state = ifp->int_flags & (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET); if (ifp->int_flags & IFF_POINTOPOINT && (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) & ifp->int_netmask) != ifp->int_net) state &= ~RTS_SUBNET; if (ifp->int_flags & IFF_LOOPBACK) state |= RTS_EXTERNAL; rtadd(dst, &ifp->int_addr, ifp->int_metric, state); if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) add_ptopt_localrt(ifp); }
void timer(int signum) { register struct rthash *rh; register struct rt_entry *rt; struct rthash *base = hosthash; int doinghost = 1, timetobroadcast; (void)signum; (void) gettimeofday(&now, (struct timezone *)NULL); faketime += TIMER_RATE; if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0) ifinit(); timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0; again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { /* * We don't advance time on a routing entry for * a passive gateway, or any interface if we're * not acting as supplier. */ if (!(rt->rt_state & RTS_PASSIVE) && (supplier || !(rt->rt_state & RTS_INTERFACE))) rt->rt_timer += TIMER_RATE; if (rt->rt_timer >= GARBAGE_TIME) { rt = rt->rt_back; rtdelete(rt->rt_forw); continue; } if (rt->rt_timer >= EXPIRE_TIME && rt->rt_metric < HOPCNT_INFINITY) rtchange(rt, &rt->rt_router, HOPCNT_INFINITY); rt->rt_state &= ~RTS_CHANGED; } } if (doinghost) { doinghost = 0; base = nethash; goto again; } if (timetobroadcast) { toall(supply, 0, (struct interface *)NULL); lastbcast = now; lastfullupdate = now; needupdate = 0; /* cancel any pending dynamic update */ nextbcast.tv_sec = 0; } #ifdef EMBED signal(signum, timer); #endif }
void addrouteforif(struct interface *ifp) { struct sockaddr_ipx net; struct sockaddr *dst; struct rt_entry *rt; if (ifp->int_flags & IFF_POINTOPOINT) { int (*match)(); struct interface *ifp2 = ifnet; dst = &ifp->int_dstaddr; /* Search for interfaces with the same net */ ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq); match = afswitch[dst->sa_family].af_netmatch; if (match) for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) { if ((ifp->int_flags & IFF_POINTOPOINT) == 0) continue; if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) { insque(&ifp2->int_sq,&ifp->int_sq); break; } } } else { bzero(&net, sizeof(net)); net.sipx_family = AF_IPX; net.sipx_len = sizeof (net); net.sipx_addr.x_net = satoipx_addr(ifp->int_broadaddr).x_net; dst = (struct sockaddr *)&net; } rt = rtlookup(dst); if (rt) rtdelete(rt); if (tracing) fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); if (ifp->int_transitions++ > 0) syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); rtadd(dst, &ifp->int_addr, ifp->int_metric, 0, ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); }
static void addrouteforif(struct interface *ifp) { struct rt_entry *rt; struct in6_addr *dst; if (ifp->int_flags & RIP6_IFF_POINTOPOINT) dst = &ifp->int_dstaddr; else dst = &ifp->int_addr; rt = rtlookup(dst, ifp->int_prefix_length); if (rt != NULL) { if (rt->rt_state & RTS_INTERFACE) return; rtdelete(rt); } rtadd(dst, &ifp->int_addr, ifp->int_prefix_length, ifp->int_metric, 0, _B_TRUE, ifp); }
/* * Timer routine. Performs routing information supply * duties and manages timers on routing and SAP table entries. */ void timer(void) { struct rthash *rh; struct rt_entry *rt; struct sap_hash *sh; struct sap_entry *sap; struct sap_hash *sap_base = sap_head; int timetobroadcast, ripbroadcast, sapbroadcast; timeval += TIMER_RATE; if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) ifinit(); timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; ripbroadcast = supplier && timetobroadcast && (timeval % RIP_INTERVAL) == 0; sapbroadcast = timetobroadcast && dosap && !ripbroadcast; for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_clone) { struct rt_entry *trt, *prt; /* * If a clone expire free it and mark the * main route RTS_CHANGED. */ prt = rt; trt = rt->rt_clone; while (trt) { trt->rt_timer += TIMER_RATE; if (trt->rt_timer >= EXPIRE_TIME) { prt->rt_clone = trt->rt_clone; free((char *)trt); trt = prt->rt_clone; rt->rt_state |= RTS_CHANGED; } else { prt = trt; trt = prt->rt_clone; } } } /* * We don't advance time on a routing entry for * a passive gateway or that for our only interface. * The latter is excused because we don't act as * a routing information supplier and hence would * time it out. This is fair as if it's down * we're cut off from the world anyway and it's * not likely we'll grow any new hardware in * the mean time. */ if (!(rt->rt_state & RTS_PASSIVE) && !(rt->rt_state & RTS_INTERFACE)) rt->rt_timer += TIMER_RATE; if (rt->rt_timer >= EXPIRE_TIME) { rt->rt_metric = HOPCNT_INFINITY; rt->rt_state |= RTS_CHANGED; } if (rt->rt_timer >= GARBAGE_TIME) { rt = rt->rt_back; /* Perhaps we should send a REQUEST for this route? */ rtdelete(rt->rt_forw); continue; } if (rt->rt_state & RTS_CHANGED) { rt->rt_state &= ~RTS_CHANGED; /* don't send extraneous packets */ if (!supplier || ripbroadcast) continue; if ((rt->rt_metric + 1) == HOPCNT_INFINITY) continue; msg->rip_cmd = htons(RIPCMD_RESPONSE); msg->rip_nets[0].rip_dst = (satoipx_addr(rt->rt_dst)).x_net; msg->rip_nets[0].rip_metric = htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); msg->rip_nets[0].rip_ticks = htons(rt->rt_ticks + 1); toall(sndmsg, rt, 0); } } } if (ripbroadcast) toall(supply, NULL, 0); /* * Now do the SAP stuff. */ for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) { sap = sh->forw; for (; sap != (struct sap_entry *)sh; sap = sap->forw) { if (sap->clone) { struct sap_entry *tsap, *psap; /* * If a clone expire free it and mark the * main sap entry RTS_CHANGED. */ psap = sap; tsap = sap->clone; while (tsap) { tsap->timer += TIMER_RATE; if (tsap->timer >= EXPIRE_TIME) { psap->clone = tsap->clone; free((char *)tsap); tsap = psap->clone; sap->state |= RTS_CHANGED; } else { psap = tsap; tsap = psap->clone; } } } sap->timer += TIMER_RATE; if (sap->timer >= EXPIRE_TIME) { sap->sap.hops = htons(HOPCNT_INFINITY); sap->state |= RTS_CHANGED; } if (sap->timer >= GARBAGE_TIME) { sap = sap->back; /* Perhaps we should send a REQUEST for this route? */ sap_delete(sap->forw); continue; } /* * XXX sap_sndmsg on RTS_CHANGED */ if (sap->state & RTS_CHANGED) { sap->state &= ~RTS_CHANGED; #ifdef notyet /* don't send extraneous packets */ if (!supplier || sapbroadcast) continue; if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY) continue; sap_msg->sap_cmd = htons(SAP_RESP); sap_msg->sap[0] = sap->sap; sap_msg->sap[0].hops = htons(min(sap->sap.hops+1, HOPCNT_INFINITY)); toall(sapsndmsg, rt, 0); #endif } } } if (sapbroadcast) sap_supply_toall(0); if (ftrace && sapbroadcast) dumpsaptable(ftrace, sap_head); }