⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldp_fec.c

📁 Linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  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 "ldp_struct.h"#include "ldp_fec.h"#include "ldp_if.h"#include "ldp_attr.h"#include "ldp_addr.h"#include "ldp_nexthop.h"#include "ldp_session.h"#include "ldp_inlabel.h"#include "ldp_outlabel.h"#include "ldp_global.h"#include "ldp_label_mapping.h"#include "ldp_label_request.h"#include "ldp_label_abort.h"#include "ldp_label_rel_with.h"#include "mpls_assert.h"#include "mpls_compare.h"#include "mpls_mm_impl.h"#include "mpls_tree_impl.h"#include "mpls_policy_impl.h"#include "mpls_trace_impl.h"#if MPLS_USE_LSR#include "lsr_cfg.h"#else#include "mpls_mpls_impl.h"#endifstatic uint32_t _ldp_fec_next_index = 1;static mpls_return_enum ldp_fec_insert(ldp_global *g, ldp_fec * fec){  mpls_return_enum retval = MPLS_SUCCESS;  uint32_t key;  uint8_t len;  MPLS_ASSERT(g && fec);  LDP_ENTER(g->user_data, "ldp_fec_insert");  switch(fec->info.type) {    case MPLS_FEC_PREFIX:      key = fec->info.u.prefix.network.u.ipv4;      len = fec->info.u.prefix.length;      break;    case MPLS_FEC_HOST:      key = fec->info.u.host.u.ipv4;      len = 32;      break;    case MPLS_FEC_L2CC:      /* they had better insert it into the global list */      LDP_EXIT(g->user_data, "ldp_fec_insert: l2cc");      return MPLS_SUCCESS;    default:      MPLS_ASSERT(0);  }  LDP_PRINT(g->user_data, "ldp_fec_insert: 0x%08x/%d\n", key, len);  if (mpls_tree_insert(g->fec_tree, key, len, (void *)fec) != MPLS_SUCCESS) {    LDP_PRINT(g->user_data, "ldp_fec_insert: error adding fec\n");    retval = MPLS_FATAL;  }  LDP_EXIT(g->user_data, "ldp_fec_insert");  return retval;}static void ldp_fec_remove(ldp_global *g, mpls_fec *fec){  ldp_fec *f = NULL;  uint32_t key;  uint8_t len;  MPLS_ASSERT(g && fec);  LDP_ENTER(g->user_data, "ldp_fec_remove");  switch(fec->type) {    case MPLS_FEC_PREFIX:      key = fec->u.prefix.network.u.ipv4;      len = fec->u.prefix.length;      break;    case MPLS_FEC_HOST:      key = fec->u.host.u.ipv4;      len = 32;      break;    case MPLS_FEC_L2CC:      /* they had better remove it from the global list */      LDP_EXIT(g->user_data, "ldp_fec_remove");      return;    default:      MPLS_ASSERT(0);  }  LDP_PRINT(g->user_data, "ldp_fec_remove: 0x%08x/%d\n", key, len);  mpls_tree_remove(g->fec_tree, key, len, (void **)&f);  MPLS_ASSERT(f);  LDP_EXIT(g->user_data, "ldp_fec_remove");}static uint32_t _ldp_fec_get_next_index(){  uint32_t retval = _ldp_fec_next_index;  _ldp_fec_next_index++;  if (retval > _ldp_fec_next_index) {    _ldp_fec_next_index = 1;  }  return retval;}ldp_fec *ldp_fec_create(ldp_global *g, mpls_fec *f){  ldp_fec *fec = (ldp_fec *) mpls_malloc(sizeof(ldp_fec));  if (fec != NULL) {    memset(fec, 0, sizeof(ldp_fec));    /*     * note: this is init to 1 for a reason!     * We're placing it in the global list, so this is our refcnt     * when this refcnt gets to zero, it will be removed from the     * global list and deleted     */    /*     * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up     * when it no longer has a nexthop, addr, or label, the only things that     * should increment the ref are those (nh, addr, label etc), not global     * nor inserting into the tree.  I also added this comment in     * _ldp_global_add_fec()    MPLS_REFCNT_INIT(fec, 1);     */    MPLS_REFCNT_INIT(fec, 0);    MPLS_LIST_ELEM_INIT(fec, _global);    MPLS_LIST_ELEM_INIT(fec, _inlabel);    MPLS_LIST_ELEM_INIT(fec, _outlabel);    MPLS_LIST_ELEM_INIT(fec, _fec);    MPLS_LIST_INIT(&fec->nh_root, ldp_nexthop);    MPLS_LIST_INIT(&fec->fs_root_us, ldp_fs);    MPLS_LIST_INIT(&fec->fs_root_ds, ldp_fs);    fec->index = _ldp_fec_get_next_index();    fec->is_route = MPLS_BOOL_FALSE;    mpls_fec2ldp_fec(f,fec);    _ldp_global_add_fec(g, fec);    ldp_fec_insert(g, fec);  }  return fec;}void ldp_fec_delete(ldp_global *g, ldp_fec * fec){  LDP_PRINT(g->user_data, "fec delete: %08x/%d",    fec->info.u.prefix.network.u.ipv4, fec->info.u.prefix.length);  ldp_fec_remove(g, &fec->info);  _ldp_global_del_fec(g, fec);  mpls_free(fec);}ldp_fec *ldp_fec_find(ldp_global *g, mpls_fec *fec){  ldp_fec *f = NULL;  uint32_t key;  uint8_t len;  switch(fec->type) {    case MPLS_FEC_PREFIX:      key = fec->u.prefix.network.u.ipv4;      len = fec->u.prefix.length;      break;    case MPLS_FEC_HOST:      key = fec->u.host.u.ipv4;      len = 32;      break;    case MPLS_FEC_L2CC:      if (ldp_global_find_fec(g, fec, &f) == MPLS_SUCCESS) {	return f;      }      return NULL;    default:      MPLS_ASSERT(0);  }  LDP_PRINT(g->user_data, "ldp_fec_find: 0x%08x/%d\n", key, len);  if (mpls_tree_get(g->fec_tree, key, len, (void **)&f) != MPLS_SUCCESS) {    return NULL;  }  return f;}ldp_fec *ldp_fec_find2(ldp_global *g, mpls_fec *fec){  ldp_fec *f = NULL;  f = ldp_fec_find(g, fec);  if (!f) {    f = ldp_fec_create(g, fec);  }  return f;}ldp_nexthop *ldp_fec_nexthop_find(ldp_fec *f, mpls_nexthop *n){  ldp_nexthop *nh = NULL;  MPLS_ASSERT(f && n);  nh = MPLS_LIST_HEAD(&f->nh_root);  while (nh) {    if (!mpls_nexthop_compare(&nh->info, n)) {      return nh;    }    nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);  }  return NULL;}mpls_return_enum ldp_fec_find_nexthop_index(ldp_fec *f, int index,  ldp_nexthop **n){  ldp_nexthop *nh = NULL;  MPLS_ASSERT(f);  if (index > 0) {    /* because we sort our inserts by index, this lets us know       if we've "walked" past the end of the list */    nh = MPLS_LIST_TAIL(&f->nh_root);    if (!nh || nh->index < index) {      *n = NULL;      return MPLS_END_OF_LIST;    }    nh = MPLS_LIST_HEAD(&f->nh_root);    do {      if (nh->index == index) {        *n = nh;        return MPLS_SUCCESS;      }    } while((nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec)));  }  *n = NULL;  return MPLS_FAILURE;}mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec * f,  ldp_nexthop * nh){  MPLS_ASSERT(f && nh);  LDP_ENTER(g->user_data, "ldp_fec_add_nexthop");  MPLS_REFCNT_HOLD(nh);  MPLS_LIST_ADD_HEAD(&f->nh_root, nh, _fec, ldp_nexthop);  ldp_nexthop_add_fec(nh, f);  LDP_EXIT(g->user_data, "ldp_fec_add_nexthop: success");  return MPLS_SUCCESS;ldp_fec_add_nexthop_error:  ldp_fec_del_nexthop(g, f, nh);  LDP_EXIT(g->user_data, "ldp_fec_add_nexthop: fail");  return MPLS_FATAL;}void ldp_fec_del_nexthop(ldp_global *g, ldp_fec * f, ldp_nexthop *nh){  MPLS_ASSERT(f && nh);  MPLS_LIST_REMOVE(&f->nh_root, nh, _fec);  ldp_nexthop_del_fec(g, nh);  MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete);}mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f,  ldp_nexthop *nh, ldp_session *nh_session){  ldp_session *peer = NULL;  ldp_attr *ds_attr = NULL;  ldp_attr *us_attr = NULL;  mpls_bool egress;  ldp_outlabel *out;  LDP_ENTER(g->user_data, "ldp_fec_process_add");  /*   * find the info about the next hop for this FEC   */  if (!nh_session) {    nh_session = ldp_get_next_hop_session_for_fec2(f, nh);  }  if (nh_session) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -