]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
132a782e | 2 | /* |
3 | * ospf_ldp_sync.c: OSPF LDP-IGP Sync handling routines | |
4 | * Copyright (C) 2020 Volta Networks, Inc. | |
132a782e | 5 | */ |
6 | ||
7 | #include <zebra.h> | |
8 | #include <string.h> | |
9 | ||
10 | #include "monotime.h" | |
11 | #include "memory.h" | |
12 | #include "thread.h" | |
13 | #include "prefix.h" | |
14 | #include "table.h" | |
15 | #include "vty.h" | |
16 | #include "command.h" | |
17 | #include "plist.h" | |
18 | #include "log.h" | |
19 | #include "zclient.h" | |
20 | #include <lib/json.h> | |
21 | #include "defaults.h" | |
22 | #include "ldp_sync.h" | |
23 | ||
24 | #include "ospfd.h" | |
25 | #include "ospf_interface.h" | |
26 | #include "ospf_vty.h" | |
27 | #include "ospf_ldp_sync.h" | |
28 | #include "ospf_dump.h" | |
29 | #include "ospf_ism.h" | |
30 | ||
31 | extern struct zclient *zclient; | |
32 | ||
33 | /* | |
34 | * LDP-SYNC msg between IGP and LDP | |
35 | */ | |
36 | int ospf_ldp_sync_state_update(struct ldp_igp_sync_if_state state) | |
37 | { | |
38 | struct ospf *ospf; | |
39 | struct interface *ifp; | |
40 | ||
41 | /* if ospf is not enabled or LDP-SYNC is not configured ignore */ | |
42 | ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); | |
43 | if (ospf == NULL || | |
44 | !CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) | |
45 | return 0; | |
46 | ||
47 | /* received ldp-sync interface state from LDP */ | |
48 | ifp = if_lookup_by_index(state.ifindex, VRF_DEFAULT); | |
49 | if (ifp == NULL || if_is_loopback(ifp)) | |
50 | return 0; | |
51 | ||
f96ec6a6 | 52 | ols_debug("%s: rcvd %s from LDP if %s", __func__, |
53 | state.sync_start ? "sync-start" : "sync-complete", ifp->name); | |
132a782e | 54 | if (state.sync_start) |
55 | ospf_ldp_sync_if_start(ifp, false); | |
56 | else | |
57 | ospf_ldp_sync_if_complete(ifp); | |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce) | |
63 | { | |
64 | struct ospf *ospf; | |
65 | struct vrf *vrf; | |
66 | struct interface *ifp; | |
67 | ||
68 | /* if ospf is not enabled or LDP-SYNC is not configured ignore */ | |
69 | ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); | |
70 | if (ospf == NULL || | |
71 | !CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) | |
72 | return 0; | |
73 | ||
74 | if (announce.proto != ZEBRA_ROUTE_LDP) | |
75 | return 0; | |
76 | ||
f96ec6a6 | 77 | ols_debug("%s: rcvd announce from LDP", __func__); |
132a782e | 78 | |
79 | /* LDP just started up: | |
80 | * set cost to LSInfinity | |
81 | * send request to LDP for LDP-SYNC state for each interface | |
132a782e | 82 | */ |
83 | vrf = vrf_lookup_by_id(ospf->vrf_id); | |
84 | FOR_ALL_INTERFACES (vrf, ifp) | |
85 | ospf_ldp_sync_if_start(ifp, true); | |
86 | ||
132a782e | 87 | return 0; |
88 | } | |
89 | ||
90 | void ospf_ldp_sync_state_req_msg(struct interface *ifp) | |
91 | { | |
92 | struct ldp_igp_sync_if_state_req request; | |
93 | ||
f96ec6a6 | 94 | ols_debug("%s: send state request to LDP for %s", __func__, ifp->name); |
132a782e | 95 | |
dd53fd08 | 96 | memset(&request, 0, sizeof(request)); |
132a782e | 97 | strlcpy(request.name, ifp->name, sizeof(ifp->name)); |
98 | request.proto = LDP_IGP_SYNC_IF_STATE_REQUEST; | |
99 | request.ifindex = ifp->ifindex; | |
100 | ||
101 | zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST, | |
102 | (uint8_t *)&request, sizeof(request)); | |
103 | } | |
104 | ||
105 | /* | |
106 | * LDP-SYNC general interface routines | |
107 | */ | |
108 | void ospf_ldp_sync_if_init(struct ospf_interface *oi) | |
109 | { | |
110 | struct ospf_if_params *params; | |
111 | struct ldp_sync_info *ldp_sync_info; | |
112 | struct interface *ifp = oi->ifp; | |
113 | ||
114 | /* called when OSPF is configured on an interface: | |
115 | * if LDP-IGP Sync is configured globally set state | |
116 | * if ptop interface inform LDP LDP-SYNC is enabled | |
117 | */ | |
096f7609 IR |
118 | if (if_is_loopback(ifp) || (ifp->vrf->vrf_id != VRF_DEFAULT) |
119 | || !(CHECK_FLAG(oi->ospf->ldp_sync_cmd.flags, | |
120 | LDP_SYNC_FLAG_ENABLE))) | |
132a782e | 121 | return; |
122 | ||
f96ec6a6 | 123 | ols_debug("%s: init if %s", __func__, ifp->name); |
132a782e | 124 | params = IF_DEF_PARAMS(ifp); |
125 | if (params->ldp_sync_info == NULL) | |
126 | params->ldp_sync_info = ldp_sync_info_create(); | |
127 | ||
128 | ldp_sync_info = params->ldp_sync_info; | |
129 | ||
bd4f51b1 | 130 | /* specified on interface overrides global config. */ |
132a782e | 131 | if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN)) |
132 | ldp_sync_info->holddown = oi->ospf->ldp_sync_cmd.holddown; | |
133 | ||
134 | if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) | |
135 | ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED; | |
136 | ||
137 | if ((params->type == OSPF_IFTYPE_POINTOPOINT || | |
138 | if_is_pointopoint(ifp)) && | |
139 | ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) | |
140 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; | |
141 | } | |
142 | ||
143 | void ospf_ldp_sync_if_start(struct interface *ifp, bool send_state_req) | |
144 | { | |
145 | struct ospf_if_params *params; | |
146 | struct ldp_sync_info *ldp_sync_info; | |
147 | ||
148 | if (if_is_loopback(ifp)) | |
149 | return; | |
150 | ||
151 | params = IF_DEF_PARAMS(ifp); | |
152 | ldp_sync_info = params->ldp_sync_info; | |
153 | ||
154 | /* Start LDP-SYNC on this interface: | |
155 | * set cost of interface to LSInfinity so traffic will use different | |
156 | * interface until LDP has learned all labels from peer | |
157 | * start holddown timer if configured | |
158 | * send msg to LDP to get LDP-SYNC state | |
159 | */ | |
160 | if (ldp_sync_info && | |
161 | ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && | |
162 | ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { | |
f96ec6a6 | 163 | ols_debug("%s: start on if %s state: %s", __func__, ifp->name, |
164 | "Holding down until Sync"); | |
132a782e | 165 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; |
166 | ospf_if_recalculate_output_cost(ifp); | |
167 | ospf_ldp_sync_holddown_timer_add(ifp); | |
168 | ||
169 | if (send_state_req) | |
170 | ospf_ldp_sync_state_req_msg(ifp); | |
171 | } | |
172 | } | |
173 | ||
174 | void ospf_ldp_sync_if_complete(struct interface *ifp) | |
175 | { | |
176 | struct ospf_if_params *params; | |
177 | struct ldp_sync_info *ldp_sync_info; | |
178 | ||
179 | if (if_is_loopback(ifp)) | |
180 | return; | |
181 | ||
182 | params = IF_DEF_PARAMS(ifp); | |
183 | ldp_sync_info = params->ldp_sync_info; | |
184 | ||
185 | /* received sync-complete from LDP: | |
186 | * set state to up | |
187 | * stop timer | |
188 | * restore interface cost to original value | |
189 | */ | |
190 | if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { | |
191 | if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP) | |
192 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP; | |
50478845 | 193 | THREAD_OFF(ldp_sync_info->t_holddown); |
132a782e | 194 | ospf_if_recalculate_output_cost(ifp); |
195 | } | |
196 | } | |
197 | ||
cb135cc9 KS |
198 | void ospf_ldp_sync_handle_client_close(struct zapi_client_close_info *info) |
199 | { | |
200 | struct ospf *ospf; | |
201 | struct vrf *vrf; | |
202 | struct interface *ifp; | |
203 | ||
204 | /* if ospf is not enabled or LDP-SYNC is not configured ignore */ | |
205 | ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); | |
206 | if (ospf == NULL | |
207 | || !CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) | |
208 | return; | |
209 | ||
210 | /* Check if the LDP main client session closed */ | |
211 | if (info->proto != ZEBRA_ROUTE_LDP || info->session_id == 0) | |
212 | return; | |
213 | ||
214 | /* Handle the zebra notification that the LDP client session closed. | |
215 | * set cost to LSInfinity | |
216 | * send request to LDP for LDP-SYNC state for each interface | |
217 | */ | |
f96ec6a6 | 218 | zlog_err("%s: LDP down", __func__); |
cb135cc9 KS |
219 | |
220 | vrf = vrf_lookup_by_id(ospf->vrf_id); | |
221 | FOR_ALL_INTERFACES (vrf, ifp) | |
c3783ac0 | 222 | ospf_ldp_sync_ldp_fail(ifp); |
cb135cc9 KS |
223 | } |
224 | ||
132a782e | 225 | void ospf_ldp_sync_ldp_fail(struct interface *ifp) |
226 | { | |
227 | struct ospf_if_params *params; | |
228 | struct ldp_sync_info *ldp_sync_info; | |
229 | ||
230 | if (if_is_loopback(ifp)) | |
231 | return; | |
232 | ||
233 | params = IF_DEF_PARAMS(ifp); | |
234 | ldp_sync_info = params->ldp_sync_info; | |
235 | ||
cb135cc9 | 236 | /* LDP client close detected: |
132a782e | 237 | * stop holddown timer |
238 | * set cost of interface to LSInfinity so traffic will use different | |
239 | * interface until LDP has learned all labels from peer | |
240 | */ | |
241 | if (ldp_sync_info && | |
242 | ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && | |
243 | ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { | |
50478845 | 244 | THREAD_OFF(ldp_sync_info->t_holddown); |
132a782e | 245 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; |
246 | ospf_if_recalculate_output_cost(ifp); | |
247 | } | |
248 | } | |
249 | ||
250 | void ospf_ldp_sync_if_down(struct interface *ifp) | |
251 | { | |
252 | struct ospf_if_params *params; | |
253 | struct ldp_sync_info *ldp_sync_info; | |
254 | ||
255 | if (if_is_loopback(ifp)) | |
256 | return; | |
257 | ||
258 | params = IF_DEF_PARAMS(ifp); | |
259 | ldp_sync_info = params->ldp_sync_info; | |
260 | ||
261 | if (ldp_sync_if_down(ldp_sync_info) == false) | |
262 | return; | |
263 | ||
f96ec6a6 | 264 | ols_debug("%s: down on if %s", __func__, ifp->name); |
132a782e | 265 | |
266 | /* Interface down: | |
267 | * can occur from a link down or changing config | |
268 | * ospf network type change interface is brought down/up | |
269 | */ | |
270 | switch (ldp_sync_info->state) { | |
271 | case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP: | |
272 | case LDP_IGP_SYNC_STATE_REQUIRED_UP: | |
273 | if (params->type != OSPF_IFTYPE_POINTOPOINT && | |
274 | !if_is_pointopoint(ifp)) | |
275 | /* LDP-SYNC not able to run on non-ptop interface */ | |
276 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; | |
277 | break; | |
278 | case LDP_IGP_SYNC_STATE_NOT_REQUIRED: | |
279 | if (params->type == OSPF_IFTYPE_POINTOPOINT || | |
280 | if_is_pointopoint(ifp)) | |
281 | /* LDP-SYNC is able to run on ptop interface */ | |
282 | ldp_sync_info->state = | |
283 | LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; | |
284 | break; | |
285 | default: | |
286 | break; | |
287 | } | |
288 | } | |
289 | ||
290 | void ospf_ldp_sync_if_remove(struct interface *ifp, bool remove) | |
291 | { | |
292 | struct ospf_if_params *params; | |
293 | struct ldp_sync_info *ldp_sync_info; | |
294 | ||
295 | params = IF_DEF_PARAMS(ifp); | |
296 | if (params->ldp_sync_info == NULL) | |
297 | return; | |
298 | ||
299 | ldp_sync_info = params->ldp_sync_info; | |
300 | ||
301 | /* Stop LDP-SYNC on this interface: | |
302 | * if holddown timer is running stop it | |
303 | * delete ldp instance on interface | |
304 | * restore cost | |
305 | */ | |
f96ec6a6 | 306 | ols_debug("%s: Removed from if %s", __func__, ifp->name); |
50478845 MS |
307 | |
308 | THREAD_OFF(ldp_sync_info->t_holddown); | |
309 | ||
132a782e | 310 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; |
311 | ospf_if_recalculate_output_cost(ifp); | |
312 | if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) | |
313 | ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; | |
314 | if (remove) { | |
8998807f | 315 | ldp_sync_info_free(&ldp_sync_info); |
132a782e | 316 | params->ldp_sync_info = NULL; |
317 | } | |
318 | } | |
319 | ||
320 | static int ospf_ldp_sync_ism_change(struct ospf_interface *oi, int state, | |
321 | int old_state) | |
322 | { | |
323 | /* Terminal state or regression */ | |
324 | switch (state) { | |
325 | case ISM_PointToPoint: | |
326 | /* If LDP-SYNC is configure on interface then start */ | |
327 | ospf_ldp_sync_if_start(oi->ifp, true); | |
328 | break; | |
329 | case ISM_Down: | |
330 | /* If LDP-SYNC is configure on this interface then stop it */ | |
331 | ospf_ldp_sync_if_down(oi->ifp); | |
332 | break; | |
333 | default: | |
334 | break; | |
335 | } | |
336 | return 0; | |
337 | } | |
338 | ||
339 | /* | |
340 | * LDP-SYNC holddown timer routines | |
341 | */ | |
cc9f21da | 342 | static void ospf_ldp_sync_holddown_timer(struct thread *thread) |
132a782e | 343 | { |
344 | struct interface *ifp; | |
345 | struct ospf_if_params *params; | |
346 | struct ldp_sync_info *ldp_sync_info; | |
347 | ||
348 | /* holddown timer expired: | |
349 | * didn't receive msg from LDP indicating sync-complete | |
350 | * restore interface cost to original value | |
351 | */ | |
352 | ifp = THREAD_ARG(thread); | |
353 | params = IF_DEF_PARAMS(ifp); | |
354 | if (params->ldp_sync_info) { | |
355 | ldp_sync_info = params->ldp_sync_info; | |
356 | ||
357 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP; | |
132a782e | 358 | |
f96ec6a6 | 359 | ols_debug("%s: holddown timer expired for %s state: %s", |
360 | __func__, ifp->name, "Sync achieved"); | |
132a782e | 361 | |
362 | ospf_if_recalculate_output_cost(ifp); | |
363 | } | |
132a782e | 364 | } |
365 | ||
366 | void ospf_ldp_sync_holddown_timer_add(struct interface *ifp) | |
367 | { | |
368 | struct ospf_if_params *params; | |
369 | struct ldp_sync_info *ldp_sync_info; | |
370 | ||
371 | params = IF_DEF_PARAMS(ifp); | |
372 | ldp_sync_info = params->ldp_sync_info; | |
373 | ||
374 | /* Start holddown timer: | |
375 | * this timer is used to keep interface cost at LSInfinity | |
376 | * once expires returns cost to original value | |
377 | * if timer is already running or holddown time is off just return | |
378 | */ | |
379 | if (ldp_sync_info->t_holddown || | |
380 | ldp_sync_info->holddown == LDP_IGP_SYNC_HOLDDOWN_DEFAULT) | |
381 | return; | |
382 | ||
f96ec6a6 | 383 | ols_debug("%s: start holddown timer for %s time %d", __func__, |
132a782e | 384 | ifp->name, ldp_sync_info->holddown); |
385 | ||
386 | thread_add_timer(master, ospf_ldp_sync_holddown_timer, | |
387 | ifp, ldp_sync_info->holddown, | |
388 | &ldp_sync_info->t_holddown); | |
389 | } | |
390 | ||
132a782e | 391 | /* |
392 | * LDP-SYNC exit routes. | |
393 | */ | |
394 | void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove) | |
395 | { | |
396 | struct interface *ifp; | |
397 | struct vrf *vrf; | |
398 | ||
399 | /* ospf is being removed | |
132a782e | 400 | * stop any holddown timers |
401 | */ | |
402 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { | |
403 | /* unregister with opaque client to recv LDP-IGP Sync msgs */ | |
404 | zclient_unregister_opaque(zclient, | |
405 | LDP_IGP_SYNC_IF_STATE_UPDATE); | |
406 | zclient_unregister_opaque(zclient, | |
407 | LDP_IGP_SYNC_ANNOUNCE_UPDATE); | |
132a782e | 408 | |
409 | /* disable LDP globally */ | |
410 | UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE); | |
411 | UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN); | |
412 | ospf->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; | |
50478845 | 413 | |
132a782e | 414 | /* turn off LDP-IGP Sync on all OSPF interfaces */ |
415 | vrf = vrf_lookup_by_id(ospf->vrf_id); | |
416 | FOR_ALL_INTERFACES (vrf, ifp) | |
417 | ospf_ldp_sync_if_remove(ifp, remove); | |
418 | } | |
419 | } | |
420 | ||
421 | /* | |
422 | * LDP-SYNC routes used by set commands. | |
423 | */ | |
424 | void ospf_if_set_ldp_sync_enable(struct ospf *ospf, struct interface *ifp) | |
425 | { | |
426 | struct ospf_if_params *params; | |
427 | struct ldp_sync_info *ldp_sync_info; | |
428 | ||
429 | /* called when setting LDP-SYNC at the global level: | |
bd4f51b1 | 430 | * specified on interface overrides global config |
132a782e | 431 | * if ptop link send msg to LDP indicating ldp-sync enabled |
432 | */ | |
433 | if (if_is_loopback(ifp)) | |
434 | return; | |
435 | ||
436 | params = IF_DEF_PARAMS(ifp); | |
437 | if (params->ldp_sync_info == NULL) | |
438 | params->ldp_sync_info = ldp_sync_info_create(); | |
439 | ldp_sync_info = params->ldp_sync_info; | |
440 | ||
441 | /* config on interface, overrides global config. */ | |
442 | if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) | |
443 | if (ldp_sync_info->enabled != LDP_IGP_SYNC_ENABLED) | |
444 | return; | |
445 | ||
446 | ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED; | |
447 | ||
f96ec6a6 | 448 | ols_debug("%s: enable if %s", __func__, ifp->name); |
132a782e | 449 | |
450 | /* send message to LDP if ptop link */ | |
451 | if (params->type == OSPF_IFTYPE_POINTOPOINT || | |
452 | if_is_pointopoint(ifp)) { | |
453 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; | |
454 | ospf_ldp_sync_state_req_msg(ifp); | |
455 | } else { | |
456 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; | |
f96ec6a6 | 457 | zlog_debug("%s: Sync only runs on P2P links %s", __func__, |
132a782e | 458 | ifp->name); |
459 | } | |
460 | } | |
461 | ||
462 | void ospf_if_set_ldp_sync_holddown(struct ospf *ospf, struct interface *ifp) | |
463 | { | |
464 | struct ospf_if_params *params; | |
465 | struct ldp_sync_info *ldp_sync_info; | |
466 | ||
467 | /* called when setting LDP-SYNC at the global level: | |
bd4f51b1 | 468 | * specified on interface overrides global config. |
132a782e | 469 | */ |
470 | if (if_is_loopback(ifp)) | |
471 | return; | |
472 | ||
473 | params = IF_DEF_PARAMS(ifp); | |
474 | if (params->ldp_sync_info == NULL) | |
475 | params->ldp_sync_info = ldp_sync_info_create(); | |
476 | ldp_sync_info = params->ldp_sync_info; | |
477 | ||
478 | /* config on interface, overrides global config. */ | |
479 | if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN)) | |
480 | return; | |
481 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN)) | |
482 | ldp_sync_info->holddown = ospf->ldp_sync_cmd.holddown; | |
483 | else | |
484 | ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; | |
485 | } | |
486 | ||
487 | /* | |
488 | * LDP-SYNC routines used by show commands. | |
489 | */ | |
490 | ||
491 | void ospf_ldp_sync_show_info(struct vty *vty, struct ospf *ospf, | |
492 | json_object *json_vrf, bool use_json) | |
493 | { | |
494 | ||
495 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { | |
496 | if (use_json) { | |
77a2f8e5 DA |
497 | json_object_boolean_true_add(json_vrf, |
498 | "mplsLdpIgpSyncEnabled"); | |
77a2f8e5 DA |
499 | json_object_int_add(json_vrf, "mplsLdpIgpSyncHolddown", |
500 | ospf->ldp_sync_cmd.holddown); | |
132a782e | 501 | } else { |
502 | vty_out(vty, " MPLS LDP-IGP Sync is enabled\n"); | |
503 | if (ospf->ldp_sync_cmd.holddown == 0) | |
504 | vty_out(vty, | |
505 | " MPLS LDP-IGP Sync holddown timer is disabled\n"); | |
506 | else | |
507 | vty_out(vty, | |
508 | " MPLS LDP-IGP Sync holddown timer %d sec\n", | |
509 | ospf->ldp_sync_cmd.holddown); | |
510 | } | |
511 | } | |
512 | } | |
513 | ||
514 | static void show_ip_ospf_mpls_ldp_interface_sub(struct vty *vty, | |
515 | struct ospf_interface *oi, | |
516 | struct interface *ifp, | |
517 | json_object *json_interface_sub, | |
518 | bool use_json) | |
519 | { | |
520 | const char *ldp_state; | |
521 | struct ospf_if_params *params; | |
522 | char timebuf[OSPF_TIME_DUMP_SIZE]; | |
523 | struct ldp_sync_info *ldp_sync_info; | |
524 | ||
525 | params = IF_DEF_PARAMS(oi->ifp); | |
526 | if (params->ldp_sync_info == NULL) | |
527 | return; | |
528 | ||
529 | ldp_sync_info = params->ldp_sync_info; | |
530 | if (use_json) { | |
531 | if (ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) | |
532 | json_object_boolean_true_add(json_interface_sub, | |
533 | "ldpIgpSyncEnabled"); | |
534 | else | |
535 | json_object_boolean_false_add(json_interface_sub, | |
536 | "ldpIgpSyncEnabled"); | |
537 | ||
538 | json_object_int_add(json_interface_sub, "holdDownTimeInSec", | |
539 | ldp_sync_info->holddown); | |
540 | ||
541 | } else { | |
542 | vty_out(vty, "%-10s\n", ifp->name); | |
543 | vty_out(vty, " LDP-IGP Synchronization enabled: %s\n", | |
544 | ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED | |
545 | ? "yes" | |
546 | : "no"); | |
547 | vty_out(vty, " Holddown timer in seconds: %u\n", | |
548 | ldp_sync_info->holddown); | |
549 | } | |
550 | ||
551 | switch (ldp_sync_info->state) { | |
552 | case LDP_IGP_SYNC_STATE_REQUIRED_UP: | |
553 | if (use_json) | |
554 | json_object_string_add(json_interface_sub, | |
555 | "ldpIgpSyncState", | |
556 | "Sync achieved"); | |
557 | else | |
558 | vty_out(vty, " State: Sync achieved\n"); | |
559 | break; | |
560 | case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP: | |
561 | if (ldp_sync_info->t_holddown != NULL) { | |
562 | if (use_json) { | |
563 | long time_store; | |
564 | ||
565 | time_store = monotime_until( | |
566 | &ldp_sync_info->t_holddown->u.sands, | |
567 | NULL) | |
568 | /1000LL; | |
569 | ||
570 | json_object_int_add(json_interface_sub, | |
571 | "ldpIgpSyncTimeRemainInMsec", | |
572 | time_store); | |
573 | ||
574 | json_object_string_add(json_interface_sub, | |
575 | "ldpIgpSyncState", | |
576 | "Holding down until Sync"); | |
577 | } else { | |
578 | vty_out(vty, | |
579 | " Holddown timer is running %s remaining\n", | |
580 | ospf_timer_dump( | |
581 | ldp_sync_info->t_holddown, | |
582 | timebuf, | |
583 | sizeof(timebuf))); | |
584 | ||
585 | vty_out(vty, | |
586 | " State: Holding down until Sync\n"); | |
587 | } | |
588 | } else { | |
589 | if (use_json) | |
590 | json_object_string_add(json_interface_sub, | |
591 | "ldpIgpSyncState", | |
592 | "Sync not achieved"); | |
593 | else | |
594 | vty_out(vty, " State: Sync not achieved\n"); | |
595 | } | |
596 | break; | |
597 | case LDP_IGP_SYNC_STATE_NOT_REQUIRED: | |
598 | default: | |
599 | if (IF_DEF_PARAMS(ifp)->type != OSPF_IFTYPE_POINTOPOINT && | |
600 | !if_is_pointopoint(ifp)) | |
601 | ldp_state = "Sync not required: non-p2p link"; | |
602 | else | |
603 | ldp_state = "Sync not required"; | |
604 | ||
605 | if (use_json) | |
606 | json_object_string_add(json_interface_sub, | |
607 | "ldpIgpSyncState", | |
608 | ldp_state); | |
609 | else | |
610 | vty_out(vty, " State: %s\n", ldp_state); | |
611 | break; | |
612 | } | |
613 | } | |
614 | ||
615 | static int show_ip_ospf_mpls_ldp_interface_common(struct vty *vty, | |
616 | struct ospf *ospf, | |
617 | char *intf_name, | |
618 | json_object *json, | |
619 | bool use_json) | |
620 | { | |
621 | struct interface *ifp; | |
622 | struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); | |
623 | json_object *json_interface_sub = NULL; | |
624 | ||
625 | if (intf_name == NULL) { | |
626 | /* Show All Interfaces.*/ | |
627 | FOR_ALL_INTERFACES (vrf, ifp) { | |
628 | struct route_node *rn; | |
629 | struct ospf_interface *oi; | |
630 | ||
9919bec7 | 631 | if (ospf_oi_count(ifp) == 0 && !use_json) { |
632 | if (!if_is_up(ifp)) | |
633 | vty_out(vty, "%s\n Interface down\n", | |
634 | ifp->name); | |
132a782e | 635 | continue; |
9919bec7 | 636 | } |
132a782e | 637 | for (rn = route_top(IF_OIFS(ifp)); rn; |
638 | rn = route_next(rn)) { | |
639 | oi = rn->info; | |
640 | ||
641 | if (use_json) { | |
642 | json_interface_sub = | |
643 | json_object_new_object(); | |
644 | } | |
645 | show_ip_ospf_mpls_ldp_interface_sub( | |
646 | vty, oi, ifp, json_interface_sub, | |
647 | use_json); | |
648 | ||
649 | if (use_json) { | |
650 | json_object_object_add( | |
651 | json, ifp->name, | |
652 | json_interface_sub); | |
653 | } | |
654 | } | |
655 | } | |
656 | } else { | |
657 | /* Interface name is specified. */ | |
658 | ifp = if_lookup_by_name(intf_name, ospf->vrf_id); | |
659 | if (ifp != NULL) { | |
660 | struct route_node *rn; | |
661 | struct ospf_interface *oi; | |
662 | ||
663 | if (ospf_oi_count(ifp) == 0 && !use_json) { | |
9919bec7 | 664 | if (if_is_up(ifp)) |
665 | vty_out(vty, "%s\n OSPF not enabled\n", | |
666 | ifp->name); | |
667 | else | |
668 | vty_out(vty, "%s\n Interface down\n", | |
669 | ifp->name); | |
132a782e | 670 | return CMD_SUCCESS; |
671 | } | |
672 | for (rn = route_top(IF_OIFS(ifp)); rn; | |
673 | rn = route_next(rn)) { | |
674 | oi = rn->info; | |
675 | ||
676 | if (use_json) | |
677 | json_interface_sub = | |
678 | json_object_new_object(); | |
679 | ||
680 | show_ip_ospf_mpls_ldp_interface_sub( | |
681 | vty, oi, ifp, json_interface_sub, | |
682 | use_json); | |
683 | ||
684 | if (use_json) { | |
685 | json_object_object_add( | |
686 | json, ifp->name, | |
687 | json_interface_sub); | |
688 | } | |
689 | } | |
690 | } | |
691 | } | |
692 | return CMD_SUCCESS; | |
693 | } | |
694 | ||
695 | /* | |
696 | * Write the global LDP-SYNC configuration. | |
697 | */ | |
698 | void ospf_ldp_sync_write_config(struct vty *vty, struct ospf *ospf) | |
699 | { | |
700 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) | |
701 | vty_out(vty, " mpls ldp-sync\n"); | |
702 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN)) | |
703 | vty_out(vty, " mpls ldp-sync holddown %u\n", | |
704 | ospf->ldp_sync_cmd.holddown); | |
705 | } | |
706 | ||
707 | /* | |
708 | * Write the interface LDP-SYNC configuration. | |
709 | */ | |
710 | void ospf_ldp_sync_if_write_config(struct vty *vty, | |
711 | struct ospf_if_params *params) | |
712 | ||
713 | { | |
714 | struct ldp_sync_info *ldp_sync_info; | |
715 | ||
716 | ldp_sync_info = params->ldp_sync_info; | |
717 | if (ldp_sync_info == NULL) | |
718 | return; | |
719 | ||
720 | if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) { | |
721 | if (ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) | |
722 | vty_out(vty, " ip ospf mpls ldp-sync\n"); | |
723 | else | |
724 | vty_out(vty, " no ip ospf mpls ldp-sync\n"); | |
725 | } | |
726 | if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN)) | |
727 | vty_out(vty, " ip ospf mpls ldp-sync holddown %u\n", | |
728 | ldp_sync_info->holddown); | |
729 | } | |
730 | ||
731 | /* | |
732 | * LDP-SYNC commands. | |
733 | */ | |
132a782e | 734 | #include "ospfd/ospf_ldp_sync_clippy.c" |
132a782e | 735 | |
736 | DEFPY (ospf_mpls_ldp_sync, | |
737 | ospf_mpls_ldp_sync_cmd, | |
738 | "mpls ldp-sync", | |
739 | "MPLS specific commands\n" | |
740 | "Enable MPLS LDP-IGP Sync\n") | |
741 | { | |
742 | VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); | |
743 | struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); | |
744 | struct interface *ifp; | |
745 | ||
746 | if (ospf->vrf_id != VRF_DEFAULT) { | |
747 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); | |
748 | return CMD_ERR_NOTHING_TODO; | |
749 | } | |
750 | ||
751 | /* register with opaque client to recv LDP-IGP Sync msgs */ | |
752 | zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); | |
753 | zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); | |
132a782e | 754 | |
755 | if (!CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { | |
756 | SET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE); | |
757 | /* turn on LDP-IGP Sync on all ptop OSPF interfaces */ | |
758 | FOR_ALL_INTERFACES (vrf, ifp) | |
759 | ospf_if_set_ldp_sync_enable(ospf, ifp); | |
760 | } | |
761 | return CMD_SUCCESS; | |
762 | } | |
763 | ||
764 | DEFPY (no_ospf_mpls_ldp_sync, | |
765 | no_ospf_mpls_ldp_sync_cmd, | |
766 | "no mpls ldp-sync", | |
767 | NO_STR | |
768 | "MPLS specific commands\n" | |
769 | "Disable MPLS LDP-IGP Sync\n") | |
770 | { | |
771 | VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); | |
772 | ospf_ldp_sync_gbl_exit(ospf, false); | |
773 | return CMD_SUCCESS; | |
774 | } | |
775 | ||
776 | DEFPY (ospf_mpls_ldp_sync_holddown, | |
777 | ospf_mpls_ldp_sync_holddown_cmd, | |
778 | "mpls ldp-sync holddown (1-10000)", | |
779 | "MPLS specific commands\n" | |
780 | "Enable MPLS LDP-IGP Sync\n" | |
781 | "Set holddown timer\n" | |
782 | "seconds\n") | |
783 | { | |
784 | VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); | |
785 | struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); | |
786 | struct interface *ifp; | |
787 | ||
788 | if (ospf->vrf_id != VRF_DEFAULT) { | |
789 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); | |
790 | return CMD_ERR_NOTHING_TODO; | |
791 | } | |
792 | ||
793 | SET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN); | |
794 | ospf->ldp_sync_cmd.holddown = holddown; | |
795 | /* set holddown time on all OSPF interfaces */ | |
796 | FOR_ALL_INTERFACES (vrf, ifp) | |
797 | ospf_if_set_ldp_sync_holddown(ospf, ifp); | |
798 | ||
799 | return CMD_SUCCESS; | |
800 | } | |
801 | ||
802 | DEFPY (no_ospf_mpls_ldp_sync_holddown, | |
803 | no_ospf_mpls_ldp_sync_holddown_cmd, | |
804 | "no mpls ldp-sync holddown [<(1-10000)>]", | |
805 | NO_STR | |
806 | "MPLS specific commands\n" | |
807 | "Disable MPLS LDP-IGP Sync\n" | |
31011d9c IR |
808 | "holddown timer disable\n" |
809 | "Time in seconds\n") | |
132a782e | 810 | { |
811 | VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); | |
812 | struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); | |
813 | struct interface *ifp; | |
814 | ||
815 | if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN)) { | |
816 | UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN); | |
817 | ospf->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; | |
818 | /* turn off holddown timer on all OSPF interfaces */ | |
819 | FOR_ALL_INTERFACES (vrf, ifp) | |
820 | ospf_if_set_ldp_sync_holddown(ospf, ifp); | |
821 | } | |
822 | return CMD_SUCCESS; | |
823 | } | |
824 | ||
825 | ||
826 | DEFPY (mpls_ldp_sync, | |
827 | mpls_ldp_sync_cmd, | |
828 | "ip ospf mpls ldp-sync", | |
829 | IP_STR | |
830 | "OSPF interface commands\n" | |
831 | MPLS_STR | |
132a782e | 832 | MPLS_LDP_SYNC_STR) |
833 | { | |
834 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
835 | struct ospf_if_params *params; | |
836 | struct ldp_sync_info *ldp_sync_info; | |
837 | ||
838 | if (if_is_loopback(ifp)) { | |
839 | vty_out(vty, "ldp-sync does not run on loopback interface\n"); | |
840 | return CMD_ERR_NOTHING_TODO; | |
841 | } | |
842 | ||
096f7609 | 843 | if (ifp->vrf->vrf_id != VRF_DEFAULT) { |
132a782e | 844 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); |
845 | return CMD_ERR_NOTHING_TODO; | |
846 | } | |
847 | ||
848 | params = IF_DEF_PARAMS(ifp); | |
849 | if (params->ldp_sync_info == NULL) | |
850 | params->ldp_sync_info = ldp_sync_info_create(); | |
851 | ||
852 | ldp_sync_info = params->ldp_sync_info; | |
853 | ||
854 | SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); | |
855 | ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED; | |
856 | if (params->type == OSPF_IFTYPE_POINTOPOINT || if_is_pointopoint(ifp)) { | |
857 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; | |
858 | ospf_ldp_sync_state_req_msg(ifp); | |
859 | } else { | |
860 | zlog_debug("ldp_sync: only runs on P2P links %s", ifp->name); | |
861 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; | |
862 | } | |
863 | return CMD_SUCCESS; | |
864 | } | |
865 | ||
866 | DEFPY (no_mpls_ldp_sync, | |
867 | no_mpls_ldp_sync_cmd, | |
868 | "no ip ospf mpls ldp-sync", | |
869 | NO_STR | |
870 | IP_STR | |
871 | "OSPF interface commands\n" | |
872 | MPLS_STR | |
873 | NO_MPLS_LDP_SYNC_STR) | |
874 | { | |
875 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
876 | struct ospf_if_params *params; | |
877 | struct ldp_sync_info *ldp_sync_info; | |
878 | ||
879 | if (if_is_loopback(ifp)) { | |
880 | vty_out(vty, "ldp-sync: does not run on loopback interface\n"); | |
881 | return CMD_ERR_NOTHING_TODO; | |
882 | } | |
883 | ||
096f7609 | 884 | if (ifp->vrf->vrf_id != VRF_DEFAULT) { |
132a782e | 885 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); |
886 | return CMD_ERR_NOTHING_TODO; | |
887 | } | |
888 | ||
889 | params = IF_DEF_PARAMS(ifp); | |
890 | if (params->ldp_sync_info == NULL) | |
891 | params->ldp_sync_info = ldp_sync_info_create(); | |
892 | ||
893 | ldp_sync_info = params->ldp_sync_info; | |
894 | ||
895 | /* disable LDP-SYNC on an interface | |
896 | * stop holddown timer if running | |
897 | * restore ospf cost | |
898 | */ | |
899 | SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); | |
900 | ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; | |
901 | ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; | |
50478845 | 902 | THREAD_OFF(ldp_sync_info->t_holddown); |
132a782e | 903 | ospf_if_recalculate_output_cost(ifp); |
904 | ||
905 | return CMD_SUCCESS; | |
906 | } | |
907 | ||
908 | DEFPY (mpls_ldp_sync_holddown, | |
909 | mpls_ldp_sync_holddown_cmd, | |
910 | "ip ospf mpls ldp-sync holddown (0-10000)", | |
911 | IP_STR | |
912 | "OSPF interface commands\n" | |
913 | MPLS_STR | |
914 | MPLS_LDP_SYNC_STR | |
915 | "Time to wait for LDP-SYNC to occur before restoring interface cost\n" | |
916 | "Time in seconds\n") | |
917 | { | |
918 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
919 | struct ospf_if_params *params; | |
920 | struct ldp_sync_info *ldp_sync_info; | |
921 | ||
922 | if (if_is_loopback(ifp)) { | |
923 | vty_out(vty, "ldp-sync: does not run on loopback interface\n"); | |
924 | return CMD_ERR_NOTHING_TODO; | |
925 | } | |
926 | ||
096f7609 | 927 | if (ifp->vrf->vrf_id != VRF_DEFAULT) { |
132a782e | 928 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); |
929 | return CMD_ERR_NOTHING_TODO; | |
930 | } | |
931 | ||
932 | params = IF_DEF_PARAMS(ifp); | |
933 | if (params->ldp_sync_info == NULL) | |
934 | params->ldp_sync_info = ldp_sync_info_create(); | |
935 | ||
936 | ldp_sync_info = params->ldp_sync_info; | |
937 | ||
938 | SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN); | |
939 | ldp_sync_info->holddown = holddown; | |
940 | ||
941 | return CMD_SUCCESS; | |
942 | } | |
943 | ||
944 | DEFPY (no_mpls_ldp_sync_holddown, | |
945 | no_mpls_ldp_sync_holddown_cmd, | |
946 | "no ip ospf mpls ldp-sync holddown [<(1-10000)>]", | |
947 | NO_STR | |
948 | IP_STR | |
949 | "OSPF interface commands\n" | |
950 | MPLS_STR | |
951 | NO_MPLS_LDP_SYNC_STR | |
31011d9c IR |
952 | NO_MPLS_LDP_SYNC_HOLDDOWN_STR |
953 | "Time in seconds\n") | |
132a782e | 954 | { |
955 | VTY_DECLVAR_CONTEXT(interface, ifp); | |
956 | struct ospf_if_params *params; | |
957 | struct ldp_sync_info *ldp_sync_info; | |
958 | struct ospf *ospf; | |
959 | ||
960 | if (if_is_loopback(ifp)) { | |
961 | vty_out(vty, "ldp-sync: does not run on loopback interface\n"); | |
962 | return CMD_ERR_NOTHING_TODO; | |
963 | } | |
964 | ||
096f7609 | 965 | if (ifp->vrf->vrf_id != VRF_DEFAULT) { |
132a782e | 966 | vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n"); |
967 | return CMD_ERR_NOTHING_TODO; | |
968 | } | |
969 | ||
970 | params = IF_DEF_PARAMS(ifp); | |
971 | ldp_sync_info = params->ldp_sync_info; | |
972 | if (ldp_sync_info == NULL) | |
973 | return CMD_SUCCESS; | |
974 | ||
975 | /* use global configured value if set */ | |
976 | if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN)) { | |
977 | UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN); | |
978 | ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); | |
979 | if (ospf && CHECK_FLAG(ospf->ldp_sync_cmd.flags, | |
980 | LDP_SYNC_FLAG_HOLDDOWN)) | |
981 | ldp_sync_info->holddown = ospf->ldp_sync_cmd.holddown; | |
982 | else | |
983 | ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; | |
984 | } | |
985 | return CMD_SUCCESS; | |
986 | } | |
987 | ||
988 | DEFPY (show_ip_ospf_mpls_ldp_interface, | |
989 | show_ip_ospf_mpls_ldp_interface_cmd, | |
990 | "show ip ospf mpls ldp-sync [interface <INTERFACE|all>] [json]", | |
991 | SHOW_STR | |
992 | IP_STR | |
993 | "OSPF information\n" | |
994 | MPLS_STR | |
995 | "LDP-IGP Sync information\n" | |
31011d9c | 996 | "Interface information\n" |
132a782e | 997 | "Interface name\n" |
31011d9c | 998 | "All interfaces\n" |
132a782e | 999 | JSON_STR) |
1000 | { | |
1001 | struct ospf *ospf; | |
1002 | bool uj = use_json(argc, argv); | |
1003 | char *intf_name = NULL; | |
1004 | int ret = CMD_SUCCESS; | |
1005 | int idx_intf = 0; | |
1006 | json_object *json = NULL; | |
1007 | ||
1008 | if (argv_find(argv, argc, "INTERFACE", &idx_intf)) | |
1009 | intf_name = argv[idx_intf]->arg; | |
1010 | ||
1011 | if (uj) | |
1012 | json = json_object_new_object(); | |
1013 | ||
1014 | /* Display default ospf (instance 0) info */ | |
1015 | ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); | |
1016 | if (ospf == NULL || !ospf->oi_running) { | |
c48349e3 | 1017 | if (uj) |
92ef0078 | 1018 | vty_json(vty, json); |
c48349e3 | 1019 | else |
132a782e | 1020 | vty_out(vty, "%% OSPF instance not found\n"); |
1021 | return CMD_SUCCESS; | |
1022 | } | |
1023 | ||
1024 | if (!CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) { | |
c48349e3 | 1025 | if (uj) |
92ef0078 | 1026 | vty_json(vty, json); |
c48349e3 | 1027 | else |
132a782e | 1028 | vty_out(vty, "LDP-sync is disabled\n"); |
1029 | return CMD_SUCCESS; | |
1030 | } | |
1031 | ||
1032 | ret = show_ip_ospf_mpls_ldp_interface_common(vty, ospf, intf_name, | |
1033 | json, uj); | |
c48349e3 | 1034 | if (uj) |
92ef0078 | 1035 | vty_json(vty, json); |
132a782e | 1036 | |
1037 | return ret; | |
1038 | } | |
1039 | ||
1040 | void ospf_ldp_sync_init(void) | |
1041 | { | |
1042 | /* Install global ldp-igp sync commands */ | |
1043 | install_element(OSPF_NODE, &ospf_mpls_ldp_sync_cmd); | |
1044 | install_element(OSPF_NODE, &no_ospf_mpls_ldp_sync_cmd); | |
1045 | install_element(OSPF_NODE, &ospf_mpls_ldp_sync_holddown_cmd); | |
1046 | install_element(OSPF_NODE, &no_ospf_mpls_ldp_sync_holddown_cmd); | |
1047 | ||
1048 | /* Interface lsp-igp sync commands */ | |
1049 | install_element(INTERFACE_NODE, &mpls_ldp_sync_cmd); | |
1050 | install_element(INTERFACE_NODE, &no_mpls_ldp_sync_cmd); | |
1051 | install_element(INTERFACE_NODE, &mpls_ldp_sync_holddown_cmd); | |
1052 | install_element(INTERFACE_NODE, &no_mpls_ldp_sync_holddown_cmd); | |
1053 | ||
1054 | /* "show ip ospf mpls ldp interface" commands. */ | |
1055 | install_element(VIEW_NODE, &show_ip_ospf_mpls_ldp_interface_cmd); | |
1056 | ||
1057 | hook_register(ospf_ism_change, ospf_ldp_sync_ism_change); | |
1058 | ||
1059 | } |