void bgp_adj_out_set (struct bgp_node *rn, struct peer *peer, struct prefix *p, struct attr *attr, afi_t afi, safi_t safi, struct bgp_info *binfo) { struct bgp_adj_out *adj = NULL; struct bgp_advertise *adv; #ifdef DISABLE_BGP_ANNOUNCE return; #endif /* DISABLE_BGP_ANNOUNCE */ /* Look for adjacency information. */ if (rn) { for (adj = rn->adj_out; adj; adj = adj->next) if (adj->peer == peer) break; } if (! adj) { adj = XCALLOC (MTYPE_BGP_ADJ_OUT, sizeof (struct bgp_adj_out)); adj->peer = peer_lock (peer); /* adj_out peer reference */ if (rn) { BGP_ADJ_OUT_ADD (rn, adj); bgp_lock_node (rn); } } if (adj->adv) bgp_advertise_clean (peer, adj, afi, safi); adj->adv = bgp_advertise_new (); adv = adj->adv; adv->rn = rn; assert (adv->binfo == NULL); adv->binfo = bgp_info_lock (binfo); /* bgp_info adj_out reference */ if (attr) adv->baa = bgp_advertise_intern (peer->hash[afi][safi], attr); else adv->baa = baa_new (); adv->adj = adj; /* Add new advertisement to advertisement attribute list. */ bgp_advertise_add (adv->baa, adv); FIFO_ADD (&peer->sync[afi][safi]->update, &adv->fifo); }
void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, uint8_t maxlen, struct list *matches) { struct bgp_node *node = bgp_node_from_rnode(table->route_table->top); struct bgp_node *matched = NULL; while (node && node->p.prefixlen <= p->prefixlen && prefix_match(&node->p, p)) { if (node->info && node->p.prefixlen == p->prefixlen) { matched = node; break; } node = bgp_node_from_rnode(node->link[prefix_bit( &p->u.prefix, node->p.prefixlen)]); } if (node == NULL) return; if ((matched == NULL && node->p.prefixlen > maxlen) || !node->parent) return; else if (matched == NULL) matched = node = bgp_node_from_rnode(node->parent); if (matched->info) { bgp_lock_node(matched); listnode_add(matches, matched); } while ((node = bgp_route_next_until_maxlen(node, matched, maxlen))) { if (prefix_match(p, &node->p)) { if (node->info) { bgp_lock_node(node); listnode_add(matches, node); } } } }
void bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr) { struct bgp_adj_in *adj; for (adj = rn->adj_in; adj; adj = adj->next) { if (adj->peer == peer) { if (adj->attr != attr) { bgp_attr_unintern (adj->attr); adj->attr = bgp_attr_intern (attr); } return; } } adj = XCALLOC (MTYPE_BGP_ADJ_IN, sizeof (struct bgp_adj_in)); adj->peer = peer_lock (peer); /* adj_in peer reference */ adj->attr = bgp_attr_intern (attr); BGP_ADJ_IN_ADD (rn, adj); bgp_lock_node (rn); }