/* * Copyright (C) James R. Leu 2000 * jleu@mindspring.com * * This software is covered under the LGPL, for more * info check out http://www.gnu.org/copyleft/lgpl.html */ #include #include #include "ldp_struct.h" #include "ldp_inet_addr.h" #include "ldp_session.h" #include "ldp_entity.h" #include "ldp_global.h" #include "ldp_outlabel.h" #include "ldp_inlabel.h" #include "ldp_hello.h" #include "ldp_range.h" #include "ldp_peer.h" #include "ldp_attr.h" #include "ldp_adj.h" #include "ldp_fec.h" #include "ldp_if.h" #include "ldp_label_mapping.h" #include "ldp_socket_impl.h" #include "ldp_timer_impl.h" #include "ldp_ifmgr_impl.h" #include "ldp_tree_impl.h" #include "ldp_lock_impl.h" #include "ldp_mpls_impl.h" #include "ldp_fib_impl.h" #include "ldp_mm_impl.h" #include "ldp_trace_impl.h" void _ldp_global_fib_callback(ldp_cfg_handle cfg,ldp_update_enum type, ldp_prefix* dest) { ldp_session* session = NULL; ldp_fec* fec; LDP_ENTER(cfg->user_data,"_ldp_global_fib_callback"); ldp_lock_get(cfg->global_lock); fec = ldp_fec_create_prefix(&dest->network,dest->prefix_len); session = ldp_get_session_by_next_hop(cfg,&dest->next_hop,NULL); switch(type) { case LDP_ADD: Recognize_New_Fec(cfg,fec); break; case LDP_DEL: case LDP_MODIFY: Detect_Change_Fec_Next_Hop(cfg,fec,session); break; } ldp_lock_release(cfg->global_lock); LDP_EXIT(cfg->user_data,"_ldp_global_fib_callback"); } void _ldp_global_ifmgr_callback(ldp_cfg_handle cfg,const ldp_update_enum type, const char* ifname) { ldp_if* i = NULL; LDP_ENTER(cfg->user_data,"_ldp_global_ifmgr_callback"); LDP_TRACE_LOG(cfg->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_EVENT, "Interface update received for %s: ",ifname); ldp_lock_get(cfg->global_lock); i = LDP_LIST_HEAD(&cfg->iff); while(i != NULL) { if(!strncmp(ifname,i->name,LDP_MAX_IF_NAME)) { LDP_PRINT(cfg->user_data,"Interface update matches interface %s", i->name); break; } i = LDP_LIST_NEXT(&cfg->iff,i,_global); } if(i != NULL) { switch(type) { case LDP_ADD: LDP_TRACE_LOG(cfg->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_EVENT, "ADD\n"); LDP_PRINT(cfg->user_data,"starting up interface %s", i->name); ldp_if_startup(cfg,i); break; case LDP_DEL: LDP_TRACE_LOG(cfg->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_EVENT, "DEL\n"); LDP_PRINT(cfg->user_data,"shuting down interface %s", i->name); ldp_if_shutdown(cfg,i); break; case LDP_MODIFY: LDP_TRACE_LOG(cfg->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_EVENT, "MODIFY\n"); break; } } ldp_lock_release(cfg->global_lock); LDP_EXIT(cfg->user_data,"_ldp_global_ifmgr_callback"); } ldp_global* ldp_global_create(ldp_instance_handle data) { ldp_global* g = (ldp_global*)ldp_malloc(sizeof(ldp_global)); if(g) { memset(g,0,sizeof(ldp_global)); LDP_ENTER(g->user_data,"ldp_global_create"); g->global_lock = ldp_lock_create("_ldp_global_lock_"); ldp_lock_get(g->global_lock); LDP_LIST_INIT(&g->outlabel,ldp_outlabel); LDP_LIST_INIT(&g->inlabel,ldp_inlabel); LDP_LIST_INIT(&g->session,ldp_session); LDP_LIST_INIT(&g->entity,ldp_entity); LDP_LIST_INIT(&g->range,ldp_range); LDP_LIST_INIT(&g->attr,ldp_attr); LDP_LIST_INIT(&g->peer,ldp_peer); LDP_LIST_INIT(&g->adj,ldp_adj); LDP_LIST_INIT(&g->iff,ldp_if); g->message_identifier = 1; g->configuration_sequence_number = 1; g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE; g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE; g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE; g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE; g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE; g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE; g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN; g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT; g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT; g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG; g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP; g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING; g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME; g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER; g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL; g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER; g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL; g->admin_state = LDP_DISABLE; g->user_data = data; ldp_lock_release(g->global_lock); LDP_EXIT(g->user_data,"ldp_global_create"); } return g; } ldp_return_enum ldp_global_startup(ldp_global* g) { ldp_entity* e = NULL; ldp_dest dest; LDP_ASSERT(g != NULL); LDP_ENTER(g->user_data,"ldp_global_startup"); if(g->lsr_identifier.protocol == 0) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_ERROR, "ldp_global_startup: invalid LSRID\n"); goto ldp_global_startup_cleanup; } g->timer_handle = ldp_timer_open(g->user_data); if(ldp_timer_mgr_handle_verify(g->timer_handle) == LDP_FALSE) { goto ldp_global_startup_cleanup; } g->socket_handle = ldp_socket_mgr_open(g->user_data); if(ldp_socket_mgr_handle_verify(g->socket_handle) == LDP_FALSE) { goto ldp_global_startup_cleanup; } g->ifmgr_handle = ldp_ifmgr_open(g->user_data,g,_ldp_global_ifmgr_callback); if(ldp_ifmgr_handle_verify(g->ifmgr_handle) == LDP_FALSE) { goto ldp_global_startup_cleanup; } g->fib_handle = ldp_fib_open(g->user_data,g,_ldp_global_fib_callback); if(ldp_fib_handle_verify(g->fib_handle) == LDP_FALSE) { goto ldp_global_startup_cleanup; } g->mpls_handle = ldp_mpls_open(g->user_data); if(ldp_mpls_handle_verify(g->mpls_handle) == LDP_FALSE) { goto ldp_global_startup_cleanup; } g->addr_tree = ldp_tree_create(32); g->fec_tree = ldp_tree_create(32); g->hello_socket = ldp_socket_create_udp(g->socket_handle); if(ldp_socket_handle_verify(g->socket_handle,g->hello_socket) == LDP_FALSE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error creating UDP socket\n"); goto ldp_global_startup_cleanup; } dest.addr.protocol = AF_INET; dest.port = g->local_udp_port; dest.addr.u.ipv4 = INADDR_ANY; // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP; if(ldp_socket_bind(g->socket_handle,g->hello_socket,&dest) == LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error binding UDP socket\n"); goto ldp_global_startup_cleanup; } if(ldp_socket_options(g->socket_handle,g->hello_socket, LDP_SOCKET_NONBLOCK|LDP_SOCKET_REUSE) == LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting UDP socket options\n"); goto ldp_global_startup_cleanup; } if(ldp_socket_multicast_options(g->socket_handle,g->hello_socket,1,0) == LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting UDP socket multicast options\n"); goto ldp_global_startup_cleanup; } ldp_socket_readlist_add(g->socket_handle,g->hello_socket,0,LDP_UDP_DATA); g->listen_socket = ldp_socket_create_tcp(g->socket_handle); if(ldp_socket_handle_verify(g->socket_handle,g->listen_socket) == LDP_FALSE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error creating TCP socket\n"); goto ldp_global_startup_cleanup; } if(ldp_socket_options(g->socket_handle,g->listen_socket, LDP_SOCKET_NONBLOCK|LDP_SOCKET_REUSE) == LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting TCP socket options\n"); goto ldp_global_startup_cleanup; } dest.addr.protocol = AF_INET; dest.port = g->local_tcp_port; dest.addr.u.ipv4 = INADDR_ANY; if(ldp_socket_bind(g->socket_handle,g->listen_socket,&dest) ==LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error binding TCP socket\n"); goto ldp_global_startup_cleanup; } if(ldp_socket_tcp_listen(g->socket_handle,g->listen_socket,15) == LDP_FAILURE) { LDP_TRACE_LOG(g->user_data,LDP_TRACE_STATE_ALL,LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting listen buffer for TCP socket\n"); goto ldp_global_startup_cleanup; } ldp_socket_readlist_add(g->socket_handle,g->listen_socket,0, LDP_TCP_LISTEN); e = LDP_LIST_HEAD(&g->entity); while(e != NULL) { ldp_entity_startup(g,e); e = LDP_LIST_NEXT(&g->entity,e,_global); } g->admin_state = LDP_ENABLE; LDP_EXIT(g->user_data,"ldp_global_startup"); return LDP_SUCCESS; ldp_global_startup_cleanup: ldp_global_shutdown(g); ldp_socket_close(g->socket_handle,g->hello_socket); ldp_socket_close(g->socket_handle,g->listen_socket); g->hello_socket = 0; g->listen_socket = 0; LDP_EXIT(g->user_data,"ldp_global_startup-error"); return LDP_FAILURE; } ldp_return_enum ldp_global_shutdown(ldp_global* g) { ldp_entity* e = NULL; LDP_ASSERT(g); LDP_ENTER(g->user_data,"ldp_global_shutdown"); e = LDP_LIST_HEAD(&g->entity); while(e != NULL) { ldp_entity_shutdown(g,e,1); e = LDP_LIST_NEXT(&g->entity,e,_global); } g->admin_state = LDP_DISABLE; ldp_socket_readlist_del(g->socket_handle,g->hello_socket); ldp_socket_close(g->socket_handle,g->hello_socket); ldp_socket_readlist_del(g->socket_handle,g->listen_socket); ldp_socket_close(g->socket_handle,g->listen_socket); ldp_tree_delete(g->addr_tree); ldp_tree_delete(g->fec_tree); ldp_lock_release(g->global_lock); ldp_timer_close(g->timer_handle); ldp_lock_get(g->global_lock); ldp_socket_mgr_close(g->socket_handle); ldp_ifmgr_close(g->ifmgr_handle); ldp_fib_close(g->fib_handle); ldp_mpls_close(g->mpls_handle); LDP_EXIT(g->user_data,"ldp_global_shutdown"); return LDP_SUCCESS; } ldp_return_enum ldp_global_delete(ldp_global* g) { if(g) { ldp_lock_delete(g->global_lock); LDP_PRINT(g->user_data,"global delete\n"); ldp_free(g); } return LDP_SUCCESS; } ldp_return_enum _ldp_global_add_range(ldp_global* g,ldp_range* r) { if(g && r) { LDP_REFCNT_HOLD(r); LDP_LIST_ADD_HEAD(&g->range,r,_global,ldp_range); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_range(ldp_global* g,ldp_range* r) { if(g && r) { LDP_LIST_REMOVE(&g->range,r,_global); LDP_REFCNT_RELEASE(r,ldp_range_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_attr(ldp_global* g,ldp_attr* a) { ldp_attr *ap = NULL; if(g && a) { LDP_REFCNT_HOLD(a); ap = LDP_LIST_HEAD(&g->attr); while(ap != NULL) { if(ap->index > a->index) { LDP_LIST_INSERT_BEFORE(&g->attr,ap,a,_global); return LDP_SUCCESS; } ap = LDP_LIST_NEXT(&g->attr,ap,_global); } LDP_LIST_ADD_TAIL(&g->attr,a,_global,ldp_attr); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_attr(ldp_global* g,ldp_attr* a) { if(g && a) { LDP_LIST_REMOVE(&g->attr,a,_global); LDP_REFCNT_RELEASE(a,ldp_attr_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_peer(ldp_global* g,ldp_peer* p) { ldp_peer *pp = NULL; if(g && p) { LDP_REFCNT_HOLD(p); pp = LDP_LIST_HEAD(&g->peer); while(pp != NULL) { if(pp->index > p->index) { LDP_LIST_INSERT_BEFORE(&g->peer,pp,p,_global); return LDP_SUCCESS; } pp = LDP_LIST_NEXT(&g->peer,pp,_global); } LDP_LIST_ADD_TAIL(&g->peer,p,_global,ldp_peer); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_peer(ldp_global* g,ldp_peer* p) { if(g && p) { LDP_LIST_REMOVE(&g->peer,p,_global); LDP_REFCNT_RELEASE(p,ldp_peer_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_if(ldp_global* g,ldp_if* i) { ldp_if *ip = NULL; if(g && i) { LDP_REFCNT_HOLD(i); ip = LDP_LIST_HEAD(&g->iff); while(ip != NULL) { if(ip->index > i->index) { LDP_LIST_INSERT_BEFORE(&g->iff,ip,i,_global); return LDP_SUCCESS; } ip = LDP_LIST_NEXT(&g->iff,ip,_global); } LDP_LIST_ADD_TAIL(&g->iff,i,_global,ldp_if); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_if(ldp_global* g,ldp_if* i) { if(g && i) { LDP_LIST_REMOVE(&g->iff,i,_global); LDP_REFCNT_RELEASE(i,ldp_if_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_adj(ldp_global* g,ldp_adj* a) { ldp_adj *ap = NULL; if(g && a) { LDP_REFCNT_HOLD(a); ap = LDP_LIST_HEAD(&g->adj); while(ap != NULL) { if(ap->index > a->index) { LDP_LIST_INSERT_BEFORE(&g->adj,ap,a,_global); return LDP_SUCCESS; } ap = LDP_LIST_NEXT(&g->adj,ap,_global); } LDP_LIST_ADD_TAIL(&g->adj,a,_global,ldp_adj); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_adj(ldp_global* g,ldp_adj* a) { if(g && a) { LDP_LIST_REMOVE(&g->adj,a,_global); LDP_REFCNT_RELEASE(a,ldp_adj_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_entity(ldp_global* g,ldp_entity* e) { ldp_entity *ep = NULL; if(g && e) { LDP_REFCNT_HOLD(e); ep = LDP_LIST_HEAD(&g->entity); while(ep != NULL) { if(ep->index > e->index) { LDP_LIST_INSERT_BEFORE(&g->entity,ep,e,_global); return LDP_SUCCESS; } ep = LDP_LIST_NEXT(&g->entity,ep,_global); } LDP_LIST_ADD_TAIL(&g->entity,e,_global,ldp_entity); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_entity(ldp_global* g,ldp_entity* e) { if(g && e) { LDP_LIST_REMOVE(&g->entity,e,_global); LDP_REFCNT_RELEASE(e,ldp_entity_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_session(ldp_global* g,ldp_session* s) { ldp_session *sp = NULL; if(g && s) { LDP_REFCNT_HOLD(s); s->on_global = LDP_TRUE; sp = LDP_LIST_HEAD(&g->session); while(sp != NULL) { if(sp->index > s->index) { LDP_LIST_INSERT_BEFORE(&g->session,sp,s,_global); return LDP_SUCCESS; } sp = LDP_LIST_NEXT(&g->session,sp,_global); } LDP_LIST_ADD_TAIL(&g->session,s,_global,ldp_session); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_session(ldp_global* g,ldp_session* s) { if(g && s) { LDP_ASSERT(s->on_global == LDP_TRUE); LDP_LIST_REMOVE(&g->session,s,_global); s->on_global = LDP_FALSE; LDP_REFCNT_RELEASE(s,ldp_session_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_inlabel(ldp_global* g,ldp_inlabel* i) { ldp_inlabel *ip = NULL; if(g && i) { LDP_REFCNT_HOLD(i); ip = LDP_LIST_HEAD(&g->inlabel); while(ip != NULL) { if(ip->index > i->index) { LDP_LIST_INSERT_BEFORE(&g->inlabel,ip,i,_global); return LDP_SUCCESS; } ip = LDP_LIST_NEXT(&g->inlabel,ip,_global); } LDP_LIST_ADD_TAIL(&g->inlabel,i,_global,ldp_inlabel); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_inlabel(ldp_global* g,ldp_inlabel* i) { if(g && i) { LDP_ASSERT(i->reuse_count == 0); LDP_LIST_REMOVE(&g->inlabel,i,_global); LDP_REFCNT_RELEASE(i,ldp_inlabel_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_add_outlabel(ldp_global* g,ldp_outlabel* o) { ldp_outlabel *op = NULL; if(g && o) { LDP_REFCNT_HOLD(o); op = LDP_LIST_HEAD(&g->outlabel); while(op != NULL) { if(op->index > o->index) { LDP_LIST_INSERT_BEFORE(&g->outlabel,op,o,_global); return LDP_SUCCESS; } op = LDP_LIST_NEXT(&g->outlabel,op,_global); } LDP_LIST_ADD_TAIL(&g->outlabel,o,_global,ldp_outlabel); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_global_del_outlabel(ldp_global* g,ldp_outlabel* o) { if(g && o) { LDP_ASSERT(o->merge_count == 0); LDP_LIST_REMOVE(&g->outlabel,o,_global); LDP_REFCNT_RELEASE(o,ldp_outlabel_delete); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum ldp_global_find_attr_index(ldp_global* g,uint32_t index, ldp_attr** attr) { ldp_attr* a = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ a = LDP_LIST_TAIL(&g->attr); if(a == NULL || a->index < index) { return LDP_END_OF_LIST; *attr = NULL; } a = LDP_LIST_HEAD(&g->attr); while(a != NULL) { if(a->index == index) { *attr = a; return LDP_SUCCESS; } a = LDP_LIST_NEXT(&g->attr,a,_global); } } *attr = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_session_index(ldp_global* g,uint32_t index, ldp_session** session) { ldp_session* s = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ s = LDP_LIST_TAIL(&g->session); if(s == NULL || s->index < index) { *session = NULL; return LDP_END_OF_LIST; } s = LDP_LIST_HEAD(&g->session); while(s != NULL) { if(s->index == index) { *session = s; return LDP_SUCCESS; } s = LDP_LIST_NEXT(&g->session,s,_global); } } *session = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_inlabel_index(ldp_global* g,uint32_t index, ldp_inlabel** inlabel) { ldp_inlabel* i = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ i = LDP_LIST_TAIL(&g->inlabel); if(i == NULL || i->index < index) { *inlabel = NULL; return LDP_END_OF_LIST; } i = LDP_LIST_HEAD(&g->inlabel); while(i != NULL) { if(i->index == index) { *inlabel = i; return LDP_SUCCESS; } i = LDP_LIST_NEXT(&g->inlabel,i,_global); } } *inlabel = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_outlabel_index(ldp_global* g,uint32_t index, ldp_outlabel** outlabel) { ldp_outlabel* o = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ o = LDP_LIST_TAIL(&g->outlabel); if(o == NULL || o->index < index) { *outlabel = NULL; return LDP_END_OF_LIST; } o = LDP_LIST_HEAD(&g->outlabel); while(o != NULL) { if(o->index == index) { *outlabel = o; return LDP_SUCCESS; } o = LDP_LIST_NEXT(&g->outlabel,o,_global); } } *outlabel = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_entity_index(ldp_global* g,uint32_t index, ldp_entity** entity) { ldp_entity* e = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ e = LDP_LIST_TAIL(&g->entity); if(e == NULL || e->index < index) { *entity = NULL; return LDP_END_OF_LIST; } e = LDP_LIST_HEAD(&g->entity); while(e != NULL) { if(e->index == index) { *entity = e; return LDP_SUCCESS; } e = LDP_LIST_NEXT(&g->entity,e,_global); } } *entity = NULL; return LDP_FAILURE; } ldp_range* ldp_global_find_range_label_space(ldp_global* g,int32_t label_space) { ldp_range* r = LDP_LIST_HEAD(&g->range); if(g && label_space >= 0) { while(r != NULL) { if(r->label_space == label_space) return r; r = LDP_LIST_NEXT(&g->range,r,_global); } } return NULL; } ldp_peer* ldp_global_find_peer_lsrid(ldp_global* g,ldp_inet_addr *lsrid) { ldp_peer* p = LDP_LIST_HEAD(&g->peer); /* JLEU: we will need to add a tree to optimize this search, known peers will be in tree, unknown will take a "slow path" to verify them, then be added to tree */ if(g && lsrid) { while(p != NULL) { LDP_PRINT(g->user_data, "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n", p->dest.addr.u.ipv4,lsrid->u.ipv4); if(ldp_inet_addr_is_equal(&p->dest.addr,lsrid) == LDP_TRUE) { return p; } p = LDP_LIST_NEXT(&g->peer,p,_global); } } return NULL; } ldp_return_enum ldp_global_find_adj_index(ldp_global* g,uint32_t index, ldp_adj** adj) { ldp_adj* a = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ a = LDP_LIST_TAIL(&g->adj); if(a == NULL || a->index < index) { return LDP_END_OF_LIST; *adj = NULL; } a = LDP_LIST_HEAD(&g->adj); while(a != NULL) { if(a->index == index) { *adj = a; return LDP_SUCCESS; } a = LDP_LIST_NEXT(&g->adj,a,_global); } } *adj = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_peer_index(ldp_global* g,uint32_t index, ldp_peer** peer) { ldp_peer* p = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ p = LDP_LIST_TAIL(&g->peer); if(p == NULL || p->index < index) { *peer = NULL; return LDP_END_OF_LIST; } p = LDP_LIST_HEAD(&g->peer); while(p != NULL) { if(p->index == index) { *peer = p; return LDP_SUCCESS; } p = LDP_LIST_NEXT(&g->peer,p,_global); } } *peer = NULL; return LDP_FAILURE; } ldp_return_enum ldp_global_find_if_index(ldp_global* g,uint32_t index, ldp_if** iff) { ldp_if* i = NULL; if(g && index > 0) { /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ i = LDP_LIST_TAIL(&g->iff); if(i == NULL || i->index < index) { *iff = NULL; return LDP_END_OF_LIST; } i = LDP_LIST_HEAD(&g->iff); while(i != NULL) { if(i->index == index) { *iff = i; return LDP_SUCCESS; } i = LDP_LIST_NEXT(&g->iff,i,_global); } } *iff = NULL; return LDP_FAILURE; } ldp_if* ldp_global_find_if_handle(ldp_global* g,ldp_if_handle handle) { ldp_if* i = LDP_LIST_HEAD(&g->iff); if(g) { while(i != NULL) { if(i->handle == handle) return i; i = LDP_LIST_NEXT(&g->iff,i,_global); } } return NULL; } ldp_adj* ldp_global_find_adj_ldpid(ldp_global* g,ldp_inet_addr* lsraddr, int labelspace) { ldp_adj* a = LDP_LIST_HEAD(&g->adj); while(a != NULL) { if((ldp_inet_addr_is_equal(lsraddr,&a->remote_lsr_address) == LDP_TRUE) && labelspace == a->remote_label_space) return a; a = LDP_LIST_NEXT(&g->adj,a,_global); } return NULL; }