3 * Copyright (C) James R. Leu 2000
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
10 #include "ldp_struct.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
,
27 mplsLdpLblAbortMsg_t
*abrt
= NULL
;
29 ldp_mesg_prepare(msg
, MPLS_LBLABORT_MSGTYPE
, msgid
);
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
,
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
) {
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");
77 ldp_label_abort_send_error
:
80 ldp_attr_remove_complete(g
, s_attr
, MPLS_BOOL_FALSE
);
82 LDP_EXIT(g
->user_data
, "ldp_label_abort_send-error");
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
, mpls_fec
* fec
)
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_all(g
, s
, fec
))) {
98 us_temp
= MPLS_LIST_HEAD(us_list
);
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
)) {
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
;
114 if (ldp_notif_send(g
, s
, us_attr
, LDP_NOTIF_LABEL_ABORT
) != MPLS_SUCCESS
) {
115 retval
= MPLS_FAILURE
;
119 if (us_attr
->ds_attr
&& (us_attr
->ds_attr
->state
== LDP_LSP_STATE_REQ_SENT
)) {
120 ds_req_attr
= us_attr
->ds_attr
;
124 if (us_attr
->ds_attr
&& (us_attr
->ds_attr
->state
== LDP_LSP_STATE_MAP_RECV
)) {
125 ds_map_attr
= us_attr
->ds_attr
;
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
, fec
) != MPLS_SUCCESS
) { /* LAbR.6 */
133 retval
= MPLS_FAILURE
;
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 */
147 if (ldp_label_abort_send(g
, ds_req_attr
->session
, ds_req_attr
) != MPLS_SUCCESS
) { /* LAbR.9,10 */
148 retval
= MPLS_FAILURE
;
154 ldp_attr_remove_complete(g
, us_attr
, MPLS_BOOL_FALSE
);
159 LDP_EXIT(g
->user_data
, "ldp_label_abort_processed");
163 void abort2attr(mplsLdpLblAbortMsg_t
* abrt
, ldp_attr
* a
, uint32_t flag
)