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

📄 ldp_if.c

📁 Linux平台下
💻 C
字号:
/* *  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 <stdlib.h>#include <netinet/in.h>#include <sys/socket.h>#include "ldp_struct.h"#include "ldp_global.h"#include "ldp_entity.h"#include "ldp_nexthop.h"#include "ldp_nortel.h"#include "ldp_addr.h"#include "ldp_if.h"#include "ldp_fec.h"#include "ldp_mesg.h"#include "ldp_buf.h"#include "ldp_hello.h"#include "mpls_assert.h"#include "mpls_mm_impl.h"#include "mpls_compare.h"#include "mpls_socket_impl.h"#include "mpls_timer_impl.h"#include "mpls_ifmgr_impl.h"#include "mpls_trace_impl.h"extern uint32_t _ldp_sub_entity_next_index;ldp_if *ldp_if_create(ldp_global *g){  ldp_if *i = (ldp_if *) mpls_malloc(sizeof(ldp_if));  if (i) {    memset(i, 0, sizeof(ldp_if));    /*     * 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 iff to be cleaned up     * when it no longer has a nexthop, fec, or label, the only things that     * should increment the ref are those (nh, fec, label etc), not global     * nor inserting into the tree.    MPLS_REFCNT_INIT(i, 1);     */    MPLS_LIST_ELEM_INIT(i, _global);    MPLS_LIST_INIT(&i->nh_root, ldp_nexthop);    MPLS_LIST_INIT(&i->addr_root, ldp_addr);    i->label_space = -1;    i->dest.addr.type = MPLS_FAMILY_IPV4;    i->dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;    i->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);    i->tx_message = ldp_mesg_create();    i->index = _ldp_if_get_next_index();    i->oper_state = MPLS_OPER_DOWN;    i->is_p2p = MPLS_BOOL_FALSE;    _ldp_global_add_if(g, i);  }  return i;}void ldp_if_delete(ldp_global *g, ldp_if * i){  LDP_PRINT(g->user_data, "if delete: %p", i);  MPLS_REFCNT_ASSERT(i, 0);  mpls_free(i->tx_buffer);  mpls_free(i->tx_message);  i->tx_buffer = NULL;  i->tx_message = NULL;  _ldp_global_del_if(g, i);  mpls_free(i);}/* * ldp_if_insert and ldp_if_remove should ONLY be used in conjuction with * adding and removing nexthops (or fecs). */ldp_if *ldp_if_insert(ldp_global *g, mpls_if_handle handle){  ldp_if *iff = NULL;  MPLS_ASSERT(g);  MPLS_ASSERT(mpls_if_handle_verify(g->ifmgr_handle, handle) == MPLS_BOOL_TRUE);  if ((iff = ldp_if_create(g)) == NULL) {    LDP_PRINT(g->user_data,"ldp_if_insert: unable to alloc ldp_if\n");    return NULL;  }  iff->handle = handle;  return iff;}#if 0void ldp_if_remove(ldp_global *g, ldp_if *iff){  MPLS_ASSERT(g && iff);  MPLS_REFCNT_RELEASE2(g, iff, ldp_if_delete);}#endif/* * We do not hold a ref to the nexthop.  The nexthop holds a ref to the * if.  Nexthop creation calls ldp_if_add_nexthop, nexthop deletion * calls ldp_if_del_nexthop.  There is no way a nexthop can be deleted * without removing the ifs ref to the nexthop. */void ldp_if_add_nexthop(ldp_if * i, ldp_nexthop * n){  ldp_nexthop *np = NULL;  MPLS_ASSERT(i && n);  ldp_nexthop_add_if(n,i);  np = MPLS_LIST_HEAD(&i->nh_root);  while (np != NULL) {    if (np->index > n->index) {       MPLS_LIST_INSERT_BEFORE(&i->nh_root, np, n, _if);       return;    }    np = MPLS_LIST_NEXT(&i->nh_root, np, _if);  }  MPLS_LIST_ADD_TAIL(&i->nh_root, n, _if, ldp_nexthop);}void ldp_if_del_nexthop(ldp_global *g, ldp_if * i, ldp_nexthop * n){  MPLS_ASSERT(i && n);  MPLS_LIST_REMOVE(&i->nh_root, n, _if);  ldp_nexthop_del_if(g, n);}void ldp_if_add_addr(ldp_if * i, ldp_addr * a){  ldp_addr *ap = NULL;  MPLS_ASSERT(i && a);  MPLS_REFCNT_HOLD(a);  ldp_addr_add_if(a,i);  ap = MPLS_LIST_HEAD(&i->addr_root);  while (ap != NULL) {    if (ap->index > a->index) {       MPLS_LIST_INSERT_BEFORE(&i->addr_root, ap, a, _if);       return;    }    ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if);  }  MPLS_LIST_ADD_TAIL(&i->addr_root, a, _if, ldp_addr);}void ldp_if_del_addr(ldp_global *g, ldp_if * i, ldp_addr * a){  MPLS_ASSERT(i && a);  MPLS_LIST_REMOVE(&i->addr_root, a, _if);  ldp_addr_del_if(g, a);  MPLS_REFCNT_RELEASE2(g, a, ldp_addr_delete);}mpls_return_enum ldp_if_find_addr_index(ldp_if *i, int index, ldp_addr **a){  ldp_addr *ap = NULL;  MPLS_ASSERT(i);  if (index > 0) {    /* because we sort our inserts by index, this lets us know       if we've "walked" past the end of the list */    ap = MPLS_LIST_TAIL(&i->addr_root);    if (!ap || ap->index < index) {      *a = NULL;      return MPLS_END_OF_LIST;    }    ap = MPLS_LIST_HEAD(&i->addr_root);    do {      if (ap->index == index) {        *a = ap;        return MPLS_SUCCESS;      }    } while((ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if)));  }  *a = NULL;  return MPLS_FAILURE;}ldp_addr *ldp_if_addr_find(ldp_if *i, mpls_inet_addr *a){  ldp_addr *ap = NULL;  MPLS_ASSERT(i && a);  ap = MPLS_LIST_HEAD(&i->addr_root);    while(ap) {    if (!mpls_inet_addr_compare(&ap->address, a)) {      return ap;    }    ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if);  }  return NULL;}mpls_return_enum ldp_if_startup(ldp_global * g, ldp_if * i){  ldp_entity *e = NULL;  LDP_ENTER(g->user_data, "ldp_if_startup");  MPLS_ASSERT(i != NULL);  e = i->entity;  MPLS_ASSERT(e != NULL);  MPLS_ASSERT(e->p.iff != NULL);  if (mpls_socket_multicast_if_join(g->socket_handle, g->hello_socket, i,      &i->dest.addr) == MPLS_FAILURE) {    goto ldp_if_startup_delay;  }  i->dest.port = e->remote_udp_port;  if (ldp_hello_send(g, e) == MPLS_FAILURE) {    ldp_if_shutdown(g, i);    return MPLS_FAILURE;  }  i->oper_state = MPLS_OPER_UP;  LDP_EXIT(g->user_data, "ldp_if_startup");  return MPLS_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 = MPLS_OPER_DOWN;  LDP_EXIT(g->user_data, "ldp_if_startup-delayed");  return MPLS_SUCCESS;}mpls_return_enum ldp_if_shutdown(ldp_global * g, ldp_if * i){  ldp_entity *e = NULL;  MPLS_ASSERT(i != NULL && ((e = i->entity) != NULL));  LDP_ENTER(g->user_data, "ldp_if_shutdown");  i->oper_state = MPLS_OPER_DOWN;  mpls_socket_multicast_if_drop(g->socket_handle, g->hello_socket, i,    &i->dest.addr);  mpls_timer_stop(g->timer_handle, i->hellotime_send_timer);  mpls_timer_delete(g->timer_handle, i->hellotime_send_timer);  i->hellotime_send_timer_duration = 0;  i->hellotime_send_timer = 0;  /* the entity is held in ldp_hello_send when it creates the timer   * ldp_hello_send is called by ldp_if_startup   */  MPLS_ASSERT(e != NULL);  MPLS_REFCNT_RELEASE(e, ldp_entity_delete);  if (i->hello) {    ldp_mesg_delete(i->hello);    i->hello = NULL;  }  LDP_EXIT(g->user_data, "ldp_if_shutdown");  return MPLS_SUCCESS;}mpls_bool ldp_if_is_active(ldp_if * i){  if (i && i->entity && i->entity->admin_state == MPLS_ADMIN_ENABLE)    return MPLS_BOOL_TRUE;  return MPLS_BOOL_FALSE;}mpls_return_enum _ldp_if_add_entity(ldp_if * i, ldp_entity * e){  if (i && e) {    MPLS_REFCNT_HOLD(e);    i->entity = e;    return MPLS_SUCCESS;  }  return MPLS_FAILURE;}ldp_entity *ldp_if_get_entity(ldp_if * i){  return i->entity;}mpls_return_enum _ldp_if_del_entity(ldp_if * i){  if (i && i->entity) {    MPLS_REFCNT_RELEASE(i->entity, ldp_entity_delete);    i->entity = NULL;    return MPLS_SUCCESS;  }  return MPLS_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;}

⌨️ 快捷键说明

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