📄 lsr_global.c
字号:
/* * Copyright (C) James R. Leu 2002 * jleu@mindspring.com * * This software is covered under the LGPL, for more * info check out http://www.gnu.org/copyleft/lgpl.html */#include "lsr_struct.h"#include "lsr_global.h"#include "lsr_outsegment.h"#include "lsr_insegment.h"#include "lsr_xconnect.h"#include "lsr_ftn.h"#include "lsr_if.h"#include "mpls_ifmgr_impl.h"#include "mpls_mpls_impl.h"#include "mpls_lock_impl.h"#include "mpls_mm_impl.h"#include "mpls_trace_impl.h"lsr_global *lsr_global_create(mpls_instance_handle data){ lsr_global *g = (lsr_global *) mpls_malloc(sizeof(lsr_global)); if (g) { memset(g, 0, sizeof(lsr_global)); LDP_ENTER(g->user_data, "lsr_global_create"); g->global_lock = mpls_lock_create("_lsr_global_lock_"); mpls_lock_get(g->global_lock); MPLS_LIST_INIT(&g->outsegment, lsr_outsegment); MPLS_LIST_INIT(&g->insegment, lsr_insegment); MPLS_LIST_INIT(&g->xconnect, lsr_xconnect); MPLS_LIST_INIT(&g->ftn, lsr_ftn); MPLS_LIST_INIT(&g->iff, lsr_if); g->admin_state = MPLS_ADMIN_DISABLE; g->user_data = data; mpls_lock_release(g->global_lock); LDP_EXIT(g->user_data, "lsr_global_create"); } return g;}mpls_return_enum lsr_global_startup(lsr_global * g){ MPLS_ASSERT(g != NULL); LDP_ENTER(g->user_data, "lsr_global_startup"); g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g); if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) { goto lsr_global_startup_cleanup; } g->mpls_handle = mpls_mpls_open(g->user_data); if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) { goto lsr_global_startup_cleanup; } g->admin_state = MPLS_ADMIN_ENABLE; LDP_EXIT(g->user_data, "lsr_global_startup"); return MPLS_SUCCESS;lsr_global_startup_cleanup: lsr_global_shutdown(g); LDP_EXIT(g->user_data, "lsr_global_startup-error"); return MPLS_FAILURE;}mpls_return_enum lsr_global_shutdown(lsr_global * g){ MPLS_ASSERT(g); LDP_ENTER(g->user_data, "lsr_global_shutdown"); g->admin_state = MPLS_ADMIN_DISABLE; mpls_lock_release(g->global_lock); mpls_lock_get(g->global_lock); mpls_ifmgr_close(g->ifmgr_handle); mpls_mpls_close(g->mpls_handle); LDP_EXIT(g->user_data, "lsr_global_shutdown"); return MPLS_SUCCESS;}mpls_return_enum lsr_global_delete(lsr_global * g){ if (g) { mpls_lock_delete(g->global_lock); LDP_PRINT(g->user_data, "global delete\n"); mpls_free(g); } return MPLS_SUCCESS;}/* struct if */mpls_return_enum _lsr_global_add_if(lsr_global * g, lsr_if * i){ lsr_if *ip = NULL; if (g && i) { MPLS_REFCNT_HOLD(i); ip = MPLS_LIST_HEAD(&g->iff); while (ip != NULL) { if (ip->index > i->index) { MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global); return MPLS_SUCCESS; } ip = MPLS_LIST_NEXT(&g->iff, ip, _global); } MPLS_LIST_ADD_TAIL(&g->iff, i, _global, lsr_if); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum _lsr_global_del_if(lsr_global * g, lsr_if * i){ if (g && i) { MPLS_LIST_REMOVE(&g->iff, i, _global); MPLS_REFCNT_RELEASE(i, lsr_if_delete); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum lsr_global_find_if_index(lsr_global * g, uint32_t index, lsr_if ** iff){ lsr_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 = MPLS_LIST_TAIL(&g->iff); if (i == NULL || i->index < index) { *iff = NULL; return MPLS_END_OF_LIST; } i = MPLS_LIST_HEAD(&g->iff); while (i != NULL) { if (i->index == index) { *iff = i; return MPLS_SUCCESS; } i = MPLS_LIST_NEXT(&g->iff, i, _global); } } *iff = NULL; return MPLS_FAILURE;}lsr_if * lsr_global_find_if_handle(lsr_global * g, mpls_if_handle ifhandle){ lsr_if *i = NULL; if (g && mpls_if_handle_verify(g->ifmgr_handle, ifhandle) == MPLS_BOOL_TRUE) { i = MPLS_LIST_HEAD(&g->iff); while (i != NULL) { if (!mpls_if_handle_compare(i->handle, ifhandle)) { return i; } i = MPLS_LIST_NEXT(&g->iff, i, _global); } } return NULL;}/* struct outsegment */mpls_return_enum _lsr_global_add_outsegment(lsr_global * g, lsr_outsegment * o){ lsr_outsegment *op = NULL; if (g && o) { MPLS_REFCNT_HOLD(o); op = MPLS_LIST_HEAD(&g->outsegment); while (op != NULL) { if (op->index > o->index) { MPLS_LIST_INSERT_BEFORE(&g->outsegment, op, o, _global); return MPLS_SUCCESS; } op = MPLS_LIST_NEXT(&g->outsegment, op, _global); } MPLS_LIST_ADD_TAIL(&g->outsegment, o, _global, lsr_outsegment); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum _lsr_global_del_outsegment(lsr_global * g, lsr_outsegment * o){ if (g && o) { MPLS_LIST_REMOVE(&g->outsegment, o, _global); MPLS_REFCNT_RELEASE(o, lsr_outsegment_delete); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum lsr_global_find_outsegment_index(lsr_global * g, uint32_t index, lsr_outsegment ** outsegment){ lsr_outsegment *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 = MPLS_LIST_TAIL(&g->outsegment); if (o == NULL || o->index < index) { *outsegment = NULL; return MPLS_END_OF_LIST; } o = MPLS_LIST_HEAD(&g->outsegment); while (o != NULL) { if (o->index == index) { *outsegment = o; return MPLS_SUCCESS; } o = MPLS_LIST_NEXT(&g->outsegment, o, _global); } } *outsegment = NULL; return MPLS_FAILURE;}/* struct insegment */mpls_return_enum _lsr_global_add_insegment(lsr_global * g, lsr_insegment * i){ lsr_insegment *ip = NULL; if (g && i) { MPLS_REFCNT_HOLD(i); ip = MPLS_LIST_HEAD(&g->insegment); while (ip != NULL) { if (ip->index > i->index) { MPLS_LIST_INSERT_BEFORE(&g->insegment, ip, i, _global); return MPLS_SUCCESS; } ip = MPLS_LIST_NEXT(&g->insegment, ip, _global); } MPLS_LIST_ADD_TAIL(&g->insegment, i, _global, lsr_insegment); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum _lsr_global_del_insegment(lsr_global * g, lsr_insegment * i){ if (g && i) { MPLS_LIST_REMOVE(&g->insegment, i, _global); MPLS_REFCNT_RELEASE(i, lsr_insegment_delete); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum lsr_global_find_insegment_index(lsr_global * g, uint32_t index, lsr_insegment ** insegment){ lsr_insegment *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 = MPLS_LIST_TAIL(&g->insegment); if (i == NULL || i->index < index) { *insegment = NULL; return MPLS_END_OF_LIST; } i = MPLS_LIST_HEAD(&g->insegment); while (i != NULL) { if (i->index == index) { *insegment = i; return MPLS_SUCCESS; } i = MPLS_LIST_NEXT(&g->insegment, i, _global); } } *insegment = NULL; return MPLS_FAILURE;}/* struct xconnect */mpls_return_enum _lsr_global_add_xconnect(lsr_global * g, lsr_xconnect * x){ lsr_xconnect *xp = NULL; if (g && x) { MPLS_REFCNT_HOLD(x); xp = MPLS_LIST_HEAD(&g->xconnect); while (xp != NULL) { if (xp->index > x->index) { MPLS_LIST_INSERT_BEFORE(&g->xconnect, xp, x, _global); return MPLS_SUCCESS; } xp = MPLS_LIST_NEXT(&g->xconnect, xp, _global); } MPLS_LIST_ADD_TAIL(&g->xconnect, x, _global, lsr_xconnect); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum _lsr_global_del_xconnect(lsr_global * g, lsr_xconnect * x){ if (g && x) { MPLS_LIST_REMOVE(&g->xconnect, x, _global); MPLS_REFCNT_RELEASE(x, lsr_xconnect_delete); return MPLS_SUCCESS; } return MPLS_FAILURE;}mpls_return_enum lsr_global_find_xconnect_index(lsr_global * g, uint32_t index, lsr_xconnect ** xconnect){ lsr_xconnect *x = 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 */ x = MPLS_LIST_TAIL(&g->xconnect); if (x == NULL || x->index < index) { *xconnect = NULL; return MPLS_END_OF_LIST; } x = MPLS_LIST_HEAD(&g->xconnect); while (x != NULL) { if (x->index == index) { *xconnect = x; return MPLS_SUCCESS; } x = MPLS_LIST_NEXT(&g->xconnect, x, _global); } } *xconnect = NULL; return MPLS_FAILURE;}mpls_return_enum lsr_global_find_xconnect_index2(lsr_global * g, uint32_t in, uint32_t out, lsr_xconnect ** xconnect){ lsr_insegment *iseg = NULL; lsr_xconnect *x = NULL; if (g && in > 0 && out > 0) { if (lsr_global_find_insegment_index(g,in,&iseg) != MPLS_SUCCESS) { return MPLS_FAILURE; } x = MPLS_LIST_HEAD(&iseg->xconnect_root); while (x != NULL) { if (x->outsegment && x->outsegment->index == out) { *xconnect = x; return MPLS_SUCCESS; } x = MPLS_LIST_NEXT(&iseg->xconnect_root, x, _insegment); } } *xconnect = NULL; return MPLS_FAILURE;}/* struct ftn */void _lsr_global_add_ftn(lsr_global * g, lsr_ftn * f){ lsr_ftn *fp = NULL; MPLS_ASSERT(g && f); MPLS_REFCNT_HOLD(f); fp = MPLS_LIST_HEAD(&g->ftn); while (fp != NULL) { if (fp->index > f->index) { MPLS_LIST_INSERT_BEFORE(&g->ftn, fp, f, _global); return; } fp = MPLS_LIST_NEXT(&g->ftn, fp, _global); } MPLS_LIST_ADD_TAIL(&g->ftn, f, _global, lsr_ftn);}void _lsr_global_del_ftn(lsr_global * g, lsr_ftn * f){ MPLS_ASSERT(g && f); MPLS_LIST_REMOVE(&g->ftn, f, _global); MPLS_REFCNT_RELEASE(f, lsr_ftn_delete);}mpls_return_enum lsr_global_find_ftn_index(lsr_global * g, uint32_t index, lsr_ftn ** ftn){ lsr_ftn *f = NULL; MPLS_ASSERT(g && index > 0); /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ f = MPLS_LIST_TAIL(&g->ftn); if (f == NULL || f->index < index) { *ftn = NULL; return MPLS_END_OF_LIST; } f = MPLS_LIST_HEAD(&g->ftn); while (f != NULL) { if (f->index == index) { *ftn = f; return MPLS_SUCCESS; } f = MPLS_LIST_NEXT(&g->ftn, f, _global); } *ftn = NULL; return MPLS_FAILURE;}mpls_return_enum lsr_global_find_ftn_index2(lsr_global * g, lsr_ftn * f, lsr_ftn ** ftn){ lsr_ftn *fp = NULL; if (g && f) { fp = MPLS_LIST_HEAD(&g->ftn); while (fp != NULL) { if (fp->outsegment->index == f->outsegment_index) { if (fp->fec.type == f->fec.type) { switch(fp->fec.type) { case MPLS_FEC_PREFIX: if (fp->fec.u.prefix.network.u.ipv4 == f->fec.u.prefix.network.u.ipv4 && fp->fec.u.prefix.length == f->fec.u.prefix.length) { *ftn = fp; return MPLS_SUCCESS; } break; case MPLS_FEC_HOST: if (fp->fec.u.host.u.ipv4 == f->fec.u.host.u.ipv4) { *ftn = fp; return MPLS_SUCCESS; } break; case MPLS_FEC_L2CC: if (fp->fec.u.l2cc.connection_id == f->fec.u.l2cc.connection_id && fp->fec.u.l2cc.group_id == f->fec.u.l2cc.group_id && fp->fec.u.l2cc.type == f->fec.u.l2cc.type) { *ftn = fp; return MPLS_SUCCESS; } break; default: MPLS_ASSERT(0); } } } fp = MPLS_LIST_NEXT(&g->ftn, fp, _global); } } *ftn = NULL; return MPLS_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -