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_RELEASE2(g, ds, ldp_attr_delete); MPLS_LIST_REMOVE(&ds->us_attr_root, us, _ds_attr); MPLS_REFCNT_RELEASE2(g, us, ldp_attr_delete); } else { MPLS_ASSERT(0); } }
void ldp_attr_del_fec(ldp_global *g, ldp_attr *a) { MPLS_ASSERT(a); if (a->fec) { MPLS_REFCNT_RELEASE2(g, a->fec, ldp_fec_delete); a->fec = NULL; } }
void ldp_attr_delete_upstream(ldp_global * g, ldp_session * s, ldp_attr * a) { ldp_fec *fnode = NULL; ldp_fs *fs = NULL; MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE); MPLS_REFCNT_HOLD(a); /* 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(g, a); ldp_attr_del_fec(g, a); a->in_tree = MPLS_BOOL_FALSE; MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); }
mpls_return_enum ldp_attr_del_outlabel(ldp_global * g, ldp_attr * a) { if (a && a->outlabel) { _ldp_outlabel_del_attr(g, a->outlabel); MPLS_REFCNT_RELEASE2(g, a->outlabel, ldp_outlabel_delete); a->outlabel = NULL; return MPLS_SUCCESS; } return MPLS_FAILURE; }
void ldp_fec_del_nexthop(ldp_global *g, ldp_fec * f, ldp_nexthop *nh) { MPLS_ASSERT(f && nh); if (nh->addr) { ldp_addr_del_nexthop(g, nh->addr, nh); } if (nh->iff) { ldp_if_del_nexthop(g, nh->iff, nh); } if (nh->outlabel) { ldp_outlabel_del_nexthop(g, nh->outlabel, nh); } MPLS_LIST_REMOVE(&f->nh_root, nh, _fec); ldp_nexthop_del_fec(g, nh); MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete); }
void ldp_attr_delete_downstream(ldp_global * g, ldp_session * s, ldp_attr * a) { ldp_fec *fnode = NULL; ldp_fs *fs = NULL; MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE); 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(g, a); ldp_attr_del_fec(g, a); a->in_tree = MPLS_BOOL_FALSE; MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete); }
void ldp_nexthop_del_if(ldp_global *g, ldp_nexthop * nh) { MPLS_ASSERT(nh); MPLS_REFCNT_RELEASE2(g, nh->iff, ldp_if_delete); nh->iff = NULL; }
void ldp_nexthop_del_fec(ldp_global *g, ldp_nexthop * nh) { MPLS_ASSERT(nh); MPLS_REFCNT_RELEASE2(g, nh->fec, ldp_fec_delete); nh->fec = NULL; }
void ldp_nexthop_del_addr(ldp_global *g, ldp_nexthop * nh) { MPLS_ASSERT(nh); MPLS_REFCNT_RELEASE2(g, nh->addr, ldp_addr_delete); nh->addr = NULL; }
mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f) { mpls_bool label_exists = MPLS_BOOL_FALSE; ldp_attr_list *ds_list = NULL; ldp_attr *ds_attr = NULL; ldp_attr *ds_temp = NULL; ldp_attr *us_temp = NULL; ldp_nexthop *nh = NULL; mpls_return_enum retval = MPLS_SUCCESS; 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 %s\n", s->session_name); if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists || r_attr->frLblTlvExists) { label_exists = MPLS_BOOL_TRUE; } else { MPLS_ASSERT(0); } if (f) { if ((ds_list = ldp_attr_find_downstream_all2(g, s, f)) != NULL) { ds_temp = MPLS_LIST_HEAD(ds_list); while (ds_temp) { if (ds_temp->state == LDP_LSP_STATE_MAP_RECV) { /* LWd.3 */ if (ldp_attr_is_equal(r_attr, ds_temp, LDP_ATTR_LABEL)) { ds_attr = ds_temp; break; } } ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs); } } if (!ds_attr) { retval = MPLS_FAILURE; LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL, "Withdraw Recv for a non-existant mapping from %s\n",s->session_name); goto LWd_13; } /* * we want to remove it from the tree, but not delete it yet * so hold a refcnt, we will release that refcnt at the end, thus * deleting it if no one else it holding a refcnt */ MPLS_REFCNT_HOLD(ds_attr); ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LWd.4 */ /* LWd.2 */ if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) { retval = MPLS_FATAL; goto LWd_13; } if (g->lsp_control_mode == LDP_CONTROL_ORDERED) { /* LWd.5 */ goto LWd_8; } if (s->oper_distribution_mode != LDP_DISTRIBUTION_ONDEMAND) { /* LWd.6 */ goto LWd_13; } MPLS_ASSERT((nh = ldp_nexthop_for_fec_session(f, s))); retval = ldp_fec_process_add(g, f, nh, s); /* LWd.7 */ goto LWd_13; LWd_8: /* I can only propogate a label withdraw to the upstreams attached to the downstream found above */ us_temp = MPLS_LIST_HEAD(&ds_attr->us_attr_root); while (us_temp) { if (us_temp->state == LDP_LSP_STATE_MAP_SENT) { if (ldp_label_withdraw_send(g, us_temp->session, us_temp, LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* LWd.11 */ retval = MPLS_FATAL; goto LWd_13; } } us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_temp, _ds_attr); } } else { /* JLEU: process wildcard FEC stuff here */ MPLS_ASSERT(0); } LWd_13: if (ds_attr) { MPLS_REFCNT_RELEASE2(g, ds_attr, ldp_attr_delete); } LDP_EXIT(g->user_data, "ldp_label_withdraw_process"); return retval; }