/* * 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 #include "ldp_struct.h" #include "ldp_assert.h" #include "ldp_entity.h" #include "ldp_range.h" #include "ldp_nortel.h" #include "ldp_if.h" #include "ldp_msg.h" #include "ldp_hello.h" #include "ldp_mm_impl.h" #include "ldp_socket_impl.h" #include "ldp_timer_impl.h" #include "ldp_ifmgr_impl.h" #include "ldp_trace_impl.h" extern uint32_t _ldp_sub_entity_next_index; ldp_if* ldp_if_create() { ldp_if* i = (ldp_if*)ldp_malloc(sizeof(ldp_if)); if(i) { memset(i,0,sizeof(ldp_if)); LDP_REFCNT_INIT(i,0); LDP_LIST_ELEM_INIT(i,_global); LDP_LIST_ELEM_INIT(i,_range); i->label_space = -1; i->dest.addr.protocol = AF_INET; i->dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP; i->buffer_size = MPLS_PDUMAXLEN; i->index = _ldp_if_get_next_index(); i->oper_state = LDP_DOWN; } return i; } void ldp_if_delete(ldp_if* i) { // LDP_PRINT(g->user_data,"if delete\n"); LDP_REFCNT_ASSERT(i,0); ldp_free(i); } ldp_return_enum ldp_if_startup(ldp_global *g,ldp_if *i) { ldp_entity *e = NULL; LDP_ENTER(g->user_data,"ldp_if_startup"); LDP_ASSERT(i != NULL); e = i->entity; LDP_ASSERT(e != NULL); LDP_ASSERT(e->p.iff != NULL); if(ldp_ifmgr_get_address(g->ifmgr_handle,i->handle,&i->local_source_address, NULL,NULL) == LDP_FAILURE) { goto ldp_if_startup_delay; } if(ldp_socket_multicast_if_join(g->socket_handle,g->hello_socket,i, &i->dest.addr) == LDP_FAILURE) { goto ldp_if_startup_delay; } i->dest.port = e->remote_udp_port; if(ldp_hello_send(g,e) == LDP_FAILURE) { ldp_if_shutdown(g,i); return LDP_FAILURE; } i->oper_state = LDP_UP; LDP_EXIT(g->user_data,"ldp_if_startup"); return LDP_SUCCESS; ldp_if_startup_delay: /* * when a interface update comes in, it will search the global * list of interfaces, and start up the interface then */ i->oper_state = LDP_DOWN; LDP_EXIT(g->user_data,"ldp_if_startup-delayed"); return LDP_SUCCESS; } ldp_return_enum ldp_if_shutdown(ldp_global *g,ldp_if *i) { ldp_entity *e = NULL; LDP_ASSERT(i != NULL && ((e = i->entity) != NULL)); LDP_ENTER(g->user_data,"ldp_if_shutdown"); i->oper_state = LDP_DOWN; ldp_socket_multicast_if_drop(g->socket_handle,g->hello_socket,i, &i->dest.addr); ldp_timer_stop(g->timer_handle,i->hellotime_send_timer); ldp_timer_delete(g->timer_handle,i->hellotime_send_timer); i->hellotime_send_timer_duration = 0; i->hellotime_send_timer = 0; LDP_REFCNT_RELEASE(e,ldp_entity_delete); LDP_ASSERT(e != NULL); ldp_msg_delete(i->hello); i->hello = NULL; LDP_EXIT(g->user_data,"ldp_if_shutdown"); return LDP_SUCCESS; } ldp_bool ldp_if_is_active(ldp_if* i) { if(i && i->entity && i->entity->admin_state == LDP_ENABLE) return LDP_TRUE; return LDP_FALSE; } ldp_return_enum ldp_if_add_range(ldp_if* i,ldp_range* r) { if(i && r) { LDP_REFCNT_HOLD(r); i->range = r; i->label_space = r->label_space; _ldp_range_add_if(r,i); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum ldp_if_del_range(ldp_if* i) { if(i && i->range) { _ldp_range_del_if(i->range,i); LDP_REFCNT_RELEASE(i->range,ldp_range_delete); i->range = NULL; i->label_space = -1; return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_if_add_entity(ldp_if* i,ldp_entity* e) { if(i && e) { LDP_REFCNT_HOLD(e); i->entity = e; return LDP_SUCCESS; } return LDP_FAILURE; } ldp_entity *ldp_if_get_entity(ldp_if *i) { return i->entity; } ldp_return_enum _ldp_if_del_entity(ldp_if *i) { if(i && i->entity) { LDP_REFCNT_RELEASE(i->entity,ldp_entity_delete); i->entity = NULL; return LDP_SUCCESS; } return LDP_FAILURE; } uint32_t _ldp_if_get_next_index() { uint32_t retval = _ldp_sub_entity_next_index; _ldp_sub_entity_next_index++; if(retval > _ldp_sub_entity_next_index++) { _ldp_sub_entity_next_index = 1; } return retval; }