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 EVENT_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 EVENT_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 EVENT_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 event
*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
= EVENT_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 event_add_timer(master
, ospf_ldp_sync_holddown_timer
, ifp
,
387 ldp_sync_info
->holddown
, &ldp_sync_info
->t_holddown
);
391 * LDP-SYNC exit routes.
393 void ospf_ldp_sync_gbl_exit(struct ospf
*ospf
, bool remove
)
395 struct interface
*ifp
;
398 /* ospf is being removed
399 * stop any holddown timers
401 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
402 /* unregister with opaque client to recv LDP-IGP Sync msgs */
403 zclient_unregister_opaque(zclient
,
404 LDP_IGP_SYNC_IF_STATE_UPDATE
);
405 zclient_unregister_opaque(zclient
,
406 LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
408 /* disable LDP globally */
409 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
410 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
411 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
413 /* turn off LDP-IGP Sync on all OSPF interfaces */
414 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
415 FOR_ALL_INTERFACES (vrf
, ifp
)
416 ospf_ldp_sync_if_remove(ifp
, remove
);
421 * LDP-SYNC routes used by set commands.
423 void ospf_if_set_ldp_sync_enable(struct ospf
*ospf
, struct interface
*ifp
)
425 struct ospf_if_params
*params
;
426 struct ldp_sync_info
*ldp_sync_info
;
428 /* called when setting LDP-SYNC at the global level:
429 * specified on interface overrides global config
430 * if ptop link send msg to LDP indicating ldp-sync enabled
432 if (if_is_loopback(ifp
))
435 params
= IF_DEF_PARAMS(ifp
);
436 if (params
->ldp_sync_info
== NULL
)
437 params
->ldp_sync_info
= ldp_sync_info_create();
438 ldp_sync_info
= params
->ldp_sync_info
;
440 /* config on interface, overrides global config. */
441 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
442 if (ldp_sync_info
->enabled
!= LDP_IGP_SYNC_ENABLED
)
445 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
447 ols_debug("%s: enable if %s", __func__
, ifp
->name
);
449 /* send message to LDP if ptop link */
450 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
451 if_is_pointopoint(ifp
)) {
452 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
453 ospf_ldp_sync_state_req_msg(ifp
);
455 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
456 zlog_debug("%s: Sync only runs on P2P links %s", __func__
,
461 void ospf_if_set_ldp_sync_holddown(struct ospf
*ospf
, struct interface
*ifp
)
463 struct ospf_if_params
*params
;
464 struct ldp_sync_info
*ldp_sync_info
;
466 /* called when setting LDP-SYNC at the global level:
467 * specified on interface overrides global config.
469 if (if_is_loopback(ifp
))
472 params
= IF_DEF_PARAMS(ifp
);
473 if (params
->ldp_sync_info
== NULL
)
474 params
->ldp_sync_info
= ldp_sync_info_create();
475 ldp_sync_info
= params
->ldp_sync_info
;
477 /* config on interface, overrides global config. */
478 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
480 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
481 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
483 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
487 * LDP-SYNC routines used by show commands.
490 void ospf_ldp_sync_show_info(struct vty
*vty
, struct ospf
*ospf
,
491 json_object
*json_vrf
, bool use_json
)
494 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
496 json_object_boolean_true_add(json_vrf
,
497 "mplsLdpIgpSyncEnabled");
498 json_object_int_add(json_vrf
, "mplsLdpIgpSyncHolddown",
499 ospf
->ldp_sync_cmd
.holddown
);
501 vty_out(vty
, " MPLS LDP-IGP Sync is enabled\n");
502 if (ospf
->ldp_sync_cmd
.holddown
== 0)
504 " MPLS LDP-IGP Sync holddown timer is disabled\n");
507 " MPLS LDP-IGP Sync holddown timer %d sec\n",
508 ospf
->ldp_sync_cmd
.holddown
);
513 static void show_ip_ospf_mpls_ldp_interface_sub(struct vty
*vty
,
514 struct ospf_interface
*oi
,
515 struct interface
*ifp
,
516 json_object
*json_interface_sub
,
519 const char *ldp_state
;
520 struct ospf_if_params
*params
;
521 char timebuf
[OSPF_TIME_DUMP_SIZE
];
522 struct ldp_sync_info
*ldp_sync_info
;
524 params
= IF_DEF_PARAMS(oi
->ifp
);
525 if (params
->ldp_sync_info
== NULL
)
528 ldp_sync_info
= params
->ldp_sync_info
;
530 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
531 json_object_boolean_true_add(json_interface_sub
,
532 "ldpIgpSyncEnabled");
534 json_object_boolean_false_add(json_interface_sub
,
535 "ldpIgpSyncEnabled");
537 json_object_int_add(json_interface_sub
, "holdDownTimeInSec",
538 ldp_sync_info
->holddown
);
541 vty_out(vty
, "%-10s\n", ifp
->name
);
542 vty_out(vty
, " LDP-IGP Synchronization enabled: %s\n",
543 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
546 vty_out(vty
, " Holddown timer in seconds: %u\n",
547 ldp_sync_info
->holddown
);
550 switch (ldp_sync_info
->state
) {
551 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
553 json_object_string_add(json_interface_sub
,
557 vty_out(vty
, " State: Sync achieved\n");
559 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
560 if (ldp_sync_info
->t_holddown
!= NULL
) {
564 time_store
= monotime_until(
565 &ldp_sync_info
->t_holddown
->u
.sands
,
569 json_object_int_add(json_interface_sub
,
570 "ldpIgpSyncTimeRemainInMsec",
573 json_object_string_add(json_interface_sub
,
575 "Holding down until Sync");
578 " Holddown timer is running %s remaining\n",
580 ldp_sync_info
->t_holddown
,
585 " State: Holding down until Sync\n");
589 json_object_string_add(json_interface_sub
,
591 "Sync not achieved");
593 vty_out(vty
, " State: Sync not achieved\n");
596 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
598 if (IF_DEF_PARAMS(ifp
)->type
!= OSPF_IFTYPE_POINTOPOINT
&&
599 !if_is_pointopoint(ifp
))
600 ldp_state
= "Sync not required: non-p2p link";
602 ldp_state
= "Sync not required";
605 json_object_string_add(json_interface_sub
,
609 vty_out(vty
, " State: %s\n", ldp_state
);
614 static int show_ip_ospf_mpls_ldp_interface_common(struct vty
*vty
,
620 struct interface
*ifp
;
621 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
622 json_object
*json_interface_sub
= NULL
;
624 if (intf_name
== NULL
) {
625 /* Show All Interfaces.*/
626 FOR_ALL_INTERFACES (vrf
, ifp
) {
627 struct route_node
*rn
;
628 struct ospf_interface
*oi
;
630 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
632 vty_out(vty
, "%s\n Interface down\n",
636 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
637 rn
= route_next(rn
)) {
642 json_object_new_object();
644 show_ip_ospf_mpls_ldp_interface_sub(
645 vty
, oi
, ifp
, json_interface_sub
,
649 json_object_object_add(
656 /* Interface name is specified. */
657 ifp
= if_lookup_by_name(intf_name
, ospf
->vrf_id
);
659 struct route_node
*rn
;
660 struct ospf_interface
*oi
;
662 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
664 vty_out(vty
, "%s\n OSPF not enabled\n",
667 vty_out(vty
, "%s\n Interface down\n",
671 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
672 rn
= route_next(rn
)) {
677 json_object_new_object();
679 show_ip_ospf_mpls_ldp_interface_sub(
680 vty
, oi
, ifp
, json_interface_sub
,
684 json_object_object_add(
695 * Write the global LDP-SYNC configuration.
697 void ospf_ldp_sync_write_config(struct vty
*vty
, struct ospf
*ospf
)
699 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
700 vty_out(vty
, " mpls ldp-sync\n");
701 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
702 vty_out(vty
, " mpls ldp-sync holddown %u\n",
703 ospf
->ldp_sync_cmd
.holddown
);
707 * Write the interface LDP-SYNC configuration.
709 void ospf_ldp_sync_if_write_config(struct vty
*vty
,
710 struct ospf_if_params
*params
)
713 struct ldp_sync_info
*ldp_sync_info
;
715 ldp_sync_info
= params
->ldp_sync_info
;
716 if (ldp_sync_info
== NULL
)
719 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
)) {
720 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
721 vty_out(vty
, " ip ospf mpls ldp-sync\n");
723 vty_out(vty
, " no ip ospf mpls ldp-sync\n");
725 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
726 vty_out(vty
, " ip ospf mpls ldp-sync holddown %u\n",
727 ldp_sync_info
->holddown
);
733 #include "ospfd/ospf_ldp_sync_clippy.c"
735 DEFPY (ospf_mpls_ldp_sync
,
736 ospf_mpls_ldp_sync_cmd
,
738 "MPLS specific commands\n"
739 "Enable MPLS LDP-IGP Sync\n")
741 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
742 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
743 struct interface
*ifp
;
745 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
746 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
747 return CMD_ERR_NOTHING_TODO
;
750 /* register with opaque client to recv LDP-IGP Sync msgs */
751 zclient_register_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_UPDATE
);
752 zclient_register_opaque(zclient
, LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
754 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
755 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
756 /* turn on LDP-IGP Sync on all ptop OSPF interfaces */
757 FOR_ALL_INTERFACES (vrf
, ifp
)
758 ospf_if_set_ldp_sync_enable(ospf
, ifp
);
763 DEFPY (no_ospf_mpls_ldp_sync
,
764 no_ospf_mpls_ldp_sync_cmd
,
767 "MPLS specific commands\n"
768 "Disable MPLS LDP-IGP Sync\n")
770 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
771 ospf_ldp_sync_gbl_exit(ospf
, false);
775 DEFPY (ospf_mpls_ldp_sync_holddown
,
776 ospf_mpls_ldp_sync_holddown_cmd
,
777 "mpls ldp-sync holddown (1-10000)",
778 "MPLS specific commands\n"
779 "Enable MPLS LDP-IGP Sync\n"
780 "Set holddown timer\n"
783 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
784 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
785 struct interface
*ifp
;
787 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
788 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
789 return CMD_ERR_NOTHING_TODO
;
792 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
793 ospf
->ldp_sync_cmd
.holddown
= holddown
;
794 /* set holddown time on all OSPF interfaces */
795 FOR_ALL_INTERFACES (vrf
, ifp
)
796 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
801 DEFPY (no_ospf_mpls_ldp_sync_holddown
,
802 no_ospf_mpls_ldp_sync_holddown_cmd
,
803 "no mpls ldp-sync holddown [<(1-10000)>]",
805 "MPLS specific commands\n"
806 "Disable MPLS LDP-IGP Sync\n"
807 "holddown timer disable\n"
810 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
811 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
812 struct interface
*ifp
;
814 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
815 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
816 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
817 /* turn off holddown timer on all OSPF interfaces */
818 FOR_ALL_INTERFACES (vrf
, ifp
)
819 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
825 DEFPY (mpls_ldp_sync
,
827 "ip ospf mpls ldp-sync",
829 "OSPF interface commands\n"
833 VTY_DECLVAR_CONTEXT(interface
, ifp
);
834 struct ospf_if_params
*params
;
835 struct ldp_sync_info
*ldp_sync_info
;
837 if (if_is_loopback(ifp
)) {
838 vty_out(vty
, "ldp-sync does not run on loopback interface\n");
839 return CMD_ERR_NOTHING_TODO
;
842 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
843 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
844 return CMD_ERR_NOTHING_TODO
;
847 params
= IF_DEF_PARAMS(ifp
);
848 if (params
->ldp_sync_info
== NULL
)
849 params
->ldp_sync_info
= ldp_sync_info_create();
851 ldp_sync_info
= params
->ldp_sync_info
;
853 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
854 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
855 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
|| if_is_pointopoint(ifp
)) {
856 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
857 ospf_ldp_sync_state_req_msg(ifp
);
859 zlog_debug("ldp_sync: only runs on P2P links %s", ifp
->name
);
860 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
865 DEFPY (no_mpls_ldp_sync
,
866 no_mpls_ldp_sync_cmd
,
867 "no ip ospf mpls ldp-sync",
870 "OSPF interface commands\n"
872 NO_MPLS_LDP_SYNC_STR
)
874 VTY_DECLVAR_CONTEXT(interface
, ifp
);
875 struct ospf_if_params
*params
;
876 struct ldp_sync_info
*ldp_sync_info
;
878 if (if_is_loopback(ifp
)) {
879 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
880 return CMD_ERR_NOTHING_TODO
;
883 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
884 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
885 return CMD_ERR_NOTHING_TODO
;
888 params
= IF_DEF_PARAMS(ifp
);
889 if (params
->ldp_sync_info
== NULL
)
890 params
->ldp_sync_info
= ldp_sync_info_create();
892 ldp_sync_info
= params
->ldp_sync_info
;
894 /* disable LDP-SYNC on an interface
895 * stop holddown timer if running
898 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
899 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
900 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
901 EVENT_OFF(ldp_sync_info
->t_holddown
);
902 ospf_if_recalculate_output_cost(ifp
);
907 DEFPY (mpls_ldp_sync_holddown
,
908 mpls_ldp_sync_holddown_cmd
,
909 "ip ospf mpls ldp-sync holddown (0-10000)",
911 "OSPF interface commands\n"
914 "Time to wait for LDP-SYNC to occur before restoring interface cost\n"
917 VTY_DECLVAR_CONTEXT(interface
, ifp
);
918 struct ospf_if_params
*params
;
919 struct ldp_sync_info
*ldp_sync_info
;
921 if (if_is_loopback(ifp
)) {
922 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
923 return CMD_ERR_NOTHING_TODO
;
926 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
927 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
928 return CMD_ERR_NOTHING_TODO
;
931 params
= IF_DEF_PARAMS(ifp
);
932 if (params
->ldp_sync_info
== NULL
)
933 params
->ldp_sync_info
= ldp_sync_info_create();
935 ldp_sync_info
= params
->ldp_sync_info
;
937 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
938 ldp_sync_info
->holddown
= holddown
;
943 DEFPY (no_mpls_ldp_sync_holddown
,
944 no_mpls_ldp_sync_holddown_cmd
,
945 "no ip ospf mpls ldp-sync holddown [<(1-10000)>]",
948 "OSPF interface commands\n"
951 NO_MPLS_LDP_SYNC_HOLDDOWN_STR
954 VTY_DECLVAR_CONTEXT(interface
, ifp
);
955 struct ospf_if_params
*params
;
956 struct ldp_sync_info
*ldp_sync_info
;
959 if (if_is_loopback(ifp
)) {
960 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
961 return CMD_ERR_NOTHING_TODO
;
964 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
965 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
966 return CMD_ERR_NOTHING_TODO
;
969 params
= IF_DEF_PARAMS(ifp
);
970 ldp_sync_info
= params
->ldp_sync_info
;
971 if (ldp_sync_info
== NULL
)
974 /* use global configured value if set */
975 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
976 UNSET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
977 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
978 if (ospf
&& CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
,
979 LDP_SYNC_FLAG_HOLDDOWN
))
980 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
982 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
987 DEFPY (show_ip_ospf_mpls_ldp_interface
,
988 show_ip_ospf_mpls_ldp_interface_cmd
,
989 "show ip ospf mpls ldp-sync [interface <INTERFACE|all>] [json]",
994 "LDP-IGP Sync information\n"
995 "Interface information\n"
1001 bool uj
= use_json(argc
, argv
);
1002 char *intf_name
= NULL
;
1003 int ret
= CMD_SUCCESS
;
1005 json_object
*json
= NULL
;
1007 if (argv_find(argv
, argc
, "INTERFACE", &idx_intf
))
1008 intf_name
= argv
[idx_intf
]->arg
;
1011 json
= json_object_new_object();
1013 /* Display default ospf (instance 0) info */
1014 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1015 if (ospf
== NULL
|| !ospf
->oi_running
) {
1017 vty_json(vty
, json
);
1019 vty_out(vty
, "%% OSPF instance not found\n");
1023 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
1025 vty_json(vty
, json
);
1027 vty_out(vty
, "LDP-sync is disabled\n");
1031 ret
= show_ip_ospf_mpls_ldp_interface_common(vty
, ospf
, intf_name
,
1034 vty_json(vty
, json
);
1039 void ospf_ldp_sync_init(void)
1041 /* Install global ldp-igp sync commands */
1042 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_cmd
);
1043 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_cmd
);
1044 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_holddown_cmd
);
1045 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_holddown_cmd
);
1047 /* Interface lsp-igp sync commands */
1048 install_element(INTERFACE_NODE
, &mpls_ldp_sync_cmd
);
1049 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_cmd
);
1050 install_element(INTERFACE_NODE
, &mpls_ldp_sync_holddown_cmd
);
1051 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_holddown_cmd
);
1053 /* "show ip ospf mpls ldp interface" commands. */
1054 install_element(VIEW_NODE
, &show_ip_ospf_mpls_ldp_interface_cmd
);
1056 hook_register(ospf_ism_change
, ospf_ldp_sync_ism_change
);