Minor fix up to label release and withdrawl processing. Main change
[mpls-ldp-portable.git] / ldp / ldp_init.c
blob52ecccc7c962956c7c4407e4e4004fa1efe85632
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_mesg.h"
12 #include "ldp_entity.h"
13 #include "ldp_nortel.h"
14 #include "ldp_buf.h"
15 #include "ldp_pdu_setup.h"
17 #include "mpls_assert.h"
18 #include "mpls_socket_impl.h"
19 #include "mpls_trace_impl.h"
20 #if MPLS_USE_LSR
21 #include "lsr_cfg.h"
22 #else
23 #include "mpls_mpls_impl.h"
24 #endif
26 void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
27 ldp_session * s)
29 mplsLdpInitMsg_t *init = NULL;
30 uint32_t remote_labelspace;
31 uint32_t path_vector_limit;
32 uint32_t remote_lsraddr;
33 uint8_t direction = 0;
34 ldp_adj *a = MPLS_LIST_HEAD(&s->adj_root);
35 uint32_t loop = 0;
36 uint8_t merge = 0;
37 mpls_range range;
38 uint8_t len = 0;
40 MPLS_ASSERT(s && a);
42 LDP_ENTER(g->user_data, "ldp_init_create");
44 ldp_mesg_prepare(msg, MPLS_INIT_MSGTYPE, msgid);
45 init = &msg->u.init;
47 remote_lsraddr = a->remote_lsr_address.u.ipv4;
48 remote_labelspace = a->remote_label_space;
50 loop = (s->cfg_loop_detection_mode == LDP_LOOP_NONE) ? (0) : (1);
51 if (loop == LDP_LOOP_NONE) {
52 path_vector_limit = 0;
53 } else {
54 path_vector_limit = s->cfg_path_vector_limit;
57 init->cspExists = 1;
59 init->baseMsg.msgLength += setupCspTlv(&(init->csp), s->cfg_keepalive,
60 s->cfg_distribution_mode, loop, path_vector_limit, s->cfg_max_pdu,
61 remote_lsraddr, remote_labelspace, 0);
63 init->aspExists = 0;
64 init->fspExists = 0;
66 range.label_space = s->cfg_label_space;
67 #if MPLS_USE_LSR
68 #else
69 mpls_mpls_get_label_space_range(g->mpls_handle,&range);
70 #endif
72 switch (range.type) {
73 case MPLS_LABEL_RANGE_ATM_VP:
74 MPLS_ASSERT(0);
75 case MPLS_LABEL_RANGE_ATM_VC:
76 case MPLS_LABEL_RANGE_ATM_VP_VC:
77 init->aspExists = 1;
78 init->baseMsg.msgLength += setupAspTlv(&(init->asp), merge, direction);
79 init->baseMsg.msgLength += addLblRng2AspTlv(&(init->asp),
80 range.min.u.atm.vpi, range.min.u.atm.vci, range.max.u.atm.vpi,
81 range.max.u.atm.vci);
82 break;
83 case MPLS_LABEL_RANGE_FR_10:
84 len = 0; /* Section 3.5.3 fspTlv */
85 case MPLS_LABEL_RANGE_FR_24:
86 init->fspExists = 1;
88 if (range.type == MPLS_LABEL_RANGE_FR_24) {
89 len = 2; /* Section 3.5.3 fspTlv */
92 init->baseMsg.msgLength += setupFspTlv(&(init->fsp), merge, direction);
93 init->baseMsg.msgLength += addLblRng2FspTlv(&(init->fsp), 0, len,
94 range.min.u.fr.dlci, 0, range.max.u.fr.dlci);
95 break;
96 case MPLS_LABEL_RANGE_GENERIC:
97 break;
99 LDP_EXIT(g->user_data, "ldp_init_create");
102 mpls_return_enum ldp_init_send(ldp_global * g, ldp_session * s)
104 mpls_return_enum result = MPLS_FAILURE;
106 MPLS_ASSERT(s);
108 LDP_ENTER(g->user_data, "ldp_init_send");
110 ldp_init_prepare(s->tx_message, g, g->message_identifier++, s);
112 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_INIT,
113 "Init Send: session(%d)\n", s->index);
115 result = ldp_mesg_send_tcp(g, s, s->tx_message);
117 LDP_EXIT(g->user_data, "ldp_init_send");
119 return result;
122 mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s,
123 ldp_mesg * msg)
125 mpls_range range;
127 MPLS_MSGPTR(Init);
129 MPLS_ASSERT(s);
131 LDP_ENTER(g->user_data, "ldp_init_process");
133 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
134 "Init Recv: session(%d)\n", s->index);
136 MPLS_MSGPARAM(Init) = &msg->u.init;
138 range.label_space = s->cfg_label_space;
140 #if MPLS_USE_LSR
141 range.type = MPLS_LABEL_RANGE_GENERIC;
142 #else
143 mpls_mpls_get_label_space_range(g->mpls_handle, &range);
144 #endif
146 if (MPLS_MSGPARAM(Init)->csp.rcvLsrAddress != g->lsr_identifier.u.ipv4 ||
147 MPLS_MSGPARAM(Init)->csp.rcvLsId != range.label_space) {
148 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
149 "Init failed(%d): sending bad LDP-ID\n", s->index);
150 LDP_EXIT(g->user_data, "ldp_init_process-error");
151 s->shutdown_notif = LDP_NOTIF_BAD_LDP_ID;
152 s->shutdown_fatal = MPLS_BOOL_FALSE;
153 return MPLS_FAILURE;
156 if (MPLS_MSGPARAM(Init)->csp.holdTime == 0) {
157 LDP_EXIT(g->user_data, "ldp_init_process-error");
158 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
159 "Init failed(%d): sending bad Keepalive Time\n", s->index);
160 s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME;
161 s->shutdown_fatal = MPLS_BOOL_FALSE;
162 return MPLS_FAILURE;
165 if (MPLS_MSGPARAM(Init)->csp.maxPduLen <= 255)
166 MPLS_MSGPARAM(Init)->csp.maxPduLen = 4096; /* Section 3.5.3. */
168 s->remote_max_pdu = MPLS_MSGPARAM(Init)->csp.maxPduLen;
169 s->remote_keepalive = MPLS_MSGPARAM(Init)->csp.holdTime;
170 s->remote_path_vector_limit = MPLS_MSGPARAM(Init)->csp.flags.flags.pvl;
171 s->remote_distribution_mode =
172 (ldp_distribution_mode) MPLS_MSGPARAM(Init)->csp.flags.flags.lad;
174 if (s->remote_keepalive < s->cfg_keepalive) {
175 s->oper_keepalive = s->remote_keepalive;
176 } else {
177 s->oper_keepalive = s->cfg_keepalive;
180 /* JLEU: eventually this should be configured by the user */
181 s->oper_keepalive_interval = s->oper_keepalive / 3;
183 if (MPLS_MSGPARAM(Init)->csp.flags.flags.ld == 0) {
184 s->remote_loop_detection = MPLS_BOOL_FALSE;
185 } else {
186 s->remote_loop_detection = MPLS_BOOL_TRUE;
189 if (s->remote_max_pdu < s->cfg_max_pdu) {
190 s->oper_max_pdu = s->remote_max_pdu;
193 if (s->remote_distribution_mode != s->cfg_distribution_mode) {
194 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
195 "Init(%d): distribution modes do not match, using default\n", s->index);
196 if (range.type == MPLS_LABEL_RANGE_GENERIC) {
197 s->oper_distribution_mode = LDP_DISTRIBUTION_UNSOLICITED;
198 } else {
199 s->oper_distribution_mode = LDP_DISTRIBUTION_ONDEMAND;
203 if ((s->remote_loop_detection == MPLS_BOOL_TRUE) &&
204 (g->loop_detection_mode != LDP_LOOP_NONE)) {
205 s->oper_loop_detection = s->cfg_loop_detection_mode;
206 } else {
207 s->oper_loop_detection = LDP_LOOP_NONE;
210 if (MPLS_MSGPARAM(Init)->aspExists) {
211 if (range.type >= MPLS_LABEL_RANGE_ATM_VP && range.type <= MPLS_LABEL_RANGE_ATM_VP_VC) {
212 MPLS_ASSERT(0);
213 } else {
214 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
215 "Init Failed(%d): sending bad Label Range (ATM)\n", s->index);
216 s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE;
217 s->shutdown_fatal = MPLS_BOOL_FALSE;
218 return MPLS_FAILURE;
220 } else if (MPLS_MSGPARAM(Init)->fspExists) {
221 if (range.type >= MPLS_LABEL_RANGE_FR_10 && range.type <= MPLS_LABEL_RANGE_FR_24) {
222 MPLS_ASSERT(0);
223 } else {
224 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
225 "Init Failed(%d): sending bad Label Range (FR)\n", s->index);
226 s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE;
227 s->shutdown_fatal = MPLS_BOOL_FALSE;
228 return MPLS_FAILURE;
232 LDP_EXIT(g->user_data, "ldp_init_process");
234 return MPLS_SUCCESS;