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"
12 #include "ldp_entity.h"
13 #include "ldp_nortel.h"
15 #include "ldp_pdu_setup.h"
17 #include "mpls_assert.h"
18 #include "mpls_socket_impl.h"
19 #include "mpls_trace_impl.h"
23 #include "mpls_mpls_impl.h"
26 void ldp_init_prepare(ldp_mesg
* msg
, ldp_global
* g
, uint32_t msgid
,
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
);
42 LDP_ENTER(g
->user_data
, "ldp_init_create");
44 ldp_mesg_prepare(msg
, MPLS_INIT_MSGTYPE
, msgid
);
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;
54 path_vector_limit
= s
->cfg_path_vector_limit
;
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);
66 range
.label_space
= s
->cfg_label_space
;
69 mpls_mpls_get_label_space_range(g
->mpls_handle
,&range
);
73 case MPLS_LABEL_RANGE_ATM_VP
:
75 case MPLS_LABEL_RANGE_ATM_VC
:
76 case MPLS_LABEL_RANGE_ATM_VP_VC
:
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
,
83 case MPLS_LABEL_RANGE_FR_10
:
84 len
= 0; /* Section 3.5.3 fspTlv */
85 case MPLS_LABEL_RANGE_FR_24
:
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
);
96 case MPLS_LABEL_RANGE_GENERIC
:
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
;
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");
122 mpls_return_enum
ldp_init_process(ldp_global
* g
, ldp_session
* 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
;
141 range
.type
= MPLS_LABEL_RANGE_GENERIC
;
143 mpls_mpls_get_label_space_range(g
->mpls_handle
, &range
);
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
;
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
;
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
;
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
;
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
;
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
;
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
) {
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
;
220 } else if (MPLS_MSGPARAM(Init
)->fspExists
) {
221 if (range
.type
>= MPLS_LABEL_RANGE_FR_10
&& range
.type
<= MPLS_LABEL_RANGE_FR_24
) {
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
;
232 LDP_EXIT(g
->user_data
, "ldp_init_process");