From 4471a55af3aa0f695dbc93a6437cba8f39bb325f Mon Sep 17 00:00:00 2001 From: "James R. Leu" Date: Fri, 8 Aug 2003 22:49:34 -0600 Subject: [PATCH] First step towards making this work: -make sure CFG requests to add a FEC and NEXHOP do the right things -update the ldp_struct.txt pic to represet the new FEC->NH and NH->Addr|If|Out label relationships [git-p4: depot-paths = "//depot/ldp-portable/": change = 386] --- doc/ldp_struct.txt | 32 ++--- ldp/ldp_cfg.c | 2 +- ldp/ldp_fec.c | 388 ++++++++--------------------------------------------- ldp/ldp_fec.h | 3 +- ldp/ldp_nexthop.c | 14 ++ ldp/ldp_nexthop.h | 2 + 6 files changed, 91 insertions(+), 350 deletions(-) diff --git a/doc/ldp_struct.txt b/doc/ldp_struct.txt index b3a0422..4d176f9 100644 --- a/doc/ldp_struct.txt +++ b/doc/ldp_struct.txt @@ -1,9 +1,8 @@ ----- - | | .------| Adj | - (think || links) / | | - ---------- \ / ----- + (think || links) / ----- + ---------- \ / | | In Label |-------. 1:N | ---------- N:M / | | \ / 1:N-(think eth subnet) @@ -17,21 +16,24 @@ N:M 1:1 | | ------ ----- - | | | | | Addr | | If | - | | | | ------ ----- - - ----- - | | - .---------| Fec |---------. - | | | | - | ----- | - | Downstream FS list | - | ------ ------ | - '-| FS |-------| FS |-' - ------\ ------ + ---- + |Addr| + ---- + | + |1:N + | + ----- 1:N ---- 1:N ---- + | |-----------------| NH |-------| If | + .---------| Fec |---------. ---- ---- + | | | | | + | ----- | |1:N + | Downstream FS list | | + | ------ ------ | --------- + '-| FS |-------| FS |-' |Out label| + ------\ ------ --------- | `-------------------. | \--------- .--------------------------------. | session | diff --git a/ldp/ldp_cfg.c b/ldp/ldp_cfg.c index c7b124c..b67abd0 100644 --- a/ldp/ldp_cfg.c +++ b/ldp/ldp_cfg.c @@ -1421,7 +1421,7 @@ mpls_return_enum ldp_cfg_fec_nexthop_set(mpls_cfg_handle handle, mpls_fec * f, n->index = nh->index; mpls_nexthop2ldp_nexthop(n, nh); _ldp_global_add_nexthop(global, nh); - ldp_fec_add_nexthop(fec, nh); + ldp_fec_add_nexthop(global, fec, nh); } else { if (flag & LDP_FEC_NEXTHOP_CFG_BY_INDEX) { ldp_fec_find_nexthop_index(fec, n->index, &nh); diff --git a/ldp/ldp_fec.c b/ldp/ldp_fec.c index 5ee02c2..fb70aba 100644 --- a/ldp/ldp_fec.c +++ b/ldp/ldp_fec.c @@ -87,40 +87,8 @@ mpls_return_enum ldp_fec_insert2(ldp_global *g, ldp_fec * fec) { uint32_t key; uint8_t len; - ldp_nexthop *nh = MPLS_LIST_HEAD(&fec->nh_root); - - while (nh) { - if (nh->type & MPLS_NH_IP) { - ldp_addr *addr = NULL; - if (!(addr = ldp_addr_find(g, &nh->info.ip))) { - if (!(addr = ldp_addr_insert(g, &nh->info.ip))) { - goto ldp_fec_insert2_error; - } - } - - ldp_addr_add_nexthop(addr, nh); - } - - if (nh->type & MPLS_NH_IF) { - ldp_if *iff = NULL; - if (!(iff = ldp_global_find_if_handle(g, nh->info.if_handle))) { - if (!(iff = ldp_if_insert(g, nh->info.if_handle))) { - goto ldp_fec_insert2_error; - } - } - - ldp_if_add_nexthop(iff, nh); - } - if (nh->type & MPLS_NH_OUTSEGMENT) { - ldp_outlabel *out = NULL; - MPLS_ASSERT((out = ldp_global_find_outlabel_handle(g, - nh->info.outsegment_handle))); - - ldp_outlabel_add_nexthop(out, nh); - } - nh = MPLS_LIST_NEXT(&fec->nh_root, nh, _fec); - } + MPLS_ASSERT(MPLS_LIST_EMPTY(&fec->nh_root)); switch(fec->info.type) { case MPLS_FEC_PREFIX: @@ -178,7 +146,6 @@ void ldp_fec_remove(ldp_global *g, mpls_fec *fec) ldp_fec *f = NULL; uint32_t key; uint8_t len; - ldp_nexthop *nh; switch(fec->type) { case MPLS_FEC_PREFIX: @@ -199,23 +166,10 @@ void ldp_fec_remove(ldp_global *g, mpls_fec *fec) if (!f) { return; } - MPLS_REFCNT_RELEASE(f, ldp_fec_delete); - /* if this fec has a IP nexthop unlink it from the corresponding addr node */ + MPLS_ASSERT(MPLS_LIST_EMPTY(&f->nh_root)); - nh = MPLS_LIST_HEAD(&f->nh_root); - while (nh) { - if (nh->type & MPLS_NH_IP) { - ldp_addr_del_nexthop(nh->addr, nh); - } - if (nh->type & MPLS_NH_IF) { - ldp_if_del_nexthop(nh->iff, nh); - } - if (nh->type & MPLS_NH_OUTSEGMENT) { - ldp_outlabel_del_nexthop(nh->outlabel, nh); - } - nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec); - } + MPLS_REFCNT_RELEASE(f, ldp_fec_delete); } mpls_bool ldp_fec_empty(ldp_fec *fec) @@ -257,26 +211,71 @@ mpls_return_enum ldp_fec_find_nexthop_index(ldp_fec *f, int index, return MPLS_FAILURE; } -void ldp_fec_add_nexthop(ldp_fec * f, ldp_nexthop * nh) +mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec * f, + ldp_nexthop * nh) { MPLS_ASSERT(f && nh); MPLS_REFCNT_HOLD(nh); MPLS_LIST_ADD_HEAD(&f->nh_root, nh, _fec, ldp_nexthop); - MPLS_REFCNT_HOLD(f); - nh->fec = f; + ldp_nexthop_add_fec(nh, f); + + if (nh->type & MPLS_NH_IP) { + ldp_addr *addr = NULL; + if (!(addr = ldp_addr_find(g, &nh->info.ip))) { + if (!(addr = ldp_addr_insert(g, &nh->info.ip))) { + goto ldp_fec_add_nexthop_error; + } + } + + ldp_addr_add_nexthop(addr, nh); + } + + if (nh->type & MPLS_NH_IF) { + ldp_if *iff = NULL; + if (!(iff = ldp_global_find_if_handle(g, nh->info.if_handle))) { + if (!(iff = ldp_if_insert(g, nh->info.if_handle))) { + goto ldp_fec_add_nexthop_error; + } + } + + ldp_if_add_nexthop(iff, nh); + } + + if (nh->type & MPLS_NH_OUTSEGMENT) { + ldp_outlabel *out = NULL; + MPLS_ASSERT((out = ldp_global_find_outlabel_handle(g, + nh->info.outsegment_handle))); + + ldp_outlabel_add_nexthop(out, nh); + } + return MPLS_SUCCESS; + +ldp_fec_add_nexthop_error: + + ldp_fec_del_nexthop(f, nh); + return MPLS_FATAL; } void ldp_fec_del_nexthop(ldp_fec * f, ldp_nexthop *nh) { MPLS_ASSERT(f && nh); + if (nh->addr) { + ldp_addr_del_nexthop(nh->addr, nh); + } + if (nh->iff) { + ldp_if_del_nexthop(nh->iff, nh); + } + if (nh->outlabel) { + ldp_outlabel_del_nexthop(nh->outlabel, nh); + } + MPLS_LIST_REMOVE(&f->nh_root, nh, _fec); - nh->fec = NULL; + ldp_nexthop_del_fec(nh); MPLS_REFCNT_RELEASE(nh, ldp_nexthop_delete); - MPLS_REFCNT_RELEASE(f, ldp_fec_delete); } mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f, @@ -294,7 +293,7 @@ mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f, /* * find the info about the next hop for this FEC */ - nh_session = ldp_get_next_hop_session_for_fec2(f,nh); + nh_session = ldp_session_for_nexthop(nh); if (nh_session) { ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f, @@ -524,284 +523,6 @@ Detect_Change_Fec_Next_Hop_20: return MPLS_SUCCESS; } -#if 0 -mpls_return_enum Recognize_New_Fec(ldp_global * g, mpls_fec * f) -{ - ldp_session *peer = NULL; - ldp_session *nh_session = NULL; - ldp_attr *ds_attr = NULL; - ldp_attr *us_attr = NULL; - mpls_bool egress = MPLS_BOOL_FALSE; - ldp_outlabel *out; - - LDP_ENTER(g->user_data, "Recognize_New_Fec"); - - /* - * try to add the fec and the associated next hop to the tree - * if this fails we have no hope of sending a label or a request - */ - if (!ldp_fec_find(g, f)) { - ldp_fec *fec = NULL; - if ((fec = ldp_fec_insert(g,f)) == NULL) { - return MPLS_FATAL; - } - _ldp_global_add_fec(g, fec); - } else { - LDP_PRINT(g->user_data, "Recognize_New_Fec: attempt at ECMP\n"); - MPLS_ASSERT(0); - } - - /* - * find the info about the next hop for this FEC - */ - switch (ldp_get_next_hop_session_for_fec(g, f, &nh_session)) { - case MPLS_SUCCESS: - break; - case MPLS_FAILURE: - /* - * we found the route, but no next hop - */ - egress = MPLS_BOOL_TRUE; - break; - case MPLS_NO_ROUTE: - return MPLS_FAILURE; - default: - MPLS_ASSERT(0); - } - - if (nh_session) { - ds_attr = ldp_attr_find_downstream_state(g, nh_session, f, - LDP_LSP_STATE_MAP_RECV); - if (ds_attr && !ds_attr->outlabel) { - out = ldp_outlabel_create_complete(g, nh_session, ds_attr); - if (!out) { - return MPLS_FAILURE; - } - ds_attr->outlabel = out; - } - } - - /* - * for every peer except the nh hop peer, check to see if we need to - * send a mapping - */ - peer = MPLS_LIST_HEAD(&g->session); - while (peer != NULL) { /* FEC.1 */ - if ((peer->state != LDP_STATE_OPERATIONAL) || - (nh_session && peer->index == nh_session->index)) { - goto next_peer; - } - /* have I already sent a mapping for FEC to peer */ - if ((us_attr = ldp_attr_find_upstream_state(g, peer, f, - LDP_LSP_STATE_MAP_SENT))) { - /* yep, don't send another */ - if (ds_attr) { - if (ldp_inlabel_add_outlabel(g, us_attr->inlabel, - ds_attr->outlabel) != MPLS_SUCCESS) { - return MPLS_FAILURE; - } - } - goto next_peer; - } - - if (peer->oper_distribution_mode == LDP_DISTRIBUTION_UNSOLICITED) { - if (g->lsp_control_mode == LDP_CONTROL_INDEPENDENT) { - us_attr = - ldp_attr_find_upstream_state(g, peer, f, LDP_LSP_STATE_REQ_RECV); - - /* FEC.1.DUI3,4 */ - 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, MPLS_BOOL_FALSE); - } - goto next_peer; - } - } else { - /* - *LDP_CONTROL_ORDERED - */ - - if (ds_attr || egress == MPLS_BOOL_TRUE) { /* FEC.1.DUO2 */ - if (!(us_attr = ldp_attr_create(f))) { - return MPLS_FAILURE; - } - /* FEC.1.DUO3-4 */ - if ((egress == MPLS_BOOL_TRUE) && (mpls_policy_egress_check( - g->user_data, f, &f->nh) == MPLS_BOOL_TRUE)) { - goto next_peer; - } - - if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) != - MPLS_SUCCESS) { - return MPLS_FAILURE; - } - } - } - } - next_peer: - peer = MPLS_LIST_NEXT(&g->session, peer, _global); - } - - if (ds_attr) { /* FEC.2 */ - if (ldp_label_mapping_process(g, nh_session, NULL, NULL, ds_attr, f) == - MPLS_FAILURE) { /* FEC.5 */ - return MPLS_FAILURE; - } - return MPLS_SUCCESS; - } - - /* - * LDP_DISTRIBUTION_ONDEMAND - */ - /* FEC.3 */ - if (nh_session && - nh_session->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND) { - /* assume we're always "request when needed" */ - ds_attr = NULL; - if (ldp_label_request_for_xc(g, nh_session, f, NULL, &ds_attr) == - MPLS_FAILURE) { /* FEC.4 */ - return MPLS_FAILURE; - } - } - - LDP_EXIT(g->user_data, "Recognize_New_Fec"); - - return MPLS_SUCCESS; /* FEC.6 */ -} - -mpls_return_enum Detect_Change_Fec_Next_Hop(ldp_global * g, mpls_fec * f, - ldp_session * nh_old) -{ - ldp_session *peer = NULL; - ldp_attr *us_attr = NULL; - ldp_attr *ds_attr = NULL; - ldp_session *nh_session_new = NULL; - mpls_return_enum result; - - LDP_ENTER(g->user_data, "Detect_Change_Fec_Next_Hop"); - - result = ldp_get_next_hop_session_for_fec(g, f, &nh_session_new); - - /* - * NH 1-5 decide if we need to release an existing mapping - */ - ds_attr = - ldp_attr_find_downstream_state(g, nh_old, f, LDP_LSP_STATE_MAP_RECV); - if (!ds_attr) { /* NH.1 */ - goto Detect_Change_Fec_Next_Hop_6; - } - - if (ds_attr->ingress == MPLS_BOOL_TRUE) { - -#if MPLS_USE_LSR - lsr_ftn ftn; - ftn.outsegment_index = ds_attr->outlabel->info.handle; - memcpy(&ftn.fec, f, sizeof(mpls_fec)); - lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_DEL); -#else - mpls_mpls_fec2out_del(g->mpls_handle, f, &ds_attr->outlabel->info); -#endif - ds_attr->ingress = MPLS_BOOL_FALSE; - ds_attr->outlabel->merge_count--; - } - - if (g->label_retention_mode == LDP_RETENTION_LIBERAL) { /* NH.3 */ - ldp_attr *us_temp; - us_attr = MPLS_LIST_HEAD(&ds_attr->us_attr_root); - while (us_attr) { - /* need to walk the list in such a way as not to - * "pull the rug out from under me self" - */ - us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_attr, _ds_attr); - if (us_attr->state == LDP_LSP_STATE_MAP_SENT) { - ldp_inlabel_del_outlabel(g, us_attr->inlabel); /* NH.2 */ - ldp_attr_del_us2ds(us_attr, ds_attr); - } - us_attr = us_temp; - } - goto Detect_Change_Fec_Next_Hop_6; - } - - ldp_label_release_send(g, nh_old, ds_attr, LDP_NOTIF_NONE); /* NH.4 */ - ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* NH.2,5 */ - -Detect_Change_Fec_Next_Hop_6: - - /* - * NH 6-9 decides is we need to send a label request abort - */ - ds_attr = - ldp_attr_find_downstream_state(g, nh_old, f, LDP_LSP_STATE_REQ_SENT); - if (ds_attr) { /* NH.6 */ - if (g->label_retention_mode != LDP_RETENTION_CONSERVATIVE) { /* NH.7 */ - /* NH.8,9 */ - if (ldp_label_abort_send(g, nh_old, ds_attr) != MPLS_SUCCESS) { - return MPLS_FAILURE; - } - } - } - - /* - * NH 10-12 decides if we can use a mapping from our database - */ - if (result != MPLS_SUCCESS) { - goto Detect_Change_Fec_Next_Hop_16; - } - - ds_attr = - ldp_attr_find_downstream_state(g, nh_session_new, f, LDP_LSP_STATE_MAP_RECV); - if (!ds_attr) { /* NH.11 */ - goto Detect_Change_Fec_Next_Hop_13; - } - - if (ldp_label_mapping_process(g, nh_session_new, NULL, NULL, ds_attr, f) != - MPLS_SUCCESS) { /* NH.12 */ - return MPLS_FAILURE; - } - goto Detect_Change_Fec_Next_Hop_20; - -Detect_Change_Fec_Next_Hop_13: - - /* - * NH 13-15 decides if we need to make a label request - */ - if (nh_session_new->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND && - g->label_retention_mode == LDP_RETENTION_CONSERVATIVE) { - /* NH.14-15 */ - if (ldp_label_request_for_xc(g, nh_session_new, f, NULL, &ds_attr) != - MPLS_SUCCESS) { - return MPLS_FAILURE; - } - } - goto Detect_Change_Fec_Next_Hop_20; - -Detect_Change_Fec_Next_Hop_16: - - peer = MPLS_LIST_HEAD(&g->session); - while (peer) { - if (peer->state == LDP_STATE_OPERATIONAL) { - us_attr = ldp_attr_find_upstream_state(g, peer, f, - LDP_LSP_STATE_MAP_SENT); - 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, MPLS_BOOL_FALSE); - return MPLS_FAILURE; - } - } - } - peer = MPLS_LIST_NEXT(&g->session, peer, _global); - } - -Detect_Change_Fec_Next_Hop_20: - - LDP_EXIT(g->user_data, "Detect_Change_Fec_Next_Hop"); - - return MPLS_SUCCESS; -} -#endif - ldp_fec *ldp_fec_create() { ldp_fec *fec = (ldp_fec *) mpls_malloc(sizeof(ldp_fec)); @@ -906,3 +627,4 @@ static uint32_t _ldp_fec_get_next_index() return retval; } + diff --git a/ldp/ldp_fec.h b/ldp/ldp_fec.h index a746df7..15edeff 100644 --- a/ldp/ldp_fec.h +++ b/ldp/ldp_fec.h @@ -18,7 +18,8 @@ extern ldp_fec *ldp_fec_insert(ldp_global *g, mpls_fec * fec); extern mpls_return_enum ldp_fec_insert2(ldp_global *g, ldp_fec * fec); extern void ldp_fec_remove(ldp_global *g, mpls_fec *fec); extern mpls_bool ldp_fec_empty(ldp_fec *fec); -extern void ldp_fec_add_nexthop(ldp_fec *f, ldp_nexthop *n); +extern mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec *f, + ldp_nexthop *n); extern void ldp_fec_del_nexthop(ldp_fec *f, ldp_nexthop *n); extern ldp_fec *ldp_fec_create(); extern ldp_fec *ldp_fec_create_prefix(mpls_inet_addr * prefix, int prefix_len); diff --git a/ldp/ldp_nexthop.c b/ldp/ldp_nexthop.c index 479a71c..ae6ab65 100644 --- a/ldp/ldp_nexthop.c +++ b/ldp/ldp_nexthop.c @@ -106,6 +106,20 @@ void ldp_nexthop_del_outlabel(ldp_nexthop * nh) nh->outlabel = NULL; } +void ldp_nexthop_add_fec(ldp_nexthop *nh, ldp_fec *f) +{ + MPLS_ASSERT(nh && f); + MPLS_REFCNT_HOLD(f); + nh->fec = f; +} + +void ldp_nexthop_del_fec(ldp_nexthop * nh) +{ + MPLS_ASSERT(nh); + MPLS_REFCNT_RELEASE(nh->fec, ldp_fec_delete); + nh->fec = NULL; +} + void mpls_nexthop2ldp_nexthop(mpls_nexthop *mnh, ldp_nexthop *lnh) { lnh->type = mnh->type; diff --git a/ldp/ldp_nexthop.h b/ldp/ldp_nexthop.h index 27e5e3c..4e142d6 100644 --- a/ldp/ldp_nexthop.h +++ b/ldp/ldp_nexthop.h @@ -19,6 +19,8 @@ extern void ldp_nexthop_add_addr(ldp_nexthop * nh, ldp_addr * a); extern void ldp_nexthop_del_addr(ldp_nexthop * nh); extern void ldp_nexthop_add_outlabel(ldp_nexthop * nh, ldp_outlabel * o); extern void ldp_nexthop_del_outlabel(ldp_nexthop * nh); +extern void ldp_nexthop_add_fec(ldp_nexthop * nh, ldp_fec * f); +extern void ldp_nexthop_del_fec(ldp_nexthop * nh); extern void mpls_nexthop2ldp_nexthop(mpls_nexthop *mnh, ldp_nexthop *lnh); -- 2.11.4.GIT