📄 ldp_global.c.new
字号:
/* * 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 "ldp_struct.h"#include "ldp_inet_addr.h"#include "ldp_session.h"#include "ldp_entity.h"#include "ldp_global.h"#include "ldp_nexthop.h"#include "ldp_outlabel.h"#include "ldp_inlabel.h"#include "ldp_hello.h"#include "ldp_peer.h"#include "ldp_attr.h"#include "ldp_addr.h"#include "ldp_adj.h"#include "ldp_fec.h"#include "ldp_if.h"#include "ldp_label_mapping.h"#include "ldp_tunnel.h"#include "ldp_resource.h"#include "ldp_hop_list.h"#include "mpls_compare.h"#include "mpls_socket_impl.h"#include "mpls_timer_impl.h"#include "mpls_ifmgr_impl.h"#include "mpls_tree_impl.h"#include "mpls_lock_impl.h"#include "mpls_fib_impl.h"#include "mpls_policy_impl.h"#include "mpls_mm_impl.h"#include "mpls_trace_impl.h"#if MPLS_USE_LSR#include "lsr_cfg.h"#else#include "mpls_mpls_impl.h"#endifldp_global *ldp_global_create(mpls_instance_handle data){ ldp_global *g = (ldp_global *) mpls_malloc(sizeof(ldp_global)); if (g) { memset(g, 0, sizeof(ldp_global)); LDP_ENTER(g->user_data, "ldp_global_create"); g->global_lock = mpls_lock_create("_ldp_global_lock_"); mpls_lock_get(g->global_lock); MPLS_LIST_INIT(&g->hop_list, ldp_hop_list); MPLS_LIST_INIT(&g->outlabel, ldp_outlabel); MPLS_LIST_INIT(&g->resource, ldp_resource); MPLS_LIST_INIT(&g->inlabel, ldp_inlabel); MPLS_LIST_INIT(&g->session, ldp_session); MPLS_LIST_INIT(&g->nexthop, ldp_nexthop); MPLS_LIST_INIT(&g->tunnel, ldp_tunnel); MPLS_LIST_INIT(&g->entity, ldp_entity); MPLS_LIST_INIT(&g->addr, ldp_addr); MPLS_LIST_INIT(&g->attr, ldp_attr); MPLS_LIST_INIT(&g->peer, ldp_peer); MPLS_LIST_INIT(&g->fec, ldp_fec); MPLS_LIST_INIT(&g->adj, ldp_adj); MPLS_LIST_INIT(&g->iff, ldp_if); g->message_identifier = 1; g->configuration_sequence_number = 1; g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE; g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE; g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE; g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE; g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE; g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE; g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN; g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT; g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT; g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG; g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP; g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING; g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME; g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER; g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL; g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER; g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL; g->admin_state = MPLS_ADMIN_DISABLE; g->user_data = data; g->addr_tree = mpls_tree_create(32); g->fec_tree = mpls_tree_create(32); mpls_lock_release(g->global_lock); LDP_EXIT(g->user_data, "ldp_global_create"); } return g;}mpls_return_enum ldp_global_startup(ldp_global * g){ ldp_entity *e = NULL; mpls_dest dest; MPLS_ASSERT(g != NULL); LDP_ENTER(g->user_data, "ldp_global_startup"); if (g->lsr_identifier.type == MPLS_FAMILY_NONE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR, "ldp_global_startup: invalid LSRID\n"); goto ldp_global_startup_cleanup; } g->timer_handle = mpls_timer_open(g->user_data); if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) { goto ldp_global_startup_cleanup; } g->socket_handle = mpls_socket_mgr_open(g->user_data); if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) { goto ldp_global_startup_cleanup; } g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g); if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) { goto ldp_global_startup_cleanup; } g->fib_handle = mpls_fib_open(g->user_data, g); if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) { goto ldp_global_startup_cleanup; }#if MPLS_USE_LSR if (!g->lsr_handle) { goto ldp_global_startup_cleanup; }#else g->mpls_handle = mpls_mpls_open(g->user_data); if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) { goto ldp_global_startup_cleanup; }#endif g->hello_socket = mpls_socket_create_udp(g->socket_handle); if (mpls_socket_handle_verify(g->socket_handle, g->hello_socket) == MPLS_BOOL_FALSE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error creating UDP socket\n"); goto ldp_global_startup_cleanup; } dest.addr.type = MPLS_FAMILY_IPV4; dest.port = g->local_udp_port; dest.addr.u.ipv4 = INADDR_ANY; // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP; if (mpls_socket_bind(g->socket_handle, g->hello_socket, &dest) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error binding UDP socket\n"); goto ldp_global_startup_cleanup; } if (mpls_socket_options(g->socket_handle, g->hello_socket, MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting UDP socket options\n"); goto ldp_global_startup_cleanup; } if (mpls_socket_multicast_options(g->socket_handle, g->hello_socket, 1, 0) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting UDP socket multicast options\n"); goto ldp_global_startup_cleanup; } mpls_socket_readlist_add(g->socket_handle, g->hello_socket, 0, MPLS_SOCKET_UDP_DATA); g->listen_socket = mpls_socket_create_tcp(g->socket_handle); if (mpls_socket_handle_verify(g->socket_handle, g->listen_socket) == MPLS_BOOL_FALSE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error creating TCP socket\n"); goto ldp_global_startup_cleanup; } if (mpls_socket_options(g->socket_handle, g->listen_socket, MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting TCP socket options\n"); goto ldp_global_startup_cleanup; } dest.addr.type = MPLS_FAMILY_IPV4; dest.port = g->local_tcp_port; dest.addr.u.ipv4 = INADDR_ANY; if (mpls_socket_bind(g->socket_handle, g->listen_socket, &dest) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error binding TCP socket\n"); goto ldp_global_startup_cleanup; } if (mpls_socket_tcp_listen(g->socket_handle, g->listen_socket, 15) == MPLS_FAILURE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_global_startup: error setting listen buffer for TCP socket\n"); goto ldp_global_startup_cleanup; } mpls_socket_readlist_add(g->socket_handle, g->listen_socket, 0, MPLS_SOCKET_TCP_LISTEN); e = MPLS_LIST_HEAD(&g->entity); while (e != NULL) { ldp_entity_startup(g, e); e = MPLS_LIST_NEXT(&g->entity, e, _global); } g->admin_state = MPLS_ADMIN_ENABLE; LDP_EXIT(g->user_data, "ldp_global_startup"); return MPLS_SUCCESS;ldp_global_startup_cleanup: ldp_global_shutdown(g); mpls_socket_close(g->socket_handle, g->hello_socket); mpls_socket_close(g->socket_handle, g->listen_socket); g->hello_socket = 0; g->listen_socket = 0; LDP_EXIT(g->user_data, "ldp_global_startup-error"); return MPLS_FAILURE;}mpls_return_enum ldp_global_shutdown(ldp_global * g){ ldp_entity *e = NULL; ldp_nexthop *n; ldp_fec *f; ldp_addr *a; ldp_if *i; MPLS_ASSERT(g); LDP_ENTER(g->user_data, "ldp_global_shutdown"); e = MPLS_LIST_HEAD(&g->entity); while (e != NULL) { ldp_entity_shutdown(g, e, 1); e = MPLS_LIST_NEXT(&g->entity, e, _global); } g->admin_state = MPLS_ADMIN_DISABLE; mpls_socket_readlist_del(g->socket_handle, g->hello_socket); mpls_socket_close(g->socket_handle, g->hello_socket); mpls_socket_readlist_del(g->socket_handle, g->listen_socket); mpls_socket_close(g->socket_handle, g->listen_socket); mpls_lock_release(g->global_lock); mpls_timer_close(g->timer_handle); mpls_lock_get(g->global_lock); mpls_socket_mgr_close(g->socket_handle); mpls_ifmgr_close(g->ifmgr_handle); mpls_fib_close(g->fib_handle);#if MPLS_USE_LSR#else mpls_mpls_close(g->mpls_handle);#endif LDP_EXIT(g->user_data, "ldp_global_shutdown"); return MPLS_SUCCESS;}mpls_return_enum ldp_global_delete(ldp_global * g){ if (g) { mpls_tree_delete(g->addr_tree); mpls_tree_delete(g->fec_tree); mpls_lock_delete(g->global_lock); LDP_PRINT(g->user_data, "global delete\n"); mpls_free(g); } return MPLS_SUCCESS;}void _ldp_global_add_attr(ldp_global * g, ldp_attr * a){ ldp_attr *ap = NULL; MPLS_ASSERT(g && a); MPLS_REFCNT_HOLD(a); ap = MPLS_LIST_HEAD(&g->attr); while (ap != NULL) { if (ap->index > a->index) { MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global); return; } ap = MPLS_LIST_NEXT(&g->attr, ap, _global); } MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);}void _ldp_global_del_attr(ldp_global * g, ldp_attr * a){ MPLS_ASSERT(g && a); MPLS_LIST_REMOVE(&g->attr, a, _global); MPLS_REFCNT_RELEASE(a, ldp_attr_delete);}void _ldp_global_add_peer(ldp_global * g, ldp_peer * p){ ldp_peer *pp = NULL; MPLS_ASSERT(g && p); MPLS_REFCNT_HOLD(p); pp = MPLS_LIST_HEAD(&g->peer); while (pp != NULL) { if (pp->index > p->index) { MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global); return; } pp = MPLS_LIST_NEXT(&g->peer, pp, _global); } MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);}void _ldp_global_del_peer(ldp_global * g, ldp_peer * p){ MPLS_ASSERT(g && p); MPLS_LIST_REMOVE(&g->peer, p, _global); MPLS_REFCNT_RELEASE(p, ldp_peer_delete);}/* * _ldp_global_add_if/del_if and _ldp_global_add_addr/del_addr are * not the same as the rest of the global_add/del functions. They * do not hold refcnts, they are used as part of the create and delete * process of these structures */void _ldp_global_add_if(ldp_global * g, ldp_if * i){ ldp_if *ip = NULL; MPLS_ASSERT(g && 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; } ip = MPLS_LIST_NEXT(&g->iff, ip, _global); } MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);}void _ldp_global_del_if(ldp_global * g, ldp_if * i){ MPLS_ASSERT(g && i); MPLS_LIST_REMOVE(&g->iff, i, _global);}void _ldp_global_add_addr(ldp_global * g, ldp_addr * a){ ldp_addr *ap = NULL; MPLS_ASSERT(g && a); ap = MPLS_LIST_HEAD(&g->addr); while (ap != NULL) { if (ap->index > a->index) { MPLS_LIST_INSERT_BEFORE(&g->addr, ap, a, _global); return; } ap = MPLS_LIST_NEXT(&g->addr, ap, _global); } MPLS_LIST_ADD_TAIL(&g->addr, a, _global, ldp_addr);}void _ldp_global_del_addr(ldp_global * g, ldp_addr * a){ MPLS_ASSERT(g && a); MPLS_LIST_REMOVE(&g->addr, a, _global);}void _ldp_global_add_adj(ldp_global * g, ldp_adj * a){ ldp_adj *ap = NULL; MPLS_ASSERT(g && a); MPLS_REFCNT_HOLD(a); ap = MPLS_LIST_HEAD(&g->adj); while (ap != NULL) { if (ap->index > a->index) { MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global); return; } ap = MPLS_LIST_NEXT(&g->adj, ap, _global); } MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);}void _ldp_global_del_adj(ldp_global * g, ldp_adj * a){ MPLS_ASSERT(g && a); MPLS_LIST_REMOVE(&g->adj, a, _global); MPLS_REFCNT_RELEASE(a, ldp_adj_delete);}void _ldp_global_add_entity(ldp_global * g, ldp_entity * e){ ldp_entity *ep = NULL; MPLS_ASSERT(g && e); MPLS_REFCNT_HOLD(e); ep = MPLS_LIST_HEAD(&g->entity); while (ep != NULL) { if (ep->index > e->index) { MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global); return; } ep = MPLS_LIST_NEXT(&g->entity, ep, _global); } MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);}void _ldp_global_del_entity(ldp_global * g, ldp_entity * e){ MPLS_ASSERT(g && e); MPLS_LIST_REMOVE(&g->entity, e, _global); MPLS_REFCNT_RELEASE(e, ldp_entity_delete);}void _ldp_global_add_session(ldp_global * g, ldp_session * s){ ldp_session *sp = NULL; MPLS_ASSERT(g && s); MPLS_REFCNT_HOLD(s); s->on_global = MPLS_BOOL_TRUE; sp = MPLS_LIST_HEAD(&g->session); while (sp != NULL) { if (sp->index > s->index) { MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global); return; } sp = MPLS_LIST_NEXT(&g->session, sp, _global); } MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);}void _ldp_global_del_session(ldp_global * g, ldp_session * s){ MPLS_ASSERT(g && s); MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE); MPLS_LIST_REMOVE(&g->session, s, _global); s->on_global = MPLS_BOOL_FALSE; MPLS_REFCNT_RELEASE(s, ldp_session_delete);}mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i){ ldp_inlabel *ip = NULL; mpls_return_enum result; MPLS_ASSERT(g && i);#if MPLS_USE_LSR { lsr_insegment iseg; memcpy(&iseg.info,&i->info,sizeof(mpls_insegment)); result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD| LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY| LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL| LSR_INSEGMENT_CFG_OWNER); memcpy(&i->info, &iseg.info, sizeof(mpls_insegment)); i->info.handle = iseg.index; }#else result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);#endif if (result != MPLS_SUCCESS) { return result; } MPLS_REFCNT_HOLD(i); ip = MPLS_LIST_HEAD(&g->inlabel); while (ip != NULL) { if (ip->index > i->index) { MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global); return MPLS_SUCCESS; } ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global); } MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel); return MPLS_SUCCESS;}mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i){ MPLS_ASSERT(g && i); MPLS_ASSERT(i->reuse_count == 0);#if MPLS_USE_LSR { lsr_insegment iseg; iseg.index = i->info.handle; lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL); }#else mpls_mpls_insegment_del(g->mpls_handle, &i->info);#endif MPLS_LIST_REMOVE(&g->inlabel, i, _global); MPLS_REFCNT_RELEASE(i, ldp_inlabel_delete); return MPLS_SUCCESS;}mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o){ ldp_outlabel *op = NULL; mpls_return_enum result; MPLS_ASSERT(g && o);#if MPLS_USE_LSR { lsr_outsegment oseg; memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment)); result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD| LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER| LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL| LSR_OUTSEGMENT_CFG_NEXTHOP); o->info.handle = oseg.index; }#else result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);#endif if (result != MPLS_SUCCESS) { return result; } MPLS_REFCNT_HOLD(o); o->switching = MPLS_BOOL_TRUE; op = MPLS_LIST_HEAD(&g->outlabel); while (op != NULL) { if (op->index > o->index) { MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global); return MPLS_SUCCESS; } op = MPLS_LIST_NEXT(&g->outlabel, op, _global); } MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel); return MPLS_SUCCESS;}mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o){ MPLS_ASSERT(g && o);#if MPLS_USE_LSR { lsr_outsegment oseg; oseg.index = o->info.handle; lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL); }#else mpls_mpls_outsegment_del(g->mpls_handle, &o->info);#endif o->switching = MPLS_BOOL_FALSE; MPLS_ASSERT(o->merge_count == 0); MPLS_LIST_REMOVE(&g->outlabel, o, _global); MPLS_REFCNT_RELEASE(o, ldp_outlabel_delete);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -