/*------------------------------------------------------------------------ * lsr_xmit - transmit pending Link State Request packets *------------------------------------------------------------------------ */ int lsr_xmit(struct ospf_if *pif, struct ospf_nb *pnb) { struct ep *pephead, *pep; struct ip *pip; struct ospf *po; int len; pephead = (struct ep *)headq(pnb->nb_lsrl); if (pephead == 0) return OK; pep = (struct ep *)getbuf(Net.netpool); if ((int)pep == SYSERR) return SYSERR; /* make a copy */ pip = (struct ip *)pephead->ep_data; po = (struct ospf *)pip->ip_data; len = EP_HLEN + IPMHLEN + po->ospf_len; memcpy(pep, pephead, len); pip = (struct ip *)pep->ep_data; po = (struct ospf *)pip->ip_data; po->ospf_authtype = hs2net(pif->if_area->ar_authtype); memset(po->ospf_auth, 0, AUTHLEN); len = po->ospf_len; po->ospf_len = hs2net(po->ospf_len); pep->ep_order &= ~EPO_OSPF; po->ospf_cksum = 0; po->ospf_cksum = cksum((WORD *)po, len); memcpy(po->ospf_auth, pif->if_area->ar_auth, AUTHLEN); pip->ip_src = ip_anyaddr; ipsend(pnb->nb_ipa, pep, len, IPT_OSPF, IPP_INCTL, IP_TTL); pnb->nb_tlsr = pif->if_rintv; return OK; }
/*------------------------------------------------------------------------ * lsu_in - handle a received link state update packet *------------------------------------------------------------------------ */ void lsu_in(struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; struct ospf *po; struct ospf_if *pif = &ospf_if[pep->ep_ifn]; struct ospf_lsu *plsu; struct ospf_db *pdb, *db_lookup(); struct ospf_nb *pnb; int i; if (pif->if_state <= IFS_WAITING) return; pnb = &pif->if_nbtab[1]; po = (struct ospf *)((char *)pip+IP_HLEN(pip)); for (i=0; i<MAXNBR; ++i, ++pnb) if (pnb->nb_rid == po->ospf_rid) break; if (i == MAXNBR || pnb->nb_state < NBS_EXCHNG) return; /* db update here */ if (headq(pnb->nb_lsrl) && lsr_check(pnb)) freebuf(deq(pnb->nb_lsrl)); /* flooding procedure */ }
/*------------------------------------------------------------------------ * ospftimer - update neighbor time-out values *------------------------------------------------------------------------ */ int ospftimer(int delay) { struct ospf_if *pif; struct ospf_nb *pnb; int ifn, i; pif = &ospf_if[0]; for (ifn=0; ifn<NIF; ++ifn, ++pif) { switch (pif->if_state) { case IFS_DOWN: continue; case IFS_WAITING: pif->if_twait -= delay; if (pif->if_twait <= 0) if_elect(ifn); break; default: break; } wait(pif->if_nbmutex); pnb = &ospf_if[ifn].if_nbtab[1]; for (i=0; i<MAXNBR; ++i, ++pnb) { if (pnb->nb_state == NBS_DOWN) continue; pnb->nb_lastheard -= delay; if (pnb->nb_lastheard <= 0) { pnb->nb_state = NBS_DOWN; pif->if_event |= IFE_NCHNG; } if (pnb->nb_state == NBS_EXSTART) { pnb->nb_trexmt -= delay; if (pnb->nb_trexmt <= 0) nb_rexmt(pif, pnb); } if (pnb->nb_state >= NBS_FULL && pnb->nb_tlastdd > 0) { pnb->nb_tlastdd -= delay; if (pnb->nb_tlastdd < 0) freebuf(deq(pnb->nb_dsl)); } if (headq(pnb->nb_lsrl)) { pnb->nb_tlsr -= delay; if (pnb->nb_tlsr <= 0) lsr_xmit(pif, pnb); } } signal(pif->if_nbmutex); if (pif->if_event & IFE_NCHNG) { if_elect(ifn); pif->if_event &= ~IFE_NCHNG; } } }
static void merge(item_type s[], int low, int middle, int high) { int i; /* counter */ queue buffer1, buffer2; /* buffers to hold elements for merging */ init_queue(&buffer1); init_queue(&buffer2); for(i = low; i <= middle; i++) enqueue(&buffer1, s[i]); for(i = middle + 1; i <= high; i++) enqueue(&buffer2, s[i]); i = low; while(!(empty_queue(&buffer1) || empty_queue(&buffer2))) { if(headq(&buffer1) <= headq(&buffer2)) s[i++] = dequeue(&buffer1); else s[i++] = dequeue(&buffer2); } while(!empty_queue(&buffer1)) s[i++] = dequeue(&buffer1); while(!empty_queue(&buffer2)) s[i++] = dequeue(&buffer2); }
void merge(int s[], int l, int m, int h) { int i; queue_t buffer1, buffer2; init_queue(&buffer1); init_queue(&buffer2); for(i = l; i <= m; ++i) enqueue(&buffer1, s[i]); for(i = m+1; i <= h; ++i) enqueue(&buffer2, s[i]); i = l; while(!(empty_queue(&buffer1) || empty_queue(&buffer2))) { if(headq(&buffer1) <= headq(&buffer2)) s[i++] = dequeue(&buffer1); else s[i++] = dequeue(&buffer2); } while(!empty_queue(&buffer1)) s[i++] = dequeue(&buffer1); while(!empty_queue(&buffer2)) s[i++] = dequeue(&buffer2); }