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("%s: rcvd %s from LDP if %s", __func__
,
66 state
.sync_start
? "sync-start" : "sync-complete", ifp
->name
);
68 ospf_ldp_sync_if_start(ifp
, false);
70 ospf_ldp_sync_if_complete(ifp
);
75 int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce
)
79 struct interface
*ifp
;
81 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
82 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
84 !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
87 if (announce
.proto
!= ZEBRA_ROUTE_LDP
)
90 ols_debug("%s: rcvd announce from LDP", __func__
);
92 /* LDP just started up:
93 * set cost to LSInfinity
94 * send request to LDP for LDP-SYNC state for each interface
96 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
97 FOR_ALL_INTERFACES (vrf
, ifp
)
98 ospf_ldp_sync_if_start(ifp
, true);
103 void ospf_ldp_sync_state_req_msg(struct interface
*ifp
)
105 struct ldp_igp_sync_if_state_req request
;
107 ols_debug("%s: send state request to LDP for %s", __func__
, ifp
->name
);
109 memset(&request
, 0, sizeof(request
));
110 strlcpy(request
.name
, ifp
->name
, sizeof(ifp
->name
));
111 request
.proto
= LDP_IGP_SYNC_IF_STATE_REQUEST
;
112 request
.ifindex
= ifp
->ifindex
;
114 zclient_send_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_REQUEST
,
115 (uint8_t *)&request
, sizeof(request
));
119 * LDP-SYNC general interface routines
121 void ospf_ldp_sync_if_init(struct ospf_interface
*oi
)
123 struct ospf_if_params
*params
;
124 struct ldp_sync_info
*ldp_sync_info
;
125 struct interface
*ifp
= oi
->ifp
;
127 /* called when OSPF is configured on an interface:
128 * if LDP-IGP Sync is configured globally set state
129 * if ptop interface inform LDP LDP-SYNC is enabled
131 if (if_is_loopback(ifp
) || (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
)
132 || !(CHECK_FLAG(oi
->ospf
->ldp_sync_cmd
.flags
,
133 LDP_SYNC_FLAG_ENABLE
)))
136 ols_debug("%s: init if %s", __func__
, ifp
->name
);
137 params
= IF_DEF_PARAMS(ifp
);
138 if (params
->ldp_sync_info
== NULL
)
139 params
->ldp_sync_info
= ldp_sync_info_create();
141 ldp_sync_info
= params
->ldp_sync_info
;
143 /* specified on interface overrides global config. */
144 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
145 ldp_sync_info
->holddown
= oi
->ospf
->ldp_sync_cmd
.holddown
;
147 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
148 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
150 if ((params
->type
== OSPF_IFTYPE_POINTOPOINT
||
151 if_is_pointopoint(ifp
)) &&
152 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
153 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
156 void ospf_ldp_sync_if_start(struct interface
*ifp
, bool send_state_req
)
158 struct ospf_if_params
*params
;
159 struct ldp_sync_info
*ldp_sync_info
;
161 if (if_is_loopback(ifp
))
164 params
= IF_DEF_PARAMS(ifp
);
165 ldp_sync_info
= params
->ldp_sync_info
;
167 /* Start LDP-SYNC on this interface:
168 * set cost of interface to LSInfinity so traffic will use different
169 * interface until LDP has learned all labels from peer
170 * start holddown timer if configured
171 * send msg to LDP to get LDP-SYNC state
174 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
175 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
176 ols_debug("%s: start on if %s state: %s", __func__
, ifp
->name
,
177 "Holding down until Sync");
178 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
179 ospf_if_recalculate_output_cost(ifp
);
180 ospf_ldp_sync_holddown_timer_add(ifp
);
183 ospf_ldp_sync_state_req_msg(ifp
);
187 void ospf_ldp_sync_if_complete(struct interface
*ifp
)
189 struct ospf_if_params
*params
;
190 struct ldp_sync_info
*ldp_sync_info
;
192 if (if_is_loopback(ifp
))
195 params
= IF_DEF_PARAMS(ifp
);
196 ldp_sync_info
= params
->ldp_sync_info
;
198 /* received sync-complete from LDP:
201 * restore interface cost to original value
203 if (ldp_sync_info
&& ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
) {
204 if (ldp_sync_info
->state
== LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
)
205 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_UP
;
206 THREAD_OFF(ldp_sync_info
->t_holddown
);
207 ospf_if_recalculate_output_cost(ifp
);
211 void ospf_ldp_sync_handle_client_close(struct zapi_client_close_info
*info
)
215 struct interface
*ifp
;
217 /* if ospf is not enabled or LDP-SYNC is not configured ignore */
218 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
220 || !CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
223 /* Check if the LDP main client session closed */
224 if (info
->proto
!= ZEBRA_ROUTE_LDP
|| info
->session_id
== 0)
227 /* Handle the zebra notification that the LDP client session closed.
228 * set cost to LSInfinity
229 * send request to LDP for LDP-SYNC state for each interface
231 zlog_err("%s: LDP down", __func__
);
233 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
234 FOR_ALL_INTERFACES (vrf
, ifp
)
235 ospf_ldp_sync_ldp_fail(ifp
);
238 void ospf_ldp_sync_ldp_fail(struct interface
*ifp
)
240 struct ospf_if_params
*params
;
241 struct ldp_sync_info
*ldp_sync_info
;
243 if (if_is_loopback(ifp
))
246 params
= IF_DEF_PARAMS(ifp
);
247 ldp_sync_info
= params
->ldp_sync_info
;
249 /* LDP client close detected:
250 * stop holddown timer
251 * set cost of interface to LSInfinity so traffic will use different
252 * interface until LDP has learned all labels from peer
255 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
&&
256 ldp_sync_info
->state
!= LDP_IGP_SYNC_STATE_NOT_REQUIRED
) {
257 THREAD_OFF(ldp_sync_info
->t_holddown
);
258 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
259 ospf_if_recalculate_output_cost(ifp
);
263 void ospf_ldp_sync_if_down(struct interface
*ifp
)
265 struct ospf_if_params
*params
;
266 struct ldp_sync_info
*ldp_sync_info
;
268 if (if_is_loopback(ifp
))
271 params
= IF_DEF_PARAMS(ifp
);
272 ldp_sync_info
= params
->ldp_sync_info
;
274 if (ldp_sync_if_down(ldp_sync_info
) == false)
277 ols_debug("%s: down on if %s", __func__
, ifp
->name
);
280 * can occur from a link down or changing config
281 * ospf network type change interface is brought down/up
283 switch (ldp_sync_info
->state
) {
284 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
285 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
286 if (params
->type
!= OSPF_IFTYPE_POINTOPOINT
&&
287 !if_is_pointopoint(ifp
))
288 /* LDP-SYNC not able to run on non-ptop interface */
289 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
291 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
292 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
293 if_is_pointopoint(ifp
))
294 /* LDP-SYNC is able to run on ptop interface */
295 ldp_sync_info
->state
=
296 LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
303 void ospf_ldp_sync_if_remove(struct interface
*ifp
, bool remove
)
305 struct ospf_if_params
*params
;
306 struct ldp_sync_info
*ldp_sync_info
;
308 params
= IF_DEF_PARAMS(ifp
);
309 if (params
->ldp_sync_info
== NULL
)
312 ldp_sync_info
= params
->ldp_sync_info
;
314 /* Stop LDP-SYNC on this interface:
315 * if holddown timer is running stop it
316 * delete ldp instance on interface
319 ols_debug("%s: Removed from if %s", __func__
, ifp
->name
);
321 THREAD_OFF(ldp_sync_info
->t_holddown
);
323 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
324 ospf_if_recalculate_output_cost(ifp
);
325 if (!CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
326 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
328 ldp_sync_info_free(&ldp_sync_info
);
329 params
->ldp_sync_info
= NULL
;
333 static int ospf_ldp_sync_ism_change(struct ospf_interface
*oi
, int state
,
336 /* Terminal state or regression */
338 case ISM_PointToPoint
:
339 /* If LDP-SYNC is configure on interface then start */
340 ospf_ldp_sync_if_start(oi
->ifp
, true);
343 /* If LDP-SYNC is configure on this interface then stop it */
344 ospf_ldp_sync_if_down(oi
->ifp
);
353 * LDP-SYNC holddown timer routines
355 static void ospf_ldp_sync_holddown_timer(struct thread
*thread
)
357 struct interface
*ifp
;
358 struct ospf_if_params
*params
;
359 struct ldp_sync_info
*ldp_sync_info
;
361 /* holddown timer expired:
362 * didn't receive msg from LDP indicating sync-complete
363 * restore interface cost to original value
365 ifp
= THREAD_ARG(thread
);
366 params
= IF_DEF_PARAMS(ifp
);
367 if (params
->ldp_sync_info
) {
368 ldp_sync_info
= params
->ldp_sync_info
;
370 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_UP
;
372 ols_debug("%s: holddown timer expired for %s state: %s",
373 __func__
, ifp
->name
, "Sync achieved");
375 ospf_if_recalculate_output_cost(ifp
);
379 void ospf_ldp_sync_holddown_timer_add(struct interface
*ifp
)
381 struct ospf_if_params
*params
;
382 struct ldp_sync_info
*ldp_sync_info
;
384 params
= IF_DEF_PARAMS(ifp
);
385 ldp_sync_info
= params
->ldp_sync_info
;
387 /* Start holddown timer:
388 * this timer is used to keep interface cost at LSInfinity
389 * once expires returns cost to original value
390 * if timer is already running or holddown time is off just return
392 if (ldp_sync_info
->t_holddown
||
393 ldp_sync_info
->holddown
== LDP_IGP_SYNC_HOLDDOWN_DEFAULT
)
396 ols_debug("%s: start holddown timer for %s time %d", __func__
,
397 ifp
->name
, ldp_sync_info
->holddown
);
399 thread_add_timer(master
, ospf_ldp_sync_holddown_timer
,
400 ifp
, ldp_sync_info
->holddown
,
401 &ldp_sync_info
->t_holddown
);
405 * LDP-SYNC exit routes.
407 void ospf_ldp_sync_gbl_exit(struct ospf
*ospf
, bool remove
)
409 struct interface
*ifp
;
412 /* ospf is being removed
413 * stop any holddown timers
415 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
416 /* unregister with opaque client to recv LDP-IGP Sync msgs */
417 zclient_unregister_opaque(zclient
,
418 LDP_IGP_SYNC_IF_STATE_UPDATE
);
419 zclient_unregister_opaque(zclient
,
420 LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
422 /* disable LDP globally */
423 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
424 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
425 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
427 /* turn off LDP-IGP Sync on all OSPF interfaces */
428 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
429 FOR_ALL_INTERFACES (vrf
, ifp
)
430 ospf_ldp_sync_if_remove(ifp
, remove
);
435 * LDP-SYNC routes used by set commands.
437 void ospf_if_set_ldp_sync_enable(struct ospf
*ospf
, struct interface
*ifp
)
439 struct ospf_if_params
*params
;
440 struct ldp_sync_info
*ldp_sync_info
;
442 /* called when setting LDP-SYNC at the global level:
443 * specified on interface overrides global config
444 * if ptop link send msg to LDP indicating ldp-sync enabled
446 if (if_is_loopback(ifp
))
449 params
= IF_DEF_PARAMS(ifp
);
450 if (params
->ldp_sync_info
== NULL
)
451 params
->ldp_sync_info
= ldp_sync_info_create();
452 ldp_sync_info
= params
->ldp_sync_info
;
454 /* config on interface, overrides global config. */
455 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
456 if (ldp_sync_info
->enabled
!= LDP_IGP_SYNC_ENABLED
)
459 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
461 ols_debug("%s: enable if %s", __func__
, ifp
->name
);
463 /* send message to LDP if ptop link */
464 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
465 if_is_pointopoint(ifp
)) {
466 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
467 ospf_ldp_sync_state_req_msg(ifp
);
469 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
470 zlog_debug("%s: Sync only runs on P2P links %s", __func__
,
475 void ospf_if_set_ldp_sync_holddown(struct ospf
*ospf
, struct interface
*ifp
)
477 struct ospf_if_params
*params
;
478 struct ldp_sync_info
*ldp_sync_info
;
480 /* called when setting LDP-SYNC at the global level:
481 * specified on interface overrides global config.
483 if (if_is_loopback(ifp
))
486 params
= IF_DEF_PARAMS(ifp
);
487 if (params
->ldp_sync_info
== NULL
)
488 params
->ldp_sync_info
= ldp_sync_info_create();
489 ldp_sync_info
= params
->ldp_sync_info
;
491 /* config on interface, overrides global config. */
492 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
494 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
495 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
497 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
501 * LDP-SYNC routines used by show commands.
504 void ospf_ldp_sync_show_info(struct vty
*vty
, struct ospf
*ospf
,
505 json_object
*json_vrf
, bool use_json
)
508 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
510 #if CONFDATE > 20230131
511 CPP_NOTICE("Remove JSON object commands with keys starting with capital")
513 json_object_boolean_true_add(json_vrf
,
514 "MplsLdpIgpSyncEnabled");
515 json_object_boolean_true_add(json_vrf
,
516 "mplsLdpIgpSyncEnabled");
517 json_object_int_add(json_vrf
, "MplsLdpIgpSyncHolddown",
518 ospf
->ldp_sync_cmd
.holddown
);
519 json_object_int_add(json_vrf
, "mplsLdpIgpSyncHolddown",
520 ospf
->ldp_sync_cmd
.holddown
);
522 vty_out(vty
, " MPLS LDP-IGP Sync is enabled\n");
523 if (ospf
->ldp_sync_cmd
.holddown
== 0)
525 " MPLS LDP-IGP Sync holddown timer is disabled\n");
528 " MPLS LDP-IGP Sync holddown timer %d sec\n",
529 ospf
->ldp_sync_cmd
.holddown
);
534 static void show_ip_ospf_mpls_ldp_interface_sub(struct vty
*vty
,
535 struct ospf_interface
*oi
,
536 struct interface
*ifp
,
537 json_object
*json_interface_sub
,
540 const char *ldp_state
;
541 struct ospf_if_params
*params
;
542 char timebuf
[OSPF_TIME_DUMP_SIZE
];
543 struct ldp_sync_info
*ldp_sync_info
;
545 params
= IF_DEF_PARAMS(oi
->ifp
);
546 if (params
->ldp_sync_info
== NULL
)
549 ldp_sync_info
= params
->ldp_sync_info
;
551 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
552 json_object_boolean_true_add(json_interface_sub
,
553 "ldpIgpSyncEnabled");
555 json_object_boolean_false_add(json_interface_sub
,
556 "ldpIgpSyncEnabled");
558 json_object_int_add(json_interface_sub
, "holdDownTimeInSec",
559 ldp_sync_info
->holddown
);
562 vty_out(vty
, "%-10s\n", ifp
->name
);
563 vty_out(vty
, " LDP-IGP Synchronization enabled: %s\n",
564 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
567 vty_out(vty
, " Holddown timer in seconds: %u\n",
568 ldp_sync_info
->holddown
);
571 switch (ldp_sync_info
->state
) {
572 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
574 json_object_string_add(json_interface_sub
,
578 vty_out(vty
, " State: Sync achieved\n");
580 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
581 if (ldp_sync_info
->t_holddown
!= NULL
) {
585 time_store
= monotime_until(
586 &ldp_sync_info
->t_holddown
->u
.sands
,
590 json_object_int_add(json_interface_sub
,
591 "ldpIgpSyncTimeRemainInMsec",
594 json_object_string_add(json_interface_sub
,
596 "Holding down until Sync");
599 " Holddown timer is running %s remaining\n",
601 ldp_sync_info
->t_holddown
,
606 " State: Holding down until Sync\n");
610 json_object_string_add(json_interface_sub
,
612 "Sync not achieved");
614 vty_out(vty
, " State: Sync not achieved\n");
617 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
619 if (IF_DEF_PARAMS(ifp
)->type
!= OSPF_IFTYPE_POINTOPOINT
&&
620 !if_is_pointopoint(ifp
))
621 ldp_state
= "Sync not required: non-p2p link";
623 ldp_state
= "Sync not required";
626 json_object_string_add(json_interface_sub
,
630 vty_out(vty
, " State: %s\n", ldp_state
);
635 static int show_ip_ospf_mpls_ldp_interface_common(struct vty
*vty
,
641 struct interface
*ifp
;
642 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
643 json_object
*json_interface_sub
= NULL
;
645 if (intf_name
== NULL
) {
646 /* Show All Interfaces.*/
647 FOR_ALL_INTERFACES (vrf
, ifp
) {
648 struct route_node
*rn
;
649 struct ospf_interface
*oi
;
651 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
653 vty_out(vty
, "%s\n Interface down\n",
657 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
658 rn
= route_next(rn
)) {
663 json_object_new_object();
665 show_ip_ospf_mpls_ldp_interface_sub(
666 vty
, oi
, ifp
, json_interface_sub
,
670 json_object_object_add(
677 /* Interface name is specified. */
678 ifp
= if_lookup_by_name(intf_name
, ospf
->vrf_id
);
680 struct route_node
*rn
;
681 struct ospf_interface
*oi
;
683 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
685 vty_out(vty
, "%s\n OSPF not enabled\n",
688 vty_out(vty
, "%s\n Interface down\n",
692 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
693 rn
= route_next(rn
)) {
698 json_object_new_object();
700 show_ip_ospf_mpls_ldp_interface_sub(
701 vty
, oi
, ifp
, json_interface_sub
,
705 json_object_object_add(
716 * Write the global LDP-SYNC configuration.
718 void ospf_ldp_sync_write_config(struct vty
*vty
, struct ospf
*ospf
)
720 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
721 vty_out(vty
, " mpls ldp-sync\n");
722 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
723 vty_out(vty
, " mpls ldp-sync holddown %u\n",
724 ospf
->ldp_sync_cmd
.holddown
);
728 * Write the interface LDP-SYNC configuration.
730 void ospf_ldp_sync_if_write_config(struct vty
*vty
,
731 struct ospf_if_params
*params
)
734 struct ldp_sync_info
*ldp_sync_info
;
736 ldp_sync_info
= params
->ldp_sync_info
;
737 if (ldp_sync_info
== NULL
)
740 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
)) {
741 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
742 vty_out(vty
, " ip ospf mpls ldp-sync\n");
744 vty_out(vty
, " no ip ospf mpls ldp-sync\n");
746 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
747 vty_out(vty
, " ip ospf mpls ldp-sync holddown %u\n",
748 ldp_sync_info
->holddown
);
754 #include "ospfd/ospf_ldp_sync_clippy.c"
756 DEFPY (ospf_mpls_ldp_sync
,
757 ospf_mpls_ldp_sync_cmd
,
759 "MPLS specific commands\n"
760 "Enable MPLS LDP-IGP Sync\n")
762 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
763 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
764 struct interface
*ifp
;
766 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
767 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
768 return CMD_ERR_NOTHING_TODO
;
771 /* register with opaque client to recv LDP-IGP Sync msgs */
772 zclient_register_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_UPDATE
);
773 zclient_register_opaque(zclient
, LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
775 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
776 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
777 /* turn on LDP-IGP Sync on all ptop OSPF interfaces */
778 FOR_ALL_INTERFACES (vrf
, ifp
)
779 ospf_if_set_ldp_sync_enable(ospf
, ifp
);
784 DEFPY (no_ospf_mpls_ldp_sync
,
785 no_ospf_mpls_ldp_sync_cmd
,
788 "MPLS specific commands\n"
789 "Disable MPLS LDP-IGP Sync\n")
791 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
792 ospf_ldp_sync_gbl_exit(ospf
, false);
796 DEFPY (ospf_mpls_ldp_sync_holddown
,
797 ospf_mpls_ldp_sync_holddown_cmd
,
798 "mpls ldp-sync holddown (1-10000)",
799 "MPLS specific commands\n"
800 "Enable MPLS LDP-IGP Sync\n"
801 "Set holddown timer\n"
804 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
805 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
806 struct interface
*ifp
;
808 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
809 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
810 return CMD_ERR_NOTHING_TODO
;
813 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
814 ospf
->ldp_sync_cmd
.holddown
= holddown
;
815 /* set holddown time on all OSPF interfaces */
816 FOR_ALL_INTERFACES (vrf
, ifp
)
817 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
822 DEFPY (no_ospf_mpls_ldp_sync_holddown
,
823 no_ospf_mpls_ldp_sync_holddown_cmd
,
824 "no mpls ldp-sync holddown [<(1-10000)>]",
826 "MPLS specific commands\n"
827 "Disable MPLS LDP-IGP Sync\n"
828 "holddown timer disable\n"
831 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
832 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
833 struct interface
*ifp
;
835 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
836 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
837 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
838 /* turn off holddown timer on all OSPF interfaces */
839 FOR_ALL_INTERFACES (vrf
, ifp
)
840 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
846 DEFPY (mpls_ldp_sync
,
848 "ip ospf mpls ldp-sync",
850 "OSPF interface commands\n"
854 VTY_DECLVAR_CONTEXT(interface
, ifp
);
855 struct ospf_if_params
*params
;
856 struct ldp_sync_info
*ldp_sync_info
;
858 if (if_is_loopback(ifp
)) {
859 vty_out(vty
, "ldp-sync does not run on loopback interface\n");
860 return CMD_ERR_NOTHING_TODO
;
863 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
864 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
865 return CMD_ERR_NOTHING_TODO
;
868 params
= IF_DEF_PARAMS(ifp
);
869 if (params
->ldp_sync_info
== NULL
)
870 params
->ldp_sync_info
= ldp_sync_info_create();
872 ldp_sync_info
= params
->ldp_sync_info
;
874 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
875 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
876 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
|| if_is_pointopoint(ifp
)) {
877 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
878 ospf_ldp_sync_state_req_msg(ifp
);
880 zlog_debug("ldp_sync: only runs on P2P links %s", ifp
->name
);
881 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
886 DEFPY (no_mpls_ldp_sync
,
887 no_mpls_ldp_sync_cmd
,
888 "no ip ospf mpls ldp-sync",
891 "OSPF interface commands\n"
893 NO_MPLS_LDP_SYNC_STR
)
895 VTY_DECLVAR_CONTEXT(interface
, ifp
);
896 struct ospf_if_params
*params
;
897 struct ldp_sync_info
*ldp_sync_info
;
899 if (if_is_loopback(ifp
)) {
900 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
901 return CMD_ERR_NOTHING_TODO
;
904 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
905 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
906 return CMD_ERR_NOTHING_TODO
;
909 params
= IF_DEF_PARAMS(ifp
);
910 if (params
->ldp_sync_info
== NULL
)
911 params
->ldp_sync_info
= ldp_sync_info_create();
913 ldp_sync_info
= params
->ldp_sync_info
;
915 /* disable LDP-SYNC on an interface
916 * stop holddown timer if running
919 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
920 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
921 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
922 THREAD_OFF(ldp_sync_info
->t_holddown
);
923 ospf_if_recalculate_output_cost(ifp
);
928 DEFPY (mpls_ldp_sync_holddown
,
929 mpls_ldp_sync_holddown_cmd
,
930 "ip ospf mpls ldp-sync holddown (0-10000)",
932 "OSPF interface commands\n"
935 "Time to wait for LDP-SYNC to occur before restoring interface cost\n"
938 VTY_DECLVAR_CONTEXT(interface
, ifp
);
939 struct ospf_if_params
*params
;
940 struct ldp_sync_info
*ldp_sync_info
;
942 if (if_is_loopback(ifp
)) {
943 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
944 return CMD_ERR_NOTHING_TODO
;
947 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
948 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
949 return CMD_ERR_NOTHING_TODO
;
952 params
= IF_DEF_PARAMS(ifp
);
953 if (params
->ldp_sync_info
== NULL
)
954 params
->ldp_sync_info
= ldp_sync_info_create();
956 ldp_sync_info
= params
->ldp_sync_info
;
958 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
959 ldp_sync_info
->holddown
= holddown
;
964 DEFPY (no_mpls_ldp_sync_holddown
,
965 no_mpls_ldp_sync_holddown_cmd
,
966 "no ip ospf mpls ldp-sync holddown [<(1-10000)>]",
969 "OSPF interface commands\n"
972 NO_MPLS_LDP_SYNC_HOLDDOWN_STR
975 VTY_DECLVAR_CONTEXT(interface
, ifp
);
976 struct ospf_if_params
*params
;
977 struct ldp_sync_info
*ldp_sync_info
;
980 if (if_is_loopback(ifp
)) {
981 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
982 return CMD_ERR_NOTHING_TODO
;
985 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
986 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
987 return CMD_ERR_NOTHING_TODO
;
990 params
= IF_DEF_PARAMS(ifp
);
991 ldp_sync_info
= params
->ldp_sync_info
;
992 if (ldp_sync_info
== NULL
)
995 /* use global configured value if set */
996 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
997 UNSET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
998 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
999 if (ospf
&& CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
,
1000 LDP_SYNC_FLAG_HOLDDOWN
))
1001 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
1003 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
1008 DEFPY (show_ip_ospf_mpls_ldp_interface
,
1009 show_ip_ospf_mpls_ldp_interface_cmd
,
1010 "show ip ospf mpls ldp-sync [interface <INTERFACE|all>] [json]",
1013 "OSPF information\n"
1015 "LDP-IGP Sync information\n"
1016 "Interface information\n"
1022 bool uj
= use_json(argc
, argv
);
1023 char *intf_name
= NULL
;
1024 int ret
= CMD_SUCCESS
;
1026 json_object
*json
= NULL
;
1028 if (argv_find(argv
, argc
, "INTERFACE", &idx_intf
))
1029 intf_name
= argv
[idx_intf
]->arg
;
1032 json
= json_object_new_object();
1034 /* Display default ospf (instance 0) info */
1035 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1036 if (ospf
== NULL
|| !ospf
->oi_running
) {
1038 vty_json(vty
, json
);
1040 vty_out(vty
, "%% OSPF instance not found\n");
1044 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
1046 vty_json(vty
, json
);
1048 vty_out(vty
, "LDP-sync is disabled\n");
1052 ret
= show_ip_ospf_mpls_ldp_interface_common(vty
, ospf
, intf_name
,
1055 vty_json(vty
, json
);
1060 void ospf_ldp_sync_init(void)
1062 /* Install global ldp-igp sync commands */
1063 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_cmd
);
1064 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_cmd
);
1065 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_holddown_cmd
);
1066 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_holddown_cmd
);
1068 /* Interface lsp-igp sync commands */
1069 install_element(INTERFACE_NODE
, &mpls_ldp_sync_cmd
);
1070 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_cmd
);
1071 install_element(INTERFACE_NODE
, &mpls_ldp_sync_holddown_cmd
);
1072 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_holddown_cmd
);
1074 /* "show ip ospf mpls ldp interface" commands. */
1075 install_element(VIEW_NODE
, &show_ip_ospf_mpls_ldp_interface_cmd
);
1077 hook_register(ospf_ism_change
, ospf_ldp_sync_ism_change
);