1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ospf_ldp_sync.c: OSPF LDP-IGP Sync handling routines
4 * Copyright (C) 2020 Volta Networks, Inc.
25 #include "ospf_interface.h"
27 #include "ospf_ldp_sync.h"
28 #include "ospf_dump.h"
31 extern struct zclient
*zclient
;
34 * LDP-SYNC msg between IGP and LDP
36 int ospf_ldp_sync_state_update(struct ldp_igp_sync_if_state state
)
39 struct interface
*ifp
;
41 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
42 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
44 !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
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
))
52 ols_debug("%s: rcvd %s from LDP if %s", __func__
,
53 state
.sync_start
? "sync-start" : "sync-complete", ifp
->name
);
55 ospf_ldp_sync_if_start(ifp
, false);
57 ospf_ldp_sync_if_complete(ifp
);
62 int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce
)
66 struct interface
*ifp
;
68 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
69 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
71 !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
74 if (announce
.proto
!= ZEBRA_ROUTE_LDP
)
77 ols_debug("%s: rcvd announce from LDP", __func__
);
79 /* LDP just started up:
80 * set cost to LSInfinity
81 * send request to LDP for LDP-SYNC state for each interface
83 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
84 FOR_ALL_INTERFACES (vrf
, ifp
)
85 ospf_ldp_sync_if_start(ifp
, true);
90 void ospf_ldp_sync_state_req_msg(struct interface
*ifp
)
92 struct ldp_igp_sync_if_state_req request
;
94 ols_debug("%s: send state request to LDP for %s", __func__
, ifp
->name
);
96 memset(&request
, 0, sizeof(request
));
97 strlcpy(request
.name
, ifp
->name
, sizeof(ifp
->name
));
98 request
.proto
= LDP_IGP_SYNC_IF_STATE_REQUEST
;
99 request
.ifindex
= ifp
->ifindex
;
101 zclient_send_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_REQUEST
,
102 (uint8_t *)&request
, sizeof(request
));
106 * LDP-SYNC general interface routines
108 void ospf_ldp_sync_if_init(struct ospf_interface
*oi
)
110 struct ospf_if_params
*params
;
111 struct ldp_sync_info
*ldp_sync_info
;
112 struct interface
*ifp
= oi
->ifp
;
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
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
)))
123 ols_debug("%s: init if %s", __func__
, ifp
->name
);
124 params
= IF_DEF_PARAMS(ifp
);
125 if (params
->ldp_sync_info
== NULL
)
126 params
->ldp_sync_info
= ldp_sync_info_create();
128 ldp_sync_info
= params
->ldp_sync_info
;
130 /* specified on interface overrides global config. */
131 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
132 ldp_sync_info
->holddown
= oi
->ospf
->ldp_sync_cmd
.holddown
;
134 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
135 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
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
;
143 void ospf_ldp_sync_if_start(struct interface
*ifp
, bool send_state_req
)
145 struct ospf_if_params
*params
;
146 struct ldp_sync_info
*ldp_sync_info
;
148 if (if_is_loopback(ifp
))
151 params
= IF_DEF_PARAMS(ifp
);
152 ldp_sync_info
= params
->ldp_sync_info
;
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
161 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
162 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
163 ols_debug("%s: start on if %s state: %s", __func__
, ifp
->name
,
164 "Holding down until Sync");
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
);
170 ospf_ldp_sync_state_req_msg(ifp
);
174 void ospf_ldp_sync_if_complete(struct interface
*ifp
)
176 struct ospf_if_params
*params
;
177 struct ldp_sync_info
*ldp_sync_info
;
179 if (if_is_loopback(ifp
))
182 params
= IF_DEF_PARAMS(ifp
);
183 ldp_sync_info
= params
->ldp_sync_info
;
185 /* received sync-complete from LDP:
188 * restore interface cost to original value
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
;
193 THREAD_OFF(ldp_sync_info
->t_holddown
);
194 ospf_if_recalculate_output_cost(ifp
);
198 void ospf_ldp_sync_handle_client_close(struct zapi_client_close_info
*info
)
202 struct interface
*ifp
;
204 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
205 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
207 || !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
210 /* Check if the LDP main client session closed */
211 if (info
->proto
!= ZEBRA_ROUTE_LDP
|| info
->session_id
== 0)
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
218 zlog_err("%s: LDP down", __func__
);
220 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
221 FOR_ALL_INTERFACES (vrf
, ifp
)
222 ospf_ldp_sync_ldp_fail(ifp
);
225 void ospf_ldp_sync_ldp_fail(struct interface
*ifp
)
227 struct ospf_if_params
*params
;
228 struct ldp_sync_info
*ldp_sync_info
;
230 if (if_is_loopback(ifp
))
233 params
= IF_DEF_PARAMS(ifp
);
234 ldp_sync_info
= params
->ldp_sync_info
;
236 /* LDP client close detected:
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
242 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
243 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
244 THREAD_OFF(ldp_sync_info
->t_holddown
);
245 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
246 ospf_if_recalculate_output_cost(ifp
);
250 void ospf_ldp_sync_if_down(struct interface
*ifp
)
252 struct ospf_if_params
*params
;
253 struct ldp_sync_info
*ldp_sync_info
;
255 if (if_is_loopback(ifp
))
258 params
= IF_DEF_PARAMS(ifp
);
259 ldp_sync_info
= params
->ldp_sync_info
;
261 if (ldp_sync_if_down(ldp_sync_info
) == false)
264 ols_debug("%s: down on if %s", __func__
, ifp
->name
);
267 * can occur from a link down or changing config
268 * ospf network type change interface is brought down/up
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
;
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
;
290 void ospf_ldp_sync_if_remove(struct interface
*ifp
, bool remove
)
292 struct ospf_if_params
*params
;
293 struct ldp_sync_info
*ldp_sync_info
;
295 params
= IF_DEF_PARAMS(ifp
);
296 if (params
->ldp_sync_info
== NULL
)
299 ldp_sync_info
= params
->ldp_sync_info
;
301 /* Stop LDP-SYNC on this interface:
302 * if holddown timer is running stop it
303 * delete ldp instance on interface
306 ols_debug("%s: Removed from if %s", __func__
, ifp
->name
);
308 THREAD_OFF(ldp_sync_info
->t_holddown
);
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
;
315 ldp_sync_info_free(&ldp_sync_info
);
316 params
->ldp_sync_info
= NULL
;
320 static int ospf_ldp_sync_ism_change(struct ospf_interface
*oi
, int state
,
323 /* Terminal state or regression */
325 case ISM_PointToPoint
:
326 /* If LDP-SYNC is configure on interface then start */
327 ospf_ldp_sync_if_start(oi
->ifp
, true);
330 /* If LDP-SYNC is configure on this interface then stop it */
331 ospf_ldp_sync_if_down(oi
->ifp
);
340 * LDP-SYNC holddown timer routines
342 static void ospf_ldp_sync_holddown_timer(struct thread
*thread
)
344 struct interface
*ifp
;
345 struct ospf_if_params
*params
;
346 struct ldp_sync_info
*ldp_sync_info
;
348 /* holddown timer expired:
349 * didn't receive msg from LDP indicating sync-complete
350 * restore interface cost to original value
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
;
357 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_UP
;
359 ols_debug("%s: holddown timer expired for %s state: %s",
360 __func__
, ifp
->name
, "Sync achieved");
362 ospf_if_recalculate_output_cost(ifp
);
366 void ospf_ldp_sync_holddown_timer_add(struct interface
*ifp
)
368 struct ospf_if_params
*params
;
369 struct ldp_sync_info
*ldp_sync_info
;
371 params
= IF_DEF_PARAMS(ifp
);
372 ldp_sync_info
= params
->ldp_sync_info
;
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
379 if (ldp_sync_info
->t_holddown
||
380 ldp_sync_info
->holddown
== LDP_IGP_SYNC_HOLDDOWN_DEFAULT
)
383 ols_debug("%s: start holddown timer for %s time %d", __func__
,
384 ifp
->name
, ldp_sync_info
->holddown
);
386 thread_add_timer(master
, ospf_ldp_sync_holddown_timer
,
387 ifp
, ldp_sync_info
->holddown
,
388 &ldp_sync_info
->t_holddown
);
392 * LDP-SYNC exit routes.
394 void ospf_ldp_sync_gbl_exit(struct ospf
*ospf
, bool remove
)
396 struct interface
*ifp
;
399 /* ospf is being removed
400 * stop any holddown timers
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
);
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
;
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
);
422 * LDP-SYNC routes used by set commands.
424 void ospf_if_set_ldp_sync_enable(struct ospf
*ospf
, struct interface
*ifp
)
426 struct ospf_if_params
*params
;
427 struct ldp_sync_info
*ldp_sync_info
;
429 /* called when setting LDP-SYNC at the global level:
430 * specified on interface overrides global config
431 * if ptop link send msg to LDP indicating ldp-sync enabled
433 if (if_is_loopback(ifp
))
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
;
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
)
446 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
448 ols_debug("%s: enable if %s", __func__
, ifp
->name
);
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
);
456 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
457 zlog_debug("%s: Sync only runs on P2P links %s", __func__
,
462 void ospf_if_set_ldp_sync_holddown(struct ospf
*ospf
, struct interface
*ifp
)
464 struct ospf_if_params
*params
;
465 struct ldp_sync_info
*ldp_sync_info
;
467 /* called when setting LDP-SYNC at the global level:
468 * specified on interface overrides global config.
470 if (if_is_loopback(ifp
))
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
;
478 /* config on interface, overrides global config. */
479 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
481 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
482 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
484 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
488 * LDP-SYNC routines used by show commands.
491 void ospf_ldp_sync_show_info(struct vty
*vty
, struct ospf
*ospf
,
492 json_object
*json_vrf
, bool use_json
)
495 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
497 json_object_boolean_true_add(json_vrf
,
498 "mplsLdpIgpSyncEnabled");
499 json_object_int_add(json_vrf
, "mplsLdpIgpSyncHolddown",
500 ospf
->ldp_sync_cmd
.holddown
);
502 vty_out(vty
, " MPLS LDP-IGP Sync is enabled\n");
503 if (ospf
->ldp_sync_cmd
.holddown
== 0)
505 " MPLS LDP-IGP Sync holddown timer is disabled\n");
508 " MPLS LDP-IGP Sync holddown timer %d sec\n",
509 ospf
->ldp_sync_cmd
.holddown
);
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
,
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
;
525 params
= IF_DEF_PARAMS(oi
->ifp
);
526 if (params
->ldp_sync_info
== NULL
)
529 ldp_sync_info
= params
->ldp_sync_info
;
531 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
532 json_object_boolean_true_add(json_interface_sub
,
533 "ldpIgpSyncEnabled");
535 json_object_boolean_false_add(json_interface_sub
,
536 "ldpIgpSyncEnabled");
538 json_object_int_add(json_interface_sub
, "holdDownTimeInSec",
539 ldp_sync_info
->holddown
);
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
547 vty_out(vty
, " Holddown timer in seconds: %u\n",
548 ldp_sync_info
->holddown
);
551 switch (ldp_sync_info
->state
) {
552 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
554 json_object_string_add(json_interface_sub
,
558 vty_out(vty
, " State: Sync achieved\n");
560 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
561 if (ldp_sync_info
->t_holddown
!= NULL
) {
565 time_store
= monotime_until(
566 &ldp_sync_info
->t_holddown
->u
.sands
,
570 json_object_int_add(json_interface_sub
,
571 "ldpIgpSyncTimeRemainInMsec",
574 json_object_string_add(json_interface_sub
,
576 "Holding down until Sync");
579 " Holddown timer is running %s remaining\n",
581 ldp_sync_info
->t_holddown
,
586 " State: Holding down until Sync\n");
590 json_object_string_add(json_interface_sub
,
592 "Sync not achieved");
594 vty_out(vty
, " State: Sync not achieved\n");
597 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
599 if (IF_DEF_PARAMS(ifp
)->type
!= OSPF_IFTYPE_POINTOPOINT
&&
600 !if_is_pointopoint(ifp
))
601 ldp_state
= "Sync not required: non-p2p link";
603 ldp_state
= "Sync not required";
606 json_object_string_add(json_interface_sub
,
610 vty_out(vty
, " State: %s\n", ldp_state
);
615 static int show_ip_ospf_mpls_ldp_interface_common(struct vty
*vty
,
621 struct interface
*ifp
;
622 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
623 json_object
*json_interface_sub
= NULL
;
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
;
631 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
633 vty_out(vty
, "%s\n Interface down\n",
637 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
638 rn
= route_next(rn
)) {
643 json_object_new_object();
645 show_ip_ospf_mpls_ldp_interface_sub(
646 vty
, oi
, ifp
, json_interface_sub
,
650 json_object_object_add(
657 /* Interface name is specified. */
658 ifp
= if_lookup_by_name(intf_name
, ospf
->vrf_id
);
660 struct route_node
*rn
;
661 struct ospf_interface
*oi
;
663 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
665 vty_out(vty
, "%s\n OSPF not enabled\n",
668 vty_out(vty
, "%s\n Interface down\n",
672 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
673 rn
= route_next(rn
)) {
678 json_object_new_object();
680 show_ip_ospf_mpls_ldp_interface_sub(
681 vty
, oi
, ifp
, json_interface_sub
,
685 json_object_object_add(
696 * Write the global LDP-SYNC configuration.
698 void ospf_ldp_sync_write_config(struct vty
*vty
, struct ospf
*ospf
)
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
);
708 * Write the interface LDP-SYNC configuration.
710 void ospf_ldp_sync_if_write_config(struct vty
*vty
,
711 struct ospf_if_params
*params
)
714 struct ldp_sync_info
*ldp_sync_info
;
716 ldp_sync_info
= params
->ldp_sync_info
;
717 if (ldp_sync_info
== NULL
)
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");
724 vty_out(vty
, " no ip ospf mpls ldp-sync\n");
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
);
734 #include "ospfd/ospf_ldp_sync_clippy.c"
736 DEFPY (ospf_mpls_ldp_sync
,
737 ospf_mpls_ldp_sync_cmd
,
739 "MPLS specific commands\n"
740 "Enable MPLS LDP-IGP Sync\n")
742 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
743 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
744 struct interface
*ifp
;
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
;
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
);
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
);
764 DEFPY (no_ospf_mpls_ldp_sync
,
765 no_ospf_mpls_ldp_sync_cmd
,
768 "MPLS specific commands\n"
769 "Disable MPLS LDP-IGP Sync\n")
771 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
772 ospf_ldp_sync_gbl_exit(ospf
, false);
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"
784 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
785 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
786 struct interface
*ifp
;
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
;
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
);
802 DEFPY (no_ospf_mpls_ldp_sync_holddown
,
803 no_ospf_mpls_ldp_sync_holddown_cmd
,
804 "no mpls ldp-sync holddown [<(1-10000)>]",
806 "MPLS specific commands\n"
807 "Disable MPLS LDP-IGP Sync\n"
808 "holddown timer disable\n"
811 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
812 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
813 struct interface
*ifp
;
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
);
826 DEFPY (mpls_ldp_sync
,
828 "ip ospf mpls ldp-sync",
830 "OSPF interface commands\n"
834 VTY_DECLVAR_CONTEXT(interface
, ifp
);
835 struct ospf_if_params
*params
;
836 struct ldp_sync_info
*ldp_sync_info
;
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
;
843 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
844 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
845 return CMD_ERR_NOTHING_TODO
;
848 params
= IF_DEF_PARAMS(ifp
);
849 if (params
->ldp_sync_info
== NULL
)
850 params
->ldp_sync_info
= ldp_sync_info_create();
852 ldp_sync_info
= params
->ldp_sync_info
;
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
);
860 zlog_debug("ldp_sync: only runs on P2P links %s", ifp
->name
);
861 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
866 DEFPY (no_mpls_ldp_sync
,
867 no_mpls_ldp_sync_cmd
,
868 "no ip ospf mpls ldp-sync",
871 "OSPF interface commands\n"
873 NO_MPLS_LDP_SYNC_STR
)
875 VTY_DECLVAR_CONTEXT(interface
, ifp
);
876 struct ospf_if_params
*params
;
877 struct ldp_sync_info
*ldp_sync_info
;
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
;
884 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
885 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
886 return CMD_ERR_NOTHING_TODO
;
889 params
= IF_DEF_PARAMS(ifp
);
890 if (params
->ldp_sync_info
== NULL
)
891 params
->ldp_sync_info
= ldp_sync_info_create();
893 ldp_sync_info
= params
->ldp_sync_info
;
895 /* disable LDP-SYNC on an interface
896 * stop holddown timer if running
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
;
902 THREAD_OFF(ldp_sync_info
->t_holddown
);
903 ospf_if_recalculate_output_cost(ifp
);
908 DEFPY (mpls_ldp_sync_holddown
,
909 mpls_ldp_sync_holddown_cmd
,
910 "ip ospf mpls ldp-sync holddown (0-10000)",
912 "OSPF interface commands\n"
915 "Time to wait for LDP-SYNC to occur before restoring interface cost\n"
918 VTY_DECLVAR_CONTEXT(interface
, ifp
);
919 struct ospf_if_params
*params
;
920 struct ldp_sync_info
*ldp_sync_info
;
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
;
927 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
928 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
929 return CMD_ERR_NOTHING_TODO
;
932 params
= IF_DEF_PARAMS(ifp
);
933 if (params
->ldp_sync_info
== NULL
)
934 params
->ldp_sync_info
= ldp_sync_info_create();
936 ldp_sync_info
= params
->ldp_sync_info
;
938 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
939 ldp_sync_info
->holddown
= holddown
;
944 DEFPY (no_mpls_ldp_sync_holddown
,
945 no_mpls_ldp_sync_holddown_cmd
,
946 "no ip ospf mpls ldp-sync holddown [<(1-10000)>]",
949 "OSPF interface commands\n"
952 NO_MPLS_LDP_SYNC_HOLDDOWN_STR
955 VTY_DECLVAR_CONTEXT(interface
, ifp
);
956 struct ospf_if_params
*params
;
957 struct ldp_sync_info
*ldp_sync_info
;
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
;
965 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
966 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
967 return CMD_ERR_NOTHING_TODO
;
970 params
= IF_DEF_PARAMS(ifp
);
971 ldp_sync_info
= params
->ldp_sync_info
;
972 if (ldp_sync_info
== NULL
)
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
;
983 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
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]",
995 "LDP-IGP Sync information\n"
996 "Interface information\n"
1002 bool uj
= use_json(argc
, argv
);
1003 char *intf_name
= NULL
;
1004 int ret
= CMD_SUCCESS
;
1006 json_object
*json
= NULL
;
1008 if (argv_find(argv
, argc
, "INTERFACE", &idx_intf
))
1009 intf_name
= argv
[idx_intf
]->arg
;
1012 json
= json_object_new_object();
1014 /* Display default ospf (instance 0) info */
1015 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1016 if (ospf
== NULL
|| !ospf
->oi_running
) {
1018 vty_json(vty
, json
);
1020 vty_out(vty
, "%% OSPF instance not found\n");
1024 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
1026 vty_json(vty
, json
);
1028 vty_out(vty
, "LDP-sync is disabled\n");
1032 ret
= show_ip_ospf_mpls_ldp_interface_common(vty
, ospf
, intf_name
,
1035 vty_json(vty
, json
);
1040 void ospf_ldp_sync_init(void)
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
);
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
);
1054 /* "show ip ospf mpls ldp interface" commands. */
1055 install_element(VIEW_NODE
, &show_ip_ospf_mpls_ldp_interface_cmd
);
1057 hook_register(ospf_ism_change
, ospf_ldp_sync_ism_change
);