if (iface->state & IF_STA_DOWN) continue;  log_debug("orig_rtr_lsa: interface %s", iface->name);
orig_rtr_lsa(struct area *area){	struct lsa_hdr		 lsa_hdr;	struct lsa_rtr		 lsa_rtr;	struct lsa_rtr_link	 rtr_link;	struct iface		*iface;	struct buf		*buf;	struct nbr		*nbr, *self = NULL;	u_int16_t		 num_links = 0;	u_int16_t		 chksum;	u_int8_t		 border, virtual = 0;	log_debug("orig_rtr_lsa: area %s", inet_ntoa(area->id));	/* XXX READ_BUF_SIZE */	if ((buf = buf_dynamic(sizeof(lsa_hdr), READ_BUF_SIZE)) == NULL)		fatal("orig_rtr_lsa");	/* reserve space for LSA header and LSA Router header */	if (buf_reserve(buf, sizeof(lsa_hdr)) == NULL)		fatal("orig_rtr_lsa: buf_reserve failed");	if (buf_reserve(buf, sizeof(lsa_rtr)) == NULL)		fatal("orig_rtr_lsa: buf_reserve failed");	/* links */	LIST_FOREACH(iface, &area->iface_list, entry) {		if (self == NULL && iface->self != NULL)			self = iface->self;		if (iface->state & IF_STA_DOWN)			continue;		log_debug("orig_rtr_lsa: interface %s", iface->name);		bzero(&rtr_link, sizeof(rtr_link));		if (iface->state & IF_STA_LOOPBACK) {			rtr_link.id = iface->addr.s_addr;			rtr_link.data = 0xffffffff;			rtr_link.type = LINK_TYPE_STUB_NET;			num_links++;			if (buf_add(buf, &rtr_link, sizeof(rtr_link)))				fatalx("orig_rtr_lsa: buf_add failed");			continue;		}		switch (iface->type) {		case IF_TYPE_POINTOPOINT:			LIST_FOREACH(nbr, &iface->nbr_list, entry)				if (nbr != iface->self &&				    nbr->state & NBR_STA_FULL)					break;			if (nbr) {				log_debug("orig_rtr_lsa: point-to-point, "				    "interface %s", iface->name);				rtr_link.id = nbr->id.s_addr;				rtr_link.data = iface->addr.s_addr;				rtr_link.type = LINK_TYPE_POINTTOPOINT;				rtr_link.metric = htons(iface->metric);				num_links++;				if (buf_add(buf, &rtr_link, sizeof(rtr_link)))					fatalx("orig_rtr_lsa: buf_add failed");			}			if (iface->state & IF_STA_POINTTOPOINT) {				log_debug("orig_rtr_lsa: stub net, "				    "interface %s", iface->name);				bzero(&rtr_link, sizeof(rtr_link));				if (nbr) {					rtr_link.id = nbr->addr.s_addr;					rtr_link.data = 0xffffffff;				} else {					rtr_link.id = iface->addr.s_addr;					rtr_link.data = iface->mask.s_addr;				}				rtr_link.metric = htons(iface->metric);				rtr_link.type = LINK_TYPE_STUB_NET;				num_links++;				if (buf_add(buf, &rtr_link, sizeof(rtr_link)))					fatalx("orig_rtr_lsa: buf_add failed");			}			continue;		case IF_TYPE_BROADCAST:		case IF_TYPE_NBMA:			if ((iface->state & IF_STA_MULTI)) {				if (iface->dr == iface->self) {					LIST_FOREACH(nbr, &iface->nbr_list,					    entry)						if (nbr != iface->self &&						    nbr->state & NBR_STA_FULL)							break;				} else					nbr = iface->dr;				if (nbr && nbr->state & NBR_STA_FULL) {					log_debug("orig_rtr_lsa: transit net, "					    "interface %s", iface->name);					rtr_link.id = iface->dr->addr.s_addr;					rtr_link.data = iface->addr.s_addr;					rtr_link.type = LINK_TYPE_TRANSIT_NET;					break;				}			}			log_debug("orig_rtr_lsa: stub net, "			    "interface %s", iface->name);			rtr_link.id =			    iface->addr.s_addr & iface->mask.s_addr;			rtr_link.data = iface->mask.s_addr;			rtr_link.type = LINK_TYPE_STUB_NET;			break;		case IF_TYPE_VIRTUALLINK:			LIST_FOREACH(nbr, &iface->nbr_list, entry) {				if (nbr != iface->self &&				    nbr->state & NBR_STA_FULL)					break;			}			if (nbr) {				rtr_link.id = nbr->id.s_addr;				rtr_link.data = iface->addr.s_addr;				rtr_link.type = LINK_TYPE_VIRTUAL;				rtr_link.metric = htons(iface->metric);				num_links++;				virtual = 1;				if (buf_add(buf, &rtr_link, sizeof(rtr_link)))					fatalx("orig_rtr_lsa: buf_add failed");				log_debug("orig_rtr_lsa: virtual link, interface %s",				     iface->name);			}			continue;		case IF_TYPE_POINTOMULTIPOINT:			log_debug("orig_rtr_lsa: stub net, "			    "interface %s", iface->name);			rtr_link.id = iface->addr.s_addr;			rtr_link.data = 0xffffffff;			rtr_link.type = LINK_TYPE_STUB_NET;			num_links++;			if (buf_add(buf, &rtr_link, sizeof(rtr_link)))				fatalx("orig_rtr_lsa: buf_add failed");			LIST_FOREACH(nbr, &iface->nbr_list, entry) {				if (nbr != iface->self &&				    nbr->state & NBR_STA_FULL) {					bzero(&rtr_link, sizeof(rtr_link));					log_debug("orig_rtr_lsa: "					    "point-to-point, interface %s",					    iface->name);					rtr_link.id = nbr->addr.s_addr;					rtr_link.data = iface->addr.s_addr;					rtr_link.type = LINK_TYPE_POINTTOPOINT;					rtr_link.metric = htons(iface->metric);					num_links++;					if (buf_add(buf, &rtr_link,					    sizeof(rtr_link)))						fatalx("orig_rtr_lsa: "						    "buf_add failed");				}			}			continue;		default:			fatalx("orig_rtr_lsa: unknown interface type");		}		rtr_link.num_tos = 0;		rtr_link.metric = htons(iface->metric);		num_links++;		if (buf_add(buf, &rtr_link, sizeof(rtr_link)))			fatalx("orig_rtr_lsa: buf_add failed");	}	/* LSA router header */	lsa_rtr.flags = 0;	/*	 * Set the E bit as soon as an as-ext lsa may be redistributed, only	 * setting it in case we redistribute something is not worth the fuss.	 */	if (oeconf->redistribute_flags && (oeconf->options & OSPF_OPTION_E))		lsa_rtr.flags |= OSPF_RTR_E;	border = area_border_router(oeconf);	if (border != oeconf->border) {		oeconf->border = border;		orig_rtr_lsa_all(area);	}	if (oeconf->border)		lsa_rtr.flags |= OSPF_RTR_B;	if (virtual)		lsa_rtr.flags |= OSPF_RTR_V;	/* TODO set V flag if a active virtual link ends here and the	 * area is the tranist area for this link. */	lsa_rtr.dummy = 0;	lsa_rtr.nlinks = htons(num_links);	memcpy(buf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_rtr)),	    &lsa_rtr, sizeof(lsa_rtr));	/* LSA header */	lsa_hdr.age = htons(DEFAULT_AGE);	lsa_hdr.opts = oeconf->options;		/* XXX */	lsa_hdr.type = LSA_TYPE_ROUTER;	lsa_hdr.ls_id = oeconf->rtr_id.s_addr;	lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;	lsa_hdr.seq_num = htonl(INIT_SEQ_NUM);	lsa_hdr.len = htons(buf->wpos);	lsa_hdr.ls_chksum = 0;		/* updated later */	memcpy(buf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr));	chksum = htons(iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET));	memcpy(buf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)),	    &chksum, sizeof(chksum));	if (self)		imsg_compose(ibuf_rde, IMSG_LS_UPD,		    self->peerid, 0, -1, buf->buf, buf->wpos);	else		log_warnx("orig_rtr_lsa: empty area %s",		    inet_ntoa(area->id));	buf_free(buf);}