/* * 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 "ldp_struct.h" #include "ldp_assert.h" #include "ldp_outlabel.h" #include "ldp_inlabel.h" #include "ldp_session.h" #include "ldp_entity.h" #include "ldp_attr.h" #include "ldp_global.h" #include "ldp_mpls_impl.h" #include "ldp_mm_impl.h" #include "ldp_trace_impl.h" /* temporary until I get a logginh facility setup */ #include static uint32_t _ldp_inlabel_next_index = 1; ldp_inlabel* ldp_inlabel_create() { ldp_inlabel* i = (ldp_inlabel*)ldp_malloc(sizeof(ldp_inlabel)); if(i) { memset(i,0,sizeof(ldp_inlabel)); LDP_REFCNT_INIT(i,0); LDP_LIST_INIT(&i->session_root,ldp_session_elem); LDP_LIST_INIT(&i->attr_root,ldp_attr_elem); LDP_LIST_ELEM_INIT(i,_global); LDP_LIST_ELEM_INIT(i,_outlabel); i->index = _ldp_inlabel_get_next_index(); i->l.type = LDP_LABEL_NONE; } return i; } void ldp_inlabel_delete_complete(ldp_global* g,ldp_inlabel* in,ldp_session* s,ldp_attr* a) { ldp_attr_del_inlabel(a); ldp_session_del_inlabel(s,in); _ldp_global_del_inlabel(g,in); ldp_inlabel_del_outlabel(in); } ldp_inlabel* ldp_inlabel_create_complete(ldp_global* g,ldp_session* s, ldp_attr* a) { ldp_inlabel* in = ldp_inlabel_create(); if(in != NULL) { _ldp_global_add_inlabel(g,in); in->label_space = ldp_entity_label_space(s->entity); if(ldp_mpls_inlabel_add(g->mpls_handle,in) == LDP_FAILURE) { _ldp_global_del_inlabel(g,in); return NULL; } if(ldp_session_add_inlabel(s,in) == LDP_FAILURE) { _ldp_global_del_inlabel(g,in); return NULL; } ldp_attr_add_inlabel(a,in); ldp_label2ldp_attr(&in->l,a); } return in; } void ldp_inlabel_delete(ldp_inlabel* i) { // LDP_PRINT(g->user_data,"inlabel delete\n"); LDP_REFCNT_ASSERT(i,0); ldp_free(i); } ldp_return_enum ldp_inlabel_add_outlabel(ldp_inlabel* i,ldp_outlabel* o) { if(i && o) { LDP_REFCNT_HOLD(o); LDP_ASSERT(i->outlabel == NULL); i->outlabel = o; _ldp_outlabel_add_inlabel(o,i); return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum ldp_inlabel_del_outlabel(ldp_inlabel* i) { if(i && i->outlabel) { _ldp_outlabel_del_inlabel(i->outlabel,i); LDP_REFCNT_RELEASE(i->outlabel,ldp_outlabel_delete); i->outlabel = NULL; return LDP_SUCCESS; } return LDP_FAILURE; } ldp_return_enum _ldp_inlabel_add_attr(ldp_inlabel* i,ldp_attr* a) { if(i && a) { ldp_attr_elem* ae = (ldp_attr_elem*)ldp_malloc(sizeof(ldp_attr_elem)); if(ae != NULL) { LDP_LIST_ELEM_INIT(ae,_elem); LDP_REFCNT_HOLD(a); ae->attr = a; i->reuse_count++; LDP_LIST_ADD_HEAD(&i->attr_root,ae,_elem,ldp_attr_elem); return LDP_SUCCESS; } } return LDP_FAILURE; } ldp_return_enum _ldp_inlabel_del_attr(ldp_inlabel* i,ldp_attr* a) { if(i && a) { ldp_attr_elem* ae = LDP_LIST_HEAD(&i->attr_root); while(ae) { if(ae->attr->index == a->index) { LDP_LIST_REMOVE(&i->attr_root,ae,_elem); i->reuse_count--; LDP_REFCNT_RELEASE(ae->attr,ldp_attr_delete) ldp_free(ae); return LDP_SUCCESS; } ae = LDP_LIST_NEXT(&i->attr_root,ae,_elem); } } return LDP_FAILURE; } ldp_return_enum _ldp_inlabel_add_session(ldp_inlabel* i,ldp_session* s) { if(i && s) { ldp_session_elem* se = (ldp_session_elem*)ldp_malloc(sizeof(ldp_session_elem)); if(se != NULL) { LDP_LIST_ELEM_INIT(se,_elem); LDP_REFCNT_HOLD(s); se->session = s; LDP_LIST_ADD_HEAD(&i->session_root,se,_elem,ldp_session_elem); return LDP_SUCCESS; } } return LDP_FAILURE; } ldp_return_enum _ldp_inlabel_del_session(ldp_inlabel* i,ldp_session* s) { if(i && s) { ldp_session_elem* se = LDP_LIST_HEAD(&i->session_root); while(se) { if(se->session->index == s->index) { LDP_LIST_REMOVE(&i->session_root,se,_elem); LDP_REFCNT_RELEASE(se->session,ldp_session_delete) ldp_free(se); return LDP_SUCCESS; } se = LDP_LIST_NEXT(&i->session_root,se,_elem); } } return LDP_FAILURE; } uint32_t _ldp_inlabel_get_next_index() { uint32_t retval = _ldp_inlabel_next_index; _ldp_inlabel_next_index++; if(retval > _ldp_inlabel_next_index++) { _ldp_inlabel_next_index = 1; } return retval; }