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 /* specifed 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 int 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
);
381 void ospf_ldp_sync_holddown_timer_add(struct interface
*ifp
)
383 struct ospf_if_params
*params
;
384 struct ldp_sync_info
*ldp_sync_info
;
386 params
= IF_DEF_PARAMS(ifp
);
387 ldp_sync_info
= params
->ldp_sync_info
;
389 /* Start holddown timer:
390 * this timer is used to keep interface cost at LSInfinity
391 * once expires returns cost to original value
392 * if timer is already running or holddown time is off just return
394 if (ldp_sync_info
->t_holddown
||
395 ldp_sync_info
->holddown
== LDP_IGP_SYNC_HOLDDOWN_DEFAULT
)
398 ols_debug("ldp_sync: start holddown timer for %s time %d",
399 ifp
->name
, ldp_sync_info
->holddown
);
401 thread_add_timer(master
, ospf_ldp_sync_holddown_timer
,
402 ifp
, ldp_sync_info
->holddown
,
403 &ldp_sync_info
->t_holddown
);
407 * LDP-SYNC exit routes.
409 void ospf_ldp_sync_gbl_exit(struct ospf
*ospf
, bool remove
)
411 struct interface
*ifp
;
414 /* ospf is being removed
415 * stop any holddown timers
417 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
418 /* unregister with opaque client to recv LDP-IGP Sync msgs */
419 zclient_unregister_opaque(zclient
,
420 LDP_IGP_SYNC_IF_STATE_UPDATE
);
421 zclient_unregister_opaque(zclient
,
422 LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
424 /* disable LDP globally */
425 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
426 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
427 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
429 /* turn off LDP-IGP Sync on all OSPF interfaces */
430 vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
431 FOR_ALL_INTERFACES (vrf
, ifp
)
432 ospf_ldp_sync_if_remove(ifp
, remove
);
437 * LDP-SYNC routes used by set commands.
439 void ospf_if_set_ldp_sync_enable(struct ospf
*ospf
, struct interface
*ifp
)
441 struct ospf_if_params
*params
;
442 struct ldp_sync_info
*ldp_sync_info
;
444 /* called when setting LDP-SYNC at the global level:
445 * specifed on interface overrides global config
446 * if ptop link send msg to LDP indicating ldp-sync enabled
448 if (if_is_loopback(ifp
))
451 params
= IF_DEF_PARAMS(ifp
);
452 if (params
->ldp_sync_info
== NULL
)
453 params
->ldp_sync_info
= ldp_sync_info_create();
454 ldp_sync_info
= params
->ldp_sync_info
;
456 /* config on interface, overrides global config. */
457 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
))
458 if (ldp_sync_info
->enabled
!= LDP_IGP_SYNC_ENABLED
)
461 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
463 ols_debug("ldp_sync: enable if %s", ifp
->name
);
465 /* send message to LDP if ptop link */
466 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
||
467 if_is_pointopoint(ifp
)) {
468 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
469 ospf_ldp_sync_state_req_msg(ifp
);
471 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
472 zlog_debug("ldp_sync: Sync only runs on P2P links %s",
477 void ospf_if_set_ldp_sync_holddown(struct ospf
*ospf
, struct interface
*ifp
)
479 struct ospf_if_params
*params
;
480 struct ldp_sync_info
*ldp_sync_info
;
482 /* called when setting LDP-SYNC at the global level:
483 * specifed on interface overrides global config.
485 if (if_is_loopback(ifp
))
488 params
= IF_DEF_PARAMS(ifp
);
489 if (params
->ldp_sync_info
== NULL
)
490 params
->ldp_sync_info
= ldp_sync_info_create();
491 ldp_sync_info
= params
->ldp_sync_info
;
493 /* config on interface, overrides global config. */
494 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
496 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
497 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
499 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
503 * LDP-SYNC routines used by show commands.
506 void ospf_ldp_sync_show_info(struct vty
*vty
, struct ospf
*ospf
,
507 json_object
*json_vrf
, bool use_json
)
510 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
512 json_object_boolean_true_add(json_vrf
,
513 "MplsLdpIgpSyncEnabled");
514 json_object_int_add(json_vrf
, "MplsLdpIgpSyncHolddown",
515 ospf
->ldp_sync_cmd
.holddown
);
517 vty_out(vty
, " MPLS LDP-IGP Sync is enabled\n");
518 if (ospf
->ldp_sync_cmd
.holddown
== 0)
520 " MPLS LDP-IGP Sync holddown timer is disabled\n");
523 " MPLS LDP-IGP Sync holddown timer %d sec\n",
524 ospf
->ldp_sync_cmd
.holddown
);
529 static void show_ip_ospf_mpls_ldp_interface_sub(struct vty
*vty
,
530 struct ospf_interface
*oi
,
531 struct interface
*ifp
,
532 json_object
*json_interface_sub
,
535 const char *ldp_state
;
536 struct ospf_if_params
*params
;
537 char timebuf
[OSPF_TIME_DUMP_SIZE
];
538 struct ldp_sync_info
*ldp_sync_info
;
540 params
= IF_DEF_PARAMS(oi
->ifp
);
541 if (params
->ldp_sync_info
== NULL
)
544 ldp_sync_info
= params
->ldp_sync_info
;
546 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
547 json_object_boolean_true_add(json_interface_sub
,
548 "ldpIgpSyncEnabled");
550 json_object_boolean_false_add(json_interface_sub
,
551 "ldpIgpSyncEnabled");
553 json_object_int_add(json_interface_sub
, "holdDownTimeInSec",
554 ldp_sync_info
->holddown
);
557 vty_out(vty
, "%-10s\n", ifp
->name
);
558 vty_out(vty
, " LDP-IGP Synchronization enabled: %s\n",
559 ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
562 vty_out(vty
, " Holddown timer in seconds: %u\n",
563 ldp_sync_info
->holddown
);
566 switch (ldp_sync_info
->state
) {
567 case LDP_IGP_SYNC_STATE_REQUIRED_UP
:
569 json_object_string_add(json_interface_sub
,
573 vty_out(vty
, " State: Sync achieved\n");
575 case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
:
576 if (ldp_sync_info
->t_holddown
!= NULL
) {
580 time_store
= monotime_until(
581 &ldp_sync_info
->t_holddown
->u
.sands
,
585 json_object_int_add(json_interface_sub
,
586 "ldpIgpSyncTimeRemainInMsec",
589 json_object_string_add(json_interface_sub
,
591 "Holding down until Sync");
594 " Holddown timer is running %s remaining\n",
596 ldp_sync_info
->t_holddown
,
601 " State: Holding down until Sync\n");
605 json_object_string_add(json_interface_sub
,
607 "Sync not achieved");
609 vty_out(vty
, " State: Sync not achieved\n");
612 case LDP_IGP_SYNC_STATE_NOT_REQUIRED
:
614 if (IF_DEF_PARAMS(ifp
)->type
!= OSPF_IFTYPE_POINTOPOINT
&&
615 !if_is_pointopoint(ifp
))
616 ldp_state
= "Sync not required: non-p2p link";
618 ldp_state
= "Sync not required";
621 json_object_string_add(json_interface_sub
,
625 vty_out(vty
, " State: %s\n", ldp_state
);
630 static int show_ip_ospf_mpls_ldp_interface_common(struct vty
*vty
,
636 struct interface
*ifp
;
637 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
638 json_object
*json_interface_sub
= NULL
;
640 if (intf_name
== NULL
) {
641 /* Show All Interfaces.*/
642 FOR_ALL_INTERFACES (vrf
, ifp
) {
643 struct route_node
*rn
;
644 struct ospf_interface
*oi
;
646 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
648 vty_out(vty
, "%s\n Interface down\n",
652 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
653 rn
= route_next(rn
)) {
658 json_object_new_object();
660 show_ip_ospf_mpls_ldp_interface_sub(
661 vty
, oi
, ifp
, json_interface_sub
,
665 json_object_object_add(
672 /* Interface name is specified. */
673 ifp
= if_lookup_by_name(intf_name
, ospf
->vrf_id
);
675 struct route_node
*rn
;
676 struct ospf_interface
*oi
;
678 if (ospf_oi_count(ifp
) == 0 && !use_json
) {
680 vty_out(vty
, "%s\n OSPF not enabled\n",
683 vty_out(vty
, "%s\n Interface down\n",
687 for (rn
= route_top(IF_OIFS(ifp
)); rn
;
688 rn
= route_next(rn
)) {
693 json_object_new_object();
695 show_ip_ospf_mpls_ldp_interface_sub(
696 vty
, oi
, ifp
, json_interface_sub
,
700 json_object_object_add(
711 * Write the global LDP-SYNC configuration.
713 void ospf_ldp_sync_write_config(struct vty
*vty
, struct ospf
*ospf
)
715 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
))
716 vty_out(vty
, " mpls ldp-sync\n");
717 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
))
718 vty_out(vty
, " mpls ldp-sync holddown %u\n",
719 ospf
->ldp_sync_cmd
.holddown
);
723 * Write the interface LDP-SYNC configuration.
725 void ospf_ldp_sync_if_write_config(struct vty
*vty
,
726 struct ospf_if_params
*params
)
729 struct ldp_sync_info
*ldp_sync_info
;
731 ldp_sync_info
= params
->ldp_sync_info
;
732 if (ldp_sync_info
== NULL
)
735 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
)) {
736 if (ldp_sync_info
->enabled
== LDP_IGP_SYNC_ENABLED
)
737 vty_out(vty
, " ip ospf mpls ldp-sync\n");
739 vty_out(vty
, " no ip ospf mpls ldp-sync\n");
741 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
))
742 vty_out(vty
, " ip ospf mpls ldp-sync holddown %u\n",
743 ldp_sync_info
->holddown
);
749 #ifndef VTYSH_EXTRACT_PL
750 #include "ospfd/ospf_ldp_sync_clippy.c"
753 DEFPY (ospf_mpls_ldp_sync
,
754 ospf_mpls_ldp_sync_cmd
,
756 "MPLS specific commands\n"
757 "Enable MPLS LDP-IGP Sync\n")
759 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
760 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
761 struct interface
*ifp
;
763 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
764 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
765 return CMD_ERR_NOTHING_TODO
;
768 /* register with opaque client to recv LDP-IGP Sync msgs */
769 zclient_register_opaque(zclient
, LDP_IGP_SYNC_IF_STATE_UPDATE
);
770 zclient_register_opaque(zclient
, LDP_IGP_SYNC_ANNOUNCE_UPDATE
);
772 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
773 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
);
774 /* turn on LDP-IGP Sync on all ptop OSPF interfaces */
775 FOR_ALL_INTERFACES (vrf
, ifp
)
776 ospf_if_set_ldp_sync_enable(ospf
, ifp
);
781 DEFPY (no_ospf_mpls_ldp_sync
,
782 no_ospf_mpls_ldp_sync_cmd
,
785 "MPLS specific commands\n"
786 "Disable MPLS LDP-IGP Sync\n")
788 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
789 ospf_ldp_sync_gbl_exit(ospf
, false);
793 DEFPY (ospf_mpls_ldp_sync_holddown
,
794 ospf_mpls_ldp_sync_holddown_cmd
,
795 "mpls ldp-sync holddown (1-10000)",
796 "MPLS specific commands\n"
797 "Enable MPLS LDP-IGP Sync\n"
798 "Set holddown timer\n"
801 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
802 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
803 struct interface
*ifp
;
805 if (ospf
->vrf_id
!= VRF_DEFAULT
) {
806 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
807 return CMD_ERR_NOTHING_TODO
;
810 SET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
811 ospf
->ldp_sync_cmd
.holddown
= holddown
;
812 /* set holddown time on all OSPF interfaces */
813 FOR_ALL_INTERFACES (vrf
, ifp
)
814 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
819 DEFPY (no_ospf_mpls_ldp_sync_holddown
,
820 no_ospf_mpls_ldp_sync_holddown_cmd
,
821 "no mpls ldp-sync holddown [<(1-10000)>]",
823 "MPLS specific commands\n"
824 "Disable MPLS LDP-IGP Sync\n"
825 "holddown timer disable\n"
828 VTY_DECLVAR_INSTANCE_CONTEXT(ospf
, ospf
);
829 struct vrf
*vrf
= vrf_lookup_by_id(ospf
->vrf_id
);
830 struct interface
*ifp
;
832 if (CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
833 UNSET_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_HOLDDOWN
);
834 ospf
->ldp_sync_cmd
.holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
835 /* turn off holddown timer on all OSPF interfaces */
836 FOR_ALL_INTERFACES (vrf
, ifp
)
837 ospf_if_set_ldp_sync_holddown(ospf
, ifp
);
843 DEFPY (mpls_ldp_sync
,
845 "ip ospf mpls ldp-sync",
847 "OSPF interface commands\n"
851 VTY_DECLVAR_CONTEXT(interface
, ifp
);
852 struct ospf_if_params
*params
;
853 struct ldp_sync_info
*ldp_sync_info
;
855 if (if_is_loopback(ifp
)) {
856 vty_out(vty
, "ldp-sync does not run on loopback interface\n");
857 return CMD_ERR_NOTHING_TODO
;
860 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
861 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
862 return CMD_ERR_NOTHING_TODO
;
865 params
= IF_DEF_PARAMS(ifp
);
866 if (params
->ldp_sync_info
== NULL
)
867 params
->ldp_sync_info
= ldp_sync_info_create();
869 ldp_sync_info
= params
->ldp_sync_info
;
871 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
872 ldp_sync_info
->enabled
= LDP_IGP_SYNC_ENABLED
;
873 if (params
->type
== OSPF_IFTYPE_POINTOPOINT
|| if_is_pointopoint(ifp
)) {
874 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP
;
875 ospf_ldp_sync_state_req_msg(ifp
);
877 zlog_debug("ldp_sync: only runs on P2P links %s", ifp
->name
);
878 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
883 DEFPY (no_mpls_ldp_sync
,
884 no_mpls_ldp_sync_cmd
,
885 "no ip ospf mpls ldp-sync",
888 "OSPF interface commands\n"
890 NO_MPLS_LDP_SYNC_STR
)
892 VTY_DECLVAR_CONTEXT(interface
, ifp
);
893 struct ospf_if_params
*params
;
894 struct ldp_sync_info
*ldp_sync_info
;
896 if (if_is_loopback(ifp
)) {
897 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
898 return CMD_ERR_NOTHING_TODO
;
901 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
902 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
903 return CMD_ERR_NOTHING_TODO
;
906 params
= IF_DEF_PARAMS(ifp
);
907 if (params
->ldp_sync_info
== NULL
)
908 params
->ldp_sync_info
= ldp_sync_info_create();
910 ldp_sync_info
= params
->ldp_sync_info
;
912 /* disable LDP-SYNC on an interface
913 * stop holddown timer if running
916 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_IF_CONFIG
);
917 ldp_sync_info
->enabled
= LDP_IGP_SYNC_DEFAULT
;
918 ldp_sync_info
->state
= LDP_IGP_SYNC_STATE_NOT_REQUIRED
;
919 THREAD_OFF(ldp_sync_info
->t_holddown
);
920 ospf_if_recalculate_output_cost(ifp
);
925 DEFPY (mpls_ldp_sync_holddown
,
926 mpls_ldp_sync_holddown_cmd
,
927 "ip ospf mpls ldp-sync holddown (0-10000)",
929 "OSPF interface commands\n"
932 "Time to wait for LDP-SYNC to occur before restoring interface cost\n"
935 VTY_DECLVAR_CONTEXT(interface
, ifp
);
936 struct ospf_if_params
*params
;
937 struct ldp_sync_info
*ldp_sync_info
;
939 if (if_is_loopback(ifp
)) {
940 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
941 return CMD_ERR_NOTHING_TODO
;
944 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
945 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
946 return CMD_ERR_NOTHING_TODO
;
949 params
= IF_DEF_PARAMS(ifp
);
950 if (params
->ldp_sync_info
== NULL
)
951 params
->ldp_sync_info
= ldp_sync_info_create();
953 ldp_sync_info
= params
->ldp_sync_info
;
955 SET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
956 ldp_sync_info
->holddown
= holddown
;
961 DEFPY (no_mpls_ldp_sync_holddown
,
962 no_mpls_ldp_sync_holddown_cmd
,
963 "no ip ospf mpls ldp-sync holddown [<(1-10000)>]",
966 "OSPF interface commands\n"
969 NO_MPLS_LDP_SYNC_HOLDDOWN_STR
972 VTY_DECLVAR_CONTEXT(interface
, ifp
);
973 struct ospf_if_params
*params
;
974 struct ldp_sync_info
*ldp_sync_info
;
977 if (if_is_loopback(ifp
)) {
978 vty_out(vty
, "ldp-sync: does not run on loopback interface\n");
979 return CMD_ERR_NOTHING_TODO
;
982 if (ifp
->vrf
->vrf_id
!= VRF_DEFAULT
) {
983 vty_out(vty
, "ldp-sync only runs on DEFAULT VRF\n");
984 return CMD_ERR_NOTHING_TODO
;
987 params
= IF_DEF_PARAMS(ifp
);
988 ldp_sync_info
= params
->ldp_sync_info
;
989 if (ldp_sync_info
== NULL
)
992 /* use global configured value if set */
993 if (CHECK_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
)) {
994 UNSET_FLAG(ldp_sync_info
->flags
, LDP_SYNC_FLAG_HOLDDOWN
);
995 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
996 if (ospf
&& CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
,
997 LDP_SYNC_FLAG_HOLDDOWN
))
998 ldp_sync_info
->holddown
= ospf
->ldp_sync_cmd
.holddown
;
1000 ldp_sync_info
->holddown
= LDP_IGP_SYNC_HOLDDOWN_DEFAULT
;
1005 DEFPY (show_ip_ospf_mpls_ldp_interface
,
1006 show_ip_ospf_mpls_ldp_interface_cmd
,
1007 "show ip ospf mpls ldp-sync [interface <INTERFACE|all>] [json]",
1010 "OSPF information\n"
1012 "LDP-IGP Sync information\n"
1013 "Interface information\n"
1019 bool uj
= use_json(argc
, argv
);
1020 char *intf_name
= NULL
;
1021 int ret
= CMD_SUCCESS
;
1023 json_object
*json
= NULL
;
1025 if (argv_find(argv
, argc
, "INTERFACE", &idx_intf
))
1026 intf_name
= argv
[idx_intf
]->arg
;
1029 json
= json_object_new_object();
1031 /* Display default ospf (instance 0) info */
1032 ospf
= ospf_lookup_by_vrf_id(VRF_DEFAULT
);
1033 if (ospf
== NULL
|| !ospf
->oi_running
) {
1035 vty_json(vty
, json
);
1037 vty_out(vty
, "%% OSPF instance not found\n");
1041 if (!CHECK_FLAG(ospf
->ldp_sync_cmd
.flags
, LDP_SYNC_FLAG_ENABLE
)) {
1043 vty_json(vty
, json
);
1045 vty_out(vty
, "LDP-sync is disabled\n");
1049 ret
= show_ip_ospf_mpls_ldp_interface_common(vty
, ospf
, intf_name
,
1052 vty_json(vty
, json
);
1057 void ospf_ldp_sync_init(void)
1059 /* Install global ldp-igp sync commands */
1060 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_cmd
);
1061 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_cmd
);
1062 install_element(OSPF_NODE
, &ospf_mpls_ldp_sync_holddown_cmd
);
1063 install_element(OSPF_NODE
, &no_ospf_mpls_ldp_sync_holddown_cmd
);
1065 /* Interface lsp-igp sync commands */
1066 install_element(INTERFACE_NODE
, &mpls_ldp_sync_cmd
);
1067 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_cmd
);
1068 install_element(INTERFACE_NODE
, &mpls_ldp_sync_holddown_cmd
);
1069 install_element(INTERFACE_NODE
, &no_mpls_ldp_sync_holddown_cmd
);
1071 /* "show ip ospf mpls ldp interface" commands. */
1072 install_element(VIEW_NODE
, &show_ip_ospf_mpls_ldp_interface_cmd
);
1074 hook_register(ospf_ism_change
, ospf_ldp_sync_ism_change
);