From b79afeb62ba872e393537d3e1a6453a231eb16da Mon Sep 17 00:00:00 2001 From: "James R. Leu" Date: Wed, 8 Nov 2006 22:16:51 -0600 Subject: [PATCH] Results of major ATTR rework: - A majority of the changes are related to converting ATTRs to be "self installing/deleting" like ADDRs FECs and IFs - we correctly hold temp ATTRs and FECs used as part of the message processing engine (ldp_state_funcs.c) - we now differenciate between FECs added to the tree due to protocol messages and FECs added to the tree from the routing subsystem (ldp_cfg.c, mpls_struct.h, ldp_struct.h) [git-p4: depot-paths = "//depot/ldp-portable/": change = 1529] --- common/mpls_struct.h | 1 + ldp/ldp_addr.c | 2 +- ldp/ldp_attr.c | 102 ++++++++++++++++++++++------------------------- ldp/ldp_attr.h | 10 ++--- ldp/ldp_cfg.c | 16 ++++++-- ldp/ldp_fec.c | 20 +++++++--- ldp/ldp_global.c | 6 +-- ldp/ldp_inlabel.c | 10 ++--- ldp/ldp_inlabel.h | 4 +- ldp/ldp_label_mapping.c | 16 ++++++-- ldp/ldp_label_rel_with.c | 2 +- ldp/ldp_label_request.c | 3 +- ldp/ldp_outlabel.c | 4 +- ldp/ldp_outlabel.h | 2 +- ldp/ldp_session.c | 4 +- ldp/ldp_session.h | 2 +- ldp/ldp_state_funcs.c | 41 +++++++++++++------ ldp/ldp_struct.h | 1 + 18 files changed, 142 insertions(+), 104 deletions(-) diff --git a/common/mpls_struct.h b/common/mpls_struct.h index 5612fef..a04369b 100644 --- a/common/mpls_struct.h +++ b/common/mpls_struct.h @@ -207,6 +207,7 @@ typedef struct mpls_fec { } u; /* only used during gets */ + mpls_bool is_route; uint32_t index; } mpls_fec; diff --git a/ldp/ldp_addr.c b/ldp/ldp_addr.c index 9e4608e..323cb41 100644 --- a/ldp/ldp_addr.c +++ b/ldp/ldp_addr.c @@ -97,7 +97,7 @@ ldp_addr *ldp_addr_insert(ldp_global *g, mpls_inet_addr * address) mpls_return_enum ldp_addr_insert2(ldp_global *g, ldp_addr *addr) { - LDP_ENTER(g->user_data, "ldp_addr_insert2: 0x%08", addr->address.u.ipv4); + LDP_ENTER(g->user_data, "ldp_addr_insert2: 0x%08x", addr->address.u.ipv4); if (mpls_tree_insert(g->addr_tree, addr->address.u.ipv4, 32, (void *)addr) != MPLS_SUCCESS) { LDP_EXIT(g->user_data, "ldp_addr_insert2-error"); diff --git a/ldp/ldp_attr.c b/ldp/ldp_attr.c index b1746fc..391e133 100644 --- a/ldp/ldp_attr.c +++ b/ldp/ldp_attr.c @@ -42,7 +42,7 @@ static ldp_fs *_ldp_fs_create(ldp_session * s); static void _ldp_fs_delete(ldp_fs * fs); static ldp_attr *_ldp_fs_find_attr(ldp_fs * fs, ldp_attr * a); static mpls_return_enum _ldp_fs_add_attr(ldp_fs * fs, ldp_attr * a); -static mpls_bool _ldp_fs_del_attr(ldp_fs * fs, ldp_attr * a); +static mpls_bool _ldp_fs_del_attr(ldp_global *g, ldp_fs * fs, ldp_attr * a); static uint32_t _ldp_attr_get_next_index(); static uint32_t _ldp_attr_next_index = 1; @@ -68,16 +68,16 @@ mpls_bool ldp_attr_us_partof_ds(ldp_attr * us, ldp_attr * ds) return MPLS_BOOL_FALSE; } -void ldp_attr_del_us2ds(ldp_attr * us, ldp_attr * ds) +void ldp_attr_del_us2ds(ldp_global *g, ldp_attr * us, ldp_attr * ds) { if (!us || !ds) { return; } if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) { us->ds_attr = NULL; - MPLS_REFCNT_RELEASE(ds, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, ds, ldp_attr_delete); MPLS_LIST_REMOVE(&ds->us_attr_root, us, _ds_attr); - MPLS_REFCNT_RELEASE(us, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, us, ldp_attr_delete); } else { MPLS_ASSERT(0); } @@ -279,10 +279,9 @@ void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, MPLS_ASSERT(out->merge_count == 0); ldp_attr_del_outlabel(g, attr); ldp_session_del_outlabel(g, session, out); -// _ldp_global_del_outlabel(g, out); } while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) { - ldp_attr_del_us2ds(us_temp, attr); + ldp_attr_del_us2ds(g, us_temp, attr); } ldp_attr_delete_downstream(g, session, attr); break; @@ -290,15 +289,12 @@ void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, in = attr->inlabel; out = in->outlabel; - if (out != NULL) { - if (in->reuse_count == 1) { - ldp_inlabel_del_outlabel(g, in); - } + if (in->reuse_count == 1 && out) { + ldp_inlabel_del_outlabel(g, in); } - ldp_attr_del_inlabel(g, attr); ldp_attr_delete_upstream(g, session, attr); - ldp_attr_del_us2ds(attr, attr->ds_attr); + ldp_attr_del_us2ds(g, attr, attr->ds_attr); ldp_session_del_inlabel(g, session, in); break; case LDP_LSP_STATE_ABORT_SENT: @@ -307,7 +303,7 @@ void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, case LDP_LSP_STATE_WITH_SENT: case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT: { - ldp_attr_del_us2ds(attr, attr->ds_attr); + ldp_attr_del_us2ds(g, attr, attr->ds_attr); ldp_attr_delete_upstream(g, session, attr); break; } @@ -318,7 +314,7 @@ void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV: { while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) { - ldp_attr_del_us2ds(us_temp, attr); + ldp_attr_del_us2ds(g, us_temp, attr); } ldp_attr_delete_downstream(g, session, attr); break; @@ -326,7 +322,7 @@ void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, } } -ldp_attr *ldp_attr_create(mpls_fec * fec) +ldp_attr *ldp_attr_create(ldp_global *g, mpls_fec * fec) { ldp_attr *a = (ldp_attr *) mpls_malloc(sizeof(ldp_attr)); @@ -347,14 +343,17 @@ ldp_attr *ldp_attr_create(mpls_fec * fec) a->fecTlv.numberFecElements = 1; a->fecTlvExists = 1; } + _ldp_global_add_attr(g, a); } return a; } -void ldp_attr_delete(ldp_attr * a) +void ldp_attr_delete(ldp_global *g, ldp_attr * a) { fprintf(stderr, "attr delete: %p\n", a); + MPLS_REFCNT_ASSERT(a, 0); MPLS_ASSERT(a->in_tree == MPLS_BOOL_FALSE); + _ldp_global_del_attr(g, a); mpls_free(a); } @@ -396,12 +395,12 @@ void ldp_attr2ldp_attr(ldp_attr * a, ldp_attr * b, uint32_t flag) } } -mpls_return_enum ldp_attr_add_inlabel(ldp_attr * a, ldp_inlabel * i) +mpls_return_enum ldp_attr_add_inlabel(ldp_global *g, ldp_attr * a, ldp_inlabel * i) { if (a && i) { MPLS_REFCNT_HOLD(i); a->inlabel = i; - _ldp_inlabel_add_attr(i, a); + _ldp_inlabel_add_attr(g, i, a); return MPLS_SUCCESS; } return MPLS_FAILURE; @@ -410,7 +409,7 @@ mpls_return_enum ldp_attr_add_inlabel(ldp_attr * a, ldp_inlabel * i) mpls_return_enum ldp_attr_del_inlabel(ldp_global *g, ldp_attr * a) { if (a && a->inlabel) { - _ldp_inlabel_del_attr(a->inlabel, a); + _ldp_inlabel_del_attr(g, a->inlabel, a); MPLS_REFCNT_RELEASE2(g, a->inlabel, ldp_inlabel_delete); a->inlabel = NULL; return MPLS_SUCCESS; @@ -432,7 +431,7 @@ mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o) mpls_return_enum ldp_attr_del_outlabel(ldp_global * g, ldp_attr * a) { if (a && a->outlabel) { - _ldp_outlabel_del_attr(a->outlabel); + _ldp_outlabel_del_attr(g, a->outlabel); MPLS_REFCNT_RELEASE2(g, a->outlabel, ldp_outlabel_delete); a->outlabel = NULL; return MPLS_SUCCESS; @@ -451,10 +450,10 @@ mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s) return MPLS_FAILURE; } -mpls_return_enum ldp_attr_del_session(ldp_attr * a) +mpls_return_enum ldp_attr_del_session(ldp_global *g, ldp_attr * a) { if (a && a->session) { - _ldp_session_del_attr(a->session, a); + _ldp_session_del_attr(g, a->session, a); MPLS_REFCNT_RELEASE(a->session, ldp_session_delete); a->session = NULL; return MPLS_SUCCESS; @@ -586,7 +585,6 @@ mpls_return_enum ldp_attr_insert_upstream2(ldp_global * g, ldp_session * s, ldp_attr_add_fec(a, f); retval = _ldp_fs_add_attr(fs, a); - _ldp_global_add_attr(g, a); a->in_tree = MPLS_BOOL_TRUE; return retval; } @@ -624,7 +622,6 @@ mpls_return_enum ldp_attr_insert_downstream2(ldp_global * g, ldp_session * s, ldp_attr_add_fec(a, f); retval = _ldp_fs_add_attr(fs, a); - _ldp_global_add_attr(g, a); a->in_tree = MPLS_BOOL_TRUE; return retval; } @@ -727,25 +724,26 @@ void ldp_attr_delete_upstream(ldp_global * g, ldp_session * s, ldp_attr * a) MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE); - if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE)) == NULL) { - /* we couldn't get the node from the tree! */ - return; - } + MPLS_REFCNT_HOLD(a); - /* find the upstream fs for this session */ - if ((fs = _ldp_fec_find_fs_us(fnode, s, MPLS_BOOL_FALSE)) == NULL) { - /* this session isn't in the list */ - return; + /* find the fec node in the tree */ + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) { + /* find the upstream fs for this session, on the fec */ + if ((fs = _ldp_fec_find_fs_us(fnode, s, MPLS_BOOL_FALSE))) { + /* remove this attr from the fs, if this was the last + * attr on the fs, then remove the fs from the fec node + */ + if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) { + _ldp_fec_del_fs_us(fnode, fs); + } + } } - ldp_attr_del_session(a); + ldp_attr_del_session(g, a); ldp_attr_del_fec(g, a); - if (_ldp_fs_del_attr(fs, a) == MPLS_BOOL_TRUE) { - _ldp_fec_del_fs_us(fnode, fs); - } a->in_tree = MPLS_BOOL_FALSE; - _ldp_global_del_attr(g, a); + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); } void ldp_attr_delete_downstream(ldp_global * g, ldp_session * s, ldp_attr * a) @@ -755,25 +753,21 @@ void ldp_attr_delete_downstream(ldp_global * g, ldp_session * s, ldp_attr * a) MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE); - if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE)) == NULL) { - /* we couldn't get the node from the tree! */ - return; - } - - /* find the downstream fs for this session */ - if ((fs = _ldp_fec_find_fs_ds(fnode, s, MPLS_BOOL_FALSE)) == NULL) { - /* this session isn't in the list */ - return; + MPLS_REFCNT_HOLD(a); + /* see ldp_attr_delete_upstream for more info */ + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) { + if ((fs = _ldp_fec_find_fs_ds(fnode, s, MPLS_BOOL_FALSE))) { + if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) { + _ldp_fec_del_fs_ds(fnode, fs); + } + } } - ldp_attr_del_session(a); + ldp_attr_del_session(g, a); ldp_attr_del_fec(g, a); - if (_ldp_fs_del_attr(fs, a) == MPLS_BOOL_TRUE) { - _ldp_fec_del_fs_ds(fnode, fs); - } a->in_tree = MPLS_BOOL_FALSE; - _ldp_global_del_attr(g, a); + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); } void ldp_attr2mpls_label_struct(ldp_attr * a, mpls_label_struct * l) @@ -982,7 +976,7 @@ static ldp_fs *_ldp_fs_create(ldp_session * s) static void _ldp_fs_delete(ldp_fs * fs) { - LDP_PRINT(g->user_data,"fs delete\n"); + fprintf(stderr, "fs delete %p\n", fs); if (fs->session != NULL) { MPLS_REFCNT_RELEASE(fs->session, ldp_session_delete); } @@ -1012,13 +1006,13 @@ static mpls_return_enum _ldp_fs_add_attr(ldp_fs * fs, ldp_attr * a) return MPLS_SUCCESS; } -static mpls_bool _ldp_fs_del_attr(ldp_fs * fs, ldp_attr * a) +static mpls_bool _ldp_fs_del_attr(ldp_global *g, ldp_fs * fs, ldp_attr * a) { ldp_attr *ptr = _ldp_fs_find_attr(fs, a); if (ptr != NULL) { MPLS_LIST_REMOVE(&fs->attr_root, ptr, _fs); - MPLS_REFCNT_RELEASE(ptr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, ptr, ldp_attr_delete); } if (MPLS_LIST_HEAD(&fs->attr_root) == NULL) return MPLS_BOOL_TRUE; diff --git a/ldp/ldp_attr.h b/ldp/ldp_attr.h index f9cef3a..9bed617 100644 --- a/ldp/ldp_attr.h +++ b/ldp/ldp_attr.h @@ -28,12 +28,12 @@ extern void ldp_attr_add_fec(ldp_attr *a, ldp_fec *fec); extern void ldp_attr_del_fec(ldp_global *g, ldp_attr *a); extern void ldp_attr_add_us2ds(ldp_attr * us, ldp_attr * ds); -extern void ldp_attr_del_us2ds(ldp_attr * us, ldp_attr * ds); +extern void ldp_attr_del_us2ds(ldp_global *g, ldp_attr * us, ldp_attr * ds); extern mpls_bool ldp_attr_us_partof_ds(ldp_attr * us, ldp_attr * ds); 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 ldp_attr *ldp_attr_create(ldp_global * g, mpls_fec * fec); +extern void ldp_attr_delete(ldp_global * g, 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, mpls_bool); @@ -60,10 +60,10 @@ extern ldp_attr *ldp_attr_find_upstream_map_in_labelspace(ldp_fec *f, extern mpls_return_enum ldp_attr_del_outlabel(ldp_global * g,ldp_attr * a); extern mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o); -extern mpls_return_enum ldp_attr_add_inlabel(ldp_attr * a, ldp_inlabel * i); +extern mpls_return_enum ldp_attr_add_inlabel(ldp_global * g, ldp_attr * a, ldp_inlabel * i); extern mpls_return_enum ldp_attr_del_inlabel(ldp_global * g,ldp_attr * a); extern mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s); -extern mpls_return_enum ldp_attr_del_session(ldp_attr * a); +extern mpls_return_enum ldp_attr_del_session(ldp_global *g, ldp_attr * a); extern mpls_bool ldp_attr_is_equal(ldp_attr * a, ldp_attr * b, uint32_t flag); extern ldp_attr_list *ldp_attr_find_upstream_all2(ldp_global * g, diff --git a/ldp/ldp_cfg.c b/ldp/ldp_cfg.c index eab1149..3a1af45 100644 --- a/ldp/ldp_cfg.c +++ b/ldp/ldp_cfg.c @@ -1234,6 +1234,7 @@ mpls_return_enum ldp_cfg_fec_get(mpls_cfg_handle handle, mpls_fec * f, memcpy(f, &fec->info, sizeof(mpls_fec)); f->index = fec->index; + f->is_route = fec->is_route; retval = MPLS_SUCCESS; ldp_cfg_fec_get_end: @@ -1307,9 +1308,16 @@ mpls_return_enum ldp_cfg_fec_set(mpls_cfg_handle handle, mpls_fec * f, mpls_lock_get(global->global_lock); /* LOCK */ if (flag & LDP_CFG_ADD) { - if (ldp_fec_find(global, f) || (fec = ldp_fec_create(global, f)) == NULL) { - goto ldp_cfg_fec_set_end; + if ((fec = ldp_fec_find(global, f))) { + if (fec->is_route == MPLS_BOOL_TRUE) { + goto ldp_cfg_fec_set_end; + } + } else { + if ((fec = ldp_fec_create(global, f)) == NULL) { + goto ldp_cfg_fec_set_end; + } } + fec->is_route = MPLS_BOOL_TRUE; MPLS_REFCNT_HOLD(fec); f->index = fec->index; } else { @@ -1332,6 +1340,9 @@ mpls_return_enum ldp_cfg_fec_set(mpls_cfg_handle handle, mpls_fec * f, if (!MPLS_LIST_EMPTY(&fec->nh_root)) { goto ldp_cfg_fec_set_end; } + + fec->is_route = MPLS_BOOL_FALSE; + /* * we hold the last refcnt, this should result in a call to * ldp_fec_delete @@ -1345,7 +1356,6 @@ ldp_cfg_fec_set_end: mpls_lock_release(global->global_lock); /* UNLOCK */ LDP_EXIT(global->user_data, "ldp_cfg_fec_set"); - return retval; } diff --git a/ldp/ldp_fec.c b/ldp/ldp_fec.c index 49b107f..30de159 100644 --- a/ldp/ldp_fec.c +++ b/ldp/ldp_fec.c @@ -147,6 +147,7 @@ ldp_fec *ldp_fec_create(ldp_global *g, mpls_fec *f) MPLS_LIST_INIT(&fec->fs_root_us, ldp_fs); MPLS_LIST_INIT(&fec->fs_root_ds, ldp_fs); fec->index = _ldp_fec_get_next_index(); + fec->is_route = MPLS_BOOL_FALSE; mpls_fec2ldp_fec(f,fec); _ldp_global_add_fec(g, fec); @@ -280,7 +281,6 @@ void ldp_fec_del_nexthop(ldp_global *g, ldp_fec * f, ldp_nexthop *nh) MPLS_LIST_REMOVE(&f->nh_root, nh, _fec); ldp_nexthop_del_fec(g, nh); - MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete); } @@ -354,7 +354,7 @@ mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f, /* FEC.1.DUI3,4 */ if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) != MPLS_SUCCESS) { - if (!us_attr->in_tree) { + if (us_attr->in_tree) { ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); } goto next_peer; @@ -458,7 +458,7 @@ mpls_return_enum ldp_fec_process_change(ldp_global * g, ldp_fec * f, 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); + ldp_attr_del_us2ds(g, us_attr, ds_attr); } us_attr = us_temp; } @@ -526,9 +526,17 @@ Detect_Change_Fec_Next_Hop_16: us_attr = ldp_attr_find_upstream_state2(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); + mpls_return_enum retval; + MPLS_REFCNT_HOLD(us_attr); + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); + retval = ldp_label_withdraw_send(g, peer, us_attr, LDP_NOTIF_NONE); + MPLS_REFCNT_RELEASE2(g, us_attr, ldp_attr_delete); + if (retval != MPLS_SUCCESS) { /* NH.18 */ + /* + * I think it is best to exit out immediatly with an error + * and let the caller do something about it, the only real + * option is a global reset of LDP + */ return MPLS_FAILURE; } } diff --git a/ldp/ldp_global.c b/ldp/ldp_global.c index b8b650a..4d19290 100644 --- a/ldp/ldp_global.c +++ b/ldp/ldp_global.c @@ -391,7 +391,7 @@ fprintf(stderr,"Left over ADDR: %p address %08x\n", ap, ap->address.u.ipv4); atp = MPLS_LIST_HEAD(&g->attr); while (atp != NULL) { -fprintf(stderr,"Left over ATTR: %p\n", atp); +fprintf(stderr,"Left over ATTR: %p %d\n", atp, atp->_refcnt); natp = MPLS_LIST_NEXT(&g->attr, atp, _global); // _ldp_global_del_attr(g, atp); atp = natp; @@ -426,7 +426,6 @@ void _ldp_global_add_attr(ldp_global * g, ldp_attr * a) ldp_attr *ap = NULL; MPLS_ASSERT(g && a); - MPLS_REFCNT_HOLD(a); ap = MPLS_LIST_HEAD(&g->attr); while (ap != NULL) { if (ap->index > a->index) { @@ -442,7 +441,6 @@ void _ldp_global_del_attr(ldp_global * g, ldp_attr * a) { MPLS_ASSERT(g && a); MPLS_LIST_REMOVE(&g->attr, a, _global); - MPLS_REFCNT_RELEASE(a, ldp_attr_delete); } void _ldp_global_add_peer(ldp_global * g, ldp_peer * p) @@ -1247,7 +1245,7 @@ void _ldp_global_add_fec(ldp_global * g, ldp_fec * f) * should increment the ref are those (nh, addr, label etc), not global * nor inserting into the tree. I also added this comment in * ldp_fec_create() - MPLS_REFCNT_HOLD(f); + * MPLS_REFCNT_HOLD(f); */ fp = MPLS_LIST_HEAD(&g->fec); while (fp != NULL) { diff --git a/ldp/ldp_inlabel.c b/ldp/ldp_inlabel.c index 4dba774..aeb6e1b 100644 --- a/ldp/ldp_inlabel.c +++ b/ldp/ldp_inlabel.c @@ -89,7 +89,7 @@ ldp_inlabel *ldp_inlabel_create_complete(ldp_global * g, ldp_session * s, } mpls_label_struct2ldp_attr(&in->info.label, a); - ldp_attr_add_inlabel(a, in); + ldp_attr_add_inlabel(g, a, in); } return in; } @@ -150,7 +150,7 @@ mpls_return_enum ldp_inlabel_del_outlabel(ldp_global *g, ldp_inlabel * i) return MPLS_SUCCESS; } -mpls_return_enum _ldp_inlabel_add_attr(ldp_inlabel * i, ldp_attr * a) +mpls_return_enum _ldp_inlabel_add_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a) { MPLS_ASSERT(i && a); @@ -159,15 +159,15 @@ mpls_return_enum _ldp_inlabel_add_attr(ldp_inlabel * i, ldp_attr * a) i->reuse_count++; return MPLS_SUCCESS; } - MPLS_REFCNT_RELEASE(a, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); return MPLS_FAILURE; } -void _ldp_inlabel_del_attr(ldp_inlabel * i, ldp_attr * a) +void _ldp_inlabel_del_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a) { MPLS_ASSERT(i && a); mpls_link_list_remove_data(&i->attr_root, a); - MPLS_REFCNT_RELEASE(a, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); i->reuse_count--; } diff --git a/ldp/ldp_inlabel.h b/ldp/ldp_inlabel.h index e84ea77..d9b09f6 100644 --- a/ldp/ldp_inlabel.h +++ b/ldp/ldp_inlabel.h @@ -30,7 +30,7 @@ extern void _ldp_inlabel_del_session(ldp_inlabel * i, ldp_session * s); extern uint32_t _ldp_inlabel_get_next_index(); -extern mpls_return_enum _ldp_inlabel_add_attr(ldp_inlabel * i, ldp_attr * a); -extern void _ldp_inlabel_del_attr(ldp_inlabel * i, ldp_attr * a); +extern mpls_return_enum _ldp_inlabel_add_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a); +extern void _ldp_inlabel_del_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a); #endif diff --git a/ldp/ldp_label_mapping.c b/ldp/ldp_label_mapping.c index 6b227a5..c74b56b 100644 --- a/ldp/ldp_label_mapping.c +++ b/ldp/ldp_label_mapping.c @@ -58,9 +58,10 @@ mpls_return_enum ldp_label_mapping_with_xc(ldp_global * g, ldp_session * s, } if (!(*us_attr)) { - if (!((*us_attr) = ldp_attr_create(&f->info))) { + if (!((*us_attr) = ldp_attr_create(g, &f->info))) { return MPLS_FAILURE; } + MPLS_REFCNT_HOLD((*us_attr)); created = MPLS_BOOL_TRUE; } if ((!ds_attr) && (egress_flag == MPLS_BOOL_TRUE)) { @@ -74,15 +75,22 @@ mpls_return_enum ldp_label_mapping_with_xc(ldp_global * g, ldp_session * s, result = ldp_label_mapping_send(g, s, f, (*us_attr), ds_attr); if (result != MPLS_SUCCESS) { if (created == MPLS_BOOL_TRUE) { - ldp_attr_delete(*us_attr); + /* this should result in it being deleted, since we're + * the only one who should be holding a ref + */ + MPLS_REFCNT_RELEASE2(g, (*us_attr), ldp_attr_delete); } return result; } if (created == MPLS_BOOL_TRUE) { result = ldp_attr_insert_upstream2(g, s, (*us_attr), f); + /* now that it is in the tree (supposedly) we can safely + * release our ref, if it is not in the tree, then this should + * result in it beig deleted + */ + MPLS_REFCNT_RELEASE2(g, (*us_attr), ldp_attr_delete); if (result != MPLS_SUCCESS) { - ldp_attr_delete(*us_attr); return result; } } @@ -558,7 +566,7 @@ mpls_return_enum ldp_label_mapping_send(ldp_global * g, ldp_session * s, LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING, "Using an existing label\n"); in = existing->inlabel; - ldp_attr_add_inlabel(us_attr, in); + ldp_attr_add_inlabel(g, us_attr, in); } else { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING, "Generating a label\n"); diff --git a/ldp/ldp_label_rel_with.c b/ldp/ldp_label_rel_with.c index db002e8..7c67ad4 100644 --- a/ldp/ldp_label_rel_with.c +++ b/ldp/ldp_label_rel_with.c @@ -285,7 +285,7 @@ mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s, LWd_13: if (ds_attr) { - MPLS_REFCNT_RELEASE(ds_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, ds_attr, ldp_attr_delete); } LDP_EXIT(g->user_data, "ldp_label_withdraw_process"); diff --git a/ldp/ldp_label_request.c b/ldp/ldp_label_request.c index 82c88bf..fd8e675 100644 --- a/ldp/ldp_label_request.c +++ b/ldp/ldp_label_request.c @@ -32,9 +32,10 @@ mpls_return_enum ldp_label_request_for_xc(ldp_global * g, ldp_session * s, LDP_ENTER(g->user_data, "ldp_label_request_for_xc"); if (!(*ds_attr)) { - if (!((*ds_attr) = ldp_attr_create(fec))) { + if (!((*ds_attr) = ldp_attr_create(g, fec))) { return MPLS_FATAL; } + MPLS_REFCNT_HOLD((*ds_attr)); } Prepare_Label_Request_Attributes(g, s, fec, (*ds_attr), us_attr); (*ds_attr)->state = LDP_LSP_STATE_REQ_SENT; diff --git a/ldp/ldp_outlabel.c b/ldp/ldp_outlabel.c index a982a30..266a5b7 100644 --- a/ldp/ldp_outlabel.c +++ b/ldp/ldp_outlabel.c @@ -128,10 +128,10 @@ void _ldp_outlabel_add_attr(ldp_outlabel * o, ldp_attr * a) o->attr = a; } -void _ldp_outlabel_del_attr(ldp_outlabel * o) +void _ldp_outlabel_del_attr(ldp_global *g, ldp_outlabel * o) { MPLS_ASSERT(o && o->attr); - MPLS_REFCNT_RELEASE(o->attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, o->attr, ldp_attr_delete); o->attr = NULL; } diff --git a/ldp/ldp_outlabel.h b/ldp/ldp_outlabel.h index e719c2b..8dc6d0b 100644 --- a/ldp/ldp_outlabel.h +++ b/ldp/ldp_outlabel.h @@ -25,7 +25,7 @@ extern void _ldp_outlabel_add_session(ldp_outlabel *, ldp_session *); extern void _ldp_outlabel_del_session(ldp_outlabel * o); extern void _ldp_outlabel_add_attr(ldp_outlabel * o, ldp_attr * a); -extern void _ldp_outlabel_del_attr(ldp_outlabel * o); +extern void _ldp_outlabel_del_attr(ldp_global *g, ldp_outlabel * o); extern void ldp_outlabel_add_nexthop(ldp_outlabel * o, ldp_nexthop * nh); extern void ldp_outlabel_del_nexthop(ldp_global *g, ldp_outlabel * o, ldp_nexthop * nh); diff --git a/ldp/ldp_session.c b/ldp/ldp_session.c index bdc715c..3473e75 100644 --- a/ldp/ldp_session.c +++ b/ldp/ldp_session.c @@ -517,11 +517,11 @@ void _ldp_session_add_attr(ldp_session * s, ldp_attr * a) MPLS_LIST_ADD_HEAD(&s->attr_root, a, _session, ldp_attr); } -void _ldp_session_del_attr(ldp_session * s, ldp_attr * a) +void _ldp_session_del_attr(ldp_global *g, ldp_session * s, ldp_attr * a) { MPLS_ASSERT(s && a); MPLS_LIST_REMOVE(&s->attr_root, a, _session); - MPLS_REFCNT_RELEASE(a, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); } mpls_return_enum ldp_session_add_addr(ldp_global *g, ldp_session * s, diff --git a/ldp/ldp_session.h b/ldp/ldp_session.h index 46739c8..b697ea7 100644 --- a/ldp/ldp_session.h +++ b/ldp/ldp_session.h @@ -25,7 +25,7 @@ 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); +extern void _ldp_session_del_attr(ldp_global *g, ldp_session * s, ldp_attr * a); extern void ldp_session_add_outlabel(ldp_session * s, ldp_outlabel * o); extern void ldp_session_del_outlabel(ldp_global * g, ldp_session * s, ldp_outlabel * o); diff --git a/ldp/ldp_state_funcs.c b/ldp/ldp_state_funcs.c index 6718fae..885d557 100644 --- a/ldp/ldp_state_funcs.c +++ b/ldp/ldp_state_funcs.c @@ -289,7 +289,7 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, for (i = 0; i < rw->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&rw->fecTlv, i, &fec); - if (!(r_attr = ldp_attr_create(&fec))) { + if (!(r_attr = ldp_attr_create(g, &fec))) { goto ldp_state_process_error; } @@ -297,9 +297,12 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, rel_with2attr(rw, r_attr); f = ldp_fec_find2(g, &fec); + MPLS_REFCNT_HOLD(f); + retval = ldp_label_withdraw_process(g, s, a, e, r_attr, f); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); if (retval != MPLS_SUCCESS) break; } @@ -312,7 +315,7 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, for (i = 0; i < rw->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&rw->fecTlv, i, &fec); - if (!(r_attr = ldp_attr_create(&fec))) { + if (!(r_attr = ldp_attr_create(g, &fec))) { goto ldp_state_process_error; } @@ -320,9 +323,12 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, rel_with2attr(rw, r_attr); f = ldp_fec_find2(g, &fec); + MPLS_REFCNT_HOLD(f); + retval = ldp_label_release_process(g, s, a, e, r_attr, f); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); if (retval != MPLS_SUCCESS) break; } @@ -337,7 +343,7 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, for (i = 0; i < req->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&req->fecTlv, i, &fec); - if (!(r_attr = ldp_attr_create(&fec))) { + if (!(r_attr = ldp_attr_create(g, &fec))) { goto ldp_state_process_error; } @@ -345,9 +351,12 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, req2attr(req, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC); f = ldp_fec_find2(g, &fec); + MPLS_REFCNT_HOLD(f); + retval = ldp_label_request_process(g, s, a, e, r_attr, f); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); if (retval != MPLS_SUCCESS) break; } @@ -360,16 +369,20 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, for (i = 0; i < map->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&map->fecTlv, i, &fec); - if (!(r_attr = ldp_attr_create(&fec))) { + if (!(r_attr = ldp_attr_create(g, &fec))) { goto ldp_state_process_error; } + MPLS_REFCNT_HOLD(r_attr); map2attr(map, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC); f = ldp_fec_find2(g, &fec); + MPLS_REFCNT_HOLD(f); + retval = ldp_label_mapping_process(g, s, a, e, r_attr, f); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); if (retval != MPLS_SUCCESS) break; } @@ -382,16 +395,20 @@ mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a, for (i = 0; i < abrt->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&abrt->fecTlv, i, &fec); - if (!(r_attr = ldp_attr_create(&fec))) { + if (!(r_attr = ldp_attr_create(g, &fec))) { goto ldp_state_process_error; } MPLS_REFCNT_HOLD(r_attr); + abort2attr(abrt, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC); f = ldp_fec_find2(g, &fec); + MPLS_REFCNT_HOLD(f); + retval = ldp_label_abort_process(g, s, a, e, r_attr, f); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); if (retval != MPLS_SUCCESS) break; } @@ -477,7 +494,7 @@ mpls_return_enum ldp_state_notif(ldp_global * g, ldp_session * s, ldp_adj * adj, LDP_ENTER(g->user_data, "ldp_state_notif"); - if (!(r_attr = ldp_attr_create(NULL))) { + if (!(r_attr = ldp_attr_create(g, NULL))) { retval = MPLS_FAILURE; goto ldp_state_notif_end; } @@ -487,7 +504,7 @@ mpls_return_enum ldp_state_notif(ldp_global * g, ldp_session * s, ldp_adj * adj, not2attr(not, r_attr, LDP_ATTR_ALL); retval = ldp_notif_process(g, s, adj, entity, r_attr); - MPLS_REFCNT_RELEASE(r_attr, ldp_attr_delete); + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete); ldp_state_notif_end: diff --git a/ldp/ldp_struct.h b/ldp/ldp_struct.h index 23ada70..d4aad51 100644 --- a/ldp/ldp_struct.h +++ b/ldp/ldp_struct.h @@ -569,6 +569,7 @@ typedef struct ldp_fec { /* ECMP */ struct ldp_nexthop_list nh_root; struct mpls_fec info; + mpls_bool is_route; uint32_t index; } ldp_fec; -- 2.11.4.GIT