mpls_return_enum ldp_label_request_send(ldp_global * g, ldp_session * s, ldp_attr * us_attr, ldp_attr ** ds_attr) { ldp_attr *ds_temp; mpls_fec fec; LDP_ENTER(g->user_data, "ldp_label_request_send"); MPLS_ASSERT(ds_attr && *ds_attr); fec_tlv2mpls_fec(&((*ds_attr)->fecTlv), 0, &fec); if ((ds_temp = ldp_attr_find_downstream_state(g, s, &fec, LDP_LSP_STATE_REQ_SENT)) != NULL) { /* SLRq.1 */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL, "Label Request Send: request already pending(%d)\n", ds_temp->index); ldp_attr_add_us2ds(us_attr, ds_temp); /* 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, MPLS_BOOL_TRUE); *ds_attr = ds_temp; return MPLS_SUCCESS; } if (s->no_label_resource_recv == MPLS_BOOL_TRUE) { /* SLRq.2 */ goto ldp_label_request_send_error; } (*ds_attr)->msg_id = g->message_identifier++; ldp_label_request_prepare_msg(s->tx_message, (*ds_attr)->msg_id, *ds_attr); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL, "Label Request Sent: session(%d)\n", s->index); if (ldp_mesg_send_tcp(g, s, s->tx_message) == MPLS_FAILURE) { /* SLRq.3 */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR, "Label Request send failed\n"); goto ldp_label_request_send_error; } (*ds_attr)->state = LDP_LSP_STATE_REQ_SENT; if (ldp_attr_insert_downstream(g, s, (*ds_attr)) == MPLS_FAILURE) { /* SLRq.4 */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR, "Couldn't insert sent attributes in tree\n"); goto ldp_label_request_send_error; } if (us_attr) { ldp_attr_add_us2ds(us_attr, *ds_attr); } LDP_EXIT(g->user_data, "ldp_label_request_send"); return MPLS_SUCCESS; /* SLRq.5 */ ldp_label_request_send_error: LDP_PRINT(g->user_data, "SLRq.6\n"); (*ds_attr)->state = LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT; ldp_attr_insert_downstream(g, s, (*ds_attr)); /* SLRq.6 */ LDP_EXIT(g->user_data, "ldp_label_request_send-error"); return MPLS_FAILURE; /* SLRq.7 */ }
void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, mpls_bool complete) { ldp_session *session = attr->session; ldp_outlabel *out = NULL; ldp_inlabel *in = NULL; ldp_attr *us_temp = NULL; mpls_fec fec; int i; switch (attr->state) { case LDP_LSP_STATE_MAP_RECV: if (attr->ingress == MPLS_BOOL_TRUE) { out = attr->outlabel; MPLS_ASSERT(out != NULL); while ((in = MPLS_LIST_HEAD(&out->inlabel_root)) != NULL) { ldp_inlabel_del_outlabel(g, in); } if (out->merge_count > 0) { for (i = 0; i < attr->fecTlv.numberFecElements; i++) { fec_tlv2mpls_fec(&attr->fecTlv, i, &fec); out->merge_count--; #if MPLS_USE_LSR { lsr_ftn ftn; memcpy(&ftn.fec, &fec, sizeof(mpls_fec)); ftn.outsegment_index = out->info.handle; lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_DEL); } #else mpls_mpls_fec2out_del(g->mpls_handle, &fec, &out->info); #endif } } MPLS_ASSERT(out->merge_count == 0); ldp_attr_del_outlabel(g, attr); ldp_session_del_outlabel(g, session, out); } while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) { ldp_attr_del_us2ds(g, us_temp, attr); } ldp_attr_delete_downstream(g, session, attr); break; case LDP_LSP_STATE_MAP_SENT: in = attr->inlabel; out = in->outlabel; 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(g, attr, attr->ds_attr); ldp_session_del_inlabel(g, session, in); break; case LDP_LSP_STATE_ABORT_SENT: case LDP_LSP_STATE_NOTIF_SENT: case LDP_LSP_STATE_REQ_RECV: case LDP_LSP_STATE_WITH_SENT: case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT: { ldp_attr_del_us2ds(g, attr, attr->ds_attr); ldp_attr_delete_upstream(g, session, attr); break; } case LDP_LSP_STATE_ABORT_RECV: case LDP_LSP_STATE_NOTIF_RECV: case LDP_LSP_STATE_REQ_SENT: case LDP_LSP_STATE_WITH_RECV: case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV: { while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) { ldp_attr_del_us2ds(g, us_temp, attr); } ldp_attr_delete_downstream(g, session, attr); break; } } }