From 5f6683d5276767ac4942b597dc916161debbc632 Mon Sep 17 00:00:00 2001 From: "James R. Leu" Date: Wed, 26 Feb 2003 13:04:15 -0600 Subject: [PATCH] Changed the relationship between entity-adj-sessios (again) this is in hopes of supporting multiple parrell links. Changed the structure of mpls_nexthops to be more intuitive. Added support for more of the notification messages. Added the notion of shutting a session all the way down (deleting it) or just resetting it. Clean up some left over code from the 'genericized' rib Fix labelspace setting. [git-p4: depot-paths = "//depot/ldp-portable/": change = 297] --- common/mpls_list.h | 8 ++ common/mpls_struct.h | 34 ++--- doc/ldp_struct.txt | 6 +- ldp/ldp_adj.c | 203 +++++++------------------- ldp/ldp_adj.h | 9 +- ldp/ldp_attr.c | 3 +- ldp/ldp_attr.h | 2 +- ldp/ldp_cfg.c | 116 ++++++++------- ldp/ldp_cfg.h | 2 - ldp/ldp_entity.c | 60 +++----- ldp/ldp_entity.h | 2 +- ldp/ldp_fec.c | 8 +- ldp/ldp_global.c | 11 +- ldp/ldp_hello.c | 46 ++++-- ldp/ldp_init.c | 32 ++--- ldp/ldp_inlabel.c | 2 +- ldp/ldp_keepalive.c | 3 +- ldp/ldp_label_abort.c | 6 +- ldp/ldp_label_mapping.c | 102 +++++-------- ldp/ldp_label_rel_with.c | 12 +- ldp/ldp_label_request.c | 4 +- ldp/ldp_mesg.c | 2 +- ldp/ldp_notif.c | 96 +++++++++++-- ldp/ldp_outlabel.c | 12 +- ldp/ldp_peer.c | 4 +- ldp/ldp_session.c | 361 ++++++++++++++++++++++++++++++++++++----------- ldp/ldp_session.h | 12 +- ldp/ldp_state_funcs.c | 117 ++++++++------- ldp/ldp_state_machine.c | 44 +++--- ldp/ldp_struct.h | 56 ++++---- lsr/lsr_global.c | 2 +- 31 files changed, 764 insertions(+), 613 deletions(-) diff --git a/common/mpls_list.h b/common/mpls_list.h index 0fab549..e05d777 100644 --- a/common/mpls_list.h +++ b/common/mpls_list.h @@ -19,6 +19,7 @@ struct name { \ struct type *llh_first; \ struct type *llh_last; \ + int count; \ } #define MPLS_LIST_ELEM(type) \ @@ -36,6 +37,7 @@ struct { \ (head)->llh_first = (elm)->field.lle_next; \ else \ (elm)->field.lle_prev->field.lle_next = (elm)->field.lle_next; \ + (head)->count--; \ } #define MPLS_LIST_INSERT_BEFORE(head,listelm,elm,field) { \ @@ -46,11 +48,13 @@ struct { \ else \ (listelm)->field.lle_prev->field.lle_next = (elm); \ (listelm)->field.lle_prev = (elm); \ + (head)->count++; \ } #define MPLS_LIST_INIT(head,type) { \ (head)->llh_first = (struct type *)(head); \ (head)->llh_last = (struct type *)(head); \ + (head)->count = 0; \ } #define MPLS_LIST_IN_LIST(elm,field) ((elm)->field.lle_next && (elm)->field.lle_prev)) @@ -63,6 +67,7 @@ struct { \ else \ (head)->llh_first->field.lle_prev = (elm); \ (head)->llh_first = (elm); \ + (head)->count++; \ } #define MPLS_LIST_ADD_TAIL(head, elm, field, type) { \ @@ -73,6 +78,7 @@ struct { \ else \ (head)->llh_last->field.lle_next = (elm); \ (head)->llh_last = (elm); \ + (head)->count++; \ } #define MPLS_LIST_REMOVE_TAIL(root,elem,field) { \ @@ -82,6 +88,7 @@ struct { \ } else { \ (elem) = NULL; \ } \ + (head)->count--; \ } #define MPLS_LIST_REMOVE_HEAD(root,elem,field) { \ @@ -91,6 +98,7 @@ struct { \ } else { \ (elem) = NULL; \ } \ + (head)->count--; \ } #define MPLS_LIST_ELEM_INIT(elem,field) { \ diff --git a/common/mpls_struct.h b/common/mpls_struct.h index 4c609b3..4474eb6 100644 --- a/common/mpls_struct.h +++ b/common/mpls_struct.h @@ -138,21 +138,14 @@ typedef struct mpls_dest { typedef struct mpls_range { int label_space; mpls_label_range_type type; - union { - struct { - uint16_t vpi; - uint16_t vci; - } atm; - uint32_t gen; - uint32_t fr; - } max, min; + struct mpls_label_struct min, max; } mpls_range; typedef enum mpls_nexthop_enum { - MPLS_NH_NONE, - MPLS_NH_IP, - MPLS_NH_IF, - MPLS_NH_IPIF, + MPLS_NH_NONE = 0x0, + MPLS_NH_IP = 0x1, + MPLS_NH_IF = 0x2, + MPLS_NH_OUTSEGMENT = 0x4 } mpls_nexthop_enum; typedef enum mpls_fec_enum { @@ -163,15 +156,13 @@ typedef enum mpls_fec_enum { } mpls_fec_enum; typedef struct mpls_nexthop { - enum mpls_nexthop_enum type; - union { - struct mpls_inet_addr ip; - struct { - struct mpls_inet_addr ip; - mpls_if_handle if_handle; - } ipif; - mpls_if_handle if_handle; - } u; + unsigned char type; + int distance; + int metric; + mpls_bool attached; + struct mpls_inet_addr ip; + mpls_if_handle if_handle; + mpls_outsegment_handle outsegment_handle; } mpls_nexthop; typedef struct mpls_fec { @@ -189,7 +180,6 @@ typedef struct mpls_fec { } l2cc; } u; struct mpls_nexthop nh; - mpls_bool attached; } mpls_fec; typedef struct mpls_insegment { diff --git a/doc/ldp_struct.txt b/doc/ldp_struct.txt index 5f0f3fb..59065fa 100644 --- a/doc/ldp_struct.txt +++ b/doc/ldp_struct.txt @@ -4,13 +4,13 @@ .------| Adj | / | | ---------- / ----- - | In Label |-------. 1:1 | + | In Label |-------. 1:N | ---------- N:M / | - | \ / N:M + | \ / 1:N 1:N \ / | | --------- -------- ------ ----------- N:1 | | | | 1:1 | Targ | - | Out label |<----->| Session | | Entity |<----->| Peer | + | Out label |-------| Session | | Entity |-------| Peer | ----------- | | | | | | --------- -------- ------ | | diff --git a/ldp/ldp_adj.c b/ldp/ldp_adj.c index ea6fa95..f9f230b 100644 --- a/ldp/ldp_adj.c +++ b/ldp/ldp_adj.c @@ -37,6 +37,8 @@ ldp_adj *ldp_adj_create(mpls_inet_addr * source, mpls_inet_addr * lsraddr, if (a) { memset(a, 0, sizeof(ldp_adj)); MPLS_REFCNT_INIT(a, 0); + MPLS_LIST_ELEM_INIT(a, _global); + MPLS_LIST_ELEM_INIT(a, _session); MPLS_LIST_ELEM_INIT(a, _entity); a->index = _ldp_adj_get_next_index(); @@ -58,6 +60,7 @@ ldp_adj *ldp_adj_create(mpls_inet_addr * source, mpls_inet_addr * lsraddr, a->remote_hellotime = remote_hellotime; a->remote_csn = remote_csn; a->state = MPLS_OPER_DOWN; + a->role = LDP_NONE; } return a; } @@ -71,10 +74,14 @@ void ldp_adj_delete(ldp_adj * a) mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a, int request) { - /* we only do adj startup for the first entity that recieves hello */ - ldp_entity *e = (ldp_entity*)mpls_link_list_head_data(&a->entity_root); + ldp_entity *e; - MPLS_ASSERT(a && e); + MPLS_ASSERT(a && (e = a->entity)); + /* with recent changes to when the session gets created I think this + * assert is not longer valid - jleu 2003-02-20 + MPLS_ASSERT(!a->session); + */ + MPLS_ASSERT(a->state != LDP_NONE); LDP_ENTER(g->user_data, "ldp_adj_startup"); @@ -87,48 +94,32 @@ mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a, int request) if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) == MPLS_BOOL_FALSE) { MPLS_REFCNT_RELEASE(a, ldp_adj_delete); - LDP_EXIT(g->user_data, "ldp_adj_startup-error"); - return MPLS_FAILURE; + goto ldp_adj_startup_error; } - mpls_timer_start(g->timer_handle, a->hellotime_recv_timer, MPLS_TIMER_ONESHOT); - _ldp_global_add_adj(g, a); - a->state = MPLS_OPER_UP; } - a->cfg_remote_in_ttl_less_domain = e->remote_in_ttl_less_domain; - a->cfg_distribution_mode = e->label_distribution_mode; - a->cfg_loop_detection_mode = e->loop_detection_mode; - a->cfg_label_request_count = e->label_request_count; - a->cfg_label_request_timer = e->label_request_timer; - a->cfg_label_space = ldp_entity_label_space(e); - a->cfg_path_vector_limit = e->path_vector_limit; - a->cfg_hop_count_limit = e->hop_count_limit; - a->cfg_peer_tcp_port = e->remote_tcp_port; - a->cfg_keepalive = e->keepalive_timer; - a->cfg_max_pdu = e->max_pdu; - if (request && mpls_timer_handle_verify(g->timer_handle, e->p.peer->hellotime_send_timer) == MPLS_BOOL_FALSE) { /* request is ONLY specific with indirect adj */ ldp_hello_send(g, e); } - if (a->role == LDP_ACTIVE) { - ldp_session *session = NULL; - if (mpls_timer_handle_verify(g->timer_handle, a->backoff_timer)== MPLS_BOOL_TRUE) { - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_NORMAL, - "ldp_adj_startup: in backoff state(%d)\n", a->index); - } else { - if ((session = ldp_session_create_active(g, a)) == NULL) { - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_NORMAL, - "ldp_adj_startup: active startup failed(%d)\n", a->index); - ldp_adj_backoff_start(g, a); - } - } + a->state = MPLS_OPER_UP; + + if (e->hellotime_timer != 0xFFFF) { + mpls_timer_start(g->timer_handle, a->hellotime_recv_timer, + MPLS_TIMER_ONESHOT); } + LDP_EXIT(g->user_data, "ldp_adj_startup"); return MPLS_SUCCESS; + +ldp_adj_startup_error: + + LDP_EXIT(g->user_data, "ldp_adj_startup: error"); + + return MPLS_FAILURE; } #if 0 /* no one used this? */ @@ -152,32 +143,28 @@ mpls_return_enum ldp_adj_restart(ldp_global * g, ldp_adj * a) mpls_return_enum ldp_adj_shutdown(ldp_global * g, ldp_adj * a) { - ldp_entity *e = NULL; - MPLS_ASSERT(g && a); + ldp_entity *e; + + MPLS_ASSERT(g && a && (e = a->entity)); LDP_ENTER(g->user_data, "ldp_adj_shutdown"); MPLS_REFCNT_HOLD(a); - if (a->session != NULL) { - ldp_session_shutdown(g, a->session); - /* session_shutdown does this already ldp_adj_del_session(a); */ + if (a->session) { + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE); + /* session_shutdown does ldp_adj_del_session(a); */ } ldp_adj_recv_stop(g, a); - MPLS_ASSERT(a != NULL); - ldp_adj_backoff_stop(g, a); - MPLS_ASSERT(a != NULL); - /* JLEU: this assumes only one ADJ per INDIRECT entity!!! */ - e = (ldp_entity*)mpls_link_list_head_data(&a->entity_root); if (e->entity_type == LDP_INDIRECT && e->p.peer->target_role == LDP_PASSIVE) { /* we started sending due to a targeted hello with "request" - now that the adj is down we can stop */ + * now that the adj is down we can stop + */ ldp_peer_send_stop(g, e->p.peer); } - MPLS_ASSERT(a); ldp_entity_del_adj(e, a); if (a->state == MPLS_OPER_UP) { @@ -206,22 +193,25 @@ mpls_return_enum ldp_adj_maintain_timer(ldp_global * g, ldp_adj * a) return retval; } -mpls_return_enum ldp_adj_backoff_stop(ldp_global * g, ldp_adj * a) +mpls_return_enum ldp_adj_recv_start(ldp_global * g, ldp_adj * a) { + mpls_return_enum result = MPLS_SUCCESS; + + LDP_ENTER(g->user_data, "ldp_adj_recv_start"); - LDP_ENTER(g->user_data, "ldp_adj_backoff_stop"); + MPLS_REFCNT_HOLD(a); + a->hellotime_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC, + a->entity->hellotime_timer, (void *)a, g, ldp_hello_timeout_callback); - a->backoff = 0; - if (mpls_timer_handle_verify(g->timer_handle, a->backoff_timer) == MPLS_BOOL_TRUE) { - mpls_timer_stop(g->timer_handle, a->backoff_timer); - mpls_timer_delete(g->timer_handle, a->backoff_timer); - a->backoff_timer = (mpls_timer_handle) 0; + if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) == + MPLS_BOOL_FALSE) { MPLS_REFCNT_RELEASE(a, ldp_adj_delete); + result = MPLS_FAILURE; } - LDP_EXIT(g->user_data, "ldp_adj_backoff_stop"); + LDP_EXIT(g->user_data, "ldp_adj_recv_start"); - return MPLS_SUCCESS; + return result; } mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a) @@ -242,111 +232,18 @@ mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a) return MPLS_SUCCESS; } -void ldp_adj_backoff_callback(mpls_timer_handle timer, void *extra, - mpls_cfg_handle handle) +void _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e) { - ldp_adj *a = (ldp_adj *)extra; - ldp_global *g = (ldp_global*)handle; - - LDP_ENTER(g->user_data, "ldp_adj_backoff"); - - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER, - "Adj Backoff Timer fired: adj(%d)\n", a->index); - - mpls_lock_get(g->global_lock); - - a->backoff_timer = 0; - - if (ldp_session_create_active(g, a) == NULL) { - a->backoff += g->backoff_step; - a->backoff_timer = timer; - mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT); - - LDP_EXIT(g->user_data, "ldp_adj_backoff-error"); - - goto ldp_adj_backoff_end; - } - mpls_timer_stop(g->timer_handle, timer); - mpls_timer_delete(g->timer_handle, timer); - MPLS_REFCNT_RELEASE(a, ldp_adj_delete); - -ldp_adj_backoff_end: - - mpls_lock_release(g->global_lock); - - LDP_EXIT(g->user_data, "ldp_adj_backoff"); -} - -mpls_return_enum ldp_adj_backoff_start(ldp_global * g, ldp_adj * a) -{ - mpls_return_enum retval; - - MPLS_ASSERT(a != NULL); - - LDP_ENTER(g->user_data, "ldp_adj_backoff_start"); - - a->backoff += g->backoff_step; - if (mpls_timer_handle_verify(g->timer_handle, a->backoff_timer) == MPLS_BOOL_TRUE) { - /* this should never happen, but if so */ - mpls_timer_stop(g->timer_handle, a->backoff_timer); - mpls_timer_delete(g->timer_handle, a->backoff_timer); - MPLS_REFCNT_RELEASE(a, ldp_adj_delete); - a->backoff_timer = (mpls_timer_handle) 0; - } - - if (a == NULL) { /* if we deleted adj due to the above RELEASE */ - LDP_EXIT(g->user_data, "ldp_adj_backoff_start-error"); - return MPLS_FAILURE; - } - - MPLS_REFCNT_HOLD(a); - a->backoff_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC, a->backoff, - (void *)a, g, ldp_adj_backoff_callback); - if (mpls_timer_handle_verify(g->timer_handle, a->backoff_timer) == MPLS_BOOL_FALSE) { - MPLS_REFCNT_RELEASE(a, ldp_adj_delete); - - LDP_EXIT(g->user_data, "ldp_adj_backoff_start-error"); - - return MPLS_FAILURE; - } - retval = mpls_timer_start(g->timer_handle, a->backoff_timer, MPLS_TIMER_ONESHOT); - - LDP_EXIT(g->user_data, "ldp_adj_backoff_start"); - - return retval; -} - -mpls_return_enum _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e) -{ - mpls_return_enum result = MPLS_FAILURE; - struct mpls_link_list_node *lln; - struct mpls_link_list_node *llnp; - ldp_entity *data; - MPLS_ASSERT(a && e); - MPLS_REFCNT_HOLD(e); - lln = mpls_link_list_node_create(e); - if (lln) { - MPLS_LINK_LIST_LOOP(&a->entity_root, data, llnp) { - if (data->index > e->index) { - mpls_link_list_add_node_before(&a->entity_root, llnp, lln); - return MPLS_SUCCESS; - } - } - - mpls_link_list_add_node_tail(&a->entity_root, lln); - return MPLS_SUCCESS; - } - MPLS_REFCNT_RELEASE(e, ldp_entity_delete); - return result; + a->entity = e; } void _ldp_adj_del_entity(ldp_adj * a, ldp_entity *e) { MPLS_ASSERT(a && e); - mpls_link_list_remove_data(&a->entity_root, e); MPLS_REFCNT_RELEASE(e, ldp_entity_delete); + a->entity = NULL; } void ldp_adj_add_session(ldp_adj * a, ldp_session * s) @@ -358,11 +255,11 @@ void ldp_adj_add_session(ldp_adj * a, ldp_session * s) _ldp_session_add_adj(s, a); } -void ldp_adj_del_session(ldp_adj * a) +void ldp_adj_del_session(ldp_adj * a, ldp_session * s) { - MPLS_ASSERT(a && a->session); - _ldp_session_del_adj(a->session); - MPLS_REFCNT_RELEASE(a->session, ldp_session_delete); + MPLS_ASSERT(a && s); + _ldp_session_del_adj(s, a); + MPLS_REFCNT_RELEASE(s, ldp_session_delete); a->session = NULL; } diff --git a/ldp/ldp_adj.h b/ldp/ldp_adj.h index 0076f81..33099db 100644 --- a/ldp/ldp_adj.h +++ b/ldp/ldp_adj.h @@ -18,21 +18,16 @@ extern ldp_adj *ldp_adj_create(mpls_inet_addr * source, extern void ldp_adj_delete(ldp_adj * a); extern mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a, - int request); extern mpls_return_enum ldp_adj_restart(ldp_global * g, ldp_adj * a); extern mpls_return_enum ldp_adj_shutdown(ldp_global * g, ldp_adj * a); extern mpls_return_enum ldp_adj_maintain_timer(ldp_global * g, ldp_adj * a); extern mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a); -extern mpls_return_enum ldp_adj_backoff_stop(ldp_global * g, ldp_adj * a); -extern mpls_return_enum ldp_adj_backoff_start(ldp_global * g, ldp_adj * a); -extern void ldp_adj_backoff_callback(mpls_timer_handle timer, void *extra, - mpls_cfg_handle g); -extern mpls_return_enum _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e); +extern void _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e); extern void _ldp_adj_del_entity(ldp_adj * a, ldp_entity * e); extern void ldp_adj_add_session(ldp_adj * a, ldp_session * s); -extern void ldp_adj_del_session(ldp_adj * a); +extern void ldp_adj_del_session(ldp_adj * a, ldp_session * s); extern uint32_t _ldp_adj_get_next_index(); #endif diff --git a/ldp/ldp_attr.c b/ldp/ldp_attr.c index c060770..bb7eed7 100644 --- a/ldp/ldp_attr.c +++ b/ldp/ldp_attr.c @@ -187,7 +187,8 @@ ldp_attr *ldp_attr_find_upstream_state(ldp_global * g, ldp_session * s, return NULL; } -void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr) +void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, + mpls_bool complete) { ldp_session *session = attr->session; ldp_outlabel *out = NULL; diff --git a/ldp/ldp_attr.h b/ldp/ldp_attr.h index 0b0a2c0..500570e 100644 --- a/ldp/ldp_attr.h +++ b/ldp/ldp_attr.h @@ -32,7 +32,7 @@ extern int ldp_attr_num_us2ds(ldp_attr * ds); extern ldp_attr *ldp_attr_create(mpls_fec * fec); extern void ldp_attr_delete(ldp_attr * a); extern void ldp_attr2ldp_attr(ldp_attr * a, ldp_attr * b, uint32_t flag); -extern void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr); +extern void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, mpls_bool); extern ldp_attr *ldp_attr_find_downstream_state(ldp_global * g, ldp_session * s, mpls_fec * f, ldp_lsp_state state); diff --git a/ldp/ldp_cfg.c b/ldp/ldp_cfg.c index bc08920..d94021e 100644 --- a/ldp/ldp_cfg.c +++ b/ldp/ldp_cfg.c @@ -333,7 +333,7 @@ mpls_return_enum ldp_cfg_entity_get(mpls_cfg_handle handle, ldp_entity * e, e->adj_count = e->adj_root.count; } if (flag & LDP_ENTITY_CFG_ADJ_INDEX) { - ldp_adj *a = mpls_link_list_head_data(&entity->adj_root); + ldp_adj *a = MPLS_LIST_HEAD(&e->adj_root); e->adj_index = a ? a->index : 0; } if (flag & LDP_ENTITY_CFG_INHERIT_FLAG) { @@ -656,7 +656,6 @@ mpls_return_enum ldp_cfg_entity_adj_getnext(mpls_cfg_handle handle, mpls_return_enum r = MPLS_FAILURE; ldp_adj *adj_next = NULL; ldp_adj *adj = NULL; - mpls_link_list_node *lln; ldp_entity *entity = NULL; LDP_ENTER(g->user_data, "ldp_cfg_entity_adj_getnext"); @@ -671,7 +670,8 @@ mpls_return_enum ldp_cfg_entity_adj_getnext(mpls_cfg_handle handle, mpls_lock_get(g->global_lock); /* LOCK */ if (ldp_global_find_entity_index(g, e->index, &entity) == MPLS_SUCCESS) { - MPLS_LINK_LIST_LOOP(&entity->adj_root, adj, lln) { + adj = MPLS_LIST_HEAD(&entity->adj_root); + while (adj) { if (this_one == MPLS_BOOL_TRUE) { adj_next = adj; break; @@ -683,6 +683,7 @@ mpls_return_enum ldp_cfg_entity_adj_getnext(mpls_cfg_handle handle, } else if (adj->index == e->adj_index) { this_one = MPLS_BOOL_TRUE; } + adj = MPLS_LIST_NEXT(&entity->adj_root, adj, _entity); } } mpls_lock_release(g->global_lock); /* UNLOCK */ @@ -1188,8 +1189,7 @@ mpls_return_enum ldp_cfg_adj_get(mpls_cfg_handle handle, ldp_adj * a, a->remote_hellotime = adj->remote_hellotime; } if (flag & LDP_ADJ_CFG_ENTITY_INDEX) { - ldp_entity *e = mpls_link_list_head_data(&adj->entity_root); - a->entity_index = e ? e->index : 0; + a->entity_index = adj->entity ? adj->entity->index : 0; } if (flag & LDP_ADJ_CFG_REMOTE_SESSION_INDEX) { a->session_index = (adj->session) ? (adj->session->index) : 0; @@ -1197,12 +1197,6 @@ mpls_return_enum ldp_cfg_adj_get(mpls_cfg_handle handle, ldp_adj * a, if (flag & LDP_ADJ_CFG_ROLE) { a->role = adj->role; } - if (flag & LDP_ADJ_CFG_BACKOFF) { - a->backoff = adj->backoff; - } - if (flag & LDP_ADJ_CFG_LABELSPACE) { - a->cfg_label_space = adj->cfg_label_space; - } retval = MPLS_SUCCESS; ldp_cfg_adj_get_end: @@ -1256,54 +1250,6 @@ mpls_return_enum ldp_cfg_adj_getnext(mpls_cfg_handle handle, ldp_adj * a, return r; } -mpls_return_enum ldp_cfg_adj_entity_getnext(mpls_cfg_handle handle, - ldp_adj * a) -{ - ldp_global *g = (ldp_global *) handle; - mpls_bool this_one = MPLS_BOOL_FALSE; - mpls_return_enum r = MPLS_FAILURE; - ldp_entity *entity_next = NULL; - ldp_entity *entity = NULL; - mpls_link_list_node *lln; - ldp_adj *adj = NULL; - - LDP_ENTER(g->user_data, "ldp_cfg_adj_entity_getnext"); - - /* if an entity_index of zero is sent, get the index of - * the first entity in the list - */ - if (!a->entity_index) { - this_one = MPLS_BOOL_TRUE; - } - - mpls_lock_get(g->global_lock); /* LOCK */ - - if (ldp_global_find_adj_index(g, a->index, &adj) == MPLS_SUCCESS) { - MPLS_LINK_LIST_LOOP(&adj->entity_root, entity, lln) { - if (this_one == MPLS_BOOL_TRUE) { - entity_next = entity; - break; - } - - /* since the entities are sort in the list ... */ - if (entity->index > a->entity_index) { - break; - } else if (entity->index == a->entity_index) { - this_one = MPLS_BOOL_TRUE; - } - } - } - mpls_lock_release(g->global_lock); /* UNLOCK */ - - if (entity_next) { - a->entity_index = entity_next->index; - r = MPLS_SUCCESS; - } - - LDP_EXIT(g->user_data, "ldp_cfg_adj_entity_getnext"); - return r; -} - /******************* SESSION **********************/ mpls_return_enum ldp_cfg_session_get(mpls_cfg_handle handle, ldp_session * s, @@ -1372,7 +1318,8 @@ mpls_return_enum ldp_cfg_session_get(mpls_cfg_handle handle, ldp_session * s, s->no_label_resource_recv = session->no_label_resource_recv; } if (flag & LDP_SESSION_CFG_ADJ_INDEX) { - s->adj_index = (session->adj) ? (session->adj->index) : 0; + ldp_adj *a = MPLS_LIST_HEAD(&session->adj_root); + s->adj_index = a ? a->index : 0; } if (flag & LDP_SESSION_CFG_MESG_TX) { s->mesg_tx = session->mesg_tx; @@ -1435,6 +1382,55 @@ mpls_return_enum ldp_cfg_session_getnext(mpls_cfg_handle handle, ldp_session * s return r; } +mpls_return_enum ldp_cfg_session_adj_getnext(mpls_cfg_handle handle, + ldp_session * s) +{ + ldp_global *g = (ldp_global *) handle; + mpls_bool this_one = MPLS_BOOL_FALSE; + mpls_return_enum r = MPLS_FAILURE; + ldp_adj *adj_next = NULL; + ldp_adj *adj = NULL; + ldp_session *session = NULL; + + LDP_ENTER(g->user_data, "ldp_cfg_session_adj_getnext"); + + /* if an adj_index of zero is sent, get the index of + * the first adj in the list + */ + if (!s->adj_index) { + this_one = MPLS_BOOL_TRUE; + } + + mpls_lock_get(g->global_lock); /* LOCK */ + + if (ldp_global_find_session_index(g, s->index, &session) == MPLS_SUCCESS) { + adj = MPLS_LIST_HEAD(&session->adj_root); + while (adj) { + if (this_one == MPLS_BOOL_TRUE) { + adj_next = adj; + break; + } + + /* since the entities are sort in the list ... */ + if (adj->index > s->adj_index) { + break; + } else if (adj->index == s->adj_index) { + this_one = MPLS_BOOL_TRUE; + } + adj = MPLS_LIST_NEXT(&session->adj_root, adj, _session); + } + } + mpls_lock_release(g->global_lock); /* UNLOCK */ + + if (adj_next) { + s->adj_index = adj_next->index; + r = MPLS_SUCCESS; + } + + LDP_EXIT(g->user_data, "ldp_cfg_session_adj_getnext"); + return r; +} + mpls_return_enum ldp_cfg_session_raddr_get(mpls_cfg_handle handle, ldp_session * s, ldp_addr * a, uint32_t flag) { diff --git a/ldp/ldp_cfg.h b/ldp/ldp_cfg.h index bf089d0..93e8ea1 100644 --- a/ldp/ldp_cfg.h +++ b/ldp/ldp_cfg.h @@ -141,8 +141,6 @@ #define LDP_ADJ_CFG_ENTITY_INDEX 0x00000080 #define LDP_ADJ_CFG_REMOTE_SESSION_INDEX 0x00000100 #define LDP_ADJ_CFG_ROLE 0x00000200 -#define LDP_ADJ_CFG_BACKOFF 0x00000400 -#define LDP_ADJ_CFG_LABELSPACE 0x00000800 #define LDP_INLABEL_CFG_LABELSPACE 0x00000002 #define LDP_INLABEL_CFG_LABEL 0x00000004 diff --git a/ldp/ldp_entity.c b/ldp/ldp_entity.c index 3cba7aa..94fe0b9 100644 --- a/ldp/ldp_entity.c +++ b/ldp/ldp_entity.c @@ -69,7 +69,7 @@ ldp_entity *ldp_entity_create() ldp_entity_set_defaults(e); MPLS_REFCNT_INIT(e, 0); - mpls_link_list_init(&e->adj_root); + MPLS_LIST_INIT(&e->adj_root, ldp_adj); MPLS_LIST_ELEM_INIT(e, _global); e->index = _ldp_entity_get_next_index(); @@ -200,20 +200,11 @@ mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e, int flag) MPLS_ASSERT(0); } - adj = (ldp_adj*)mpls_link_list_head_data(&e->adj_root); + adj = MPLS_LIST_HEAD(&e->adj_root); while (adj) { - /* - * if the adj only has one entity contributing to it (this entity) - * then shut it down, else leavwe it since the adj can still be - * maintained by other entities - */ - if (adj->entity_root.count == 1) { - /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */ - ldp_adj_shutdown(g, adj); - } else { - ldp_entity_del_adj(e, adj); - } - adj = mpls_link_list_head_data(&e->adj_root); + /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */ + ldp_adj_shutdown(g, adj); + adj = MPLS_LIST_NEXT(&e->adj_root, adj, _entity); } LDP_EXIT(g->user_data, "ldp_entity_shutdown"); @@ -274,44 +265,35 @@ void ldp_entity_del_peer(ldp_entity * e) e->sub_index = 0; } -mpls_return_enum ldp_entity_add_adj(ldp_entity * e, ldp_adj * a) +void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a) { - struct mpls_link_list_node *lln; - struct mpls_link_list_node *llnp; - ldp_adj *data; + ldp_adj *ap = NULL; MPLS_ASSERT(e && a); - MPLS_REFCNT_HOLD(a); - lln = mpls_link_list_node_create(a); - if (lln) { - if (_ldp_adj_add_entity(a, e) == MPLS_SUCCESS) { - MPLS_LINK_LIST_LOOP(&e->adj_root, data, llnp) { - if (data->index > a->index) { - mpls_link_list_add_node_before(&e->adj_root, llnp, lln); - return MPLS_SUCCESS; - } - } - mpls_link_list_add_node_tail(&e->adj_root, lln); - return MPLS_SUCCESS; + + _ldp_adj_add_entity(a, e); + ap = MPLS_LIST_HEAD(&e->adj_root); + while (ap) { + if (ap->index > a->index) { + MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity); + return; } - mpls_link_list_node_delete(lln); + ap = MPLS_LIST_NEXT(&e->adj_root, ap, _entity); } - MPLS_REFCNT_RELEASE(a, ldp_adj_delete); - return MPLS_FAILURE; + MPLS_LIST_ADD_TAIL(&e->adj_root, a, _entity, ldp_adj); } void ldp_entity_del_adj(ldp_entity * e, ldp_adj * a) { MPLS_ASSERT(e && a); - mpls_link_list_remove_data(&e->adj_root, a); + MPLS_LIST_REMOVE(&e->adj_root, a, _entity); _ldp_adj_del_entity(a, e); MPLS_REFCNT_RELEASE(a, ldp_adj_delete); } ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg) { - struct mpls_link_list_node *node; ldp_adj *a = NULL; mpls_inet_addr lsraddr; int labelspace; @@ -321,13 +303,13 @@ ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg) ldp_mesg_hdr_get_labelspace(msg, &labelspace); ldp_mesg_hdr_get_lsraddr(msg, &lsraddr); - a = (ldp_adj*)mpls_link_list_head_data(&e->adj_root); - MPLS_LINK_LIST_LOOP(&e->adj_root, a, node) { + a = MPLS_LIST_HEAD(&e->adj_root); + while (a != NULL) { if (a->remote_label_space == labelspace && - (mpls_inet_addr_is_equal(&lsraddr, &a->remote_lsr_address) == - MPLS_BOOL_TRUE)) { + (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) { return a; } + a = MPLS_LIST_NEXT(&e->adj_root, a, _entity); } return NULL; diff --git a/ldp/ldp_entity.h b/ldp/ldp_entity.h index 14531f3..1cef3ce 100644 --- a/ldp/ldp_entity.h +++ b/ldp/ldp_entity.h @@ -33,7 +33,7 @@ extern void ldp_entity_del_if(ldp_entity * e); extern void ldp_entity_add_peer(ldp_entity * e, ldp_peer * p); extern void ldp_entity_del_peer(ldp_entity * e); -extern mpls_return_enum ldp_entity_add_adj(ldp_entity * e, ldp_adj * a); +extern void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a); extern void ldp_entity_del_adj(ldp_entity * e, ldp_adj * a); extern ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg); diff --git a/ldp/ldp_fec.c b/ldp/ldp_fec.c index 4992596..170aa54 100644 --- a/ldp/ldp_fec.c +++ b/ldp/ldp_fec.c @@ -96,7 +96,7 @@ mpls_return_enum Recognize_New_Fec(ldp_global * g, mpls_fec * f) if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) != MPLS_SUCCESS) { if (!us_attr->in_tree) { - ldp_attr_remove_complete(g, us_attr); + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); } goto next_peer; } @@ -208,7 +208,7 @@ mpls_return_enum Detect_Change_Fec_Next_Hop(ldp_global * g, mpls_fec * f, } ldp_label_release_send(g, nh_old, ds_attr, LDP_NOTIF_NONE); /* NH.4 */ - ldp_attr_remove_complete(g, ds_attr); /* NH.2,5 */ + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* NH.2,5 */ Detect_Change_Fec_Next_Hop_6: @@ -268,7 +268,7 @@ Detect_Change_Fec_Next_Hop_16: if (us_attr) { /* NH.17 */ if (ldp_label_withdraw_send(g, peer, us_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* NH.18 */ - ldp_attr_remove_complete(g, us_attr); + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); return MPLS_FAILURE; } } @@ -298,7 +298,7 @@ ldp_fec *ldp_fec_create() MPLS_LIST_INIT(&fec->fs_root_ds, ldp_fs); fec->info.type = MPLS_FEC_NONE; fec->info.nh.type = MPLS_NH_NONE; - fec->info.attached = MPLS_BOOL_FALSE; + fec->info.nh.attached = MPLS_BOOL_FALSE; } return fec; } diff --git a/ldp/ldp_global.c b/ldp/ldp_global.c index eab3ff4..17d3598 100644 --- a/ldp/ldp_global.c +++ b/ldp/ldp_global.c @@ -54,7 +54,7 @@ void _ldp_global_fib_callback(mpls_cfg_handle handle, mpls_update_enum type, mpls_lock_get(cfg->global_lock); - if (dest->nh.type == MPLS_NH_IP || dest->nh.type == MPLS_NH_IPIF) { + if (dest->nh.type & MPLS_NH_IP) { session = ldp_get_session_by_next_hop(cfg, &dest->nh, NULL); } @@ -68,6 +68,8 @@ void _ldp_global_fib_callback(mpls_cfg_handle handle, mpls_update_enum type, Detect_Change_Fec_Next_Hop(cfg, dest, session); break; default: + MPLS_ASSERT(0); + break; } mpls_lock_release(cfg->global_lock); @@ -564,7 +566,6 @@ mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o) ldp_outlabel *op = NULL; mpls_return_enum result; - fprintf(stderr, "_ldp_global_add_outlabel\n"); MPLS_ASSERT(g && o); #if MPLS_USE_LSR { @@ -778,7 +779,7 @@ ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr) LDP_PRINT(g->user_data, "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n", p->dest.addr.u.ipv4, addr->u.ipv4); - if (mpls_inet_addr_is_equal(&p->dest.addr, addr) == MPLS_BOOL_TRUE) { + if (!mpls_inet_addr_compare(&p->dest.addr, addr)) { return p; } p = MPLS_LIST_NEXT(&g->peer, p, _global); @@ -877,7 +878,7 @@ ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle) if (g) { while (i != NULL) { - if (!mpls_if_handle_compare(g->ifmgr_handle, i->handle, handle)) + if (!mpls_if_handle_compare(i->handle, handle)) return i; i = MPLS_LIST_NEXT(&g->iff, i, _global); @@ -893,7 +894,7 @@ ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr, ldp_adj *a = MPLS_LIST_HEAD(&g->adj); while (a != NULL) { - if ((mpls_inet_addr_is_equal(lsraddr, &a->remote_lsr_address) == MPLS_BOOL_TRUE) && + if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) && labelspace == a->remote_label_space) return a; diff --git a/ldp/ldp_hello.c b/ldp/ldp_hello.c index 477d48a..cd9fdaf 100644 --- a/ldp/ldp_hello.c +++ b/ldp/ldp_hello.c @@ -52,7 +52,7 @@ void ldp_hello_timeout_callback(mpls_timer_handle timer, void *extra, void ldp_hello_send_callback(mpls_timer_handle timer, void *extra, mpls_cfg_handle handle) { - ldp_entity *e = (ldp_entity *) extra; + ldp_entity *e = (ldp_entity*)extra; ldp_global *g = (ldp_global*)handle; LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER, @@ -176,7 +176,7 @@ mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a, ldp_entity *e, MPLS_ASSERT(a && e); - LDP_ENTER(g->user_data, "ldp_hello_process"); + LDP_ENTER(g->user_data, "ldp_hello_process: a = %p, e = %p", a, e); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC, "Hello Recv: entity(%d)\n", e->index); @@ -184,16 +184,18 @@ mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a, ldp_entity *e, switch (e->entity_type) { case LDP_DIRECT: /* ldp-11 3.5.2. Hello Message */ - if (hellotime == 0) + if (hellotime == 0) { hellotime = 15; + } local = &e->p.iff->local_source_address; break; case LDP_INDIRECT: /* ldp-11 3.5.2. Hello Message */ - if (hellotime == 0) + if (hellotime == 0) { hellotime = 45; + } local = &e->p.peer->local_source_address; break; @@ -210,18 +212,23 @@ mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a, ldp_entity *e, if (traddr != NULL) { memcpy(&a->remote_transport_address, traddr, sizeof(struct mpls_inet_addr)); } + if (csn != a->remote_csn) { /* the remote csn changes all we can do is clear the backoff time */ /* this will only enable a lsr in the active role to try again */ a->remote_csn = csn; - if (mpls_timer_handle_verify(g->timer_handle, a->backoff_timer) == MPLS_BOOL_TRUE) { - ldp_adj_backoff_stop(g, a); /* del timer zero a->backoff */ + if (a->session && mpls_timer_handle_verify(g->timer_handle, + a->session->backoff_timer) == MPLS_BOOL_TRUE) { + ldp_session_backoff_stop(g, a->session); } } - /* should verify that the hello hasn't changed */ + /* JLEU should verify that the hello hasn't changed */ - if (a->session != NULL) { /* we already have an established session */ + if (a->session) { + /* && a->session->state == LDP_STATE_OPERATIONAL) */ + /* all that matters is that we have a session in progress */ + /* we already have an established session */ LDP_EXIT(g->user_data, "ldp_hello_process"); return MPLS_SUCCESS; } @@ -238,27 +245,42 @@ mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a, ldp_entity *e, switch (mpls_inet_addr_compare(local, remote)) { case 1: + /* if at one point we through WE were passive */ + if (a->role == LDP_PASSIVE && a->session) { + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE); + } a->role = LDP_ACTIVE; LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE, "ldp_hello_process: ACTIVE(%d)\n", a->index); + if (ldp_session_create_active(g, a) != MPLS_SUCCESS) { + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_NORMAL, + "ldp_hello_process: creating an active session failed(%d)\n", + a->index); + /* return FAILURE so we don't try to continue with the new adj */ + return MPLS_FAILURE; + } break; case -1: + /* if at one point we through WE were active */ + if (a->role == LDP_ACTIVE && a->session) { + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE); + } a->role = LDP_PASSIVE; LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE, "ldp_hello_process: PASSIVE(%d)\n", a->index); - /* if at one point we through WE were active and the session failed */ - ldp_adj_backoff_stop(g, a); /* del timer zero a->backoff */ - break; default: LDP_PRINT(g->user_data, "ldp_hello_process: exit(%d) configuration error\n", a->index); - /* we will never get here AND have a session established */ + if (a->session) { + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE); + } + a->role = LDP_NONE; MPLS_ASSERT(a->session == NULL); /* return FAILURE so we don't try to continue with the new adj */ diff --git a/ldp/ldp_init.c b/ldp/ldp_init.c index 3b0d6ad..8123e84 100644 --- a/ldp/ldp_init.c +++ b/ldp/ldp_init.c @@ -31,13 +31,13 @@ void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid, uint32_t path_vector_limit; uint32_t remote_lsraddr; uint8_t direction = 0; - ldp_adj *a = NULL; + ldp_adj *a = MPLS_LIST_HEAD(&s->adj_root); uint32_t loop = 0; uint8_t merge = 0; mpls_range range; uint8_t len = 0; - MPLS_ASSERT(s && (a = s->adj)); + MPLS_ASSERT(s && a); LDP_ENTER(g->user_data, "ldp_init_create"); @@ -47,23 +47,23 @@ void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid, remote_lsraddr = a->remote_lsr_address.u.ipv4; remote_labelspace = a->remote_label_space; - loop = (a->cfg_loop_detection_mode == LDP_LOOP_NONE) ? (0) : (1); + loop = (s->cfg_loop_detection_mode == LDP_LOOP_NONE) ? (0) : (1); if (loop == LDP_LOOP_NONE) { path_vector_limit = 0; } else { - path_vector_limit = a->cfg_path_vector_limit; + path_vector_limit = s->cfg_path_vector_limit; } init->cspExists = 1; - init->baseMsg.msgLength += setupCspTlv(&(init->csp), a->cfg_keepalive, - a->cfg_distribution_mode, loop, path_vector_limit, a->cfg_max_pdu, + init->baseMsg.msgLength += setupCspTlv(&(init->csp), s->cfg_keepalive, + s->cfg_distribution_mode, loop, path_vector_limit, s->cfg_max_pdu, remote_lsraddr, remote_labelspace, 0); init->aspExists = 0; init->fspExists = 0; - range.label_space = a->cfg_label_space; + range.label_space = s->cfg_label_space; #if MPLS_USE_LSR #else mpls_mpls_get_label_space_range(g->mpls_handle,&range); @@ -77,8 +77,8 @@ void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid, init->aspExists = 1; init->baseMsg.msgLength += setupAspTlv(&(init->asp), merge, direction); init->baseMsg.msgLength += addLblRng2AspTlv(&(init->asp), - range.min.atm.vpi, range.min.atm.vci, range.max.atm.vpi, - range.max.atm.vci); + range.min.u.atm.vpi, range.min.u.atm.vci, range.max.u.atm.vpi, + range.max.u.atm.vci); break; case MPLS_LABEL_RANGE_FR_10: len = 0; /* Section 3.5.3 fspTlv */ @@ -91,7 +91,7 @@ void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid, init->baseMsg.msgLength += setupFspTlv(&(init->fsp), merge, direction); init->baseMsg.msgLength += addLblRng2FspTlv(&(init->fsp), 0, len, - range.min.fr, 0, range.max.fr); + range.min.u.fr.dlci, 0, range.max.u.fr.dlci); break; case MPLS_LABEL_RANGE_GENERIC: break; @@ -135,7 +135,7 @@ mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s, MPLS_MSGPARAM(Init) = &msg->u.init; - range.label_space = s->adj->cfg_label_space; + range.label_space = s->cfg_label_space; #if MPLS_USE_LSR #else @@ -166,10 +166,10 @@ mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s, s->remote_distribution_mode = (ldp_distribution_mode) MPLS_MSGPARAM(Init)->csp.flags.flags.lad; - if (s->remote_keepalive < s->adj->cfg_keepalive) { + if (s->remote_keepalive < s->cfg_keepalive) { s->oper_keepalive = s->remote_keepalive; } else { - s->oper_keepalive = s->adj->cfg_keepalive; + s->oper_keepalive = s->cfg_keepalive; } /* JLEU: eventually this should be configured by the user */ @@ -181,11 +181,11 @@ mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s, s->remote_loop_detection = MPLS_BOOL_TRUE; } - if (s->remote_max_pdu < s->adj->cfg_max_pdu) { + if (s->remote_max_pdu < s->cfg_max_pdu) { s->oper_max_pdu = s->remote_max_pdu; } - if (s->remote_distribution_mode != s->adj->cfg_distribution_mode) { + if (s->remote_distribution_mode != s->cfg_distribution_mode) { if (range.type == MPLS_LABEL_RANGE_GENERIC) { s->oper_distribution_mode = LDP_DISTRIBUTION_UNSOLICITED; } else { @@ -195,7 +195,7 @@ mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s, if ((s->remote_loop_detection == MPLS_BOOL_TRUE) && (g->loop_detection_mode != LDP_LOOP_NONE)) { - s->oper_loop_detection = s->adj->cfg_loop_detection_mode; + s->oper_loop_detection = s->cfg_loop_detection_mode; } else { s->oper_loop_detection = LDP_LOOP_NONE; } diff --git a/ldp/ldp_inlabel.c b/ldp/ldp_inlabel.c index 60e1046..c5fa92d 100644 --- a/ldp/ldp_inlabel.c +++ b/ldp/ldp_inlabel.c @@ -62,7 +62,7 @@ ldp_inlabel *ldp_inlabel_create_complete(ldp_global * g, ldp_session * s, if (in != NULL) { - in->info.labelspace = s->adj->cfg_label_space; + in->info.labelspace = s->cfg_label_space; in->info.npop = 1; in->info.family = MPLS_FAMILY_IPV4; in->info.owner = MPLS_OWNER_LDP; diff --git a/ldp/ldp_keepalive.c b/ldp/ldp_keepalive.c index a7352cd..a71f81f 100644 --- a/ldp/ldp_keepalive.c +++ b/ldp/ldp_keepalive.c @@ -34,7 +34,8 @@ void ldp_keepalive_timeout_callback(mpls_timer_handle timer, void *extra, s->shutdown_notif = LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED; s->shutdown_fatal = MPLS_BOOL_FALSE; - ldp_session_shutdown(g, s); + /* we should go into backoff, so don't completly kill the session */ + ldp_session_shutdown(g, s, MPLS_BOOL_FALSE); MPLS_REFCNT_RELEASE(s, ldp_session_delete); mpls_lock_release(g->global_lock); diff --git a/ldp/ldp_label_abort.c b/ldp/ldp_label_abort.c index 24d0de9..4906dfe 100644 --- a/ldp/ldp_label_abort.c +++ b/ldp/ldp_label_abort.c @@ -77,7 +77,7 @@ mpls_return_enum ldp_label_abort_send(ldp_global * g, ldp_session * s, ldp_label_abort_send_error: if (s_attr) { - ldp_attr_remove_complete(g, s_attr); + ldp_attr_remove_complete(g, s_attr, MPLS_BOOL_FALSE); } LDP_EXIT(g->user_data, "ldp_label_abort_send-error"); @@ -129,7 +129,7 @@ mpls_return_enum ldp_label_abort_process(ldp_global * g, ldp_session * s, /* this may results in us sending a label withdraw to s and possibly propogating a release */ - if (ldp_label_release_process(g, s, s->adj, e, us_attr, fec) != MPLS_SUCCESS) { /* LAbR.6 */ + if (ldp_label_release_process(g, s, NULL, e, us_attr, fec) != MPLS_SUCCESS) { /* LAbR.6 */ retval = MPLS_FAILURE; } goto LAbR_11; @@ -151,7 +151,7 @@ LAbR_7: LAbR_11: if (us_attr) { - ldp_attr_remove_complete(g, us_attr); + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); } LAbR_12: diff --git a/ldp/ldp_label_mapping.c b/ldp/ldp_label_mapping.c index 13263c8..7cf34d6 100644 --- a/ldp/ldp_label_mapping.c +++ b/ldp/ldp_label_mapping.c @@ -42,13 +42,11 @@ mpls_return_enum ldp_label_mapping_with_xc(ldp_global * g, ldp_session * s, mpls_return_enum result; mpls_bool propogating = MPLS_BOOL_TRUE; -fprintf(stderr,"ldp_label_mapping_with_xc: enter\n"); MPLS_ASSERT(us_attr); if (!(*us_attr)) { if (!((*us_attr) = ldp_attr_create(fec))) { -fprintf(stderr,"ldp_label_mapping_with_xc: exit attr alloc\n"); return MPLS_FAILURE; } } @@ -59,10 +57,9 @@ fprintf(stderr,"ldp_label_mapping_with_xc: exit attr alloc\n"); Prepare_Label_Mapping_Attributes(g, s, fec, ds_attr, (*us_attr), propogating, MPLS_BOOL_TRUE); if (ldp_label_mapping_send(g, s, (*us_attr), ds_attr) != MPLS_SUCCESS) { - if ((*us_attr)->in_tree == MPLS_BOOL_TRUE) { + if ((*us_attr)->in_tree != MPLS_BOOL_TRUE) { ldp_attr_delete(*us_attr); } -fprintf(stderr,"ldp_label_mapping_with_xc: exit send failure\n"); return MPLS_FAILURE; } @@ -74,11 +71,9 @@ fprintf(stderr,"ldp_label_mapping_with_xc: exit send failure\n"); result = ldp_inlabel_add_outlabel(g,(*us_attr)->inlabel,ds_attr->outlabel); if (result != MPLS_SUCCESS) { ldp_label_withdraw_send(g, s, (*us_attr), LDP_NOTIF_NONE); -fprintf(stderr,"ldp_label_mapping_with_xc: exit in2out\n"); return MPLS_FAILURE; } } -fprintf(stderr,"ldp_label_mapping_with_xc: exit\n"); return MPLS_SUCCESS; } @@ -88,32 +83,23 @@ ldp_session *ldp_get_session_by_next_hop(ldp_global * g, mpls_nexthop * a, ldp_addr *addr = NULL; uint32_t key = 0; - switch(a->type) { - case MPLS_NH_IP: - key = a->u.ip.u.ipv4; - break; - case MPLS_NH_IPIF: - key = a->u.ipif.ip.u.ipv4; - break; - case MPLS_NH_IF: - { - ldp_if *iff = ldp_global_find_if_handle(g, a->u.if_handle); - ldp_adj *a; - - if (iff) { - /* JLEU if there is more then one session on this interface - then we're in trouble, just choose the first for now */ - if (next_hop) { - *next_hop = NULL; - } -fprintf(stderr,"ldp_get_session_by_next_hop: NH_IF %p\n",*next_hop); - a = (ldp_adj*)mpls_link_list_head_data(&iff->entity->adj_root); - return a->session; + if (a->type & MPLS_NH_IP) { + key = a->ip.u.ipv4; + } else if (a->type & MPLS_NH_IF) { + ldp_if *iff = ldp_global_find_if_handle(g, a->if_handle); + ldp_adj *a; + + if (iff) { + /* JLEU if there is more then one session on this interface + then we're in trouble, just choose the first for now */ + if (next_hop) { + *next_hop = NULL; } - break; + a = MPLS_LIST_HEAD(&iff->entity->adj_root); + return a->session; } - default: - MPLS_ASSERT(0); + } else { + MPLS_ASSERT(0); } if (mpls_tree_get(g->addr_tree, key, 32, (void **)&addr) == MPLS_SUCCESS) { @@ -124,7 +110,6 @@ fprintf(stderr,"ldp_get_session_by_next_hop: NH_IF %p\n",*next_hop); if ((ses = (ldp_session*)mpls_link_list_head_data(&addr->session_root))) { if (next_hop) { *next_hop = addr; -fprintf(stderr,"ldp_get_session_by_next_hop: NH_OTHER %p\n",*next_hop); } return ses; } @@ -154,7 +139,7 @@ mpls_return_enum ldp_get_next_hop_session_for_fec(ldp_global * g, return MPLS_NO_ROUTE; } - if (route.attached == MPLS_BOOL_TRUE) { + if (route.nh.attached == MPLS_BOOL_TRUE) { return MPLS_SUCCESS; } @@ -167,7 +152,6 @@ mpls_return_enum ldp_get_next_hop_session_for_fec(ldp_global * g, } if (next_hop) { *next_hop = addr; -fprintf(stderr,"ldp_get_next_hop_session_for_fec: %p\n",*next_hop); } return MPLS_SUCCESS; } @@ -182,7 +166,7 @@ mpls_return_enum Check_Received_Attributes(ldp_global * g, ldp_session * s, goto Check_Received_Attributes_5; } - if (r_attr->hopCountTlv.hcValue >= s->adj->cfg_hop_count_limit) { /* CRa.2 */ + if (r_attr->hopCountTlv.hcValue >= s->cfg_hop_count_limit) { /* CRa.2 */ LDP_PRINT(g->user_data, "CRa.2\n"); goto Check_Received_Attributes_6; } @@ -268,7 +252,7 @@ void Prepare_Label_Mapping_Attributes(ldp_global * g, ldp_session * s, } if (!(g->ttl_less_domain == MPLS_BOOL_TRUE && - s->adj->cfg_remote_in_ttl_less_domain == MPLS_BOOL_TRUE)) { /* PMpA.5 */ + s->cfg_remote_in_ttl_less_domain == MPLS_BOOL_TRUE)) { /* PMpA.5 */ goto Prepare_Label_Mapping_Attributes_7; } @@ -461,30 +445,16 @@ void ldp_label_mapping_initial_callback(mpls_timer_handle timer, void *extra, "Processing: %08x/%d ", dest.u.prefix.network.u.ipv4, dest.u.prefix.length); - switch(dest.nh.type) { - case MPLS_NH_IP: - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, - LDP_TRACE_FLAG_ROUTE, "via %08x\n", dest.nh.u.ip.u.ipv4); - break; - case MPLS_NH_IF: - { - struct ldp_if *iff = ldp_global_find_if_handle(g,dest.nh.u.if_handle); - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, - LDP_TRACE_FLAG_ROUTE, "via %s\n", iff ? iff->name : "(not an LDP interface)\n"); - break; - } - case MPLS_NH_IPIF: - { - struct ldp_if *iff = - ldp_global_find_if_handle(g,dest.nh.u.ipif.if_handle); - - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, - LDP_TRACE_FLAG_ROUTE, "via %s/%08x\n", - iff ? iff->name : "(not an LDP interface)\n", dest.nh.u.ipif.ip.u.ipv4); - break; - } - default: - break; + if (dest.nh.type & MPLS_NH_IP) { + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, + LDP_TRACE_FLAG_ROUTE, "via %08x\n", dest.nh.ip.u.ipv4); + } else if (dest.nh.type & MPLS_NH_IF) { + struct ldp_if *iff = ldp_global_find_if_handle(g,dest.nh.if_handle); + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, + LDP_TRACE_FLAG_ROUTE, "via %s\n", + iff ? iff->name : "(not an LDP interface)\n"); + } else { + MPLS_ASSERT(0); } /* are we allowed to export this route from the rib */ @@ -604,16 +574,16 @@ mpls_return_enum ldp_label_mapping_send(ldp_global * g, ldp_session * s, if (ldp_mesg_send_tcp(g, s, s->tx_message) != MPLS_SUCCESS) { /* SL.4 */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR, - "Failed sending Label Mapping to %08x:%d\n", - s->adj->remote_lsr_address.u.ipv4, s->adj->remote_label_space); + "Failed sending Label Mapping to %s\n", + s->session_name); goto ldp_label_mapping_send_error; } ldp_attr_add_us2ds(us_attr, ds_attr); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL, - "Label Mapping Sent to %08x:%d for %08x/%d\n", - s->adj->remote_lsr_address.u.ipv4, s->adj->remote_label_space, + "Label Mapping Sent to %s for %08x/%d\n", + s->session_name, us_attr->fecTlv.fecElArray[0].addressEl.address, us_attr->fecTlv.fecElArray[0].addressEl.preLen); @@ -726,8 +696,8 @@ mpls_return_enum ldp_label_mapping_process(ldp_global * g, ldp_session * s, LDP_ENTER(g->user_data, "ldp_label_mapping_process"); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL, - "Label Mapping Recv from %08x:%d for %08x/%d\n", - s->adj->remote_lsr_address.u.ipv4, s->adj->remote_label_space, + "Label Mapping Recv from %s for %08x/%d\n", + s->session_name, r_attr->fecTlv.fecElArray[0].addressEl.address, r_attr->fecTlv.fecElArray[0].addressEl.preLen); @@ -766,7 +736,7 @@ mpls_return_enum ldp_label_mapping_process(ldp_global * g, ldp_session * s, ldp_attr_is_equal(ds_temp, ds_attr, LDP_ATTR_LABEL) == /* LMp.5 */ MPLS_BOOL_TRUE) { /* remove record of the label and remove it switching */ - ldp_attr_remove_complete(g, ds_temp); /* LMp.6,7 */ + ldp_attr_remove_complete(g, ds_temp, MPLS_BOOL_TRUE); /* LMp.6,7 */ /* * I think this is supposed to be 32 NOT 33, we need to release * it don't we? diff --git a/ldp/ldp_label_rel_with.c b/ldp/ldp_label_rel_with.c index 9efe455..038e50f 100644 --- a/ldp/ldp_label_rel_with.c +++ b/ldp/ldp_label_rel_with.c @@ -132,8 +132,7 @@ mpls_return_enum ldp_label_release_process(ldp_global * g, ldp_session * s, LDP_ENTER(g->user_data, "ldp_label_release_process"); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL, - "Release Recv from %08x:%d\n", s->adj->remote_lsr_address.u.ipv4, - s->adj->remote_label_space); + "Release Recv from %s\n", s->session_name); if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists || r_attr->frLblTlvExists) { @@ -177,10 +176,10 @@ mpls_return_enum ldp_label_release_process(ldp_global * g, ldp_session * s, if (ldp_label_release_send(g, ds_attr->session, ds_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* LRl.9 */ retval = MPLS_FAILURE; } - ldp_attr_remove_complete(g, ds_attr); + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); LRl_10: - ldp_attr_remove_complete(g, us_attr); /* LRl.10,11 */ + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); /* LRl.10,11 */ } else { LDP_PRINT(g->user_data, "No FEC in release, need to implement\n"); @@ -205,8 +204,7 @@ mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s, LDP_ENTER(g->user_data, "ldp_label_withdraw_process"); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL, - "Withdraw Recv for %08x:%d\n", s->adj->remote_lsr_address.u.ipv4, - s->adj->remote_label_space); + "Withdraw Recv for %s\n", s->session_name); if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists || r_attr->frLblTlvExists) { @@ -272,7 +270,7 @@ mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s, LWd_13: if (ds_attr) { - ldp_attr_remove_complete(g, ds_attr); /* LWd.4 */ + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LWd.4 */ } LDP_EXIT(g->user_data, "ldp_label_withdraw_process"); diff --git a/ldp/ldp_label_request.c b/ldp/ldp_label_request.c index dfb4997..4f9b794 100644 --- a/ldp/ldp_label_request.c +++ b/ldp/ldp_label_request.c @@ -100,7 +100,7 @@ mpls_return_enum ldp_label_request_send(ldp_global * g, ldp_session * s, /* we do not need the one passed in, but make sure that the caller is using this one from here forth */ - ldp_attr_remove_complete(g, *ds_attr); + ldp_attr_remove_complete(g, *ds_attr, MPLS_BOOL_TRUE); *ds_attr = ds_temp; return MPLS_SUCCESS; } @@ -432,7 +432,7 @@ LRq_11: /* the work done by LRq_11 is handled in ldp_label_mapping_with_xc() */ LRq_13: if (ds_attr != NULL && ds_attr->in_tree == MPLS_BOOL_FALSE) { - ldp_attr_remove_complete(g, ds_attr); + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); } return MPLS_SUCCESS; diff --git a/ldp/ldp_mesg.c b/ldp/ldp_mesg.c index 6761dc7..f445edf 100644 --- a/ldp/ldp_mesg.c +++ b/ldp/ldp_mesg.c @@ -26,7 +26,7 @@ mpls_return_enum ldp_mesg_send_tcp(ldp_global * g, ldp_session * s, MPLS_ASSERT(s); result = ldp_encode_one_mesg(g, g->lsr_identifier.u.ipv4, - s->adj->cfg_label_space, s->tx_buffer, msg); + s->cfg_label_space, s->tx_buffer, msg); if (result <= 0) return MPLS_FAILURE; diff --git a/ldp/ldp_notif.c b/ldp/ldp_notif.c index ed59925..c470af0 100644 --- a/ldp/ldp_notif.c +++ b/ldp/ldp_notif.c @@ -25,7 +25,8 @@ void ldp_notif_prepare_msg(ldp_mesg * msg, uint32_t msgid, ldp_attr * r_attr, { mplsLdpNotifMsg_t *notif = NULL; int error, forward = 0; - uint32_t msg_type; + uint32_t msg_type = 0; + uint32_t msg_id = 0; ldp_mesg_prepare(msg, MPLS_NOT_MSGTYPE, msgid); notif = &msg->u.notif; @@ -60,15 +61,18 @@ void ldp_notif_prepare_msg(ldp_mesg * msg, uint32_t msgid, ldp_attr * r_attr, forward = 0; } - switch (r_attr->state) { - case LDP_LSP_STATE_ABORT_RECV: - msg_type = MPLS_LBLABORT_MSGTYPE; - break; - default: - msg_type = 0; + if (r_attr) { + switch (r_attr->state) { + case LDP_LSP_STATE_ABORT_RECV: + msg_type = MPLS_LBLABORT_MSGTYPE; + msg_id = r_attr->msg_id; + break; + default: + msg_type = 0; + } } notif->baseMsg.msgLength += setupStatusTlv(¬if->status, error, forward, - status, r_attr->msg_id, msg_type); + status, msg_id, msg_type); /* We have to insert other tlv's like retpdu,extended status, returned message @@ -135,7 +139,7 @@ void not2attr(mplsLdpNotifMsg_t * not, ldp_attr * attr, uint32_t flag) mpls_return_enum ldp_notif_process(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr) { - mpls_return_enum retval; + mpls_return_enum retval = MPLS_SUCCESS; int status; LDP_ENTER(g->user_data, "ldp_notif_process"); @@ -156,8 +160,72 @@ mpls_return_enum ldp_notif_process(ldp_global * g, ldp_session * s, case LDP_NOTIF_LABEL_RESOURCES_AVAILABLE: retval = ldp_notif_label_resources_available(g, s, r_attr); break; + case LDP_NOTIF_SUCCESS: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SUCCESS:\n"); + break; + case LDP_NOTIF_BAD_LDP_ID: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_LDP_ID:\n"); + break; + case LDP_NOTIF_BAD_PROTO: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_PROTO:\n"); + break; + case LDP_NOTIF_BAD_PDU_LEN: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_PDU_LEN:\n"); + break; + case LDP_NOTIF_UNKNOWN_MESG: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_MESG:\n"); + break; + case LDP_NOTIF_BAD_MESG_LEN: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_MESG_LEN:\n"); + break; + case LDP_NOTIF_UNKNOWN_TVL: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_TVL:\n"); + break; + case LDP_NOTIF_BAD_TLV_LEN: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_TLV_LEN:\n"); + break; + case LDP_NOTIF_MALFORMED_TLV: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_MALFORMED_TLV:\n"); + break; + case LDP_NOTIF_HOLD_TIMER_EXPIRED: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_HOLD_TIMER_EXPIRED:\n"); + break; + case LDP_NOTIF_SHUTDOWN: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SHUTDOWN:\n"); + break; + case LDP_NOTIF_UNKNOWN_FEC: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_FEC:\n"); + break; + case LDP_NOTIF_SESSION_REJECTED_NO_HELLO: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_NO_HELLO:\n"); + break; + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_ADVERTISEMENT_MODE: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_ADVERTISEMENT_MODE:\n"); + break; + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_MAX_PDU_LEN: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_MAX_PDU_LEN:\n"); + break; + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE:\n"); + break; + case LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED:\n"); + break; + case LDP_NOTIF_MISSING_MSG_PARAMS: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_MISSING_MSG_PARAMS:\n"); + break; + case LDP_NOTIF_UNSUPORTED_AF: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNSUPORTED_AF:\n"); + break; + case LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME:\n"); + break; + case LDP_NOTIF_INTERNAL_ERROR: + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_INTERNAL_ERROR\n"); + break; default: - fprintf(stderr, "Receive an unknown notification: %08x\n", status); + LDP_TRACE_OUT(g->user_data, "Receive an unknown notification: %08x\n", + status); retval = MPLS_SUCCESS; break; } @@ -183,7 +251,7 @@ mpls_return_enum ldp_notif_label_request_aborted(ldp_global * g, ldp_session * s } if (ds_attr) { /* LRqA.1 */ - ldp_attr_remove_complete(g, ds_attr); /* LRqA.2 */ + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LRqA.2 */ LDP_EXIT(g->user_data, "ldp_notif_label_request_aborted"); return MPLS_SUCCESS; @@ -243,7 +311,7 @@ mpls_return_enum ldp_notif_no_route(ldp_global * g, ldp_session * s, ds_attr->action_timer) == MPLS_BOOL_FALSE) { ds_attr->action_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC, - s->adj->cfg_label_request_timer, (void *)ds_attr, g, + s->cfg_label_request_timer, (void *)ds_attr, g, ldp_attr_action_callback); } mpls_timer_start(g->timer_handle, ds_attr->action_timer, @@ -251,7 +319,7 @@ mpls_return_enum ldp_notif_no_route(ldp_global * g, ldp_session * s, } retval = MPLS_SUCCESS; } else { - ldp_attr_remove_complete(g, ds_attr); + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); retval = MPLS_FAILURE; } } @@ -298,7 +366,7 @@ mpls_return_enum ldp_notif_label_resources_available(ldp_global * g, } case MPLS_FAILURE: case MPLS_NO_ROUTE: - ldp_attr_remove_complete(g, ds_attr); /* Res.5 */ + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* Res.5 */ break; default: MPLS_ASSERT(0); diff --git a/ldp/ldp_outlabel.c b/ldp/ldp_outlabel.c index af33c27..6c645fe 100644 --- a/ldp/ldp_outlabel.c +++ b/ldp/ldp_outlabel.c @@ -44,8 +44,9 @@ ldp_outlabel *ldp_outlabel_create_complete(ldp_global * g, ldp_session * s, ldp_addr * nh, ldp_attr * a) { ldp_outlabel *out = ldp_outlabel_create(); - /* JLEU: for now pick the first entity */ - ldp_entity *e = (ldp_entity*)mpls_link_list_head_data(&s->adj->entity_root); + /* JLEU: for now pick the first adj */ + ldp_adj *adj = MPLS_LIST_HEAD(&s->adj_root); + ldp_entity *e = adj->entity; if (out != NULL) { ldp_outlabel_add_nexthop(out, nh); @@ -54,12 +55,11 @@ ldp_outlabel *ldp_outlabel_create_complete(ldp_global * g, ldp_session * s, out->info.push_label = MPLS_BOOL_TRUE; out->info.owner = MPLS_OWNER_LDP; - memcpy(&out->info.nexthop.u.ipif.ip, - &nh->address, sizeof(mpls_inet_addr)); + memcpy(&out->info.nexthop.ip, &nh->address, sizeof(mpls_inet_addr)); - memcpy(&out->info.nexthop.u.ipif.if_handle, + memcpy(&out->info.nexthop.if_handle, &e->p.iff->handle, sizeof(mpls_if_handle)); - out->info.nexthop.type = MPLS_NH_IPIF; + out->info.nexthop.type = MPLS_NH_IP | MPLS_NH_IF; ldp_attr2mpls_label_struct(a, &out->info.label); diff --git a/ldp/ldp_peer.c b/ldp/ldp_peer.c index 8e54571..e9b7e7d 100644 --- a/ldp/ldp_peer.c +++ b/ldp/ldp_peer.c @@ -103,8 +103,8 @@ mpls_return_enum ldp_peer_startup(ldp_global * g, ldp_peer * p) goto ldp_peer_startup_retry; } - if (entry[0].nh.type == MPLS_NH_IF || entry[0].nh.type == MPLS_NH_IPIF) { - memcpy(&handle, &entry[0].nh.u.if_handle, sizeof(handle)); + if (entry[0].nh.type & MPLS_NH_IF) { + memcpy(&handle, &entry[0].nh.if_handle, sizeof(handle)); if (mpls_if_handle_verify(g->ifmgr_handle, handle) == MPLS_BOOL_FALSE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, diff --git a/ldp/ldp_session.c b/ldp/ldp_session.c index de306e0..37f1ae2 100644 --- a/ldp/ldp_session.c +++ b/ldp/ldp_session.c @@ -34,9 +34,59 @@ #include "mpls_trace_impl.h" #include "mpls_ifmgr_impl.h" #include "mpls_policy_impl.h" +#include "mpls_lock_impl.h" static uint32_t _ldp_session_next_index = 1; +mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s); +mpls_return_enum ldp_session_backoff_stop(ldp_global * g, ldp_session * s); + +static void ldp_session_backoff_callback(mpls_timer_handle timer, void *extra, + mpls_cfg_handle handle) +{ + ldp_session *s = (ldp_session *)extra; + ldp_global *g = (ldp_global*)handle; + + LDP_ENTER(g->user_data, "ldp_session_backoff"); + + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER, + "Session Backoff Timer fired: session(%s)\n", s->session_name); + + mpls_lock_get(g->global_lock); + + s->backoff_timer = 0; + + if (s->oper_role == LDP_ACTIVE) { + if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) { + s->backoff += g->backoff_step; + s->backoff_timer = timer; + mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT); + + LDP_EXIT(g->user_data, "ldp_session_backoff-error"); + + goto ldp_session_backoff_end; + } + } else if (s->oper_role == LDP_PASSIVE) { + /* this is a passive session that never received an init, kill it + * session current on the global list and the timer holds a refcnt. + * shutdown takes this session off of the global list, so when the + * timer refcnt is released the session will be deleted */ + ldp_session_shutdown(g, s, MPLS_BOOL_TRUE); + } else { + MPLS_ASSERT(0); + } + + mpls_timer_stop(g->timer_handle, timer); + mpls_timer_delete(g->timer_handle, timer); + MPLS_REFCNT_RELEASE(s, ldp_session_delete); + +ldp_session_backoff_end: + + mpls_lock_release(g->global_lock); + + LDP_EXIT(g->user_data, "ldp_session_backoff"); +} + ldp_session *ldp_session_create() { ldp_session *s = (ldp_session *) mpls_malloc(sizeof(ldp_session)); @@ -46,112 +96,139 @@ ldp_session *ldp_session_create() MPLS_REFCNT_INIT(s, 0); MPLS_LIST_ELEM_INIT(s, _global); MPLS_LIST_INIT(&s->outlabel_root, ldp_outlabel); + MPLS_LIST_INIT(&s->attr_root, ldp_attr); + MPLS_LIST_INIT(&s->adj_root, ldp_adj); mpls_link_list_init(&s->inlabel_root); mpls_link_list_init(&s->addr_root); - MPLS_LIST_INIT(&s->attr_root, ldp_attr); s->on_global = MPLS_BOOL_FALSE; s->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN); s->tx_message = ldp_mesg_create(); s->index = _ldp_session_get_next_index(); + s->oper_role = LDP_NONE; } return s; } -ldp_session *ldp_session_create_active(ldp_global * g, ldp_adj * a) -{ - mpls_socket_handle socket = 0; - ldp_session *s = NULL; - mpls_inet_addr *addr = NULL; - uint8_t ret; - - MPLS_ASSERT(g && a); - - LDP_ENTER(g->user_data, "ldp_session_create_active"); +mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s) { + mpls_socket_handle socket = mpls_socket_create_tcp(g->socket_handle); + mpls_return_enum retval; - s = ldp_session_create(); + LDP_ENTER(g->user_data, "ldp_session_attempt_setup"); - if (s == NULL) { - goto ldp_session_create_active_end; - } - - if (a->remote_transport_address.type != MPLS_FAMILY_NONE) { - addr = &a->remote_transport_address; - } else { - addr = &a->remote_source_address; - } - memcpy(&s->remote_dest.addr, addr, sizeof(mpls_inet_addr)); - s->remote_dest.port = a->cfg_peer_tcp_port; - - socket = mpls_socket_create_tcp(g->socket_handle); - s->socket = socket; if (mpls_socket_handle_verify(g->socket_handle, socket) == MPLS_BOOL_FALSE) { - goto ldp_session_create_active_end; + return MPLS_FAILURE; } if (mpls_socket_options(g->socket_handle, socket, MPLS_SOCKOP_NONBLOCK) == MPLS_FAILURE) { - goto ldp_session_create_active_end; + goto ldp_session_attempt_setup_error; } - s->state = LDP_STATE_NON_EXIST; - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, - "ldp_session_create_active: (%d) changed to NON_EXIST\n", s->index); - - ldp_adj_add_session(a, s); - ret = mpls_socket_tcp_connect(g->socket_handle, socket, &s->remote_dest); + retval = mpls_socket_tcp_connect(g->socket_handle, socket, &s->remote_dest); - switch (ret) { + switch (retval) { case MPLS_NON_BLOCKING: { + LDP_TRACE_OUT(g->user_data, + "ldp_session_attempt_setup: MPLS_NON_BLOCKING\n"); mpls_socket_writelist_add(g->socket_handle, socket, (void *)s, MPLS_SOCKET_TCP_CONNECT); break; } case MPLS_SUCCESS: { - if (ldp_state_machine(g, s, a, NULL, LDP_EVENT_CONNECT, NULL, + LDP_TRACE_OUT(g->user_data, + "ldp_session_attempt_setup: MPLS_SUCCESS\n"); + if (ldp_state_machine(g, s, NULL, NULL, LDP_EVENT_CONNECT, NULL, NULL) == MPLS_FAILURE) { - goto ldp_session_create_active_end; + goto ldp_session_attempt_setup_error; } break; } default: { - goto ldp_session_create_active_end; + LDP_TRACE_OUT(g->user_data, + "ldp_session_attempt_setup: MPLS_FAILURE\n"); + goto ldp_session_attempt_setup_error; } break; } - LDP_EXIT(g->user_data, "ldp_session_create_active"); + s->socket = socket; + LDP_EXIT(g->user_data, "ldp_session_attempt_setup"); + return MPLS_SUCCESS; - return s; +ldp_session_attempt_setup_error: -ldp_session_create_active_end: + mpls_socket_close(g->socket_handle, socket); + LDP_EXIT(g->user_data, "ldp_session_attempt_setup"); + return MPLS_FAILURE; +} - /* only get here if we have a failure along this path */ - if (s) { - if (a->session == s) { - ldp_adj_del_session(a); +mpls_return_enum ldp_session_create_active(ldp_global * g, ldp_adj * a) +{ + mpls_return_enum retval = MPLS_FAILURE; + mpls_inet_addr *addr = NULL; + ldp_session *s = NULL; + ldp_adj* ap; + + MPLS_ASSERT(g && a && (!a->session)); + + LDP_ENTER(g->user_data, "ldp_session_create_active"); + + ap = MPLS_LIST_HEAD(&g->adj); + while (ap) { + if ((!mpls_inet_addr_compare(&ap->remote_lsr_address, + &a->remote_lsr_address)) && + ap->remote_label_space == a->remote_label_space && + a->index != ap->index && ap->session) { + ldp_adj_add_session(a, ap->session); + retval = MPLS_SUCCESS; + goto ldp_session_create_active; + } + ap = MPLS_LIST_NEXT(&g->adj, ap, _global); + } + + if ((s = ldp_session_create())) { + if (a->remote_transport_address.type != MPLS_FAMILY_NONE) { + addr = &a->remote_transport_address; } else { - ldp_session_delete(s); + addr = &a->remote_source_address; + } + + _ldp_global_add_session(g, s); + ldp_adj_add_session(a, s); + s->state = LDP_STATE_NON_EXIST; + + memcpy(&s->remote_dest.addr, addr, sizeof(mpls_inet_addr)); + s->remote_dest.port = s->cfg_peer_tcp_port; + + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, + "ldp_session_create_active: (%d) changed to NON_EXIST\n", s->index); + + if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) { + /* go into backoff */ + ldp_session_backoff_start(g, s); } + retval = MPLS_SUCCESS; } - LDP_EXIT(g->user_data, "ldp_session_create_active"); +ldp_session_create_active: - return NULL; + LDP_EXIT(g->user_data, "ldp_session_create_active"); + return retval; } ldp_session *ldp_session_create_passive(ldp_global * g, mpls_socket_handle socket, mpls_dest * from) { - ldp_session *s = ldp_session_create(); + ldp_session *s = NULL; MPLS_ASSERT(g); LDP_ENTER(g->user_data, "ldp_session_create_passive"); - if (s) { + if ((s = ldp_session_create())) { s->socket = socket; s->state = LDP_STATE_NON_EXIST; @@ -159,6 +236,7 @@ ldp_session *ldp_session_create_passive(ldp_global * g, MPLS_SUCCESS) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_session_create_passive: (%d) changed to NON_EXIST\n", s->index); + _ldp_global_add_session(g, s); } else { ldp_session_delete(s); s = NULL; @@ -177,42 +255,42 @@ void ldp_session_delete(ldp_session * s) mpls_free(s); } -void ldp_session_startup(ldp_global * g, ldp_session * s) +mpls_return_enum ldp_session_startup(ldp_global * g, ldp_session * s) { - ldp_adj *a = NULL; mpls_inet_addr addr; - int result; + mpls_return_enum retval; mpls_if_handle handle; void (*callback) (mpls_timer_handle timer, void *extra, mpls_cfg_handle g); - MPLS_ASSERT(s && g && (a = s->adj)); + MPLS_ASSERT(s && g && (s->oper_role != LDP_NONE)); LDP_ENTER(g->user_data, "ldp_session_startup"); /* when we make it to operational, get rid of any backoff timers */ - ldp_adj_backoff_stop(g, a); + ldp_session_backoff_stop(g, s); s->state = LDP_STATE_OPERATIONAL; s->oper_up = time(NULL); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_session_startup: (%d) changed to OPERATIONAL\n", s->index); - _ldp_global_add_session(g, s); - /* * if configured to distribute addr messages walk the if table * and send an addr message for each */ if (g->send_address_messages) { addr.u.ipv4 = 0L; - result = mpls_ifmgr_getfirst_address(g->ifmgr_handle, &handle, &addr); - while (result == MPLS_SUCCESS) { + retval = mpls_ifmgr_getfirst_address(g->ifmgr_handle, &handle, &addr); + while (retval == MPLS_SUCCESS) { if (mpls_policy_address_export_check(g->user_data, &addr) == MPLS_BOOL_TRUE) { ldp_addr_send(g, s, &addr); } - result = mpls_ifmgr_getnext_address(g->ifmgr_handle, &handle, &addr); + retval = mpls_ifmgr_getnext_address(g->ifmgr_handle, &handle, &addr); + } + if (retval != MPLS_END_OF_LIST) { + goto ldp_session_startup_end; } } @@ -246,22 +324,26 @@ void ldp_session_startup(ldp_global * g, ldp_session * s) /* timer error, we might as well shutdown the session, it's usless */ s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR; s->shutdown_fatal = MPLS_BOOL_TRUE; - ldp_session_shutdown(g, s); + retval = MPLS_FAILURE; } else { mpls_timer_start(g->timer_handle, s->initial_distribution_timer, MPLS_TIMER_ONESHOT); + retval = MPLS_SUCCESS; } +ldp_session_startup_end: + LDP_EXIT(g->user_data, "ldp_session_startup"); - return; + return retval; } -void ldp_session_shutdown(ldp_global * g, ldp_session * s) +void ldp_session_shutdown(ldp_global * g, ldp_session * s, mpls_bool complete) { ldp_addr *a = NULL; ldp_attr *attr = NULL; ldp_attr *temp_attr = NULL; + ldp_adj* ap; MPLS_ASSERT(s); @@ -294,7 +376,7 @@ void ldp_session_shutdown(ldp_global * g, ldp_session * s) MPLS_REFCNT_RELEASE(s, ldp_session_delete); s->keepalive_send_timer = (mpls_timer_handle) 0; } - if (mpls_timer_handle_verify(g->timer_handle, s->initial_distribution_timer) == + if (mpls_timer_handle_verify(g->timer_handle,s->initial_distribution_timer) == MPLS_BOOL_TRUE) { mpls_timer_stop(g->timer_handle, s->initial_distribution_timer); mpls_timer_delete(g->timer_handle, s->initial_distribution_timer); @@ -305,7 +387,8 @@ void ldp_session_shutdown(ldp_global * g, ldp_session * s) /* * get rid of the socket */ - if (mpls_socket_handle_verify(g->socket_handle, s->socket) == MPLS_BOOL_TRUE) { + if (mpls_socket_handle_verify(g->socket_handle, s->socket) == + MPLS_BOOL_TRUE) { mpls_socket_readlist_del(g->socket_handle, s->socket); mpls_socket_close(g->socket_handle, s->socket); } @@ -318,6 +401,8 @@ void ldp_session_shutdown(ldp_global * g, ldp_session * s) s->keepalive = NULL; } + ldp_session_backoff_stop(g,s); + attr = MPLS_LIST_HEAD(&g->attr); while (attr != NULL) { if (attr->session && attr->session->index == s->index) { @@ -327,7 +412,7 @@ void ldp_session_shutdown(ldp_global * g, ldp_session * s) * ldp_attr_remove_complete removed everythig associated with the attr. * in and out labels, and cross connects as well */ - ldp_attr_remove_complete(g, attr); + ldp_attr_remove_complete(g, attr, complete); } else { temp_attr = NULL; } @@ -339,33 +424,33 @@ void ldp_session_shutdown(ldp_global * g, ldp_session * s) /* * clean up the addrs we created */ - a = (ldp_addr*)mpls_link_list_head_data(&s->addr_root); - while (a) { + while ((a = (ldp_addr*)mpls_link_list_head_data(&s->addr_root))) { ldp_session_del_addr(s, a); - a = (ldp_addr*)mpls_link_list_head_data(&s->addr_root); } /* * if we have an adj AND we are shuting down for a protocol reason, start a * backoff timer, so we can try again in the near future */ - if (s->adj != NULL) { - if (s->adj->role == LDP_ACTIVE) { - ldp_adj_backoff_start(g, s->adj); + if ((complete == MPLS_BOOL_TRUE) || (s->oper_role != LDP_ACTIVE)) { + while ((ap = MPLS_LIST_HEAD(&s->adj_root))) { + ldp_adj_del_session(ap, s); } - /* this takes care of the entity reference as well */ - ldp_adj_del_session(s->adj); - } - if (s->on_global == MPLS_BOOL_TRUE) { - _ldp_global_del_session(g, s); + if (s->on_global == MPLS_BOOL_TRUE) { + _ldp_global_del_session(g, s); + } + } else { + if (s->oper_role == LDP_ACTIVE) { + ldp_session_backoff_start(g, s); + } } /* * it is safe to release this refcnt now, if it is the last one, the - * session will be deleted + * session will be deleted (this will be the last one in the case of + * 'complete' == MPLS_BOOL_TRUE */ - MPLS_REFCNT_RELEASE(s, ldp_session_delete); LDP_EXIT(g->user_data, "ldp_session_shutdown"); @@ -485,16 +570,45 @@ void ldp_session_del_addr(ldp_session * s, ldp_addr * a) { void _ldp_session_add_adj(ldp_session * s, ldp_adj * a) { + ldp_adj *ap = NULL; + struct in_addr lsr_address; + MPLS_ASSERT(s && a); MPLS_REFCNT_HOLD(a); - s->adj = a; + + s->cfg_remote_in_ttl_less_domain = a->entity->remote_in_ttl_less_domain; + s->cfg_distribution_mode = a->entity->label_distribution_mode; + s->cfg_loop_detection_mode = a->entity->loop_detection_mode; + s->cfg_label_request_count = a->entity->label_request_count; + s->cfg_label_request_timer = a->entity->label_request_timer; + s->cfg_label_space = ldp_entity_label_space(a->entity); + s->cfg_path_vector_limit = a->entity->path_vector_limit; + s->cfg_hop_count_limit = a->entity->hop_count_limit; + s->cfg_peer_tcp_port = a->entity->remote_tcp_port; + s->cfg_keepalive = a->entity->keepalive_timer; + s->cfg_max_pdu = a->entity->max_pdu; + + lsr_address.s_addr = htonl(a->remote_lsr_address.u.ipv4); + sprintf(s->session_name, "%s:%d", inet_ntoa(lsr_address), + a->remote_label_space); + s->oper_role = a->role; + + ap = MPLS_LIST_HEAD(&s->adj_root); + while (ap) { + if (ap->index > a->index) { + MPLS_LIST_INSERT_BEFORE(&s->adj_root, ap, a, _session); + return; + } + ap = MPLS_LIST_NEXT(&s->adj_root, ap, _session); + } + MPLS_LIST_ADD_TAIL(&s->adj_root, a, _session, ldp_adj); } -void _ldp_session_del_adj(ldp_session * s) +void _ldp_session_del_adj(ldp_session * s, ldp_adj * a) { - MPLS_ASSERT(s && s->adj); - MPLS_REFCNT_RELEASE(s->adj, ldp_adj_delete); - s->adj = NULL; + MPLS_ASSERT(s && a); + MPLS_LIST_REMOVE(&s->adj_root, a, _session); + MPLS_REFCNT_RELEASE(a, ldp_adj_delete); } uint32_t _ldp_session_get_next_index() @@ -518,6 +632,11 @@ mpls_return_enum ldp_session_find_raddr_index(ldp_session * s, uint32_t index, /* because we sort our inserts by index, this lets us know if we've "walked" past the end of the list */ + if (mpls_link_list_isempty(&s->addr_root)) { + *addr = NULL; + return MPLS_END_OF_LIST; + } + if ((a = (ldp_addr*)mpls_link_list_tail_data(&s->addr_root))) { if (a->index < index) { *addr = NULL; @@ -535,3 +654,77 @@ mpls_return_enum ldp_session_find_raddr_index(ldp_session * s, uint32_t index, *addr = NULL; return MPLS_FAILURE; } + +mpls_return_enum ldp_session_backoff_stop(ldp_global * g, ldp_session * s) +{ + + LDP_ENTER(g->user_data, "ldp_session_backoff_stop"); + + s->backoff = 0; + if (mpls_timer_handle_verify(g->timer_handle, s->backoff_timer) == + MPLS_BOOL_TRUE) { + + mpls_timer_stop(g->timer_handle, s->backoff_timer); + mpls_timer_delete(g->timer_handle, s->backoff_timer); + s->backoff_timer = (mpls_timer_handle) 0; + MPLS_REFCNT_RELEASE(s, ldp_session_delete); + } + + LDP_EXIT(g->user_data, "ldp_session_backoff_stop"); + + return MPLS_SUCCESS; +} + +mpls_return_enum ldp_session_backoff_start(ldp_global * g, ldp_session * s) +{ + mpls_bool valid; + + MPLS_ASSERT(s); + + LDP_ENTER(g->user_data, "ldp_session_backoff_start"); + + valid = mpls_timer_handle_verify(g->timer_handle,s->backoff_timer); + + MPLS_ASSERT(valid == MPLS_BOOL_FALSE); + + s->backoff += g->backoff_step; + +#if 0 /* if the above assert shouldn't be made this code should be executed */ + { + /* this should never happen, but if so */ + mpls_timer_stop(g->timer_handle, s->backoff_timer); + mpls_timer_delete(g->timer_handle, s->backoff_timer); + s->backoff_timer = (mpls_timer_handle) 0; + MPLS_REFCNT_RELEASE(s, ldp_session_delete); + } + + if (!s) { /* if we deleted session due to the above RELEASE */ + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error"); + return MPLS_FAILURE; + } +#endif + + MPLS_REFCNT_HOLD(s); + s->backoff_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC, + s->backoff, (void *)s, g, ldp_session_backoff_callback); + if (mpls_timer_handle_verify(g->timer_handle, s->backoff_timer) == + MPLS_BOOL_FALSE) { + + MPLS_REFCNT_RELEASE(s, ldp_session_delete); + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error"); + return MPLS_FAILURE; + } + + if (mpls_timer_start(g->timer_handle, s->backoff_timer, + MPLS_TIMER_ONESHOT) != MPLS_SUCCESS) { + + mpls_timer_delete(g->timer_handle, s->backoff_timer); + MPLS_REFCNT_RELEASE(s, ldp_session_delete); + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error"); + return MPLS_FAILURE; + } + + LDP_EXIT(g->user_data, "ldp_session_backoff_start"); + + return MPLS_SUCCESS; +} diff --git a/ldp/ldp_session.h b/ldp/ldp_session.h index da3b828..c56cf48 100644 --- a/ldp/ldp_session.h +++ b/ldp/ldp_session.h @@ -12,13 +12,17 @@ #include "ldp_struct.h" -extern ldp_session *ldp_session_create_active(ldp_global * g, ldp_adj * a); +extern mpls_return_enum ldp_session_backoff_start(ldp_global * g, + ldp_session * s); +extern mpls_return_enum ldp_session_backoff_stop(ldp_global * g, + ldp_session * s); +extern mpls_return_enum ldp_session_create_active(ldp_global * g, ldp_adj * a); extern ldp_session *ldp_session_create_passive(ldp_global * g, mpls_socket_handle socket, mpls_dest * from); extern ldp_session *ldp_session_create(); extern void ldp_session_delete(ldp_session * s); -extern void ldp_session_startup(ldp_global * g, ldp_session * s); -extern void ldp_session_shutdown(ldp_global * g, ldp_session * s); +extern mpls_return_enum ldp_session_startup(ldp_global * g, ldp_session * s); +extern void ldp_session_shutdown(ldp_global * g, ldp_session * s, mpls_bool); extern void _ldp_session_add_attr(ldp_session * s, ldp_attr * a); extern void _ldp_session_del_attr(ldp_session * s, ldp_attr * a); @@ -34,7 +38,7 @@ extern mpls_return_enum ldp_session_add_addr(ldp_session * s, ldp_addr * a); extern void ldp_session_del_addr(ldp_session * s, ldp_addr * a); extern void _ldp_session_add_adj(ldp_session * s, ldp_adj * a); -extern void _ldp_session_del_adj(ldp_session * s); +extern void _ldp_session_del_adj(ldp_session * s, ldp_adj * a); extern uint32_t _ldp_session_get_next_index(); extern mpls_return_enum ldp_session_maintain_timer(ldp_global * g, diff --git a/ldp/ldp_state_funcs.c b/ldp/ldp_state_funcs.c index 2e98d99..c5e3f24 100644 --- a/ldp/ldp_state_funcs.c +++ b/ldp/ldp_state_funcs.c @@ -27,6 +27,7 @@ #include "ldp_label_mapping.h" #include "ldp_notif.h" #include "ldp_label_abort.h" +#include "ldp_inet_addr.h" #include "mpls_assert.h" #include "mpls_tree_impl.h" @@ -43,7 +44,7 @@ mpls_return_enum ldp_state_new_adjacency(ldp_global * g, ldp_session * s, int request = 0; int target = 0; uint32_t csn = 0; - mpls_return_enum retval = MPLS_SUCCESS; + mpls_return_enum retval = MPLS_FAILURE; MPLS_ASSERT(msg && e); @@ -51,13 +52,7 @@ mpls_return_enum ldp_state_new_adjacency(ldp_global * g, ldp_session * s, ldp_mesg_hdr_get_labelspace(msg, &labelspace); ldp_mesg_hdr_get_lsraddr(msg, &lsraddr); - if (ldp_mesg_hello_get_hellotime(msg, &hellotime) != MPLS_SUCCESS) { - - retval = MPLS_FAILURE; - fprintf(stderr, "failue from hellotime\n"); - goto ldp_state_new_adjacency_end; - } - + ldp_mesg_hello_get_hellotime(msg, &hellotime); ldp_mesg_hello_get_request(msg, &request); ldp_mesg_hello_get_targeted(msg, &target); ldp_mesg_hello_get_csn(msg, &csn); @@ -68,40 +63,35 @@ mpls_return_enum ldp_state_new_adjacency(ldp_global * g, ldp_session * s, addr = &traddr; } + e->mesg_rx++; + if ((local_a = ldp_adj_create(&from->addr, &lsraddr, labelspace, hellotime, addr, csn)) == NULL) { - - retval = MPLS_FAILURE; goto ldp_state_new_adjacency_end; } - - if (ldp_entity_add_adj(e, local_a) != MPLS_SUCCESS) { - /* the only way this fails is when it is a new adj so we just need to */ - /* delete it, because we just created it */ - ldp_adj_delete(local_a); - - retval = MPLS_FAILURE; - goto ldp_state_new_adjacency_end; - } - - if ((ldp_hello_process(g, local_a, e, hellotime, csn, addr, target, - request) != MPLS_SUCCESS) || (ldp_adj_startup(g, local_a, request) != - MPLS_SUCCESS)) { - - /* if this fails then undo the e<->a linking (which will delete a) */ - + ldp_entity_add_adj(e, local_a); + _ldp_global_add_adj(g, local_a); + if (ldp_hello_process(g, local_a, e, hellotime, csn, addr, target, + request) != MPLS_SUCCESS) { + /* this can fail if we could not create an active session, or + * we're getting errored hellos, + * if this fails then undo the e<->a linking (which will delete a) */ ldp_entity_del_adj(e, local_a); - - retval = MPLS_FAILURE; + _ldp_global_del_adj(g, local_a); + } else if (ldp_adj_startup(g, local_a, request) != MPLS_SUCCESS) { + /* the only way this fail is if a timer could not be created + * if this fails then undo the e<->a linking (which will delete a) */ + ldp_entity_del_adj(e, local_a); + _ldp_global_del_adj(g, local_a); + } else { + /* by this time, we will have a e<->a binding, and some timers, + * if we're active, there will also be an active session */ + retval = MPLS_SUCCESS; } - e->mesg_rx++; ldp_state_new_adjacency_end: LDP_EXIT(g->user_data, "ldp_state_new_adjacency"); - - /* we can't do anything with errors here, just propogate them up */ - return retval; } @@ -153,27 +143,42 @@ mpls_return_enum ldp_state_recv_init(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from) { mpls_inet_addr lsraddr; + ldp_adj* ap; int labelspace = 0; + mpls_bool match = MPLS_BOOL_FALSE; MPLS_ASSERT(msg && s); LDP_ENTER(g->user_data, "ldp_state_recv_init"); - if (s->adj == NULL) { - ldp_adj *a = NULL; + /* we haven't tied this session to an adj yet, at a minimum we can + * now stop the backoff timer we started while waiting for this + * init to arrive */ + ldp_session_backoff_stop(g, s); - /* we haven't tied this session to an adj yet */ + ldp_mesg_hdr_get_lsraddr(msg, &lsraddr); + ldp_mesg_hdr_get_labelspace(msg, &labelspace); - ldp_mesg_hdr_get_lsraddr(msg, &lsraddr); - ldp_mesg_hdr_get_labelspace(msg, &labelspace); + if (s->oper_role != LDP_ACTIVE) { + /* sessions being created from the ACTIVE side of an ADJ have already + * bound to the session */ + /* there may be multiple ADJ that are matched! */ + ap = MPLS_LIST_HEAD(&g->adj); + while (ap != NULL) { + if ((!mpls_inet_addr_compare(&lsraddr, &ap->remote_lsr_address)) && + labelspace == ap->remote_label_space) { + ldp_adj_add_session(ap, s); + match = MPLS_BOOL_TRUE; + } + ap = MPLS_LIST_NEXT(&g->adj, ap, _global); + } - if ((a = ldp_global_find_adj_ldpid(g, &lsraddr, labelspace)) == NULL) { + if (match == MPLS_BOOL_FALSE) { LDP_PRINT(g->user_data, "ldp_state_recv_init: cannot find adj\n"); s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_NO_HELLO; s->shutdown_fatal = MPLS_BOOL_FALSE; goto ldp_state_recv_init_shutdown; } - ldp_adj_add_session(a, s); } if (ldp_init_process(g, s, msg) == MPLS_FAILURE) { @@ -186,7 +191,7 @@ mpls_return_enum ldp_state_recv_init(ldp_global * g, ldp_session * s, LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_state_recv_init: (%d) changed to OPENREC\n", s->index); - if (s->adj && s->adj->role == LDP_PASSIVE) { + if (s->oper_role == LDP_PASSIVE) { if (ldp_init_send(g, s) == MPLS_FAILURE) { LDP_PRINT(g->user_data, "ldp_state_recv_init: unable to send INIT\n"); s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR; @@ -218,7 +223,14 @@ mpls_return_enum ldp_state_connect(ldp_global * g, ldp_session * s, ldp_adj * a, LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, "ldp_state_connect: (%d) changed to INITIALIZED\n", s->index); - if (s->adj && s->adj->role == LDP_ACTIVE) { + /* even though as part of creating an active session, the remote_dest + * was filled in, it had port 646 specified. 'from' now contains the + * real port info that our TCP session is connected to */ + if (from) { + memcpy(&s->remote_dest, from, sizeof(mpls_dest)); + } + + if (s->oper_role == LDP_ACTIVE) { if (ldp_init_send(g, s) == MPLS_SUCCESS) { s->state = LDP_STATE_OPENSENT; LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG, @@ -229,9 +241,12 @@ mpls_return_enum ldp_state_connect(ldp_global * g, ldp_session * s, ldp_adj * a, retval = MPLS_FAILURE; } } else { - if (from) { - memcpy(&s->remote_dest, from, sizeof(mpls_dest)); - } + /* if this session is passive, we still are not associated with an + * adj. That will happen when we receive an init. There are no timers + * running yet, so we need to create a timer, to clean this socket + * up, if we do not receive a Init mesg, we'll overload the backoff + * timer for this purpose */ + retval = ldp_session_backoff_start(g, s); } LDP_EXIT(g->user_data, "ldp_state_connect"); @@ -242,13 +257,12 @@ mpls_return_enum ldp_state_connect(ldp_global * g, ldp_session * s, ldp_adj * a, mpls_return_enum ldp_state_finish_init(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from) { - + mpls_return_enum retval; MPLS_ASSERT(s); LDP_ENTER(g->user_data, "ldp_state_finish_init"); - ldp_session_startup(g, s); - /* this can't fail */ + retval = ldp_session_startup(g, s); LDP_EXIT(g->user_data, "ldp_state_finish_init"); @@ -410,11 +424,15 @@ mpls_return_enum ldp_state_close(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from) { - LDP_ENTER(g->user_data, "ldp_state_close"); + LDP_ENTER(g->user_data, "ldp_state_close: a = %p, e = %p s = %p",a,e,s); /* JLEU: this need more work */ if (s) { - ldp_session_shutdown(g, s); + /* not sure why we got here but we should tear it completely down */ + if (s->shutdown_fatal != MPLS_BOOL_TRUE) { + ldp_notif_send(g,s,NULL,s->shutdown_notif); + } + ldp_session_shutdown(g, s, MPLS_BOOL_TRUE); } LDP_EXIT(g->user_data, "ldp_state_close"); @@ -447,7 +465,6 @@ mpls_return_enum ldp_state_notif(ldp_global * g, ldp_session * s, ldp_adj * adj, MPLS_ASSERT(s && msg); - fprintf(stderr, "Entered notif state\n"); LDP_ENTER(g->user_data, "ldp_state_notif"); if (!(r_attr = ldp_attr_create(NULL))) { diff --git a/ldp/ldp_state_machine.c b/ldp/ldp_state_machine.c index 408b48b..1c83c3b 100644 --- a/ldp/ldp_state_machine.c +++ b/ldp/ldp_state_machine.c @@ -24,16 +24,16 @@ #include "mpls_trace_impl.h" /* HELLO CONNECT INIT KEEP ADDR LABEL NOTIF CLOSE HTIMER KTIMER */ -/* SES_NONE new ignore ignore ignore ignore ignore ignore ignore ignore ignore */ -/* SES_NON_EXISTENT maint connect close close close close close ignore close ignore */ +/* SES_NONE new ignore ignore ignore ignore ignore ignore close ignore ignore */ +/* SES_NON_EXISTENT maint connect close close close close close close close ignore */ /* SES_INITIALIZED maint close recv_init close close close notif close close ignore */ /* SES_OPENSENT maint close recv_init close close close notif close close ignore */ /* SES_OPENREC maint close close finish close close notif close close close */ /* SES_OPERATIONAL maint close kmaint kmaint process process notif close close close */ int ldp_state_table[LDP_STATE_NUM][LDP_EVENT_NUM] = { - {0, 6, 6, 6, 6, 6, 6, 6, 6, 6}, - {1, 3, 7, 7, 7, 7, 7, 6, 7, 6}, + {0, 6, 6, 6, 6, 6, 6, 7, 6, 6}, + {1, 3, 7, 7, 7, 7, 7, 7, 7, 6}, {1, 7, 2, 7, 7, 7, 9, 7, 7, 6}, {1, 7, 2, 7, 7, 7, 9, 7, 7, 6}, {1, 7, 7, 4, 7, 7, 9, 7, 7, 7}, @@ -92,6 +92,11 @@ mpls_return_enum ldp_event(mpls_cfg_handle handle, mpls_socket_handle socket, buf.current_size = 0; buf.want = 0; + /* do this so a failure will know which session caused it */ + if (event == LDP_EVENT_TCP_DATA) { + session = extra; + } + do { retval = ldp_buf_process(g, socket, &buf, extra, event, &from, &more); } while (retval == MPLS_SUCCESS && more == MPLS_BOOL_TRUE); @@ -118,20 +123,21 @@ mpls_return_enum ldp_event(mpls_cfg_handle handle, mpls_socket_handle socket, } case LDP_EVENT_TCP_CONNECT: { - /* only get this case if we did a non-block connect */ - mpls_socket_writelist_del(g->socket_handle, socket); - + retval = mpls_socket_connect_status(g->socket_handle, socket); session = (ldp_session *)extra; - if (mpls_socket_connect_status(g->socket_handle, socket) == - MPLS_SUCCESS) { + if (retval == MPLS_SUCCESS) { + /* only get this case if we did a non-block connect */ + mpls_socket_writelist_del(g->socket_handle, socket); retval = ldp_state_machine(g, session, NULL, NULL, LDP_EVENT_CONNECT, &mesg, &from); - } else { + } else if (retval != MPLS_NON_BLOCKING) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_TCP_CONNECT errno = %d\n", mpls_socket_get_errno(g->socket_handle, socket)); - retval = MPLS_FAILURE; + } else { + /* non-blocking connect is still blocking, we'll try again in a bit */ + retval = MPLS_SUCCESS; } break; } @@ -260,17 +266,17 @@ read_again: buf->buffer + buf->size, buf->want - buf->size); if (!size) { + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, + LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_TCP_DATA errno = %d\n", + mpls_socket_get_errno(g->socket_handle, socket)); + retval = MPLS_FAILURE; session->shutdown_notif = LDP_NOTIF_SHUTDOWN; session->shutdown_fatal = MPLS_BOOL_TRUE; goto ldp_event_end; - } + } if (size < 0) { - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, - LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_TCP_DATA errno = %d\n", - mpls_socket_get_errno(g->socket_handle, socket)); - retval = MPLS_SUCCESS; *more = MPLS_BOOL_FALSE; goto ldp_event_end; @@ -283,14 +289,14 @@ read_again: buf->buffer + buf->size, buf->total - buf->size, from); if (!size) { + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, + LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_UDP_DATA errno = %d\n", + mpls_socket_get_errno(g->socket_handle, socket)); retval = MPLS_FAILURE; goto ldp_event_end; } if (size < 0) { - LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, - LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_UDP_DATA errno = %d\n", - mpls_socket_get_errno(g->socket_handle, socket)); retval = MPLS_SUCCESS; *more = MPLS_BOOL_FALSE; goto ldp_event_end; diff --git a/ldp/ldp_struct.h b/ldp/ldp_struct.h index 0850c7f..807f961 100644 --- a/ldp/ldp_struct.h +++ b/ldp/ldp_struct.h @@ -77,7 +77,8 @@ typedef enum { } ldp_count; typedef enum { - LDP_PASSIVE = 1, + LDP_NONE, + LDP_PASSIVE, LDP_ACTIVE } ldp_role_enum; @@ -289,7 +290,7 @@ typedef struct ldp_global { typedef struct ldp_entity { MPLS_REFCNT_FIELD; MPLS_LIST_ELEM(ldp_entity) _global; - struct mpls_link_list adj_root; + struct ldp_adj_list adj_root; ldp_entity_type_enum entity_type; union { @@ -318,10 +319,6 @@ typedef struct ldp_entity { uint8_t label_request_count; uint16_t label_request_timer; ldp_loop_detection_mode loop_detection_mode; - - mpls_timer_handle keepalive_send_timer; - mpls_timer_handle keepalive_recv_timer; - mpls_admin_state_enum admin_state; mpls_bool remote_in_ttl_less_domain; mpls_bool request_retry; @@ -393,16 +390,18 @@ typedef struct ldp_session { struct mpls_link_list inlabel_root; struct mpls_link_list addr_root; struct ldp_attr_list attr_root; + struct ldp_adj_list adj_root; mpls_timer_handle initial_distribution_timer; mpls_timer_handle keepalive_recv_timer; mpls_timer_handle keepalive_send_timer; - struct ldp_adj *adj; uint32_t index; ldp_state_enum state; uint32_t oper_up; ldp_notif_status shutdown_notif; mpls_bool shutdown_fatal; mpls_socket_handle socket; + mpls_timer_handle backoff_timer; + int backoff; /* operational values learned from initialization */ int oper_max_pdu; @@ -420,6 +419,10 @@ typedef struct ldp_session { int remote_max_pdu; mpls_dest remote_dest; + + + uint8_t session_name[20]; /* xxx.xxx.xxx.xxx:yyy\0 */ + mpls_bool no_label_resource_sent; mpls_bool no_label_resource_recv; mpls_bool on_global; @@ -429,6 +432,22 @@ typedef struct ldp_session { struct ldp_mesg *tx_message; struct ldp_buf *tx_buffer; + /* cached from adj's */ + ldp_role_enum oper_role; + + /* these are config values come from entity */ + ldp_loop_detection_mode cfg_loop_detection_mode; + ldp_distribution_mode cfg_distribution_mode; + mpls_bool cfg_remote_in_ttl_less_domain; + int cfg_label_request_count; + int cfg_label_request_timer; + uint16_t cfg_peer_tcp_port; + int cfg_path_vector_limit; + int cfg_hop_count_limit; + int cfg_label_space; + int cfg_keepalive; + int cfg_max_pdu; + /* mesg counters */ uint32_t mesg_tx; uint32_t mesg_rx; @@ -439,12 +458,14 @@ typedef struct ldp_session { typedef struct ldp_adj { MPLS_REFCNT_FIELD; - MPLS_LIST_ELEM(ldp_adj) _entity; MPLS_LIST_ELEM(ldp_adj) _global; - struct mpls_link_list entity_root; + MPLS_LIST_ELEM(ldp_adj) _session; + MPLS_LIST_ELEM(ldp_adj) _entity; struct ldp_session *session; + struct ldp_entity *entity; mpls_timer_handle hellotime_recv_timer; mpls_oper_state_enum state; + ldp_role_enum role; uint32_t index; /* these values are learned form the remote peer */ @@ -455,23 +476,6 @@ typedef struct ldp_adj { int remote_hellotime; uint32_t remote_csn; - /* these are config values come from entity */ - ldp_loop_detection_mode cfg_loop_detection_mode; - ldp_distribution_mode cfg_distribution_mode; - mpls_bool cfg_remote_in_ttl_less_domain; - int cfg_label_request_count; - int cfg_label_request_timer; - uint16_t cfg_peer_tcp_port; - int cfg_path_vector_limit; - int cfg_hop_count_limit; - int cfg_label_space; - int cfg_keepalive; - int cfg_max_pdu; - - mpls_timer_handle backoff_timer; - ldp_role_enum role; - int backoff; - /* only used by cfg gets */ uint32_t session_index; uint32_t entity_index; diff --git a/lsr/lsr_global.c b/lsr/lsr_global.c index fe5f3ed..3df7254 100644 --- a/lsr/lsr_global.c +++ b/lsr/lsr_global.c @@ -176,7 +176,7 @@ lsr_if * lsr_global_find_if_ifhandle(lsr_global * g, mpls_if_handle ifhandle) 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(g->ifmgr_handle, i->handle, ifhandle)) { + if (!mpls_if_handle_compare(i->handle, ifhandle)) { return i; } i = MPLS_LIST_NEXT(&g->iff, i, _global); -- 2.11.4.GIT