// $Id: aggchk.cc,v 4.9 2002/04/09 11:48:44 katie Exp $ // Copyright (c) 2001,2002 RIPE NCC // // All Rights Reserved // // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose and without fee is hereby granted, // provided that the above copyright notice appear in all copies and that // both that copyright notice and this permission notice appear in // supporting documentation, and that the name of the author not be // used in advertising or publicity pertaining to distribution of the // software without specific, written prior permission. // // THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING // ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL // AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // // Copyright (c) 1994 by the University of Southern California // All rights reserved. // // Permission to use, copy, modify, and distribute this software and its // documentation in source and binary forms for lawful non-commercial // purposes and without fee is hereby granted, provided that the above // copyright notice appear in all copies and that both the copyright // notice and this permission notice appear in supporting documentation, // and that any documentation, advertising materials, and other materials // related to such distribution and use acknowledge that the software was // developed by the University of Southern California, Information // Sciences Institute. The name of the USC may not be used to endorse or // promote products derived from this software without specific prior // written permission. // // THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY // REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY // PURPOSE. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, // TITLE, AND NON-INFRINGEMENT. // // IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT, // OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE // OR PERFORMANCE OF THIS SOFTWARE. // // Questions concerning this software should be directed to // ratoolset@isi.edu. // // Author(s): Cengiz Alaettinoglu // John Mehringer updated for RAToolSet 4.x #include #include #include "config.h" #include #include #include #include "irr/irr.hh" #include "irr/autnum.hh" //#include "Error.hh" //#include "aut-num.hh" //#include "Route.hh" #include "radix.hh" extern radix_node *test_root; // defined in cidr.cc used for the expts //*Pix aggregator_as = NULL; //ASt aggregator_as = INVALID_AS; static BGPRoute r; // aspath used to check for looping is an attribute of r static addr * aggs_final = NULL; // do not use rt.define() 'cos it checks for the exact match in the database // and if nothing found sets origin to NULL. void unlink(addr **,addr **); addr * copy_list(addr *); addr * component_match(addr * components, Filter * filter, ASt peer_as, IRR * whois); void import_match(ASt peeras, ASt as, addr ** aggregates, int radius, IRR * whois); void append_aggregates(addr**,addr**); addr * refine_aggs(addr *); void export_match(ASt as, addr ** aggregates, int radius, IRR * whois); void examine_policy(ASt source_as, int proxies, addr *aggregates, int radius, IRR * whois); void print_aggregates(addr *,int); void append(addr ** list, addr * element); void delete_list(addr **); addr* chk_policy(ASt as1, ASt as2, addr *aggs, IRR * whois); extern addr * allowed_proxy_aggregates(ASt aggregator, ASt neighbour, addr * aggregates, IRR * irr); //-------------------------------------------------------------- // void // unlink(addr **list, addr **element) // // Removes an elemement from a list //-------------------------------------------------------------- void unlink(addr **list, addr **element) { addr *tmp; if(*list == *element) { *list = (*list)->next; delete_list(&((*element)->components)); delete *element; return; } tmp = *list; while(tmp->next != *element) tmp = tmp->next; tmp->next = (*element)->next; delete_list(&((*element)->components)); delete *element; } //-------------------------------------------------------------- // void // append(addr ** list, addr * element) { // // Makes a Copy of element and Appends it to the to the addr list //-------------------------------------------------------------- void append(addr ** list, addr * element) { addr * new_elmt, * tmp; addr * new_elmt_comps, * original_comp, * copy_comp; //- Copy element to new_elmt new_elmt = new addr(*element); //* replaced by above /*new_elmt = new addr; *new_elmt = *element; new_elmt->next = NULL; new_elmt->rt.nlri.pix = element->rt.nlri.pix; for(ListNodePix *p = (element->rt).origin.head(); p; p = (element->rt).origin.next(p->l)) { ListNodePix *origin_list = new ListNodePix(p->pix); (new_elmt->rt).origin.append(origin_list->l); }*/ //- Copy over Components to new element original_comp = element->components; if(!original_comp) new_elmt->components = NULL; else { //*new_elmt->components = new addr; new_elmt->components = new addr(*original_comp); copy_comp = new_elmt->components; } while (original_comp) { // for(; original_comp ; original_comp = original_comp->next , copy_comp = copy_comp->next) { //*tmp_comps->prefix = comps->prefix; //*tmp_comps->length = comps->length; //*tmp_comps->rt.nlri.pix = comps->rt.nlri.pix; //* Copy over origin information /* for(ListNodePix *p = (comps->rt).origin.head() ; p ; p = (comps->rt).origin.next(p->l)) { ListNodePix *list = new ListNodePix(p->pix); (tmp_comps->rt).origin.append(list->l); }*/ copy_comp->components = NULL; if(original_comp->next) { //*tmp_comps->next = new addr; copy_comp->next = new addr(* (original_comp->next)); } else copy_comp->next = NULL; original_comp = original_comp->next; copy_comp = copy_comp->next; } //- Add new_element to list if(!*list) { //- If no list create one *list = new_elmt; } else { //- Add to end of list tmp = *list; while(tmp->next != NULL) tmp = tmp->next; tmp->next = new_elmt; } // cerr << "aggcheck::append is empty" << endl; } //-------------------------------------------------------------- // void // delete_list(addr **list) // //-------------------------------------------------------------- void delete_list(addr **list) { addr *tmp; if(!(*list)) return; while(*list) { tmp = *list; *list = (*list)->next; delete_list(&(tmp->components)); delete tmp; } } //-------------------------------------------------------------- // addr * // copy_list(addr *aggregates) // // Copies all elements from aggregates to new list //-------------------------------------------------------------- addr * copy_list(addr * aggregates) { //- just cycle through aggregates and //- use append to add them to new list addr * new_list = NULL; if(aggregates) { for(; aggregates; aggregates = aggregates->next) append(&new_list, aggregates); return new_list; } else { return NULL; } } //--------------------------------------------------------------------------- // addr * // component_match(addr * components, Filter * filter, ASt PeerAS, IRR * whois) // // Tests components of an aggregate to see if they pass the filter //--------------------------------------------------------------------------- addr * component_match(addr * components, Filter * filter, ASt peer_as, IRR * whois) { addr * tmp, * old_tmp, * component_list = NULL; radix_node * root = NULL; tmp = components; while (tmp) { old_tmp = tmp; tmp = tmp->next; //* if(fap->filter->match(old_tmp->rt)) { if(old_tmp->bgproute->isMatching(peer_as, filter, whois)) { append(&component_list,old_tmp); unlink(&components,&old_tmp); } } if(component_list) root = radix_create_node(NULL,0,0,INVALID_AS,EMPTY); else return(NULL); for(; component_list ; component_list = component_list->next) { //*ListNodePix * p = (component_list->rt).origin.head(); //*radix_insert(component_list->prefix,component_list->length,p->pix,root); ItemASNO * asln = component_list->bgproute->origin->list.head(); radix_insert(component_list->prefix, component_list->length, asln->asno, root); } radix_aggregate(root); component_list = NULL; component_list = radix_get_aggs(root); tmp = radix_get_nonaggs(root); for(; tmp; tmp = tmp->next) append(&component_list,tmp); radix_delete_tree(root); return(component_list); } //--------------------------------------------------------------------------- // void // examine_policy(ASt source_as,int proxies,addr *aggregates, int radius) // // not finished //--------------------------------------------------------------------------- void examine_policy(ASt source_as, int proxies, addr * aggregates, int radius, IRR * whois) { //*ASPolicy *p; //* Filter_Action *fap; const FilterAction * fa; addr * tmp, * old_tmp, * agg_list = NULL, * proxy_aggs = NULL; addr * components = NULL, * comps_head = NULL, * aggs = NULL; //*Pix originator_as = NULL; const AutNum * source_autnum = whois->getAutNum(source_as); //- Cycle through peers of source AS //* for(p = as->peers.head();p;p = as->peers.next(p->peers)) { if (source_autnum) { // Do we have an autnum record for this as? //*AutNum * as = AS_map.define(source_as); //*r.aspath.append((new ListNodePix(source_as))->l); r.add(source_as); // Find all peers of current AS AutNumPeeringIterator itr(source_autnum); for (const Peering *peering = itr.first(); itr; peering = itr.next()) { if (proxies) { //- if we are to check proxy aggregation //- Find the allowed proxy aggregates based on routing policy proxy_aggs = allowed_proxy_aggregates(source_as, peering->peerAS, aggregates, whois); } else { proxy_aggs = copy_list(aggregates); } //*cout << AS_map.key(source_as) << "->"<< AS_map.key(p->peeras)<<"\n"; cout << "AS" << source_as << "->" << "AS" << peering->peerAS << endl; //- Save proxy_aggs head for the future tmp = proxy_aggs; //- Append peeras to as path ? hmmm //-r.aspath.append((new ListNodePix(p->peeras))->l); r.add(peering->peerAS); //- Cycle through export policies of each peer //* for (fap = p->out.head(); fap; fap = p->out.next(fap->falist)) { AutNumSelector export_itr(source_autnum, "export", NULL, peering->peerAS, &peering->peerIP, &peering->localIP); for (fa = export_itr.first(); fa; fa = export_itr.next()) { //- Check each aggregate in tmp against the peer's export policy while(tmp) { //*if(((tmp->rt).origin.size() == 1) && fap->filter->match(tmp->rt)) { if((tmp->bgproute->origin->getSize() == 1) && tmp->bgproute->isMatching(peering->peerAS, fa->filter, whois)) { append(&agg_list, tmp); old_tmp = tmp; tmp = tmp->next; unlink(&proxy_aggs,&old_tmp); } else { if(tmp->components) { components = component_match(tmp->components, fa->filter, peering->peerAS, whois); comps_head = components; for(; components ; components = components->next) append(&agg_list,components); delete_list(&comps_head); } tmp = tmp->next; } } tmp = proxy_aggs; } delete_list(&proxy_aggs); proxy_aggs = NULL; if(radius == -1) //- only the aggregator's policies are examined print_aggregates(agg_list,NO_COMPONENTS); else { //- source_as and peer AS are swtiched in this function call //*import_match(aggregator_as,p->peeras,&agg_list,radius); import_match(source_as, peering->peerAS, &agg_list, radius, whois); aggs = refine_aggs(agg_list); print_aggregates(aggs,NO_COMPONENTS); delete_list(&aggs); aggs = NULL; } delete_list(&agg_list); //* ListNodePix *lnp = r.aspath.tail(); //* r.aspath.unlink(lnp->l); //* delete lnp; r.remove(peering->peerAS); } //* delete as; } else { cout << "No Autnum record found for AS" << source_as << endl; } //end if (source_autnum) } //-------------------------------------------------------------- // void // import_match(ASt peeras, ASt as, addr **aggregates, // int radius, IRR * whois) // //--------------------------------------------------------------- void import_match(ASt peeras, ASt as, addr **aggregates, int radius, IRR * whois) { //-cerr << "import_match called" << endl; //*ASPolicy * p; //*Filter_Action * fap; FilterAction * fa; addr * tmp, * old_tmp, * import_aggs = NULL, * components = NULL; addr * comps_head = NULL, * tmp_aggs = NULL; const Peering * peering = NULL; //* if(!AS_map.define(as)) //* return; //* AutNum * autnum = (AutNum *) AS_map.contents(as).definition; const AutNum * autnum = whois->getAutNum(as); if(!*aggregates || !autnum) return; //- Check to make sure as has peeras listed as a peer //*for(p = autnum->peers.head(); p; p = autnum->peers.next(p->peers)) //* if(p->peeras == peeras) //* break; AutNumPeeringIterator itr(autnum); for (peering = itr.first(); itr; peering = itr.next()) if(peering->peerAS == peeras) break; //*if(!p) if(!peering) // peer does not exist return; tmp_aggs = copy_list(*aggregates); tmp = tmp_aggs; //* for(fap = p->in.head(); fap; fap=p->in.next(fap->falist)) { AutNumSelector import_itr(autnum, "import", NULL, peering->peerAS, &peering->peerIP, &peering->localIP); for (fa = import_itr.first(); fa; fa = import_itr.next()) { while(tmp) { //- Copy over global aspath //********************** //*(tmp->rt).aspath.clear(); //* for (ListNodePix *q = r.aspath.head() ; q && q->pix != as; q = r.aspath.next(q->l)) { //* ListNodePix *list = new ListNodePix(q->pix); //* (tmp->rt).aspath.append(list->l); //* } delete tmp->bgproute->aspath; delete tmp->bgproute->action_aspath; tmp->bgproute->aspath = new ASPath(*(r.aspath)); tmp->bgproute->action_aspath = new ASPath(*(r.action_aspath)); //*if(((tmp->rt).origin.size() == 1) && fap->filter->match(tmp->rt)) { if((tmp->bgproute->origin->getSize() == 1) && tmp->bgproute->isMatching(peering->peerAS, fa->filter, whois)) { append(&import_aggs,tmp); old_tmp = tmp; tmp = tmp->next; unlink(&tmp_aggs,&old_tmp); } else { if(tmp->components) { //*components = component_match(&(tmp->components),&fap); components = component_match(tmp->components, fa->filter, peering->peerAS, whois); comps_head = components; for(; components; components = components->next) append(&import_aggs, components); if(comps_head) if(comps_head->next) { //* cout << "import policy" << AS_map.key(as) << endl; cout << "import policy AS" << as << endl; } delete_list(&comps_head); } tmp = tmp->next; } } tmp = tmp_aggs; } delete_list(&tmp_aggs); tmp_aggs = NULL; //* ListNodePix *q = r.aspath.head(); ItemASNO * asln = r.aspath->path_list.head(); //* if(q->pix != peeras) { if(asln->asno != peeras) { append_aggregates(aggregates,&import_aggs); delete_list(&import_aggs); // tmp_aggs = refine_aggs(*aggregates); // delete_list(aggregates); // aggregates = &tmp_aggs; } else { // this is the case when peeras = aggregator AS in which case we have to // do level 2 computation delete_list(aggregates); *aggregates = import_aggs; } //*if(radius != -0.5) //* export_match(as, aggregates, radius); export_match(as, aggregates, radius, whois); } //-------------------------------------------------------------- // void // append_aggregates(addr **list,addr **append_list) // Copies over aggregate addr from append_list to // list only if they don't already exist on list // //--------------------------------------------------------------- void append_aggregates(addr ** list,addr ** append_list) { addr * old_elmt, * append_elmt,* check_elmt; int duplicate_flag = FALSE; if(!(*append_list)) return; append_elmt = * append_list; while(append_elmt) { check_elmt = * list; duplicate_flag = FALSE; //- Copy over an aggregate from "append_list" only //- if it is not already on "list" for(; check_elmt; check_elmt = check_elmt->next) //* if(elmt->rt.nlri.pix == tmp->rt.nlri.pix) if((append_elmt->prefix == check_elmt->prefix) && (append_elmt->length == check_elmt->length)) { duplicate_flag = TRUE; break; } if(!duplicate_flag) { append(list,append_elmt); } append_elmt = append_elmt->next; } } //-------------------------------------------------------------- // addr * // refine_aggs(addr *aggs) // //-------------------------------------------------------------- addr * refine_aggs(addr *aggs) { addr * tmp1, * tmp_list = NULL; addr * aggregates_list = NULL, * component_list = NULL; addr * components = NULL, * final_list = NULL; radix_node * root1 = NULL, * root2 = NULL; int recurse = FALSE; // need to recurse if there are more specifics which // contain even more specifics if(aggs) { root1 = radix_create_node(NULL,0,0,INVALID_AS,EMPTY); root2 = radix_create_node(NULL,0,0,INVALID_AS,EMPTY); } else return(NULL); for(tmp1 = aggs; tmp1; tmp1 = tmp1->next) { radix_insert(tmp1->prefix, tmp1->length, INVALID_AS, root1); if(!(tmp1->components)) { //* ListNodePix *p = (tmp1->rt).origin.head(); //* radix_insert(tmp1->prefix, tmp1->length, p->pix, root2); ItemASNO * asln = tmp1->bgproute->origin->list.head(); radix_insert(tmp1->prefix, tmp1->length, asln->asno, root2); } else for(components = tmp1->components; components; components = components->next) { //* ListNodePix *p = (tmp1->rt).origin.head(); //* radix_insert(components->prefix,components->length,p->pix,root2); ItemASNO * asln = tmp1->bgproute->origin->list.head(); radix_insert(components->prefix,components->length, asln->asno, root2); } } for(tmp1 = aggs; tmp1; tmp1 = tmp1->next) if(radix_search(tmp1->prefix, tmp1->length, root1) == MORE_SPECIFIC) { append(&tmp_list,tmp1); if(!(tmp1->components)) radix_delete(tmp1->prefix,tmp1->length,root2); else { recurse = TRUE; for(components = tmp1->components; components; components = components->next) radix_delete(components->prefix,components->length,root2); } } if(recurse) { final_list = refine_aggs(tmp_list); delete_list(&tmp_list); } else final_list = tmp_list; radix_aggregate(root2); aggregates_list = radix_get_aggs(root2); for(; aggregates_list; aggregates_list = aggregates_list->next) append(&final_list,aggregates_list); component_list = radix_get_nonaggs(root2); for(; component_list; component_list = component_list->next) append(&final_list,component_list); radix_delete_tree(root1); radix_delete_tree(root2); return(final_list); // cerr << "refine_aggs not done yet !!" << endl; // return aggs; } //-------------------------------------------------------------- // inline int // aspath_loop_check(BGPRoute & bgp_rt, ASt as) // //--------------------------------------------------------------- inline int aspath_loop_check(BGPRoute & bgp_rt, ASt as) { //*for (ListNodePix *p = r.aspath.head(); p; p = r.aspath.next(p->l)) for (ItemASNO * asln = bgp_rt.aspath->path_list.head(); asln; asln = bgp_rt.aspath->path_list.next(asln)) { //*if (p->pix == as) if (asln->asno == as) return TRUE; } return FALSE; } //-------------------------------------------------------------- // void // export_match(ASt as, addr **aggregates, int radius, IRR * whois) // //--------------------------------------------------------------- void export_match(ASt as, addr ** aggregates, int radius, IRR * whois) { //* ASPolicy *p; //* Filter_Action *fap; FilterAction * fa; //* AutNum *autnum = AS_map.define(as); const AutNum * autnum = whois->getAutNum(as); addr * tmp, * old_tmp, * agg_list = NULL, * tmp_aggs = NULL; addr * final_aggs, * components = NULL, * comps_head = NULL, * aggs = NULL; const Peering * peering = NULL; if(!*aggregates || !autnum) return; //*for(p = autnum->peers.head(); p; p = autnum->peers.next(p->peers)) { AutNumPeeringIterator itr(autnum); for (peering = itr.first(); itr; peering = itr.next()) { //* if(aspath_loop_check(r,p->peeras)) { if(aspath_loop_check(r,peering->peerAS)) { tmp_aggs = NULL; //* ListNodePix *q1 = r.aspath.head(); // aggregator AS //* ListNodePix *q2 = r.aspath.next(q1->l); // neighbour of agg for which // level > 0 is being computed ItemASNO * aggregator_asln = r.aspath->path_list.head(); // aggregator AS ItemASNO * neighbor_asln = r.aspath->path_list.next(aggregator_asln); // neighbour of agg for which // level > 0 is being computed // Checking the aggregator's export policy to the current as //*if(p->peeras == q1->pix && as != q2->pix) [ if((peering->peerAS == aggregator_asln->asno) && (as != neighbor_asln->asno)) { //*tmp_aggs = chk_policy(p->peeras,as,*aggregates); tmp_aggs = chk_policy(peering->peerAS, as, *aggregates, whois); // Checking the policies towards the aggregator's neighbour that is // being considered . Since the neigbour is always marked some of its // policies will not be checked otherwise. } else { //*if(p->peeras == q2->pix) //* tmp_aggs = chk_policy(as,p->peeras,*aggregates); if(peering->peerAS == neighbor_asln->asno) tmp_aggs = chk_policy(as, peering->peerAS, *aggregates, whois); } if(tmp_aggs) { append_aggregates(aggregates, &tmp_aggs); delete_list(&tmp_aggs); // tmp_aggs = refine_aggs(*aggregates); // delete_list(aggregates); // aggregates = &tmp_aggs; } continue; } //*r.aspath.append((new ListNodePix(p->peeras))->l); r.add(peering->peerAS); // cout << "export_match: "<< AS_map.key(as) << "->"<< AS_map.key(p->peeras)<<"\n"; tmp_aggs = copy_list(*aggregates); tmp = tmp_aggs; //*for (fap = p->out.head(); fap; fap = p->out.next(fap->falist)) { AutNumSelector export_itr(autnum, "export", NULL, peering->peerAS, &peering->peerIP, &peering->localIP); for (fa = export_itr.first(); fa; fa = export_itr.next()) { while(tmp) { //- Copy over global aspath //*(tmp->rt).aspath.clear(); //*for(ListNodePix *q = r.aspath.head() ; q && q->pix != as; q = r.aspath.next(q->l)) { //* ListNodePix *list = new ListNodePix(q->pix); //* (tmp->rt).aspath.append(list->l); //*} delete tmp->bgproute->aspath; delete tmp->bgproute->action_aspath; tmp->bgproute->aspath = new ASPath(*(r.aspath)); tmp->bgproute->action_aspath = new ASPath(*(r.action_aspath)); //*if (((tmp->rt).origin.size() == 1) && fap->filter->match(tmp->rt)) [ if((tmp->bgproute->origin->getSize() == 1) && tmp->bgproute->isMatching(peering->peerAS, fa->filter, whois)) { // first check if the aggregate matches the filter append(&agg_list,tmp); old_tmp = tmp; tmp = tmp->next; unlink(&tmp_aggs,&old_tmp); } else { // if the aggregate does not match the filter then check the // components if(tmp->components) { //*components = component_match(&(tmp->components),&fap); components = component_match(tmp->components, fa->filter, peering->peerAS, whois); comps_head = components; for(; components ; components = components->next) append(&agg_list, components); if(comps_head) if(comps_head->next) { //*cout << "Export policy " << AS_map.key(as) << endl; cout << "Export policy AS" << as << endl; } delete_list(&comps_head); } tmp = tmp->next; } } tmp = tmp_aggs; } delete_list(&tmp_aggs); tmp_aggs = NULL; // If nothing can be exported to this peer then consider the next peer if(!agg_list) { //*ListNodePix *lnp = r.aspath.tail(); //*r.aspath.unlink(lnp->l); //*delete lnp; r.remove(peering->peerAS); continue; } // Appending the possibly new aggregates we got to the old aggregates append_aggregates(aggregates, &agg_list); delete_list(&agg_list); // refining the list of aggregates // tmp_aggs = refine_aggs(*aggregates); // delete_list(aggregates); // aggregates = &tmp_aggs; //*int aspath_length = r.aspath.size(); int aspath_length = r.aspath->getPathLength(); // subtract 2 from aspath length because agg and neighbour already // included. This is because radius is distance from neighbour if(radius > (aspath_length - 2) || radius == -3) { //*import_match(as,p->peeras,aggregates,radius); import_match(as, peering->peerAS, aggregates, radius, whois); } //*ListNodePix *lnp = r.aspath.tail(); //*r.aspath.unlink(lnp->l); //*delete lnp; r.remove(peering->peerAS); } } //--------------------------------------------------------------------------- // void // print_aggregates(addr *aggregates, int print_components) // Prints out an aggregated set and its components //--------------------------------------------------------------------------- void print_aggregates(addr *aggregates, int print_components) { addr *tmp1,*tmp2; char prefix_quad[16]; int num_aggregates = 0; int num_components = 0; tmp1 = aggregates; while(tmp1) { int2dd(prefix_quad,tmp1->prefix); printf("%s/%d ",prefix_quad,tmp1->length); if(print_components) { printf("\nComponents:\n"); tmp2 = tmp1->components; while(tmp2) { ++num_components; int2dd(prefix_quad,tmp2->prefix); printf("%s/%d ( ",prefix_quad,tmp2->length); //-Print out Origins here for (ItemASNO * asln = tmp2->bgproute->origin->list.head(); asln; asln = tmp2->bgproute->origin->list.next(asln)) cout << "AS" << asln->asno << " "; cout << ")\n"; tmp2 = tmp2->next; } cout << endl; } tmp1 = tmp1->next; } cout << endl; } //--------------------------------------------------------------------------- // addr * // chk_policy(ASt as1, ASt as2, addr *aggs, IRR * whois) // //--------------------------------------------------------------------------- // Export policy of as1 and import policy of as2 are examined addr * chk_policy(ASt as1, ASt as2, addr *aggs, IRR * whois) { //*ASPolicy *p; //*Filter_Action *fap; FilterAction * fa; //*AutNum &autnum1 = *(AutNum *)(AS_map.define(as1)); //*AutNum &autnum2 = *(AutNum *)(AS_map.define(as2)); const AutNum * autnum1 = whois->getAutNum(as1); const AutNum * autnum2 = whois->getAutNum(as2); addr *tmp, *old_tmp, *agg_list = NULL, *tmp_aggs = NULL; addr *components = NULL, *comps_head = NULL; const Peering * peering = NULL; //* for(p = autnum1.peers.head(); p; p = autnum1.peers.next(p->peers)) AutNumPeeringIterator itr(autnum1); for (peering = itr.first(); itr; peering = itr.next()) { //*if(p->peeras == as2) if(peering->peerAS == as2) break; } //*if(!p) if (!peering) return(NULL); tmp_aggs = copy_list(aggs); if(!tmp_aggs) return(NULL); tmp = tmp_aggs; //*for (fap = p->out.head(); fap; fap = p->out.next(fap->falist)) { AutNumSelector export_itr(autnum1, "export", NULL, peering->peerAS, &peering->peerIP, &peering->localIP); for (fa = export_itr.first(); fa; fa = export_itr.next()) { while(tmp) { //*if (((tmp->rt).origin.size() == 1) && fap->filter->match(tmp->rt)) { if((tmp->bgproute->origin->getSize() == 1) && tmp->bgproute->isMatching(peering->peerAS, fa->filter, whois)) { append(&agg_list,tmp); old_tmp = tmp; tmp = tmp->next; unlink(&tmp_aggs,&old_tmp); } else { if(tmp->components) { //*components = component_match(&(tmp->components),&fap); components = component_match(tmp->components, fa->filter, peering->peerAS, whois); comps_head = components; for(; components ; components = components->next) append(&agg_list,components); delete_list(&comps_head); } tmp = tmp->next; } } tmp = tmp_aggs; } delete_list(&tmp_aggs); if(!agg_list) return(NULL); tmp_aggs = agg_list; agg_list = NULL; //*for(p = autnum2.peers.head(); p; p = autnum2.peers.next(p->peers)) AutNumPeeringIterator itr2(autnum2); for (peering = itr2.first(); itr2; peering = itr2.next()) { //*if(p->peeras == as1) if(peering->peerAS == as1) break; } //*if(!p) if (!peering) return(NULL); tmp = tmp_aggs; //*for (fap = p->in.head(); fap; fap = p->in.next(fap->falist)) { AutNumSelector import_itr(autnum2, "import", NULL, peering->peerAS, &peering->peerIP, &peering->localIP); for (fa = import_itr.first(); fa; fa = import_itr.next()) { while(tmp) { //*if (((tmp->rt).origin.size() == 1) && fap->filter->match(tmp->rt)) { if((tmp->bgproute->origin->getSize() == 1) && tmp->bgproute->isMatching(peering->peerAS, fa->filter, whois)) { append(&agg_list,tmp); old_tmp = tmp; tmp = tmp->next; unlink(&tmp_aggs,&old_tmp); } else { if(tmp->components) { //*components = component_match(&(tmp->components),&fap); components = component_match(tmp->components, fa->filter, peering->peerAS, whois); comps_head = components; for(; components ; components = components->next) append(&agg_list,components); delete_list(&comps_head); } tmp = tmp->next; } } tmp = tmp_aggs; } delete_list(&tmp_aggs); return(agg_list); }