Пример #1
0
/*------------------------------------------------------------------------
 *  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;
}
Пример #2
0
/*------------------------------------------------------------------------
 *  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 */
}
Пример #3
0
/*------------------------------------------------------------------------
 * 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;
		}
	}
}
Пример #4
0
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);
}
Пример #5
0
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);
}