attr_free(&attrs);
path_put(fasp);
up_generate_updates(struct rde_peer *peer,    struct prefix *new, struct prefix *old){	struct update_attr		*a;	struct update_prefix		*p;	struct attr			*atr;	struct attr_flags		 attrs;	struct bgpd_addr		 addr;	if (peer->state != PEER_UP)		return;	if (new == NULL || new->aspath->nexthop == NULL ||	    new->aspath->nexthop->state != NEXTHOP_REACH) {		if (old == NULL)			/* new prefix got filtered and no old prefex avail */			return;		if (peer == old->peer)			/* Do not send routes back to sender */			return;		if (peer->conf.ebgp &&		    !aspath_loopfree(old->aspath->flags.aspath,		    peer->conf.remote_as))			/*			 * Do not send routes back to sender which would			 * cause a aspath loop.			 */			return;		if (old->peer->conf.ebgp == 0 && peer->conf.ebgp == 0) {			/*			 * route reflector redistribution rules:			 * 1. if announce is set		-> announce			 * 2. old non-client, new non-client	-> no 			 * 3. old client, new non-client	-> yes			 * 4. old non-client, new client	-> yes			 * 5. old client, new client		-> yes			 */			if (old->peer->conf.reflector_client == 0 &&			    peer->conf.reflector_client == 0 &&			    (old->aspath->nexthop->flags &			    NEXTHOP_ANNOUNCE) == 0)				/* Do not redistribute updates to ibgp peers */				return;		}		/* announce type handling */		switch (peer->conf.announce_type) {		case ANNOUNCE_UNDEF:		case ANNOUNCE_NONE:		case ANNOUNCE_DEFAULT_ROUTE:			return;		case ANNOUNCE_ALL:			break;		case ANNOUNCE_SELF:			/*			 * pass only prefix that have a aspath count			 * of zero this is equal to the ^$ regex.			 */			if (old->aspath->flags.aspath->ascnt != 0)				return;			break;		}		/* well known communities */		if (rde_filter_community(&old->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_ADVERTISE))			return;		if (peer->conf.ebgp && rde_filter_community(&old->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPORT))			return;		if (peer->conf.ebgp && rde_filter_community(&old->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPSUBCONFED))			return;		/*		 * don't send messages back to originator 		 * NOTE this is not specified in the RFC but seems logical.		 */		if ((atr = attr_optget(&old->aspath->flags,		    ATTR_ORIGINATOR_ID)) != NULL) {			if (memcmp(atr->data, &peer->remote_bgpid,			    sizeof(peer->remote_bgpid)) == 0)				/* would cause loop don't send */				return;		}		/* copy attributes for output filter */		attr_copy(&attrs, &old->aspath->flags);		pt_getaddr(old->prefix, &addr);		if (rde_filter(peer, &attrs, &addr,		    old->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {			attr_free(&attrs);			return;		}		attr_free(&attrs);		/* withdraw prefix */		p = calloc(1, sizeof(struct update_prefix));		if (p == NULL)			fatal("up_generate_updates");		p->prefix = addr;		p->prefixlen = old->prefix->prefixlen;		if (up_add(peer, p, NULL) == -1)			log_warnx("queuing withdraw failed.");	} else {		if (peer == new->peer) {			/* Do not send routes back to sender */			up_generate_updates(peer, NULL, old);			return;		}		if (peer->conf.ebgp &&		    !aspath_loopfree(new->aspath->flags.aspath,		    peer->conf.remote_as)) {			/*			 * Do not send routes back to sender which would			 * cause a aspath loop.			 */			up_generate_updates(peer, NULL, old);			return;		}		if (new->peer->conf.ebgp == 0 && peer->conf.ebgp == 0) {			/*			 * route reflector redistribution rules:			 * 1. if announce is set		-> announce			 * 2. old non-client, new non-client	-> no 			 * 3. old client, new non-client	-> yes			 * 4. old non-client, new client	-> yes			 * 5. old client, new client		-> yes			 */			if (new->peer->conf.reflector_client == 0 &&			    peer->conf.reflector_client == 0 &&			    (new->aspath->nexthop->flags &			    NEXTHOP_ANNOUNCE) == 0) {				/* Do not redistribute updates to ibgp peers */				up_generate_updates(peer, NULL, old);				return;			}		}		/* announce type handling */		switch (peer->conf.announce_type) {		case ANNOUNCE_UNDEF:		case ANNOUNCE_NONE:		case ANNOUNCE_DEFAULT_ROUTE:			/*			 * no need to withdraw old prefix as this will be			 * filtered out to.			 */			return;		case ANNOUNCE_ALL:			break;		case ANNOUNCE_SELF:			/*			 * pass only prefix that have a aspath count			 * of zero this is equal to the ^$ regex.			 */			if (new->aspath->flags.aspath->ascnt != 0) {				up_generate_updates(peer, NULL, old);				return;			}			break;		}		/* well known communities */		if (rde_filter_community(&new->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_ADVERTISE)) {			up_generate_updates(peer, NULL, old);			return;		}		if (peer->conf.ebgp && rde_filter_community(&new->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPORT)) {			up_generate_updates(peer, NULL, old);			return;		}		if (peer->conf.ebgp && rde_filter_community(&new->aspath->flags,		    COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPSUBCONFED)) {			up_generate_updates(peer, NULL, old);			return;		}		/* copy attributes for output filter */		attr_copy(&attrs, &new->aspath->flags);		pt_getaddr(new->prefix, &addr);		if (rde_filter(peer, &attrs, &addr,		    new->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {			attr_free(&attrs);			up_generate_updates(peer, NULL, old);			return;		}		/*		 * don't send messages back to originator 		 * NOTE this is not specified in the RFC but seems logical.		 */		if ((atr = attr_optget(&new->aspath->flags,		    ATTR_ORIGINATOR_ID)) != NULL) {			if (memcmp(atr->data, &peer->remote_bgpid,			    sizeof(peer->remote_bgpid)) == 0) {				/* would cause loop don't send */				attr_free(&attrs);				return;			}		}		/* generate update */		p = calloc(1, sizeof(struct update_prefix));		if (p == NULL)			fatal("up_generate_updates");		a = calloc(1, sizeof(struct update_attr));		if (a == NULL)			fatal("up_generate_updates");		if (up_generate_attr(peer, a, &attrs,		    new->aspath->nexthop) == -1) {			log_warnx("generation of bgp path attributes failed");			free(a);			free(p);			return;		}		/*		 * use aspath_hash as attr_hash, this may be unoptimal		 * but currently I don't care.		 */		a->attr_hash = aspath_hash(attrs.aspath->data,		    attrs.aspath->len);		p->prefix = addr;		p->prefixlen = new->prefix->prefixlen;		/* no longer needed */		attr_free(&attrs);		if (up_add(peer, p, a) == -1)			log_warnx("queuing update failed.");	}}