| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	BIRD -- OSPF | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *	(c) 2000 Ondrej Filip <feela@network.cz> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *	Can be freely distributed and used under the terms of the GNU GPL. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ospf.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | #define LOCAL_DEBUG
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  | init_infib(struct fib_node *fn) | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   struct infib *f=(struct infib *)fn; | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   f->metric=LSINFINITY; | 
					
						
							|  |  |  |   f->en=NULL; | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | void | 
					
						
							|  |  |  | init_efib(struct fib_node *fn) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct extfib *f=(struct extfib *)fn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   f->metric=LSINFINITY; | 
					
						
							|  |  |  |   f->metric2=LSINFINITY; | 
					
						
							|  |  |  |   f->nh=ipa_from_u32(0); | 
					
						
							|  |  |  |   f->nhi=NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  | ospf_rt_spfa(struct ospf_area *oa) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-05-31 14:21:56 +00:00
										 |  |  |   struct top_hash_entry *en; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   u32 i,*rts; | 
					
						
							| 
									
										
										
										
											2000-04-26 20:16:36 +00:00
										 |  |  |   struct ospf_lsa_rt *rt; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   struct ospf_lsa_rt_link *rtl,*rr; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   struct fib *in=&oa->infib; | 
					
						
							|  |  |  |   struct infib *nf; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   struct fib_iterator fit; | 
					
						
							| 
									
										
										
										
											2000-05-02 22:19:41 +00:00
										 |  |  |   bird_clock_t delta; | 
					
						
							|  |  |  |   int age=0,flush=0; | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   struct proto *p=&oa->po->proto; | 
					
						
							| 
									
										
										
										
											2000-05-08 22:03:29 +00:00
										 |  |  |   struct proto_ospf *po=oa->po; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   ip_addr ip; | 
					
						
							|  |  |  |   struct ospf_lsa_net *ln; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-09 19:38:34 +00:00
										 |  |  |   debug("%s: Starting routing table calculation for area %I\n",p->name, | 
					
						
							|  |  |  |     oa->areaid); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-31 14:21:56 +00:00
										 |  |  |   WALK_SLIST(SNODE en, oa->lsal) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   { | 
					
						
							|  |  |  |     en->color=OUTSPF; | 
					
						
							|  |  |  |     en->dist=LSINFINITY; | 
					
						
							| 
									
										
										
										
											2000-05-08 22:03:29 +00:00
										 |  |  |     en->nhi=NULL; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   FIB_WALK(in,nftmp) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     nf=(struct infib *)nftmp; | 
					
						
							|  |  |  |     nf->metric=LSINFINITY; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   FIB_WALK_END; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   init_list(&oa->cand);		/* Empty list of candidates */ | 
					
						
							|  |  |  |   oa->trcap=0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   DBG("LSA db prepared, adding me into candidate list.\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   oa->rt->dist=0; | 
					
						
							|  |  |  |   oa->rt->color=CANDIDATE; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   add_head(&oa->cand, &oa->rt->cn); | 
					
						
							|  |  |  |   DBG("RT LSA: rt: %I, id: %I, type: %u\n",oa->rt->lsa.rt,oa->rt->lsa.id,oa->rt->lsa.type); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   while(!EMPTY_LIST(oa->cand)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     struct top_hash_entry *act,*tmp; | 
					
						
							|  |  |  |     node *n; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |     u16 met; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     n=HEAD(oa->cand); | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |     act=SKIP_BACK(struct top_hash_entry, cn, n); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |     rem_node(n); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |     DBG("Working on LSA: rt: %I, id: %I, type: %u\n",act->lsa.rt,act->lsa.id,act->lsa.type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |     act->color=INSPF; | 
					
						
							|  |  |  |     switch(act->lsa.type) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       case LSA_T_RT: | 
					
						
							|  |  |  |         rt=(struct ospf_lsa_rt *)act->lsa_body; | 
					
						
							|  |  |  | 	if((rt->VEB)&(1>>LSA_RT_V)) oa->trcap=1; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	rr=(struct ospf_lsa_rt_link *)(rt+1); | 
					
						
							|  |  |  | 	DBG("  Number of links: %u\n",rt->links); | 
					
						
							|  |  |  | 	for(i=0;i<rt->links;i++) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	  tmp=NULL; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	  rtl=(rr+i); | 
					
						
							|  |  |  | 	  DBG("     Working on link: %I (type: %u)  ",rtl->id,rtl->type); | 
					
						
							|  |  |  | 	  switch(rtl->type) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	  { | 
					
						
							| 
									
										
										
										
											2000-05-09 21:52:58 +00:00
										 |  |  |             case LSART_STUB: | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  | 	     DBG("\n"); | 
					
						
							|  |  |  | 	     ip=ipa_from_u32(rtl->id); | 
					
						
							|  |  |  | 	     nf=fib_get(in,&ip, ipa_mklen(ipa_from_u32(rtl->data))); | 
					
						
							|  |  |  | 	     if(nf->metric>(met=act->dist+rtl->metric)) | 
					
						
							|  |  |  | 	     { | 
					
						
							|  |  |  | 	       nf->metric=met; | 
					
						
							|  |  |  | 	       nf->en=act; | 
					
						
							|  |  |  | 	     } | 
					
						
							|  |  |  | 	     break; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	    case LSART_VLNK: | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	      DBG("Ignoring\n"); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	      continue; | 
					
						
							|  |  |  | 	      break; | 
					
						
							|  |  |  | 	    case LSART_NET: | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	      tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_NET); | 
					
						
							|  |  |  | 	      if(tmp==NULL) DBG("Fuck!\n"); | 
					
						
							|  |  |  | 	      else DBG("Found. :-)\n"); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	      break; | 
					
						
							| 
									
										
										
										
											2000-05-09 21:52:58 +00:00
										 |  |  | 	    case LSART_PTP: | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	      tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_RT); | 
					
						
							|  |  |  | 	      DBG("PTP searched.\n"); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	      break; | 
					
						
							|  |  |  | 	    default: | 
					
						
							|  |  |  | 	      log("Unknown link type in router lsa.\n"); | 
					
						
							|  |  |  | 	      break; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  | 	  add_cand(&oa->cand,tmp,act,act->dist+rtl->metric,oa); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |       case LSA_T_NET:	/* FIXME Add to fib */ | 
					
						
							|  |  |  |         ln=act->lsa_body; | 
					
						
							|  |  |  | 	ip=ipa_and(ipa_from_u32(act->lsa.id),ln->netmask); | 
					
						
							|  |  |  |         nf=fib_get(in,&ip, ipa_mklen(ln->netmask)); | 
					
						
							|  |  |  | 	if(nf->metric>act->dist) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  nf->metric=act->dist; | 
					
						
							|  |  |  | 	  nf->en=act; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rts=(u32 *)(ln+1); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	for(i=0;i<(act->lsa.length-sizeof(struct ospf_lsa_header)- | 
					
						
							|  |  |  | 	  sizeof(struct ospf_lsa_net))/sizeof(u32);i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  | 	  DBG("     Working on router %I ",*(rts+i)); | 
					
						
							|  |  |  | 	  tmp=ospf_hash_find(oa->gr, *(rts+i), *(rts+i), LSA_T_RT); | 
					
						
							|  |  |  | 	  if(tmp!=NULL) DBG("Found :-)\n"); | 
					
						
							|  |  |  | 	  else DBG("Fuck!\n"); | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |           add_cand(&oa->cand,tmp,act,act->dist,oa); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Now sync our fib with nest's */ | 
					
						
							|  |  |  |   DBG("\nNow syncing my rt table with nest's\n\n"); | 
					
						
							|  |  |  |   FIB_ITERATE_INIT(&fit,in); | 
					
						
							|  |  |  | again: | 
					
						
							|  |  |  |   FIB_ITERATE_START(in,&fit,nftmp) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     nf=(struct infib *)nftmp; | 
					
						
							|  |  |  |     if(nf->metric==LSINFINITY)  | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       net *ne; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |       struct top_hash_entry *en=nf->en; | 
					
						
							|  |  |  |       ln=en->lsa_body; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |       ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen); | 
					
						
							|  |  |  |       DBG("Deleting rt entry %I\n     (IP: %I, GW: %I, Iface: %s)\n", | 
					
						
							|  |  |  |         nf->fn.prefix,ip,en->nh,en->nhi->name); | 
					
						
							|  |  |  |       rte_update(p->table, ne, p, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* Now delete my fib */ | 
					
						
							|  |  |  |       FIB_ITERATE_PUT(&fit, nftmp); | 
					
						
							|  |  |  |       fib_delete(in, nftmp); | 
					
						
							|  |  |  |       goto again; | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |       /* Update routing table */ | 
					
						
							| 
									
										
										
										
											2000-05-08 22:03:29 +00:00
										 |  |  |       if(nf->en->nhi==NULL) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         struct top_hash_entry *en=nf->en; | 
					
						
							|  |  |  |         struct ospf_neighbor *neigh; | 
					
						
							|  |  |  |         neighbor *nn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  goto skip; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |         nn=neigh_find(p,&neigh->ip,0); | 
					
						
							|  |  |  |         DBG("     Next hop calculated: %I\n", nn->addr); | 
					
						
							|  |  |  |         en->nh=nn->addr; | 
					
						
							|  |  |  |         en->nhi=nn->iface; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |         net *ne; | 
					
						
							|  |  |  |         rta a0; | 
					
						
							|  |  |  |         rte *e; | 
					
						
							|  |  |  | 	struct top_hash_entry *en=nf->en; | 
					
						
							|  |  |  |         ln=en->lsa_body; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |         bzero(&a0, sizeof(a0)); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |         a0.proto=p; | 
					
						
							|  |  |  |         a0.source=RTS_OSPF; | 
					
						
							|  |  |  |         a0.scope=SCOPE_UNIVERSE;	/* What's this good for? */ | 
					
						
							|  |  |  |         a0.cast=RTC_UNICAST; | 
					
						
							|  |  |  |         a0.dest=RTD_ROUTER; | 
					
						
							|  |  |  |         a0.flags=0; | 
					
						
							|  |  |  |         a0.aflags=0; | 
					
						
							|  |  |  |         a0.iface=en->nhi; | 
					
						
							|  |  |  |         a0.gw=en->nh; | 
					
						
							|  |  |  |         a0.from=en->nh;		/* FIXME Just a test */ | 
					
						
							|  |  |  |         ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen); | 
					
						
							|  |  |  |         e=rte_get_temp(&a0); | 
					
						
							|  |  |  |         e->u.ospf.metric1=nf->metric; | 
					
						
							|  |  |  |         e->u.ospf.metric2=0; | 
					
						
							|  |  |  |         e->u.ospf.tag=0;			/* FIXME Some config? */ | 
					
						
							|  |  |  |         e->pflags = 0; | 
					
						
							|  |  |  |         e->net=ne; | 
					
						
							| 
									
										
										
										
											2000-05-08 10:40:00 +00:00
										 |  |  | 	e->pref = p->preference; | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |         DBG("Modifying rt entry %I\n     (IP: %I, GW: %I, Iface: %s)\n", | 
					
						
							|  |  |  |           nf->fn.prefix,ip,en->nh,en->nhi->name); | 
					
						
							|  |  |  |         rte_update(p->table, ne, p, e); | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-26 20:16:36 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-05-08 22:03:29 +00:00
										 |  |  | skip: | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  |   FIB_ITERATE_END(nftmp); | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |   ospf_ext_spfa(po); | 
					
						
							| 
									
										
										
										
											2000-05-09 00:03:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | ospf_ext_spfa(struct proto_ospf *po)	/* FIXME looking into inter-area */ | 
					
						
							| 
									
										
										
										
											2000-05-09 00:03:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   struct top_hash_entry *en,*etmp,*absr; | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |   struct fib *ef=&po->efib; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   struct extfib *nf; | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |   struct fib_iterator fit; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   struct ospf_area *oa=NULL,*atmp,*absroa; | 
					
						
							|  |  |  |   struct proto *p=&po->proto; | 
					
						
							|  |  |  |   struct ospf_lsa_ext *le; | 
					
						
							|  |  |  |   struct ospf_lsa_ext_tos *lt; | 
					
						
							|  |  |  |   int mlen; | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |   ip_addr ip,nnh; | 
					
						
							|  |  |  |   struct iface *nnhi=NULL; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   u16 met,met2; | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |   u32 tag; | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |   neighbor *nn; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   debug("%s: Starting routing table calculation for external routes\n", | 
					
						
							|  |  |  |     p->name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |   FIB_WALK(ef,nftmp) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     nf=(struct extfib *)nftmp; | 
					
						
							|  |  |  |     nf->metric=LSINFINITY; | 
					
						
							|  |  |  |     nf->metric2=LSINFINITY; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   FIB_WALK_END; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   WALK_LIST(oa,po->area_list) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(!oa->stub) break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if(oa==NULL) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WALK_SLIST(en,oa->lsal) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(en->lsa.type!=LSA_T_EXT) continue; | 
					
						
							|  |  |  |     if(en->lsa.age==LSA_MAXAGE) continue; | 
					
						
							|  |  |  |     if(en->lsa.rt==p->cf->global->router_id) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     le=en->lsa_body; | 
					
						
							|  |  |  |     lt=(struct ospf_lsa_ext_tos *)(le+1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(lt->metric==LSINFINITY) continue; | 
					
						
							|  |  |  |     ip=ipa_and(ipa_from_u32(en->lsa.id),le->netmask); | 
					
						
							|  |  |  |     mlen=ipa_mklen(le->netmask); | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |     if((mlen<0)||(mlen>32)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-05-17 00:28:45 +00:00
										 |  |  |       log("%s: Invalid mask in LSA.\nID: %I, RT: %I, Type: %u, Mask %I", | 
					
						
							| 
									
										
										
										
											2000-05-17 21:20:47 +00:00
										 |  |  |         p->name,en->lsa.id,en->lsa.rt,en->lsa.type,le->netmask); | 
					
						
							| 
									
										
										
										
											2000-05-17 00:28:45 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     nf=NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WALK_LIST(atmp,po->area_list) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |       if((nf=fib_find(&atmp->infib,&ip, mlen))!=NULL) break; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     if(nf!=NULL) continue;	/* Some intra area path exists */ | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     absr=NULL; | 
					
						
							|  |  |  |     absroa=NULL; | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |     nnhi=NULL; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |     met=0;met2=0;tag=0; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |     WALK_LIST(atmp,po->area_list) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if((etmp=ospf_hash_find(atmp->gr,en->lsa.rt,en->lsa.rt,LSA_T_RT))!=NULL) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         if((absr==NULL) || (absr->dist>etmp->dist) || | 
					
						
							|  |  |  |           ((etmp->dist==absr->dist) && (absroa->areaid<atmp->areaid))) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           absr=etmp; | 
					
						
							|  |  |  |           absroa=atmp; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if(absr==NULL) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-16 22:43:30 +00:00
										 |  |  |     if(ipa_compare(lt->fwaddr,ipa_from_u32(0))==0) | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |       if(lt->etos>0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         met=absr->dist; | 
					
						
							|  |  |  |         met2=lt->metric; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         met=absr->dist+lt->metric; | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  | 	met2=LSINFINITY; | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |       tag=lt->tag; | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       nf=NULL; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       WALK_LIST(atmp,po->area_list) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |         if((nf=fib_route(&atmp->infib,lt->fwaddr,32))!=NULL) | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |       if(nf==NULL) continue; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       if(lt->etos>0) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |         met=nf->metric; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |         met2=lt->metric; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  |         met=nf->metric+lt->metric; | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  | 	met2=LSINFINITY; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |       tag=lt->tag; | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if((nn=neigh_find(p,<->fwaddr,0))!=NULL) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         nnh=nn->addr; | 
					
						
							|  |  |  |         nnhi=nn->iface; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-05-16 22:34:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |     nf=fib_get(ef,&ip, mlen); | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     if((nf->metric>met) || ((nf->metric==met)&&(nf->metric2>met2))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       nf->metric=met; | 
					
						
							|  |  |  |       nf->metric2=met2; | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |       nf->tag=tag; | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |       if(nnhi!=NULL) | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |         nf->nh=nnh; | 
					
						
							|  |  |  |         nf->nhi=nnhi; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2000-05-16 23:24:50 +00:00
										 |  |  |         if(absr->nhi==NULL) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           struct ospf_neighbor *neigh; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if((neigh=find_neigh_noifa(po,absr->lsa.rt))==NULL) | 
					
						
							|  |  |  | 	  { | 
					
						
							|  |  |  | 	     continue; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  |           nn=neigh_find(p,&neigh->ip,0); | 
					
						
							|  |  |  |           DBG("     Next hop calculated: %I\n", nn->addr); | 
					
						
							|  |  |  |           nf->nh=nn->addr; | 
					
						
							|  |  |  |           nf->nhi=nn->iface; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           nf->nh=absr->nh; | 
					
						
							|  |  |  | 	  nf->nhi=absr->nhi; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DBG("\nNow syncing my rt table with nest's\n\n"); | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |   FIB_ITERATE_INIT(&fit,ef); | 
					
						
							|  |  |  | noch: | 
					
						
							|  |  |  |   FIB_ITERATE_START(ef,&fit,nftmp) | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |     nf=(struct extfib *)nftmp; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     if(nf->metric==LSINFINITY)  | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       net *ne; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |       ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen); | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |       DBG("Deleting rt entry %I\n     (IP: %I, GW: %I)\n", | 
					
						
							|  |  |  |         nf->fn.prefix,ip,nf->nh); | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       rte_update(p->table, ne, p, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* Now delete my fib */ | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |       FIB_ITERATE_PUT(&fit, nftmp); | 
					
						
							|  |  |  |       fib_delete(ef, nftmp); | 
					
						
							|  |  |  |       goto noch; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       net *ne; | 
					
						
							|  |  |  |       rta a0; | 
					
						
							|  |  |  |       rte *e; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |       bzero(&a0, sizeof(a0)); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |       a0.proto=p; | 
					
						
							|  |  |  |       a0.source=RTS_OSPF_EXT; | 
					
						
							|  |  |  |       a0.scope=SCOPE_UNIVERSE;	/* What's this good for? */ | 
					
						
							|  |  |  |       a0.cast=RTC_UNICAST; | 
					
						
							|  |  |  |       a0.dest=RTD_ROUTER; | 
					
						
							|  |  |  |       a0.flags=0; | 
					
						
							|  |  |  |       a0.aflags=0; | 
					
						
							|  |  |  |       a0.iface=nf->nhi; | 
					
						
							|  |  |  |       a0.gw=nf->nh; | 
					
						
							|  |  |  |       a0.from=nf->nh;		/* FIXME Just a test */ | 
					
						
							|  |  |  |       ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen); | 
					
						
							|  |  |  |       e=rte_get_temp(&a0); | 
					
						
							|  |  |  |       e->u.ospf.metric1=nf->metric; | 
					
						
							|  |  |  |       e->u.ospf.metric2=nf->metric2; | 
					
						
							| 
									
										
										
										
											2000-05-31 12:07:09 +00:00
										 |  |  |       e->u.ospf.tag=nf->tag; | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       e->pflags = 0; | 
					
						
							|  |  |  |       e->net=ne; | 
					
						
							|  |  |  |       e->pref = p->preference; | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  |       DBG("Modifying rt entry %I\n     (IP: %I, GW: %I)\n", | 
					
						
							|  |  |  |         nf->fn.prefix,ip,nf->nh); | 
					
						
							| 
									
										
										
										
											2000-05-10 10:47:17 +00:00
										 |  |  |       rte_update(p->table, ne, p, e); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-05-12 00:22:43 +00:00
										 |  |  | let: | 
					
						
							|  |  |  |   FIB_ITERATE_END(nftmp); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2000-04-29 15:57:14 +00:00
										 |  |  | add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,  | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   u16 dist, struct ospf_area *oa) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   node *prev,*n; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   int flag=0,added=0; | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   struct top_hash_entry *act; | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   struct proto *p=&oa->po->proto; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if(en==NULL) return; | 
					
						
							|  |  |  |   if(en->lsa.age==LSA_MAXAGE) return; | 
					
						
							|  |  |  |   /* FIXME Does it have link back? Test it! */ | 
					
						
							|  |  |  |   if(en->color==INSPF) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   if(dist>=en->dist) return; | 
					
						
							|  |  |  |   /*
 | 
					
						
							|  |  |  |    * FIXME The line above is not a bug, but we don't support | 
					
						
							|  |  |  |    * multiple next hops. I'll start as soon as nest will | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   DBG("     Adding candidate: rt: %I, id: %I, type: %u\n",en->lsa.rt,en->lsa.id,en->lsa.type); | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   en->nhi=NULL; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   calc_next_hop(par,en,oa); | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   if(en->color==CANDIDATE)	/* We found a shorter path */ | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |     rem_node(&en->cn); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   en->dist=dist; | 
					
						
							|  |  |  |   en->color=CANDIDATE; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   prev=NULL; | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   if(EMPTY_LIST(*l)) | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |     add_head(l,&en->cn); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     WALK_LIST(n,*l) | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |       act=SKIP_BACK(struct top_hash_entry, cn, n); | 
					
						
							|  |  |  |       if((act->dist>dist)|| | 
					
						
							|  |  |  |         ((act->dist==dist)&&(act->lsa.type==LSA_T_NET))) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         if(prev==NULL) add_head(l,&en->cn); | 
					
						
							|  |  |  |         else insert_node(&en->cn,prev); | 
					
						
							|  |  |  | 	added=1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       prev=n; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!added) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       add_tail(l,&en->cn); | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-04-30 09:32:41 +00:00
										 |  |  |   /* FIXME Some VLINK staff should be here */ | 
					
						
							| 
									
										
										
										
											2000-04-26 12:54:23 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2000-04-29 15:57:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  | void | 
					
						
							|  |  |  | calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en, | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   struct ospf_area *oa) | 
					
						
							| 
									
										
										
										
											2000-04-29 15:57:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |   struct ospf_neighbor *neigh; | 
					
						
							| 
									
										
										
										
											2000-05-03 22:23:41 +00:00
										 |  |  |   struct proto *p=&oa->po->proto; | 
					
						
							|  |  |  |   struct proto_ospf *po=oa->po; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |   DBG("     Next hop called\n"); | 
					
						
							|  |  |  |   if(par==oa->rt) return; | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |   if(par->nhi==NULL) | 
					
						
							| 
									
										
										
										
											2000-04-29 15:57:14 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |     neighbor *nn; | 
					
						
							| 
									
										
										
										
											2000-04-30 22:14:31 +00:00
										 |  |  |     DBG("     Next hop calculating for id: %I rt: %I type: %u\n",en->lsa.id,en->lsa.rt,en->lsa.type); | 
					
						
							| 
									
										
										
										
											2000-04-30 11:31:05 +00:00
										 |  |  |     if(par->lsa.type!=LSA_T_RT) return; | 
					
						
							| 
									
										
										
										
											2000-05-02 19:27:57 +00:00
										 |  |  |     if((neigh=find_neigh_noifa(po,par->lsa.rt))==NULL) return; | 
					
						
							|  |  |  |     nn=neigh_find(p,&neigh->ip,0); | 
					
						
							|  |  |  |     DBG("     Next hop calculated: %I\n", nn->addr); | 
					
						
							|  |  |  |     en->nh=nn->addr; | 
					
						
							|  |  |  |     en->nhi=nn->iface; | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   en->nh=par->nh; | 
					
						
							|  |  |  |   en->nhi=par->nhi; | 
					
						
							|  |  |  |   DBG("     Next hop calculated: %I\n", en->nh); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-05-04 01:23:03 +00:00
										 |  |  | 
 |