Convert to a generic FEC handling architecture. Part of this change
[mpls-ldp-portable.git] / ldp / ldp_label_abort.c
blob26638e03f90582b599be042de680e13f74b82085
2 /*
3 * Copyright (C) James R. Leu 2000
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include "ldp_struct.h"
11 #include "ldp_attr.h"
12 #include "ldp_fec.h"
13 #include "ldp_mesg.h"
14 #include "ldp_pdu_setup.h"
15 #include "ldp_entity.h"
16 #include "ldp_session.h"
17 #include "ldp_notif.h"
18 #include "ldp_label_abort.h"
19 #include "ldp_label_rel_with.h"
20 #include "ldp_label_mapping.h"
22 #include "mpls_trace_impl.h"
24 void ldp_label_abort_prepare_msg(ldp_mesg * msg, uint32_t msgid,
25 ldp_attr * s_attr)
27 mplsLdpLblAbortMsg_t *abrt = NULL;
29 ldp_mesg_prepare(msg, MPLS_LBLABORT_MSGTYPE, msgid);
31 abrt = &msg->u.abort;
33 if (s_attr->fecTlvExists) {
34 abrt->fecTlvExists = 1;
35 abrt->baseMsg.msgLength += setupFecTlv(&abrt->fecTlv);
36 abrt->baseMsg.msgLength +=
37 addFecElem2FecTlv(&abrt->fecTlv, &s_attr->fecTlv.fecElArray[0]);
40 if (s_attr->lblMsgIdTlvExists) {
41 abrt->lblMsgIdTlvExists = 1;
42 abrt->baseMsg.msgLength +=
43 setupLblMsgIdTlv(&abrt->lblMsgIdTlv, s_attr->msg_id);
47 mpls_return_enum ldp_label_abort_send(ldp_global * g, ldp_session * s,
48 ldp_attr * s_attr)
50 mpls_fec fec;
51 ldp_attr *ds_attr = NULL;
53 LDP_ENTER(g->user_data, "ldp_label_abort_send");
55 fec_tlv2mpls_fec(&s_attr->fecTlv, 0, &fec);
56 if ((ds_attr = ldp_attr_find_downstream_state(g, s, &fec,
57 LDP_LSP_STATE_ABORT_SENT)) != NULL) {
58 return MPLS_SUCCESS;
61 ldp_label_abort_prepare_msg(s->tx_message, g->message_identifier++, s_attr);
63 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
64 "Label Abort Sent: session (%d) \n", s->index);
66 s_attr->state = LDP_LSP_STATE_ABORT_SENT;
68 if (ldp_mesg_send_tcp(g, s, s->tx_message) == MPLS_FAILURE) {
69 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
70 "Label Abort Sent Failed .\n");
71 goto ldp_label_abort_send_error;
74 LDP_EXIT(g->user_data, "ldp_label_abort_send");
75 return MPLS_SUCCESS;
77 ldp_label_abort_send_error:
79 if (s_attr) {
80 ldp_attr_remove_complete(g, s_attr, MPLS_BOOL_FALSE);
82 LDP_EXIT(g->user_data, "ldp_label_abort_send-error");
84 return MPLS_FAILURE;
87 mpls_return_enum ldp_label_abort_process(ldp_global * g, ldp_session * s,
88 ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
90 ldp_attr_list *us_list = NULL;
91 ldp_attr *us_temp = NULL;
92 ldp_attr *us_attr = NULL;
93 ldp_attr *ds_req_attr = NULL;
94 ldp_attr *ds_map_attr = NULL;
95 mpls_return_enum retval = MPLS_SUCCESS;
97 if ((us_list = ldp_attr_find_upstream_all2(g, s, f))) {
98 us_temp = MPLS_LIST_HEAD(us_list);
99 while (us_temp) {
100 if (((us_temp->state == LDP_LSP_STATE_REQ_RECV) &&
101 (us_temp->msg_id == r_attr->msg_id)) ||
102 (us_temp->state == LDP_LSP_STATE_MAP_SENT)) {
103 us_attr = us_temp;
104 break;
106 us_temp = MPLS_LIST_NEXT(us_list, us_temp, _fs);
109 if ((!us_attr) || (us_attr->state == LDP_LSP_STATE_MAP_SENT)) { /* LAbR.1,2 */
110 retval = MPLS_FAILURE;
111 goto LAbR_12;
113 /* LAbR.3 */
114 if (ldp_notif_send(g, s, us_attr, LDP_NOTIF_LABEL_ABORT) != MPLS_SUCCESS) {
115 retval = MPLS_FAILURE;
116 goto LAbR_12;
118 /* LAbR.4 */
119 if (us_attr->ds_attr && (us_attr->ds_attr->state == LDP_LSP_STATE_REQ_SENT)) {
120 ds_req_attr = us_attr->ds_attr;
121 goto LAbR_7;
123 /* LAbR.5 */
124 if (us_attr->ds_attr && (us_attr->ds_attr->state == LDP_LSP_STATE_MAP_RECV)) {
125 ds_map_attr = us_attr->ds_attr;
126 } else {
127 goto LAbR_11;
130 /* this may results in us sending a label withdraw to s and possibly
131 propogating a release */
132 if (ldp_label_release_process(g, s, NULL, e, us_attr, f) != MPLS_SUCCESS) { /* LAbR.6 */
133 retval = MPLS_FAILURE;
135 goto LAbR_11;
137 LAbR_7:
139 if (g->label_merge == MPLS_BOOL_TRUE) { /* LAbR.7 */
140 /* by now us_attr has been removed from the downstream us_attr_root
141 so any left overs (reflect by count > 0) are from other peers */
142 if (ds_req_attr && ldp_attr_num_us2ds(ds_req_attr)) { /* LAbR.8 */
143 goto LAbR_11;
147 if (ldp_label_abort_send(g, ds_req_attr->session, ds_req_attr) != MPLS_SUCCESS) { /* LAbR.9,10 */
148 retval = MPLS_FAILURE;
151 LAbR_11:
153 if (us_attr) {
154 ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE);
157 LAbR_12:
159 LDP_EXIT(g->user_data, "ldp_label_abort_processed");
160 return retval;
163 void abort2attr(mplsLdpLblAbortMsg_t * abrt, ldp_attr * a, uint32_t flag)