2 * ospf_ldp_sync.c: OSPF LDP-IGP Sync handling routines
3 * Copyright (C) 2020 Volta Networks, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38 #include "ospf_interface.h"
40 #include "ospf_ldp_sync.h"
41 #include "ospf_dump.h"
44 extern struct zclient
*zclient
;
47 * LDP-SYNC msg between IGP and LDP
49 int ospf_ldp_sync_state_update(struct ldp_igp_sync_if_state state
)
52 struct interface
*ifp
;
54 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
55 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
57 !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
60 /* received ldp-sync interface state from LDP */
61 ifp
= if_lookup_by_index(state
.ifindex
, VRF_DEFAULT
);
62 if (ifp
== NULL
|| if_is_loopback(ifp
))
65 ols_debug("ldp_sync: rcvd %s from LDP if %s",
66 state
.sync_start
? "sync-start" : "sync-complete",
69 ospf_ldp_sync_if_start(ifp
, false);
71 ospf_ldp_sync_if_complete(ifp
);
76 int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce
)
80 struct interface
*ifp
;
82 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
83 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
85 !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
88 if (announce
.proto
!= ZEBRA_ROUTE_LDP
)
91 ols_debug("ldp_sync: rcvd announce from LDP");
93 /* LDP just started up:
94 * set cost to LSInfinity
95 * send request to LDP for LDP-SYNC state for each interface
97 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
98 FOR_ALL_INTERFACES (vrf
, ifp
)
99 ospf_ldp_sync_if_start(ifp
, true);
104 void ospf_ldp_sync_state_req_msg(struct interface
*ifp
)
106 struct ldp_igp_sync_if_state_req request
;
108 ols_debug("ldp_sync: send state request to LDP for %s", ifp
->name
);
110 memset(&request
, 0, sizeof(request
));
111 strlcpy(request
.name
, ifp
->name
, sizeof(ifp
->name
));
112 request
.proto
= LDP_IGP_SYNC_IF_STATE_REQUEST
;
113 request
.ifindex
= ifp
->ifindex
;
115 zclient_send_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_REQUEST
,
116 (uint8_t *)&request
, sizeof(request
));
120 * LDP-SYNC general interface routines
122 void ospf_ldp_sync_if_init(struct ospf_interface
*oi
)
124 struct ospf_if_params
*params
;
125 struct ldp_sync_info
*ldp_sync_info
;
126 struct interface
*ifp
= oi
->ifp
;
128 /* called when OSPF is configured on an interface:
129 * if LDP-IGP Sync is configured globally set state
130 * if ptop interface inform LDP LDP-SYNC is enabled
132 if (if_is_loopback(ifp
) || (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
)
133 || !(CHECK_FLAG(oi
->ospf
->ldp_sync_cmd
.flags
,
134 LDP_SYNC_FLAG_ENABLE
)))
137 ols_debug("ldp_sync: init if %s",ifp
->name
);
138 params
= IF_DEF_PARAMS(ifp
);
139 if (params
->ldp_sync_info
== NULL
)
140 params
->ldp_sync_info
= ldp_sync_info_create();
142 ldp_sync_info
= params
->ldp_sync_info
;
144 /* specified on interface overrides global config. */
145 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
146 ldp_sync_info
->holddown
= oi
->ospf
->ldp_sync_cmd
.holddown
;
148 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
149 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
151 if ((params
->type
== OSPF_IFTYPE_POINTOPOINT
||
152 if_is_pointopoint(ifp
)) &&
153 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
154 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
157 void ospf_ldp_sync_if_start(struct interface
*ifp
, bool send_state_req
)
159 struct ospf_if_params
*params
;
160 struct ldp_sync_info
*ldp_sync_info
;
162 if (if_is_loopback(ifp
))
165 params
= IF_DEF_PARAMS(ifp
);
166 ldp_sync_info
= params
->ldp_sync_info
;
168 /* Start LDP-SYNC on this interface:
169 * set cost of interface to LSInfinity so traffic will use different
170 * interface until LDP has learned all labels from peer
171 * start holddown timer if configured
172 * send msg to LDP to get LDP-SYNC state
175 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
176 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
177 ols_debug("ldp_sync: start on if %s state: %s",
178 ifp
->name
, "Holding down until Sync");
179 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
180 ospf_if_recalculate_output_cost(ifp
);
181 ospf_ldp_sync_holddown_timer_add(ifp
);
184 ospf_ldp_sync_state_req_msg(ifp
);
188 void ospf_ldp_sync_if_complete(struct interface
*ifp
)
190 struct ospf_if_params
*params
;
191 struct ldp_sync_info
*ldp_sync_info
;
193 if (if_is_loopback(ifp
))
196 params
= IF_DEF_PARAMS(ifp
);
197 ldp_sync_info
= params
->ldp_sync_info
;
199 /* received sync-complete from LDP:
202 * restore interface cost to original value
204 if (ldp_sync_info
&& ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
) {
205 if (ldp_sync_info
->state
== LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
)
206 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_UP
;
207 THREAD_OFF(ldp_sync_info
->t_holddown
);
208 ospf_if_recalculate_output_cost(ifp
);
212 void ospf_ldp_sync_handle_client_close(struct zapi_client_close_info
*info
)
216 struct interface
*ifp
;
218 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
219 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
221 || !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
224 /* Check if the LDP main client session closed */
225 if (info
->proto
!= ZEBRA_ROUTE_LDP
|| info
->session_id
== 0)
228 /* Handle the zebra notification that the LDP client session closed.
229 * set cost to LSInfinity
230 * send request to LDP for LDP-SYNC state for each interface
232 zlog_err("ldp_sync: LDP down");
234 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
235 FOR_ALL_INTERFACES (vrf
, ifp
)
236 ospf_ldp_sync_ldp_fail(ifp
);
239 void ospf_ldp_sync_ldp_fail(struct interface
*ifp
)
241 struct ospf_if_params
*params
;
242 struct ldp_sync_info
*ldp_sync_info
;
244 if (if_is_loopback(ifp
))
247 params
= IF_DEF_PARAMS(ifp
);
248 ldp_sync_info
= params
->ldp_sync_info
;
250 /* LDP client close detected:
251 * stop holddown timer
252 * set cost of interface to LSInfinity so traffic will use different
253 * interface until LDP has learned all labels from peer
256 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
257 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
258 THREAD_OFF(ldp_sync_info
->t_holddown
);
259 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
260 ospf_if_recalculate_output_cost(ifp
);
264 void ospf_ldp_sync_if_down(struct interface
*ifp
)
266 struct ospf_if_params
*params
;
267 struct ldp_sync_info
*ldp_sync_info
;
269 if (if_is_loopback(ifp
))
272 params
= IF_DEF_PARAMS(ifp
);
273 ldp_sync_info
= params
->ldp_sync_info
;
275 if (ldp_sync_if_down(ldp_sync_info
) == false)
278 ols_debug("ldp_sync: down on if %s", ifp
->name
);
281 * can occur from a link down or changing config
282 * ospf network type change interface is brought down/up
284 switch (ldp_sync_info
->state
) {
285 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
286 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
287 if (params
->type
!= OSPF_IFTYPE_POINTOPOINT
&&
288 !if_is_pointopoint(ifp
))
289 /* LDP-SYNC not able to run on non-ptop interface */
290 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
292 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
293 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
294 if_is_pointopoint(ifp
))
295 /* LDP-SYNC is able to run on ptop interface */
296 ldp_sync_info
->state
=
297 LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
304 void ospf_ldp_sync_if_remove(struct interface
*ifp
, bool remove
)
306 struct ospf_if_params
*params
;
307 struct ldp_sync_info
*ldp_sync_info
;
309 params
= IF_DEF_PARAMS(ifp
);
310 if (params
->ldp_sync_info
== NULL
)
313 ldp_sync_info
= params
->ldp_sync_info
;
315 /* Stop LDP-SYNC on this interface:
316 * if holddown timer is running stop it
317 * delete ldp instance on interface
320 ols_debug("ldp_sync: Removed from if %s", ifp
->name
);
322 THREAD_OFF(ldp_sync_info
->t_holddown
);
324 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
325 ospf_if_recalculate_output_cost(ifp
);
326 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
327 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
329 ldp_sync_info_free((struct ldp_sync_info
**)&(ldp_sync_info
));
330 params
->ldp_sync_info
= NULL
;
334 static int ospf_ldp_sync_ism_change(struct ospf_interface
*oi
, int state
,
337 /* Terminal state or regression */
339 case ISM_PointToPoint
:
340 /* If LDP-SYNC is configure on interface then start */
341 ospf_ldp_sync_if_start(oi
->ifp
, true);
344 /* If LDP-SYNC is configure on this interface then stop it */
345 ospf_ldp_sync_if_down(oi
->ifp
);
354 * LDP-SYNC holddown timer routines
356 static void ospf_ldp_sync_holddown_timer(struct thread
*thread
)
358 struct interface
*ifp
;
359 struct ospf_if_params
*params
;
360 struct ldp_sync_info
*ldp_sync_info
;
362 /* holddown timer expired:
363 * didn't receive msg from LDP indicating sync-complete
364 * restore interface cost to original value
366 ifp
= THREAD_ARG(thread
);
367 params
= IF_DEF_PARAMS(ifp
);
368 if (params
->ldp_sync_info
) {
369 ldp_sync_info
= params
->ldp_sync_info
;
371 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_UP
;
373 ols_debug("ldp_sync: holddown timer expired for %s state: %s",
374 ifp
->name
, "Sync achieved");
376 ospf_if_recalculate_output_cost(ifp
);
380 void ospf_ldp_sync_holddown_timer_add(struct interface
*ifp
)
382 struct ospf_if_params
*params
;
383 struct ldp_sync_info
*ldp_sync_info
;
385 params
= IF_DEF_PARAMS(ifp
);
386 ldp_sync_info
= params
->ldp_sync_info
;
388 /* Start holddown timer:
389 * this timer is used to keep interface cost at LSInfinity
390 * once expires returns cost to original value
391 * if timer is already running or holddown time is off just return
393 if (ldp_sync_info
->t_holddown
||
394 ldp_sync_info
->holddown
== LDP_IGP_SYNC_HOLDDOWN_DEFAULT
)
397 ols_debug("ldp_sync: start holddown timer for %s time %d",
398 ifp
->name
, ldp_sync_info
->holddown
);
400 thread_add_timer(master
, ospf_ldp_sync_holddown_timer
,
401 ifp
, ldp_sync_info
->holddown
,
402 &ldp_sync_info
->t_holddown
);
406 * LDP-SYNC exit routes.
408 void ospf_ldp_sync_gbl_exit(struct ospf
*ospf
, bool remove
)
410 struct interface
*ifp
;
413 /* ospf is being removed
414 * stop any holddown timers
416 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
417 /* unregister with opaque client to recv LDP-IGP Sync msgs */
418 zclient_unregister_opaque(zclient
,
419 LDP_IGP_SYNC_IF_STATE_UPDATE
);
420 zclient_unregister_opaque(zclient
,
421 LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
423 /* disable LDP globally */
424 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
425 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
426 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
428 /* turn off LDP-IGP Sync on all OSPF interfaces */
429 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
430 FOR_ALL_INTERFACES (vrf
, ifp
)
431 ospf_ldp_sync_if_remove(ifp
, remove
);
436 * LDP-SYNC routes used by set commands.
438 void ospf_if_set_ldp_sync_enable(struct ospf
*ospf
, struct interface
*ifp
)
440 struct ospf_if_params
*params
;
441 struct ldp_sync_info
*ldp_sync_info
;
443 /* called when setting LDP-SYNC at the global level:
444 * specified on interface overrides global config
445 * if ptop link send msg to LDP indicating ldp-sync enabled
447 if (if_is_loopback(ifp
))
450 params
= IF_DEF_PARAMS(ifp
);
451 if (params
->ldp_sync_info
== NULL
)
452 params
->ldp_sync_info
= ldp_sync_info_create();
453 ldp_sync_info
= params
->ldp_sync_info
;
455 /* config on interface, overrides global config. */
456 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
457 if (ldp_sync_info
->enabled
!= LDP_IGP_SYNC_ENABLED
)
460 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
462 ols_debug("ldp_sync: enable if %s", ifp
->name
);
464 /* send message to LDP if ptop link */
465 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
466 if_is_pointopoint(ifp
)) {
467 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
468 ospf_ldp_sync_state_req_msg(ifp
);
470 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
471 zlog_debug("ldp_sync: Sync only runs on P2P links %s",
476 void ospf_if_set_ldp_sync_holddown(struct ospf
*ospf
, struct interface
*ifp
)
478 struct ospf_if_params
*params
;
479 struct ldp_sync_info
*ldp_sync_info
;
481 /* called when setting LDP-SYNC at the global level:
482 * specified on interface overrides global config.
484 if (if_is_loopback(ifp
))
487 params
= IF_DEF_PARAMS(ifp
);
488 if (params
->ldp_sync_info
== NULL
)
489 params
->ldp_sync_info
= ldp_sync_info_create();
490 ldp_sync_info
= params
->ldp_sync_info
;
492 /* config on interface, overrides global config. */
493 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
495 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
496 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
498 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
502 * LDP-SYNC routines used by show commands.
505 void ospf_ldp_sync_show_info(struct vty
*vty
, struct ospf
*ospf
,
506 json_object
*json_vrf
, bool use_json
)
509 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
511 #if CONFDATE > 20230131
512 CPP_NOTICE("Remove JSON object commands with keys starting with capital")
514 json_object_boolean_true_add(json_vrf
,
515 "MplsLdpIgpSyncEnabled");
516 json_object_boolean_true_add(json_vrf
,
517 "mplsLdpIgpSyncEnabled");
518 json_object_int_add(json_vrf
, "MplsLdpIgpSyncHolddown",
519 ospf
->ldp_sync_cmd
.holddown
);
520 json_object_int_add(json_vrf
, "mplsLdpIgpSyncHolddown",
521 ospf
->ldp_sync_cmd
.holddown
);
523 vty_out(vty
, " MPLS LDP-IGP Sync is enabled\n");
524 if (ospf
->ldp_sync_cmd
.holddown
== 0)
526 " MPLS LDP-IGP Sync holddown timer is disabled\n");
529 " MPLS LDP-IGP Sync holddown timer %d sec\n",
530 ospf
->ldp_sync_cmd
.holddown
);
535 static void show_ip_ospf_mpls_ldp_interface_sub(struct vty
*vty
,
536 struct ospf_interface
*oi
,
537 struct interface
*ifp
,
538 json_object
*json_interface_sub
,
541 const char *ldp_state
;
542 struct ospf_if_params
*params
;
543 char timebuf
[OSPF_TIME_DUMP_SIZE
];
544 struct ldp_sync_info
*ldp_sync_info
;
546 params
= IF_DEF_PARAMS(oi
->ifp
);
547 if (params
->ldp_sync_info
== NULL
)
550 ldp_sync_info
= params
->ldp_sync_info
;
552 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
553 json_object_boolean_true_add(json_interface_sub
,
554 "ldpIgpSyncEnabled");
556 json_object_boolean_false_add(json_interface_sub
,
557 "ldpIgpSyncEnabled");
559 json_object_int_add(json_interface_sub
, "holdDownTimeInSec",
560 ldp_sync_info
->holddown
);
563 vty_out(vty
, "%-10s\n", ifp
->name
);
564 vty_out(vty
, " LDP-IGP Synchronization enabled: %s\n",
565 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
568 vty_out(vty
, " Holddown timer in seconds: %u\n",
569 ldp_sync_info
->holddown
);
572 switch (ldp_sync_info
->state
) {
573 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
575 json_object_string_add(json_interface_sub
,
579 vty_out(vty
, " State: Sync achieved\n");
581 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
582 if (ldp_sync_info
->t_holddown
!= NULL
) {
586 time_store
= monotime_until(
587 &ldp_sync_info
->t_holddown
->u
.sands
,
591 json_object_int_add(json_interface_sub
,
592 "ldpIgpSyncTimeRemainInMsec",
595 json_object_string_add(json_interface_sub
,
597 "Holding down until Sync");
600 " Holddown timer is running %s remaining\n",
602 ldp_sync_info
->t_holddown
,
607 " State: Holding down until Sync\n");
611 json_object_string_add(json_interface_sub
,
613 "Sync not achieved");
615 vty_out(vty
, " State: Sync not achieved\n");
618 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
620 if (IF_DEF_PARAMS(ifp
)->type
!= OSPF_IFTYPE_POINTOPOINT
&&
621 !if_is_pointopoint(ifp
))
622 ldp_state
= "Sync not required: non-p2p link";
624 ldp_state
= "Sync not required";
627 json_object_string_add(json_interface_sub
,
631 vty_out(vty
, " State: %s\n", ldp_state
);
636 static int show_ip_ospf_mpls_ldp_interface_common(struct vty
*vty
,
642 struct interface
*ifp
;
643 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
644 json_object
*json_interface_sub
= NULL
;
646 if (intf_name
== NULL
) {
647 /* Show All Interfaces.*/
648 FOR_ALL_INTERFACES (vrf
, ifp
) {
649 struct route_node
*rn
;
650 struct ospf_interface
*oi
;
652 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
654 vty_out(vty
, "%s\n Interface down\n",
658 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
659 rn
= route_next(rn
)) {
664 json_object_new_object();
666 show_ip_ospf_mpls_ldp_interface_sub(
667 vty
, oi
, ifp
, json_interface_sub
,
671 json_object_object_add(
678 /* Interface name is specified. */
679 ifp
= if_lookup_by_name(intf_name
, ospf
->vrf_id
);
681 struct route_node
*rn
;
682 struct ospf_interface
*oi
;
684 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
686 vty_out(vty
, "%s\n OSPF not enabled\n",
689 vty_out(vty
, "%s\n Interface down\n",
693 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
694 rn
= route_next(rn
)) {
699 json_object_new_object();
701 show_ip_ospf_mpls_ldp_interface_sub(
702 vty
, oi
, ifp
, json_interface_sub
,
706 json_object_object_add(
717 * Write the global LDP-SYNC configuration.
719 void ospf_ldp_sync_write_config(struct vty
*vty
, struct ospf
*ospf
)
721 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
722 vty_out(vty
, " mpls ldp-sync\n");
723 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
724 vty_out(vty
, " mpls ldp-sync holddown %u\n",
725 ospf
->ldp_sync_cmd
.holddown
);
729 * Write the interface LDP-SYNC configuration.
731 void ospf_ldp_sync_if_write_config(struct vty
*vty
,
732 struct ospf_if_params
*params
)
735 struct ldp_sync_info
*ldp_sync_info
;
737 ldp_sync_info
= params
->ldp_sync_info
;
738 if (ldp_sync_info
== NULL
)
741 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
)) {
742 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
743 vty_out(vty
, " ip ospf mpls ldp-sync\n");
745 vty_out(vty
, " no ip ospf mpls ldp-sync\n");
747 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
748 vty_out(vty
, " ip ospf mpls ldp-sync holddown %u\n",
749 ldp_sync_info
->holddown
);
755 #ifndef VTYSH_EXTRACT_PL
756 #include "ospfd/ospf_ldp_sync_clippy.c"
759 DEFPY (ospf_mpls_ldp_sync
,
760 ospf_mpls_ldp_sync_cmd
,
762 "MPLS specific commands\n"
763 "Enable MPLS LDP-IGP Sync\n")
765 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
766 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
767 struct interface
*ifp
;
769 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
770 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
771 return CMD_ERR_NOTHING_TODO
;
774 /* register with opaque client to recv LDP-IGP Sync msgs */
775 zclient_register_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_UPDATE
);
776 zclient_register_opaque(zclient
, LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
778 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
779 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
780 /* turn on LDP-IGP Sync on all ptop OSPF interfaces */
781 FOR_ALL_INTERFACES (vrf
, ifp
)
782 ospf_if_set_ldp_sync_enable(ospf
, ifp
);
787 DEFPY (no_ospf_mpls_ldp_sync
,
788 no_ospf_mpls_ldp_sync_cmd
,
791 "MPLS specific commands\n"
792 "Disable MPLS LDP-IGP Sync\n")
794 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
795 ospf_ldp_sync_gbl_exit(ospf
, false);
799 DEFPY (ospf_mpls_ldp_sync_holddown
,
800 ospf_mpls_ldp_sync_holddown_cmd
,
801 "mpls ldp-sync holddown (1-10000)",
802 "MPLS specific commands\n"
803 "Enable MPLS LDP-IGP Sync\n"
804 "Set holddown timer\n"
807 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
808 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
809 struct interface
*ifp
;
811 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
812 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
813 return CMD_ERR_NOTHING_TODO
;
816 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
817 ospf
->ldp_sync_cmd
.holddown
= holddown
;
818 /* set holddown time on all OSPF interfaces */
819 FOR_ALL_INTERFACES (vrf
, ifp
)
820 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
825 DEFPY (no_ospf_mpls_ldp_sync_holddown
,
826 no_ospf_mpls_ldp_sync_holddown_cmd
,
827 "no mpls ldp-sync holddown [<(1-10000)>]",
829 "MPLS specific commands\n"
830 "Disable MPLS LDP-IGP Sync\n"
831 "holddown timer disable\n"
834 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
835 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
836 struct interface
*ifp
;
838 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
839 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
840 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
841 /* turn off holddown timer on all OSPF interfaces */
842 FOR_ALL_INTERFACES (vrf
, ifp
)
843 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
849 DEFPY (mpls_ldp_sync
,
851 "ip ospf mpls ldp-sync",
853 "OSPF interface commands\n"
857 VTY_DECLVAR_CONTEXT(interface
, ifp
);
858 struct ospf_if_params
*params
;
859 struct ldp_sync_info
*ldp_sync_info
;
861 if (if_is_loopback(ifp
)) {
862 vty_out(vty
, "ldp-sync does not run on loopback interface\n");
863 return CMD_ERR_NOTHING_TODO
;
866 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
867 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
868 return CMD_ERR_NOTHING_TODO
;
871 params
= IF_DEF_PARAMS(ifp
);
872 if (params
->ldp_sync_info
== NULL
)
873 params
->ldp_sync_info
= ldp_sync_info_create();
875 ldp_sync_info
= params
->ldp_sync_info
;
877 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
878 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
879 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
|| if_is_pointopoint(ifp
)) {
880 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
881 ospf_ldp_sync_state_req_msg(ifp
);
883 zlog_debug("ldp_sync: only runs on P2P links %s", ifp
->name
);
884 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
889 DEFPY (no_mpls_ldp_sync
,
890 no_mpls_ldp_sync_cmd
,
891 "no ip ospf mpls ldp-sync",
894 "OSPF interface commands\n"
896 NO_MPLS_LDP_SYNC_STR
)
898 VTY_DECLVAR_CONTEXT(interface
, ifp
);
899 struct ospf_if_params
*params
;
900 struct ldp_sync_info
*ldp_sync_info
;
902 if (if_is_loopback(ifp
)) {
903 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
904 return CMD_ERR_NOTHING_TODO
;
907 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
908 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
909 return CMD_ERR_NOTHING_TODO
;
912 params
= IF_DEF_PARAMS(ifp
);
913 if (params
->ldp_sync_info
== NULL
)
914 params
->ldp_sync_info
= ldp_sync_info_create();
916 ldp_sync_info
= params
->ldp_sync_info
;
918 /* disable LDP-SYNC on an interface
919 * stop holddown timer if running
922 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
923 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
924 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
925 THREAD_OFF(ldp_sync_info
->t_holddown
);
926 ospf_if_recalculate_output_cost(ifp
);
931 DEFPY (mpls_ldp_sync_holddown
,
932 mpls_ldp_sync_holddown_cmd
,
933 "ip ospf mpls ldp-sync holddown (0-10000)",
935 "OSPF interface commands\n"
938 "Time to wait for LDP-SYNC to occur before restoring interface cost\n"
941 VTY_DECLVAR_CONTEXT(interface
, ifp
);
942 struct ospf_if_params
*params
;
943 struct ldp_sync_info
*ldp_sync_info
;
945 if (if_is_loopback(ifp
)) {
946 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
947 return CMD_ERR_NOTHING_TODO
;
950 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
951 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
952 return CMD_ERR_NOTHING_TODO
;
955 params
= IF_DEF_PARAMS(ifp
);
956 if (params
->ldp_sync_info
== NULL
)
957 params
->ldp_sync_info
= ldp_sync_info_create();
959 ldp_sync_info
= params
->ldp_sync_info
;
961 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
962 ldp_sync_info
->holddown
= holddown
;
967 DEFPY (no_mpls_ldp_sync_holddown
,
968 no_mpls_ldp_sync_holddown_cmd
,
969 "no ip ospf mpls ldp-sync holddown [<(1-10000)>]",
972 "OSPF interface commands\n"
975 NO_MPLS_LDP_SYNC_HOLDDOWN_STR
978 VTY_DECLVAR_CONTEXT(interface
, ifp
);
979 struct ospf_if_params
*params
;
980 struct ldp_sync_info
*ldp_sync_info
;
983 if (if_is_loopback(ifp
)) {
984 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
985 return CMD_ERR_NOTHING_TODO
;
988 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
989 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
990 return CMD_ERR_NOTHING_TODO
;
993 params
= IF_DEF_PARAMS(ifp
);
994 ldp_sync_info
= params
->ldp_sync_info
;
995 if (ldp_sync_info
== NULL
)
998 /* use global configured value if set */
999 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
1000 UNSET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
1001 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1002 if (ospf
&& CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
,
1003 LDP_SYNC_FLAG_HOLDDOWN
))
1004 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
1006 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
1011 DEFPY (show_ip_ospf_mpls_ldp_interface
,
1012 show_ip_ospf_mpls_ldp_interface_cmd
,
1013 "show ip ospf mpls ldp-sync [interface <INTERFACE|all>] [json]",
1016 "OSPF information\n"
1018 "LDP-IGP Sync information\n"
1019 "Interface information\n"
1025 bool uj
= use_json(argc
, argv
);
1026 char *intf_name
= NULL
;
1027 int ret
= CMD_SUCCESS
;
1029 json_object
*json
= NULL
;
1031 if (argv_find(argv
, argc
, "INTERFACE", &idx_intf
))
1032 intf_name
= argv
[idx_intf
]->arg
;
1035 json
= json_object_new_object();
1037 /* Display default ospf (instance 0) info */
1038 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1039 if (ospf
== NULL
|| !ospf
->oi_running
) {
1041 vty_json(vty
, json
);
1043 vty_out(vty
, "%% OSPF instance not found\n");
1047 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
1049 vty_json(vty
, json
);
1051 vty_out(vty
, "LDP-sync is disabled\n");
1055 ret
= show_ip_ospf_mpls_ldp_interface_common(vty
, ospf
, intf_name
,
1058 vty_json(vty
, json
);
1063 void ospf_ldp_sync_init(void)
1065 /* Install global ldp-igp sync commands */
1066 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_cmd
);
1067 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_cmd
);
1068 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_holddown_cmd
);
1069 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_holddown_cmd
);
1071 /* Interface lsp-igp sync commands */
1072 install_element(INTERFACE_NODE
, &mpls_ldp_sync_cmd
);
1073 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_cmd
);
1074 install_element(INTERFACE_NODE
, &mpls_ldp_sync_holddown_cmd
);
1075 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_holddown_cmd
);
1077 /* "show ip ospf mpls ldp interface" commands. */
1078 install_element(VIEW_NODE
, &show_ip_ospf_mpls_ldp_interface_cmd
);
1080 hook_register(ospf_ism_change
, ospf_ldp_sync_ism_change
);