1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
10 #include "lib_errors.h"
12 #include "sockunion.h"
17 #include "connected.h"
21 #include "lib/northbound_cli.h"
23 #include "zebra/rtadv.h"
25 #include "zebra_vrf.h"
26 #include "zebra/interface.h"
27 #include "zebra/rib.h"
29 #include "zebra/zebra_router.h"
30 #include "zebra/redistribute.h"
31 #include "zebra/debug.h"
32 #include "zebra/irdp.h"
33 #include "zebra/zebra_ptm.h"
34 #include "zebra/rt_netlink.h"
35 #include "zebra/if_netlink.h"
36 #include "zebra/interface.h"
37 #include "zebra/zebra_vxlan.h"
38 #include "zebra/zebra_errors.h"
39 #include "zebra/zebra_evpn_mh.h"
41 DEFINE_MTYPE_STATIC(ZEBRA
, ZINFO
, "Zebra Interface Information");
43 #define ZEBRA_PTM_SUPPORT
45 DEFINE_HOOK(zebra_if_extra_info
, (struct vty
* vty
, struct interface
*ifp
),
47 DEFINE_HOOK(zebra_if_config_wr
, (struct vty
* vty
, struct interface
*ifp
),
50 DEFINE_MTYPE(ZEBRA
, ZIF_DESC
, "Intf desc");
52 static void if_down_del_nbr_connected(struct interface
*ifp
);
54 static void if_zebra_speed_update(struct thread
*thread
)
56 struct interface
*ifp
= THREAD_ARG(thread
);
57 struct zebra_if
*zif
= ifp
->info
;
62 new_speed
= kernel_get_speed(ifp
, &error
);
64 /* error may indicate vrf not available or
65 * interfaces not available.
66 * note that loopback & virtual interfaces can return 0 as speed
71 if (new_speed
!= ifp
->speed
) {
72 zlog_info("%s: %s old speed: %u new speed: %u", __func__
,
73 ifp
->name
, ifp
->speed
, new_speed
);
74 ifp
->speed
= new_speed
;
79 if (changed
|| new_speed
== UINT32_MAX
) {
80 #define SPEED_UPDATE_SLEEP_TIME 5
81 #define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
83 * Some interfaces never actually have an associated speed
84 * with them ( I am looking at you bridges ).
85 * So instead of iterating forever, let's give the
86 * system 4 minutes to try to figure out the speed
87 * if after that it it's probably never going to become
89 * Since I don't know all the wonderful types of interfaces
90 * that may come into existence in the future I am going
91 * to not update the system to keep track of that. This
92 * is far simpler to just stop trying after 4 minutes
94 if (new_speed
== UINT32_MAX
&&
95 zif
->speed_update_count
== SPEED_UPDATE_COUNT_MAX
)
98 zif
->speed_update_count
++;
99 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
,
100 SPEED_UPDATE_SLEEP_TIME
, &zif
->speed_update
);
101 thread_ignore_late_timer(zif
->speed_update
);
105 static void zebra_if_node_destroy(route_table_delegate_t
*delegate
,
106 struct route_table
*table
,
107 struct route_node
*node
)
110 list_delete((struct list
**)&node
->info
);
111 route_node_destroy(delegate
, table
, node
);
114 static void zebra_if_nhg_dependents_free(struct zebra_if
*zebra_if
)
116 nhg_connected_tree_free(&zebra_if
->nhg_dependents
);
119 static void zebra_if_nhg_dependents_init(struct zebra_if
*zebra_if
)
121 nhg_connected_tree_init(&zebra_if
->nhg_dependents
);
125 route_table_delegate_t zebra_if_table_delegate
= {
126 .create_node
= route_node_create
,
127 .destroy_node
= zebra_if_node_destroy
};
129 /* Called when new interface is added. */
130 static int if_zebra_new_hook(struct interface
*ifp
)
132 struct zebra_if
*zebra_if
;
134 zebra_if
= XCALLOC(MTYPE_ZINFO
, sizeof(struct zebra_if
));
137 zebra_if
->multicast
= IF_ZEBRA_DATA_UNSPEC
;
138 zebra_if
->shutdown
= IF_ZEBRA_DATA_OFF
;
140 zebra_if_nhg_dependents_init(zebra_if
);
142 zebra_ptm_if_init(zebra_if
);
144 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
146 rtadv_if_init(zebra_if
);
148 memset(&zebra_if
->neigh_mac
[0], 0, 6);
150 /* Initialize installed address chains tree. */
151 zebra_if
->ipv4_subnets
=
152 route_table_init_with_delegate(&zebra_if_table_delegate
);
154 ifp
->info
= zebra_if
;
157 * Some platforms are telling us that the interface is
158 * up and ready to go. When we check the speed we
159 * sometimes get the wrong value. Wait a couple
160 * of seconds and ask again. Hopefully it's all settled
163 zebra_if
->speed_update_count
= 0;
164 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
165 &zebra_if
->speed_update
);
166 thread_ignore_late_timer(zebra_if
->speed_update
);
171 static void if_nhg_dependents_check_valid(struct nhg_hash_entry
*nhe
)
173 zebra_nhg_check_valid(nhe
);
176 static void if_down_nhg_dependents(const struct interface
*ifp
)
178 struct nhg_connected
*rb_node_dep
= NULL
;
179 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
181 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
)
182 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
185 static void if_nhg_dependents_release(const struct interface
*ifp
)
187 struct nhg_connected
*rb_node_dep
= NULL
;
188 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
190 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
) {
191 rb_node_dep
->nhe
->ifp
= NULL
; /* Null it out */
192 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
196 /* Called when interface is deleted. */
197 static int if_zebra_delete_hook(struct interface
*ifp
)
199 struct zebra_if
*zebra_if
;
202 zebra_if
= ifp
->info
;
204 /* If we set protodown, clear our reason now from the kernel */
205 if (ZEBRA_IF_IS_PROTODOWN(zebra_if
) && zebra_if
->protodown_rc
&&
206 !ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zebra_if
))
207 zebra_if_update_protodown_rc(ifp
, true,
208 (zebra_if
->protodown_rc
&
209 ~ZEBRA_PROTODOWN_ALL
));
211 /* Free installed address chains tree. */
212 if (zebra_if
->ipv4_subnets
)
213 route_table_finish(zebra_if
->ipv4_subnets
);
215 rtadv_if_fini(zebra_if
);
217 zebra_l2_bridge_if_cleanup(ifp
);
218 zebra_evpn_if_cleanup(zebra_if
);
219 zebra_evpn_mac_ifp_del(ifp
);
221 if_nhg_dependents_release(ifp
);
222 zebra_if_nhg_dependents_free(zebra_if
);
224 XFREE(MTYPE_ZIF_DESC
, zebra_if
->desc
);
226 THREAD_OFF(zebra_if
->speed_update
);
228 XFREE(MTYPE_ZINFO
, zebra_if
);
234 /* Build the table key */
235 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
238 p
->prefixlen
= IPV4_MAX_BITLEN
;
239 p
->u
.prefix4
.s_addr
= ifindex
;
242 /* Link an interface in a per NS interface tree */
243 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
246 struct route_node
*rn
;
248 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
251 if_build_key(ifp
->ifindex
, &p
);
252 rn
= route_node_get(ns
->if_table
, &p
);
254 ifp
= (struct interface
*)rn
->info
;
255 route_unlock_node(rn
); /* get */
265 /* Delete a VRF. This is called in vrf_terminate(). */
266 void if_unlink_per_ns(struct interface
*ifp
)
268 ifp
->node
->info
= NULL
;
269 route_unlock_node(ifp
->node
);
273 /* Look up an interface by identifier within a NS */
274 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
278 struct route_node
*rn
;
279 struct interface
*ifp
= NULL
;
281 if_build_key(ifindex
, &p
);
282 rn
= route_node_lookup(ns
->if_table
, &p
);
284 ifp
= (struct interface
*)rn
->info
;
285 route_unlock_node(rn
); /* lookup */
290 /* Look up an interface by name within a NS */
291 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
294 struct route_node
*rn
;
295 struct interface
*ifp
;
297 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
298 ifp
= (struct interface
*)rn
->info
;
299 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0) {
300 route_unlock_node(rn
);
308 const char *ifindex2ifname_per_ns(struct zebra_ns
*zns
, unsigned int ifindex
)
310 struct interface
*ifp
;
312 return ((ifp
= if_lookup_by_index_per_ns(zns
, ifindex
)) != NULL
)
317 /* Tie an interface address to its derived subnet list of addresses. */
318 int if_subnet_add(struct interface
*ifp
, struct connected
*ifc
)
320 struct route_node
*rn
;
321 struct zebra_if
*zebra_if
;
323 struct list
*addr_list
;
325 assert(ifp
&& ifp
->info
&& ifc
);
326 zebra_if
= ifp
->info
;
328 /* Get address derived subnet node and associated address list, while
330 address secondary attribute appropriately. */
331 cp
= *CONNECTED_PREFIX(ifc
);
333 rn
= route_node_get(zebra_if
->ipv4_subnets
, &cp
);
335 if ((addr_list
= rn
->info
))
336 SET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
338 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
339 rn
->info
= addr_list
= list_new();
343 /* Tie address at the tail of address list. */
344 listnode_add(addr_list
, ifc
);
346 /* Return list element count. */
347 return (addr_list
->count
);
350 /* Untie an interface address from its derived subnet list of addresses. */
351 int if_subnet_delete(struct interface
*ifp
, struct connected
*ifc
)
353 struct route_node
*rn
;
354 struct zebra_if
*zebra_if
;
355 struct list
*addr_list
;
358 assert(ifp
&& ifp
->info
&& ifc
);
359 zebra_if
= ifp
->info
;
361 cp
= *CONNECTED_PREFIX(ifc
);
364 /* Get address derived subnet node. */
365 rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
);
366 if (!(rn
&& rn
->info
)) {
367 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET
,
368 "Trying to remove an address from an unknown subnet. (please report this bug)");
371 route_unlock_node(rn
);
373 /* Untie address from subnet's address list. */
374 addr_list
= rn
->info
;
376 /* Deleting an address that is not registered is a bug.
377 * In any case, we shouldn't decrement the lock counter if the address
379 if (!listnode_lookup(addr_list
, ifc
)) {
381 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR
,
382 "Trying to remove an address from a subnet where it is not currently registered. (please report this bug)");
386 listnode_delete(addr_list
, ifc
);
387 route_unlock_node(rn
);
389 /* Return list element count, if not empty. */
390 if (addr_list
->count
) {
391 /* If deleted address is primary, mark subsequent one as such
393 if (!CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
395 (struct listnode
*)listhead(addr_list
));
396 zebra_interface_address_delete_update(ifp
, ifc
);
397 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
398 /* XXX: Linux kernel removes all the secondary addresses
400 * address is removed. We could try to work around that,
403 zebra_interface_address_add_update(ifp
, ifc
);
406 return addr_list
->count
;
409 /* Otherwise, free list and route node. */
410 list_delete(&addr_list
);
412 route_unlock_node(rn
);
417 /* if_flags_mangle: A place for hacks that require mangling
418 * or tweaking the interface flags.
420 * ******************** Solaris flags hacks **************************
422 * Solaris IFF_UP flag reflects only the primary interface as the
423 * routing socket only sends IFINFO for the primary interface. Hence
424 * ~IFF_UP does not per se imply all the logical interfaces are also
425 * down - which we only know of as addresses. Instead we must determine
426 * whether the interface really is up or not according to how many
427 * addresses are still attached. (Solaris always sends RTM_DELADDR if
428 * an interface, logical or not, goes ~IFF_UP).
430 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
431 * are addresses left in struct connected, not just the actual underlying
434 * We must hence remember the real state of IFF_UP, which we do in
435 * struct zebra_if.primary_state.
437 * Setting IFF_UP within zebra to administratively shutdown the
438 * interface will affect only the primary interface/address on Solaris.
439 ************************End Solaris flags hacks ***********************
441 static void if_flags_mangle(struct interface
*ifp
, uint64_t *newflags
)
446 /* Update the flags field of the ifp with the new flag set provided.
447 * Take whatever actions are required for any changes in flags we care
450 * newflags should be the raw value, as obtained from the OS.
452 void if_flags_update(struct interface
*ifp
, uint64_t newflags
)
454 if_flags_mangle(ifp
, &newflags
);
456 if (if_is_no_ptm_operative(ifp
)) {
457 /* operative -> inoperative? */
458 ifp
->flags
= newflags
;
459 if (!if_is_operative(ifp
))
462 /* inoperative -> operative? */
463 ifp
->flags
= newflags
;
464 if (if_is_operative(ifp
))
469 /* Wake up configured address if it is not in current kernel
471 void if_addr_wakeup(struct interface
*ifp
)
473 struct listnode
*node
, *nnode
;
474 struct connected
*ifc
;
476 enum zebra_dplane_result dplane_res
;
478 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, ifc
)) {
481 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)
482 && !CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)) {
484 if (p
->family
== AF_INET
) {
485 if (!if_is_up(ifp
)) {
486 /* Assume zebra is configured like
490 * ip addr 192.0.2.1/24
493 * As soon as zebra becomes first aware
494 * that gre0 exists in the
495 * kernel, it will set gre0 up and
496 * configure its addresses.
498 * (This may happen at startup when the
499 * interface already exists
500 * or during runtime when the interface
501 * is added to the kernel)
503 * XXX: IRDP code is calling here via
504 * if_add_update - this seems
506 * XXX: RUNNING is not a settable flag
508 * I (paulj) am aware of.
510 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
514 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
516 ZEBRA_DPLANE_REQUEST_FAILURE
) {
518 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
519 "Can't set interface's address: %s",
520 dplane_res2str(dplane_res
));
524 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
525 /* The address will be advertised to zebra
526 * clients when the notification
527 * from the kernel has been received.
528 * It will also be added to the interface's
529 * subnet list then. */
531 if (p
->family
== AF_INET6
) {
532 if (!if_is_up(ifp
)) {
533 /* See long comment above */
534 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
539 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
541 ZEBRA_DPLANE_REQUEST_FAILURE
) {
543 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
544 "Can't set interface's address: %s",
545 dplane_res2str(dplane_res
));
549 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
550 /* The address will be advertised to zebra
551 * clients when the notification
552 * from the kernel has been received. */
558 /* Handle interface addition */
559 void if_add_update(struct interface
*ifp
)
561 struct zebra_if
*if_data
;
562 struct zebra_ns
*zns
;
563 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
565 /* case interface populate before vrf enabled */
569 zns
= zebra_ns_lookup(NS_DEFAULT
);
570 if_link_per_ns(zns
, ifp
);
574 if (if_data
->multicast
== IF_ZEBRA_DATA_ON
)
575 if_set_flags(ifp
, IFF_MULTICAST
);
576 else if (if_data
->multicast
== IF_ZEBRA_DATA_OFF
)
577 if_unset_flags(ifp
, IFF_MULTICAST
);
579 zebra_ptm_if_set_ptm_state(ifp
, if_data
);
581 zebra_interface_add_update(ifp
);
583 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
584 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
586 if (if_data
->shutdown
== IF_ZEBRA_DATA_ON
) {
587 if (IS_ZEBRA_DEBUG_KERNEL
) {
589 "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.",
590 ifp
->name
, ifp
->vrf
->name
,
591 ifp
->vrf
->vrf_id
, ifp
->ifindex
);
599 if (IS_ZEBRA_DEBUG_KERNEL
)
601 "interface %s vrf %s(%u) index %d becomes active.",
602 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
606 if (IS_ZEBRA_DEBUG_KERNEL
)
607 zlog_debug("interface %s vrf %s(%u) index %d is added.",
608 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
613 /* Install connected routes corresponding to an interface. */
614 static void if_install_connected(struct interface
*ifp
)
616 struct listnode
*node
;
617 struct listnode
*next
;
618 struct connected
*ifc
;
620 if (ifp
->connected
) {
621 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
622 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
623 zebra_interface_address_add_update(ifp
, ifc
);
625 connected_up(ifp
, ifc
);
630 /* Uninstall connected routes corresponding to an interface. */
631 static void if_uninstall_connected(struct interface
*ifp
)
633 struct listnode
*node
;
634 struct listnode
*next
;
635 struct connected
*ifc
;
637 if (ifp
->connected
) {
638 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
639 zebra_interface_address_delete_update(ifp
, ifc
);
640 connected_down(ifp
, ifc
);
645 /* Uninstall and delete connected routes corresponding to an interface. */
646 /* TODO - Check why IPv4 handling here is different from install or if_down */
647 static void if_delete_connected(struct interface
*ifp
)
649 struct connected
*ifc
;
651 struct route_node
*rn
;
652 struct zebra_if
*zebra_if
;
653 struct listnode
*node
;
654 struct listnode
*last
= NULL
;
656 zebra_if
= ifp
->info
;
661 while ((node
= (last
? last
->next
: listhead(ifp
->connected
)))) {
662 ifc
= listgetdata(node
);
664 cp
= *CONNECTED_PREFIX(ifc
);
667 if (cp
.family
== AF_INET
668 && (rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
))) {
669 struct listnode
*anode
;
670 struct listnode
*next
;
671 struct listnode
*first
;
672 struct list
*addr_list
;
674 route_unlock_node(rn
);
675 addr_list
= (struct list
*)rn
->info
;
677 /* Remove addresses, secondaries first. */
678 first
= listhead(addr_list
);
680 for (anode
= first
->next
; anode
|| first
;
688 ifc
= listgetdata(anode
);
689 connected_down(ifp
, ifc
);
691 /* XXX: We have to send notifications
692 * here explicitly, because we destroy
693 * the ifc before receiving the
694 * notification about the address being
697 zebra_interface_address_delete_update(
700 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
701 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
703 /* Remove from subnet chain. */
704 list_delete_node(addr_list
, anode
);
705 route_unlock_node(rn
);
707 /* Remove from interface address list
708 * (unconditionally). */
709 if (!CHECK_FLAG(ifc
->conf
,
710 ZEBRA_IFC_CONFIGURED
)) {
711 listnode_delete(ifp
->connected
,
713 connected_free(&ifc
);
718 /* Free chain list and respective route node. */
719 list_delete(&addr_list
);
721 route_unlock_node(rn
);
722 } else if (cp
.family
== AF_INET6
) {
723 connected_down(ifp
, ifc
);
725 zebra_interface_address_delete_update(ifp
, ifc
);
727 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
728 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
730 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
733 listnode_delete(ifp
->connected
, ifc
);
734 connected_free(&ifc
);
742 /* Handle an interface delete event */
743 void if_delete_update(struct interface
**pifp
)
745 struct zebra_if
*zif
;
746 struct interface
*ifp
= *pifp
;
751 "interface %s vrf %s(%u) index %d is still up while being deleted.",
752 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
757 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
760 /* Mark interface as inactive */
761 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
763 if (IS_ZEBRA_DEBUG_KERNEL
)
764 zlog_debug("interface %s vrf %s(%u) index %d is now inactive.",
765 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
768 /* Delete connected routes from the kernel. */
769 if_delete_connected(ifp
);
771 /* Send out notification on interface delete. */
772 zebra_interface_delete_update(ifp
);
774 if_unlink_per_ns(ifp
);
776 /* Update ifindex after distributing the delete message. This is in
777 case any client needs to have the old value of ifindex available
778 while processing the deletion. Each client daemon is responsible
779 for setting ifindex to IFINDEX_INTERNAL after processing the
780 interface deletion message. */
781 if_set_index(ifp
, IFINDEX_INTERNAL
);
784 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
785 * desired. This operation is not done for netns implementation to avoid
786 * collision with interface with the same name in the default vrf (can
787 * occur with this implementation whereas it is not possible with
790 if (ifp
->vrf
->vrf_id
&& !vrf_is_backend_netns())
791 if_handle_vrf_change(ifp
, VRF_DEFAULT
);
793 /* Reset some zebra interface params to default values. */
796 zebra_evpn_if_cleanup(zif
);
797 zif
->zif_type
= ZEBRA_IF_OTHER
;
798 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
799 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
800 memset(&zif
->brslave_info
, 0,
801 sizeof(struct zebra_l2info_brslave
));
802 zebra_evpn_mac_ifp_del(ifp
);
805 if (!ifp
->configured
) {
806 if (IS_ZEBRA_DEBUG_KERNEL
)
807 zlog_debug("interface %s is being deleted from the system",
813 /* VRF change for an interface */
814 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
818 old_vrf_id
= ifp
->vrf
->vrf_id
;
820 /* Uninstall connected routes. */
821 if_uninstall_connected(ifp
);
823 /* Delete any IPv4 neighbors created to implement RFC 5549 */
824 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
826 /* Delete all neighbor addresses learnt through IPv6 RA */
827 if_down_del_nbr_connected(ifp
);
829 /* Send out notification on interface VRF change. */
830 /* This is to issue an UPDATE or a DELETE, as appropriate. */
831 zebra_interface_vrf_update_del(ifp
, vrf_id
);
834 if_update_to_new_vrf(ifp
, vrf_id
);
836 /* Send out notification on interface VRF change. */
837 /* This is to issue an ADD, if needed. */
838 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
841 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
843 mac
[0] = address
->s6_addr
[8] ^ 0x02;
844 mac
[1] = address
->s6_addr
[9];
845 mac
[2] = address
->s6_addr
[10];
846 mac
[3] = address
->s6_addr
[13];
847 mac
[4] = address
->s6_addr
[14];
848 mac
[5] = address
->s6_addr
[15];
851 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
853 struct in6_addr
*address
,
856 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
857 struct zebra_if
*zif
= ifp
->info
;
858 char buf
[16] = "169.254.0.1";
859 struct in_addr ipv4_ll
;
862 inet_pton(AF_INET
, buf
, &ipv4_ll
);
864 ns_id
= zvrf
->zns
->ns_id
;
867 * Remove and re-add any existing neighbor entry for this address,
868 * since Netlink doesn't currently offer update message types.
870 kernel_neigh_update(0, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
, mac
, 6,
871 ns_id
, AF_INET
, true);
873 /* Add new neighbor entry.
875 * We force installation even if current neighbor entry is the same.
876 * Since this function is used to refresh our MAC entries after an
877 * interface flap, if we don't force in our custom entries with their
878 * state set to PERMANENT or REACHABLE then the kernel will attempt to
879 * resolve our leftover entries, fail, mark them unreachable and then
880 * they'll be useless to us.
883 kernel_neigh_update(add
, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
,
884 mac
, 6, ns_id
, AF_INET
, true);
886 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
889 * We need to note whether or not we originated a v6
890 * neighbor entry for this interface. So that when
891 * someone unwisely accidentally deletes this entry
892 * we can shove it back in.
894 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
895 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
897 zvrf
->neigh_updates
++;
900 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
901 struct in6_addr
*address
, int add
)
906 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
907 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
910 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface
*ifp
)
912 if (listhead(ifp
->nbr_connected
)) {
913 struct nbr_connected
*nbr_connected
;
914 struct listnode
*node
;
916 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
918 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
919 ifp
, &nbr_connected
->address
->u
.prefix6
, 1);
923 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
925 if (listhead(ifp
->nbr_connected
)) {
926 struct nbr_connected
*nbr_connected
;
927 struct listnode
*node
;
929 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
931 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
932 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
936 static void if_down_del_nbr_connected(struct interface
*ifp
)
938 struct nbr_connected
*nbr_connected
;
939 struct listnode
*node
, *nnode
;
941 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
943 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
944 nbr_connected_free(nbr_connected
);
948 void if_nhg_dependents_add(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
951 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
953 nhg_connected_tree_add_nhe(&zif
->nhg_dependents
, nhe
);
957 void if_nhg_dependents_del(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
960 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
962 nhg_connected_tree_del_nhe(&zif
->nhg_dependents
, nhe
);
966 unsigned int if_nhg_dependents_count(const struct interface
*ifp
)
969 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
971 return nhg_connected_tree_count(&zif
->nhg_dependents
);
978 bool if_nhg_dependents_is_empty(const struct interface
*ifp
)
981 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
983 return nhg_connected_tree_is_empty(&zif
->nhg_dependents
);
989 /* Interface is up. */
990 void if_up(struct interface
*ifp
, bool install_connected
)
992 struct zebra_if
*zif
;
993 struct interface
*link_if
;
994 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
998 frr_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
1000 /* Notify the protocol daemons. */
1001 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
1002 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
1003 "%s: interface %s hasn't passed ptm check",
1004 __func__
, ifp
->name
);
1007 zebra_interface_up_update(ifp
);
1009 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
1013 /* Install connected routes to the kernel. */
1014 if (install_connected
)
1015 if_install_connected(ifp
);
1017 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1018 * are checked to see if (remote) neighbor entries need to be installed
1019 * on them for ARP suppression.
1021 if (IS_ZEBRA_IF_VXLAN(ifp
))
1022 zebra_vxlan_if_up(ifp
);
1023 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1025 zebra_vxlan_svi_up(ifp
, link_if
);
1026 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1027 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1030 zebra_vxlan_svi_up(ifp
, link_if
);
1031 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1032 zebra_vxlan_macvlan_up(ifp
);
1035 if (zif
->es_info
.es
)
1036 zebra_evpn_es_if_oper_state_change(zif
, true /*up*/);
1038 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1039 zebra_evpn_mh_uplink_oper_update(zif
);
1041 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 0,
1042 &zif
->speed_update
);
1043 thread_ignore_late_timer(zif
->speed_update
);
1046 /* Interface goes down. We have to manage different behavior of based
1048 void if_down(struct interface
*ifp
)
1050 struct zebra_if
*zif
;
1051 struct interface
*link_if
;
1052 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
1056 frr_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
1058 if_down_nhg_dependents(ifp
);
1060 /* Handle interface down for specific types for EVPN. Non-VxLAN
1062 * are checked to see if (remote) neighbor entries need to be purged
1063 * for ARP suppression.
1065 if (IS_ZEBRA_IF_VXLAN(ifp
))
1066 zebra_vxlan_if_down(ifp
);
1067 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1069 zebra_vxlan_svi_down(ifp
, link_if
);
1070 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1071 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1074 zebra_vxlan_svi_down(ifp
, link_if
);
1075 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1076 zebra_vxlan_macvlan_down(ifp
);
1079 if (zif
->es_info
.es
)
1080 zebra_evpn_es_if_oper_state_change(zif
, false /*up*/);
1082 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1083 zebra_evpn_mh_uplink_oper_update(zif
);
1085 /* Notify to the protocol daemons. */
1086 zebra_interface_down_update(ifp
);
1088 /* Uninstall connected routes from the kernel. */
1089 if_uninstall_connected(ifp
);
1091 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
1093 /* Delete all neighbor addresses learnt through IPv6 RA */
1094 if_down_del_nbr_connected(ifp
);
1097 void if_refresh(struct interface
*ifp
)
1104 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1107 struct zebra_if
*zif
;
1109 if (IS_ZEBRA_IF_VETH(ifp
))
1111 zif
= (struct zebra_if
*)ifp
->info
;
1112 zif
->link_ifindex
= link_ifindex
;
1113 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1118 * during initial link dump kernel does not order lower devices before
1119 * upper devices so we need to fixup link dependencies at the end of dump
1121 void zebra_if_update_all_links(struct zebra_ns
*zns
)
1123 struct route_node
*rn
;
1124 struct interface
*ifp
;
1125 struct zebra_if
*zif
;
1127 if (IS_ZEBRA_DEBUG_KERNEL
)
1128 zlog_info("fixup link dependencies");
1130 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1131 ifp
= (struct interface
*)rn
->info
;
1135 /* update bond-member to bond linkages */
1136 if ((IS_ZEBRA_IF_BOND_SLAVE(ifp
))
1137 && (zif
->bondslave_info
.bond_ifindex
!= IFINDEX_INTERNAL
)
1138 && !zif
->bondslave_info
.bond_if
) {
1139 if (IS_ZEBRA_DEBUG_EVPN_MH_ES
|| IS_ZEBRA_DEBUG_KERNEL
)
1140 zlog_debug("bond mbr %s map to bond %d",
1142 zif
->bondslave_info
.bond_ifindex
);
1143 zebra_l2_map_slave_to_bond(zif
, ifp
->vrf
->vrf_id
);
1146 /* update SVI linkages */
1147 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1148 zif
->link
= if_lookup_by_index_per_ns(
1149 zns
, zif
->link_ifindex
);
1150 if (IS_ZEBRA_DEBUG_KERNEL
)
1151 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1152 ifp
->name
, ifp
->ifindex
,
1153 zif
->link
?zif
->link
->name
:"unk",
1157 /* Update VLAN<=>SVI map */
1158 if (IS_ZEBRA_IF_VLAN(ifp
))
1159 zebra_evpn_acc_bd_svi_set(zif
, NULL
,
1160 !!if_is_operative(ifp
));
1164 static bool if_ignore_set_protodown(const struct interface
*ifp
, bool new_down
,
1165 uint32_t new_protodown_rc
)
1167 struct zebra_if
*zif
;
1168 bool old_down
, old_set_down
, old_unset_down
;
1172 /* Current state as we know it */
1173 old_down
= !!(ZEBRA_IF_IS_PROTODOWN(zif
));
1174 old_set_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1175 old_unset_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1177 if (new_protodown_rc
== zif
->protodown_rc
) {
1178 /* Early return if already down & reason bitfield matches */
1179 if (new_down
== old_down
) {
1180 if (IS_ZEBRA_DEBUG_KERNEL
)
1182 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already set (reason bitfield: old 0x%x new 0x%x)",
1183 new_down
? "on" : "off", ifp
->name
,
1184 ifp
->ifindex
, new_down
? "on" : "off",
1185 zif
->protodown_rc
, new_protodown_rc
);
1190 /* Early return if already set queued & reason bitfield matches
1192 if (new_down
&& old_set_down
) {
1193 if (IS_ZEBRA_DEBUG_KERNEL
)
1195 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already queued to dplane (reason bitfield: old 0x%x new 0x%x)",
1196 new_down
? "on" : "off", ifp
->name
,
1197 ifp
->ifindex
, new_down
? "on" : "off",
1198 zif
->protodown_rc
, new_protodown_rc
);
1203 /* Early return if already unset queued & reason bitfield
1205 if (!new_down
&& old_unset_down
) {
1206 if (IS_ZEBRA_DEBUG_KERNEL
)
1208 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already queued to dplane (reason bitfield: old 0x%x new 0x%x)",
1209 new_down
? "on" : "off", ifp
->name
,
1210 ifp
->ifindex
, new_down
? "on" : "off",
1211 zif
->protodown_rc
, new_protodown_rc
);
1220 int zebra_if_update_protodown_rc(struct interface
*ifp
, bool new_down
,
1221 uint32_t new_protodown_rc
)
1223 struct zebra_if
*zif
;
1227 /* Check if we already have this state or it's queued */
1228 if (if_ignore_set_protodown(ifp
, new_down
, new_protodown_rc
))
1232 "Setting protodown %s - interface %s (%u): reason bitfield change from 0x%x --> 0x%x",
1233 new_down
? "on" : "off", ifp
->name
, ifp
->ifindex
,
1234 zif
->protodown_rc
, new_protodown_rc
);
1236 zif
->protodown_rc
= new_protodown_rc
;
1239 SET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1241 SET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1244 dplane_intf_update(ifp
);
1246 zlog_warn("Protodown is not supported on this platform");
1251 int zebra_if_set_protodown(struct interface
*ifp
, bool new_down
,
1252 enum protodown_reasons new_reason
)
1254 struct zebra_if
*zif
;
1255 uint32_t new_protodown_rc
;
1260 new_protodown_rc
= zif
->protodown_rc
| new_reason
;
1262 new_protodown_rc
= zif
->protodown_rc
& ~new_reason
;
1264 return zebra_if_update_protodown_rc(ifp
, new_down
, new_protodown_rc
);
1268 * Handle an interface events based on info in a dplane context object.
1269 * This runs in the main pthread, using the info in the context object to
1270 * modify an interface.
1272 static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx
*ctx
,
1273 struct interface
*ifp
)
1276 const char *label
= NULL
;
1277 uint32_t metric
= METRIC_MAX
;
1278 const struct prefix
*addr
, *dest
= NULL
;
1279 enum dplane_op_e op
;
1281 op
= dplane_ctx_get_op(ctx
);
1282 addr
= dplane_ctx_get_intf_addr(ctx
);
1284 if (IS_ZEBRA_DEBUG_KERNEL
)
1285 zlog_debug("%s: %s: ifindex %s(%u), addr %pFX", __func__
,
1286 dplane_op2str(dplane_ctx_get_op(ctx
)), ifp
->name
,
1287 ifp
->ifindex
, addr
);
1289 /* Is there a peer or broadcast address? */
1290 dest
= dplane_ctx_get_intf_dest(ctx
);
1291 if (dest
->prefixlen
== 0)
1294 if (dplane_ctx_intf_is_connected(ctx
))
1295 SET_FLAG(flags
, ZEBRA_IFA_PEER
);
1298 if (dplane_ctx_intf_is_secondary(ctx
))
1299 SET_FLAG(flags
, ZEBRA_IFA_SECONDARY
);
1302 if (dplane_ctx_intf_has_label(ctx
))
1303 label
= dplane_ctx_get_intf_label(ctx
);
1305 if (label
&& strcmp(ifp
->name
, label
) == 0)
1308 metric
= dplane_ctx_get_intf_metric(ctx
);
1310 /* Register interface address to the interface. */
1311 if (addr
->family
== AF_INET
) {
1312 if (op
== DPLANE_OP_INTF_ADDR_ADD
)
1314 ifp
, flags
, &addr
->u
.prefix4
, addr
->prefixlen
,
1315 dest
? &dest
->u
.prefix4
: NULL
, label
, metric
);
1316 else if (CHECK_FLAG(flags
, ZEBRA_IFA_PEER
)) {
1317 /* Delete with a peer address */
1318 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1322 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1323 addr
->prefixlen
, NULL
);
1326 if (addr
->family
== AF_INET6
) {
1327 if (op
== DPLANE_OP_INTF_ADDR_ADD
) {
1328 connected_add_ipv6(ifp
, flags
, &addr
->u
.prefix6
,
1329 dest
? &dest
->u
.prefix6
: NULL
,
1330 addr
->prefixlen
, label
, metric
);
1332 connected_delete_ipv6(ifp
, &addr
->u
.prefix6
, NULL
,
1337 * Linux kernel does not send route delete on interface down/addr del
1338 * so we have to re-process routes it owns (i.e. kernel routes)
1340 if (op
!= DPLANE_OP_INTF_ADDR_ADD
)
1341 rib_update(RIB_UPDATE_KERNEL
);
1344 static void zebra_if_update_ctx(struct zebra_dplane_ctx
*ctx
,
1345 struct interface
*ifp
)
1347 enum zebra_dplane_result dp_res
;
1348 struct zebra_if
*zif
;
1352 dp_res
= dplane_ctx_get_status(ctx
);
1353 pd_reason_val
= dplane_ctx_get_intf_pd_reason_val(ctx
);
1354 down
= dplane_ctx_intf_is_protodown(ctx
);
1356 if (IS_ZEBRA_DEBUG_KERNEL
)
1357 zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason %d",
1358 __func__
, dplane_op2str(dplane_ctx_get_op(ctx
)),
1359 ifp
->name
, ifp
->ifindex
, down
? "on" : "off",
1364 if (IS_ZEBRA_DEBUG_KERNEL
)
1365 zlog_debug("%s: if %s(%u) zebra info pointer is NULL",
1366 __func__
, ifp
->name
, ifp
->ifindex
);
1370 if (dp_res
!= ZEBRA_DPLANE_REQUEST_SUCCESS
) {
1371 if (IS_ZEBRA_DEBUG_KERNEL
)
1372 zlog_debug("%s: if %s(%u) dplane update failed",
1373 __func__
, ifp
->name
, ifp
->ifindex
);
1377 /* Update our info */
1378 COND_FLAG(zif
->flags
, ZIF_FLAG_PROTODOWN
, down
);
1381 /* Clear our dplane flags */
1382 UNSET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1383 UNSET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1387 * Handle netconf change from a dplane context object; runs in the main
1388 * pthread so it can update zebra data structs.
1390 static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx
*ctx
,
1391 struct interface
*ifp
,
1394 struct zebra_if
*zif
= NULL
;
1396 enum dplane_netconf_status_e mpls
, mcast_on
, linkdown
;
1397 bool *mcast_set
, *linkdown_set
;
1399 afi
= dplane_ctx_get_afi(ctx
);
1400 mpls
= dplane_ctx_get_netconf_mpls(ctx
);
1401 linkdown
= dplane_ctx_get_netconf_linkdown(ctx
);
1402 mcast_on
= dplane_ctx_get_netconf_mcast(ctx
);
1404 if (ifindex
== DPLANE_NETCONF_IFINDEX_ALL
) {
1405 if (afi
== AFI_IP
) {
1406 mcast_set
= &zrouter
.all_mc_forwardingv4
;
1407 linkdown_set
= &zrouter
.all_linkdownv4
;
1409 mcast_set
= &zrouter
.all_mc_forwardingv6
;
1410 linkdown_set
= &zrouter
.all_linkdownv6
;
1412 } else if (ifindex
== DPLANE_NETCONF_IFINDEX_DEFAULT
) {
1413 if (afi
== AFI_IP
) {
1414 mcast_set
= &zrouter
.default_mc_forwardingv4
;
1415 linkdown_set
= &zrouter
.default_linkdownv4
;
1417 mcast_set
= &zrouter
.default_mc_forwardingv6
;
1418 linkdown_set
= &zrouter
.default_linkdownv6
;
1421 zif
= ifp
? ifp
->info
: NULL
;
1423 if (IS_ZEBRA_DEBUG_KERNEL
)
1425 "%s: if %s(%u) zebra info pointer is NULL",
1426 __func__
, ifp
? ifp
->name
: "(null)",
1427 ifp
? ifp
->ifindex
: ifindex
);
1430 if (afi
== AFI_IP
) {
1431 mcast_set
= &zif
->v4mcast_on
;
1432 linkdown_set
= &zif
->linkdown
;
1434 mcast_set
= &zif
->v6mcast_on
;
1435 linkdown_set
= &zif
->linkdownv6
;
1439 * mpls netconf data is neither v4 or v6 it's AF_MPLS!
1441 if (mpls
== DPLANE_NETCONF_STATUS_ENABLED
) {
1443 zebra_mpls_turned_on();
1444 } else if (mpls
== DPLANE_NETCONF_STATUS_DISABLED
)
1448 if (linkdown
== DPLANE_NETCONF_STATUS_ENABLED
)
1449 *linkdown_set
= true;
1450 else if (linkdown
== DPLANE_NETCONF_STATUS_DISABLED
)
1451 *linkdown_set
= false;
1453 if (mcast_on
== DPLANE_NETCONF_STATUS_ENABLED
)
1455 else if (mcast_on
== DPLANE_NETCONF_STATUS_DISABLED
)
1458 if (IS_ZEBRA_DEBUG_KERNEL
)
1460 "%s: afi: %d if %s, ifindex %d, mpls %s mc_forwarding: %s linkdown %s",
1461 __func__
, afi
, ifp
? ifp
->name
: "Global",
1462 ifp
? ifp
->ifindex
: ifindex
,
1463 (zif
? (zif
->mpls
? "ON" : "OFF") : "OFF"),
1464 (*mcast_set
? "ON" : "OFF"),
1465 (*linkdown_set
? "ON" : "OFF"));
1468 void zebra_if_dplane_result(struct zebra_dplane_ctx
*ctx
)
1470 struct zebra_ns
*zns
;
1471 struct interface
*ifp
;
1473 enum dplane_op_e op
;
1474 enum zebra_dplane_result dp_res
;
1477 ns_id
= dplane_ctx_get_ns_id(ctx
);
1478 dp_res
= dplane_ctx_get_status(ctx
);
1479 op
= dplane_ctx_get_op(ctx
);
1480 ifindex
= dplane_ctx_get_ifindex(ctx
);
1482 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
|| IS_ZEBRA_DEBUG_KERNEL
)
1483 zlog_debug("Intf dplane ctx %p, op %s, ifindex (%u), result %s",
1484 ctx
, dplane_op2str(op
), ifindex
,
1485 dplane_res2str(dp_res
));
1487 zns
= zebra_ns_lookup(ns_id
);
1489 /* No ns - deleted maybe? */
1490 if (IS_ZEBRA_DEBUG_KERNEL
)
1491 zlog_debug("%s: can't find zns id %u", __func__
, ns_id
);
1496 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
1498 if (op
!= DPLANE_OP_INTF_NETCONFIG
||
1499 (ifindex
!= -1 && ifindex
!= -2)) {
1500 if (IS_ZEBRA_DEBUG_KERNEL
)
1502 "%s: can't find ifp at nsid %u index %d",
1503 __func__
, ns_id
, ifindex
);
1510 case DPLANE_OP_INTF_ADDR_ADD
:
1511 case DPLANE_OP_INTF_ADDR_DEL
:
1512 zebra_if_addr_update_ctx(ctx
, ifp
);
1515 case DPLANE_OP_INTF_INSTALL
:
1516 case DPLANE_OP_INTF_UPDATE
:
1517 case DPLANE_OP_INTF_DELETE
:
1518 zebra_if_update_ctx(ctx
, ifp
);
1521 case DPLANE_OP_INTF_NETCONFIG
:
1522 zebra_if_netconf_update_ctx(ctx
, ifp
, ifindex
);
1525 case DPLANE_OP_ROUTE_INSTALL
:
1526 case DPLANE_OP_ROUTE_UPDATE
:
1527 case DPLANE_OP_ROUTE_DELETE
:
1528 case DPLANE_OP_NH_DELETE
:
1529 case DPLANE_OP_NH_INSTALL
:
1530 case DPLANE_OP_NH_UPDATE
:
1531 case DPLANE_OP_ROUTE_NOTIFY
:
1532 case DPLANE_OP_LSP_INSTALL
:
1533 case DPLANE_OP_LSP_UPDATE
:
1534 case DPLANE_OP_LSP_DELETE
:
1535 case DPLANE_OP_LSP_NOTIFY
:
1536 case DPLANE_OP_PW_INSTALL
:
1537 case DPLANE_OP_PW_UNINSTALL
:
1538 case DPLANE_OP_SYS_ROUTE_ADD
:
1539 case DPLANE_OP_SYS_ROUTE_DELETE
:
1540 case DPLANE_OP_ADDR_INSTALL
:
1541 case DPLANE_OP_ADDR_UNINSTALL
:
1542 case DPLANE_OP_MAC_INSTALL
:
1543 case DPLANE_OP_MAC_DELETE
:
1544 case DPLANE_OP_NEIGH_INSTALL
:
1545 case DPLANE_OP_NEIGH_UPDATE
:
1546 case DPLANE_OP_NEIGH_DELETE
:
1547 case DPLANE_OP_NEIGH_IP_INSTALL
:
1548 case DPLANE_OP_NEIGH_IP_DELETE
:
1549 case DPLANE_OP_VTEP_ADD
:
1550 case DPLANE_OP_VTEP_DELETE
:
1551 case DPLANE_OP_RULE_ADD
:
1552 case DPLANE_OP_RULE_DELETE
:
1553 case DPLANE_OP_RULE_UPDATE
:
1554 case DPLANE_OP_NEIGH_DISCOVER
:
1555 case DPLANE_OP_BR_PORT_UPDATE
:
1556 case DPLANE_OP_NONE
:
1557 case DPLANE_OP_IPTABLE_ADD
:
1558 case DPLANE_OP_IPTABLE_DELETE
:
1559 case DPLANE_OP_IPSET_ADD
:
1560 case DPLANE_OP_IPSET_DELETE
:
1561 case DPLANE_OP_IPSET_ENTRY_ADD
:
1562 case DPLANE_OP_IPSET_ENTRY_DELETE
:
1563 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
1564 case DPLANE_OP_GRE_SET
:
1565 case DPLANE_OP_TC_QDISC_INSTALL
:
1566 case DPLANE_OP_TC_QDISC_UNINSTALL
:
1567 case DPLANE_OP_TC_CLASS_ADD
:
1568 case DPLANE_OP_TC_CLASS_DELETE
:
1569 case DPLANE_OP_TC_CLASS_UPDATE
:
1570 case DPLANE_OP_TC_FILTER_ADD
:
1571 case DPLANE_OP_TC_FILTER_DELETE
:
1572 case DPLANE_OP_TC_FILTER_UPDATE
:
1573 break; /* should never hit here */
1577 /* Dump if address information to vty. */
1578 static void connected_dump_vty(struct vty
*vty
, json_object
*json
,
1579 struct connected
*connected
)
1582 json_object
*json_addr
= NULL
;
1584 /* Print interface address. */
1585 p
= connected
->address
;
1588 json_addr
= json_object_new_object();
1589 json_object_array_add(json
, json_addr
);
1590 json_object_string_addf(json_addr
, "address", "%pFX", p
);
1592 vty_out(vty
, " %s %pFX", prefix_family_str(p
), p
);
1595 /* If there is destination address, print it. */
1596 if (CONNECTED_PEER(connected
) && connected
->destination
) {
1598 json_object_string_addf(json_addr
, "peer", "%pFX",
1599 connected
->destination
);
1601 vty_out(vty
, " peer %pFX", connected
->destination
);
1606 json_object_boolean_add(
1607 json_addr
, "secondary",
1608 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
));
1609 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1610 vty_out(vty
, " secondary");
1613 json_object_boolean_add(
1614 json_addr
, "unnumbered",
1615 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
));
1616 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1617 vty_out(vty
, " unnumbered");
1619 if (connected
->label
) {
1621 json_object_string_add(json_addr
, "label",
1624 vty_out(vty
, " %s", connected
->label
);
1631 /* Dump interface neighbor address information to vty. */
1632 static void nbr_connected_dump_vty(struct vty
*vty
, json_object
*json
,
1633 struct nbr_connected
*connected
)
1636 char buf
[PREFIX2STR_BUFFER
];
1638 /* Print interface address. */
1639 p
= connected
->address
;
1641 json_array_string_add(json
, prefix2str(p
, buf
, sizeof(buf
)));
1643 vty_out(vty
, " %s %pFX\n", prefix_family_str(p
), p
);
1647 zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type
)
1649 switch (zif_slave_type
) {
1650 case ZEBRA_IF_SLAVE_BRIDGE
:
1652 case ZEBRA_IF_SLAVE_VRF
:
1654 case ZEBRA_IF_SLAVE_BOND
:
1656 case ZEBRA_IF_SLAVE_OTHER
:
1658 case ZEBRA_IF_SLAVE_NONE
:
1664 static const char *zebra_ziftype_2str(enum zebra_iftype zif_type
)
1667 case ZEBRA_IF_OTHER
:
1670 case ZEBRA_IF_BRIDGE
:
1676 case ZEBRA_IF_VXLAN
:
1688 case ZEBRA_IF_BOND_SLAVE
:
1689 return "bond_slave";
1691 case ZEBRA_IF_MACVLAN
:
1702 /* Interface's brief information print out to vty interface. */
1703 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1705 struct connected
*connected
;
1706 struct listnode
*node
;
1707 struct route_node
*rn
;
1708 struct zebra_if
*zebra_if
;
1710 struct interface
*ifp
;
1711 bool print_header
= true;
1713 FOR_ALL_INTERFACES (vrf
, ifp
) {
1714 bool first_pfx_printed
= false;
1717 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1718 "Status", "VRF", "Addresses");
1719 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1720 "------", "---", "---------");
1721 print_header
= false; /* We have at least 1 iface */
1723 zebra_if
= ifp
->info
;
1725 vty_out(vty
, "%-16s", ifp
->name
);
1728 vty_out(vty
, "%-8s", "up");
1730 vty_out(vty
, "%-8s", "down");
1732 vty_out(vty
, "%-16s", vrf
->name
);
1734 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1735 rn
= route_next(rn
)) {
1738 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1740 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1742 if (!CHECK_FLAG(connected
->flags
,
1743 ZEBRA_IFA_SECONDARY
)) {
1744 p
= connected
->address
;
1745 if (first_pfx_printed
) {
1746 /* padding to prepare row only
1748 vty_out(vty
, "%-40s", "");
1751 vty_out(vty
, "%pFX\n", p
);
1755 vty_out(vty
, "%pFX\n", p
);
1757 first_pfx_printed
= true;
1763 uint32_t v6_list_size
= 0;
1764 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1765 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1766 && (connected
->address
->family
== AF_INET6
))
1769 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1770 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1771 && !CHECK_FLAG(connected
->flags
,
1772 ZEBRA_IFA_SECONDARY
)
1773 && (connected
->address
->family
== AF_INET6
)) {
1774 p
= connected
->address
;
1775 /* Don't print link local pfx */
1776 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1777 if (first_pfx_printed
) {
1778 /* padding to prepare row only
1780 vty_out(vty
, "%-40s", "");
1781 if (v6_list_size
> 1)
1783 vty_out(vty
, "%pFX\n", p
);
1785 if (v6_list_size
> 1)
1787 vty_out(vty
, "%pFX\n", p
);
1789 first_pfx_printed
= true;
1794 if (!first_pfx_printed
)
1800 static void ifs_dump_brief_vty_json(json_object
*json
, struct vrf
*vrf
)
1802 struct connected
*connected
;
1803 struct listnode
*node
;
1804 struct interface
*ifp
;
1806 FOR_ALL_INTERFACES (vrf
, ifp
) {
1807 json_object
*json_if
;
1808 json_object
*json_addrs
;
1810 json_if
= json_object_new_object();
1811 json_object_object_add(json
, ifp
->name
, json_if
);
1813 json_object_string_add(json_if
, "status",
1814 if_is_up(ifp
) ? "up" : "down");
1815 json_object_string_add(json_if
, "vrfName", vrf
->name
);
1817 json_addrs
= json_object_new_array();
1818 json_object_object_add(json_if
, "addresses", json_addrs
);
1819 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1820 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1821 && !CHECK_FLAG(connected
->flags
,
1822 ZEBRA_IFA_SECONDARY
)
1823 && !(connected
->address
->family
== AF_INET6
1824 && IN6_IS_ADDR_LINKLOCAL(
1825 &connected
->address
->u
.prefix6
))) {
1826 char buf
[PREFIX2STR_BUFFER
];
1828 json_array_string_add(
1830 prefix2str(connected
->address
, buf
,
1837 const char *zebra_protodown_rc_str(uint32_t protodown_rc
, char *pd_buf
,
1838 uint32_t pd_buf_len
)
1843 strlcat(pd_buf
, "(", pd_buf_len
);
1845 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EXTERNAL
))
1846 strlcat(pd_buf
, "external,", pd_buf_len
);
1848 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY
))
1849 strlcat(pd_buf
, "startup-delay,", pd_buf_len
);
1851 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
))
1852 strlcat(pd_buf
, "uplinks-down,", pd_buf_len
);
1854 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_VRRP
))
1855 strlcat(pd_buf
, "vrrp,", pd_buf_len
);
1857 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_SHARP
))
1858 strlcat(pd_buf
, "sharp,", pd_buf_len
);
1860 len
= strnlen(pd_buf
, pd_buf_len
);
1862 /* Remove trailing comma */
1863 if (pd_buf
[len
- 1] == ',')
1864 pd_buf
[len
- 1] = '\0';
1866 strlcat(pd_buf
, ")", pd_buf_len
);
1871 static inline bool if_is_protodown_applicable(struct interface
*ifp
)
1873 if (IS_ZEBRA_IF_BOND(ifp
))
1879 static void zebra_vxlan_if_vni_dump_vty(struct vty
*vty
,
1880 struct zebra_vxlan_vni
*vni
)
1882 char str
[INET6_ADDRSTRLEN
];
1884 vty_out(vty
, " VxLAN Id %u", vni
->vni
);
1885 if (vni
->access_vlan
)
1886 vty_out(vty
, " Access VLAN Id %u\n", vni
->access_vlan
);
1888 if (vni
->mcast_grp
.s_addr
!= INADDR_ANY
)
1889 vty_out(vty
, " Mcast Group %s",
1890 inet_ntop(AF_INET
, &vni
->mcast_grp
, str
, sizeof(str
)));
1893 static void zebra_vxlan_if_vni_hash_dump_vty(struct hash_bucket
*bucket
,
1897 struct zebra_vxlan_vni
*vni
;
1899 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
1900 vty
= (struct vty
*)ctxt
;
1902 zebra_vxlan_if_vni_dump_vty(vty
, vni
);
1905 static void zebra_vxlan_if_dump_vty(struct vty
*vty
, struct zebra_if
*zebra_if
)
1907 struct zebra_l2info_vxlan
*vxlan_info
;
1908 struct zebra_vxlan_vni_info
*vni_info
;
1910 vxlan_info
= &zebra_if
->l2info
.vxl
;
1911 vni_info
= &vxlan_info
->vni_info
;
1913 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
1914 vty_out(vty
, " VTEP IP: %pI4", &vxlan_info
->vtep_ip
);
1916 if (vxlan_info
->ifindex_link
&& (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
1917 struct interface
*ifp
;
1919 ifp
= if_lookup_by_index_per_ns(
1920 zebra_ns_lookup(vxlan_info
->link_nsid
),
1921 vxlan_info
->ifindex_link
);
1922 vty_out(vty
, " Link Interface %s",
1923 ifp
== NULL
? "Unknown" : ifp
->name
);
1926 if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if
)) {
1927 zebra_vxlan_if_vni_dump_vty(vty
, &vni_info
->vni
);
1929 hash_iterate(vni_info
->vni_table
,
1930 zebra_vxlan_if_vni_hash_dump_vty
, vty
);
1936 /* Interface's information print out to vty interface. */
1937 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1939 struct connected
*connected
;
1940 struct nbr_connected
*nbr_connected
;
1941 struct listnode
*node
;
1942 struct route_node
*rn
;
1943 struct zebra_if
*zebra_if
;
1944 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
1946 zebra_if
= ifp
->info
;
1948 vty_out(vty
, "Interface %s is ", ifp
->name
);
1949 if (if_is_up(ifp
)) {
1950 vty_out(vty
, "up, line protocol ");
1952 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1953 if (if_is_running(ifp
))
1954 vty_out(vty
, "is up\n");
1956 vty_out(vty
, "is down\n");
1958 vty_out(vty
, "detection is disabled\n");
1961 vty_out(vty
, "down\n");
1964 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1965 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1966 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1967 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1969 zebra_ptm_show_status(vty
, NULL
, ifp
);
1971 vty_out(vty
, " vrf: %s\n", ifp
->vrf
->name
);
1974 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1976 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1978 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1979 vty_out(vty
, " pseudo interface\n");
1981 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1982 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
1986 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
1987 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
1988 if (ifp
->mtu6
!= ifp
->mtu
)
1989 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
1990 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
1993 vty_out(vty
, " MPLS enabled\n");
1995 if (zebra_if
->linkdown
)
1996 vty_out(vty
, " Ignore all v4 routes with linkdown\n");
1997 if (zebra_if
->linkdownv6
)
1998 vty_out(vty
, " Ignore all v6 routes with linkdown\n");
2000 if (zebra_if
->v4mcast_on
)
2001 vty_out(vty
, " v4 Multicast forwarding is on\n");
2002 if (zebra_if
->v6mcast_on
)
2003 vty_out(vty
, " v6 Multicast forwarding is on\n");
2005 /* Hardware address. */
2006 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
2007 if (ifp
->hw_addr_len
!= 0) {
2010 vty_out(vty
, " HWaddr: ");
2011 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
2012 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
2017 /* Bandwidth in Mbps */
2018 if (ifp
->bandwidth
!= 0) {
2019 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
2023 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
2027 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
2029 connected_dump_vty(vty
, NULL
, connected
);
2032 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
2033 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2034 && (connected
->address
->family
== AF_INET6
))
2035 connected_dump_vty(vty
, NULL
, connected
);
2038 vty_out(vty
, " Interface Type %s\n",
2039 zebra_ziftype_2str(zebra_if
->zif_type
));
2040 vty_out(vty
, " Interface Slave Type %s\n",
2041 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
2043 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
2044 vty_out(vty
, " Bridge VLAN-aware: %s\n",
2045 IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zebra_if
) ? "yes" : "no");
2046 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2047 struct zebra_l2info_vlan
*vlan_info
;
2049 vlan_info
= &zebra_if
->l2info
.vl
;
2050 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
2051 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2052 zebra_vxlan_if_dump_vty(vty
, zebra_if
);
2053 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2054 struct zebra_l2info_gre
*gre_info
;
2056 gre_info
= &zebra_if
->l2info
.gre
;
2057 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2058 vty_out(vty
, " VTEP IP: %pI4", &gre_info
->vtep_ip
);
2059 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2060 vty_out(vty
, " , remote %pI4",
2061 &gre_info
->vtep_ip_remote
);
2064 if (gre_info
->ifindex_link
&&
2065 (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2066 struct interface
*ifp
;
2068 ifp
= if_lookup_by_index_per_ns(
2069 zebra_ns_lookup(gre_info
->link_nsid
),
2070 gre_info
->ifindex_link
);
2071 vty_out(vty
, " Link Interface %s\n",
2072 ifp
== NULL
? "Unknown" :
2077 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2078 struct zebra_l2info_brslave
*br_slave
;
2080 br_slave
= &zebra_if
->brslave_info
;
2081 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2082 if (br_slave
->br_if
)
2083 vty_out(vty
, " Master interface: %s\n",
2084 br_slave
->br_if
->name
);
2086 vty_out(vty
, " Master ifindex: %u\n",
2087 br_slave
->bridge_ifindex
);
2091 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2092 struct zebra_l2info_bondslave
*bond_slave
;
2094 bond_slave
= &zebra_if
->bondslave_info
;
2095 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2096 if (bond_slave
->bond_if
)
2097 vty_out(vty
, " Master interface: %s\n",
2098 bond_slave
->bond_if
->name
);
2100 vty_out(vty
, " Master ifindex: %u\n",
2101 bond_slave
->bond_ifindex
);
2105 if (zebra_if
->flags
& ZIF_FLAG_LACP_BYPASS
)
2106 vty_out(vty
, " LACP bypass: on\n");
2108 zebra_evpn_if_es_print(vty
, NULL
, zebra_if
);
2109 vty_out(vty
, " protodown: %s %s\n",
2110 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off",
2111 if_is_protodown_applicable(ifp
) ? "" : "(n/a)");
2112 if (zebra_if
->protodown_rc
)
2113 vty_out(vty
, " protodown reasons: %s\n",
2114 zebra_protodown_rc_str(zebra_if
->protodown_rc
, pd_buf
,
2117 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2119 vty_out(vty
, " Parent interface: %s\n", zebra_if
->link
->name
);
2121 vty_out(vty
, " Parent ifindex: %d\n", zebra_if
->link_ifindex
);
2124 if (HAS_LINK_PARAMS(ifp
)) {
2126 struct if_link_params
*iflp
= ifp
->link_params
;
2127 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
2128 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2129 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
2130 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2131 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
2133 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2135 " Maximum Reservable Bandwidth %g (Byte/s)\n",
2137 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2139 " Unreserved Bandwidth per Class Type in Byte/s:\n");
2140 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
2142 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
2143 i
, iflp
->unrsv_bw
[i
], i
+ 1,
2144 iflp
->unrsv_bw
[i
+ 1]);
2147 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2148 vty_out(vty
, " Administrative Group:%u\n",
2150 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2151 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
2153 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2154 vty_out(vty
, " Min: %u (micro-sec.)",
2156 vty_out(vty
, " Max: %u (micro-sec.)",
2161 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2163 " Link Delay Variation %u (micro-sec.)\n",
2165 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2166 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
2168 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2169 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
2171 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2172 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
2174 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2175 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
2177 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2178 vty_out(vty
, " Neighbor ASBR IP: %pI4 AS: %u \n",
2179 &iflp
->rmt_ip
, iflp
->rmt_as
);
2182 hook_call(zebra_if_extra_info
, vty
, ifp
);
2184 if (listhead(ifp
->nbr_connected
))
2185 vty_out(vty
, " Neighbor address(s):\n");
2186 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
2187 nbr_connected_dump_vty(vty
, NULL
, nbr_connected
);
2189 #ifdef HAVE_PROC_NET_DEV
2190 /* Statistics print out using proc file system. */
2192 " %lu input packets (%lu multicast), %lu bytes, %lu dropped\n",
2193 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
2194 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
2197 " %lu input errors, %lu length, %lu overrun, %lu CRC, %lu frame\n",
2198 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
2199 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
2200 ifp
->stats
.rx_frame_errors
);
2202 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
2203 ifp
->stats
.rx_missed_errors
);
2205 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
2206 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
2207 ifp
->stats
.tx_dropped
);
2210 " %lu output errors, %lu aborted, %lu carrier, %lu fifo, %lu heartbeat\n",
2211 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
2212 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
2213 ifp
->stats
.tx_heartbeat_errors
);
2215 vty_out(vty
, " %lu window, %lu collisions\n",
2216 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
2217 #endif /* HAVE_PROC_NET_DEV */
2219 #ifdef HAVE_NET_RT_IFLIST
2220 /* Statistics print out using sysctl (). */
2222 " input packets %llu, bytes %llu, dropped %llu, multicast packets %llu\n",
2223 (unsigned long long)ifp
->stats
.ifi_ipackets
,
2224 (unsigned long long)ifp
->stats
.ifi_ibytes
,
2225 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
2226 (unsigned long long)ifp
->stats
.ifi_imcasts
);
2228 vty_out(vty
, " input errors %llu\n",
2229 (unsigned long long)ifp
->stats
.ifi_ierrors
);
2232 " output packets %llu, bytes %llu, multicast packets %llu\n",
2233 (unsigned long long)ifp
->stats
.ifi_opackets
,
2234 (unsigned long long)ifp
->stats
.ifi_obytes
,
2235 (unsigned long long)ifp
->stats
.ifi_omcasts
);
2237 vty_out(vty
, " output errors %llu\n",
2238 (unsigned long long)ifp
->stats
.ifi_oerrors
);
2240 vty_out(vty
, " collisions %llu\n",
2241 (unsigned long long)ifp
->stats
.ifi_collisions
);
2242 #endif /* HAVE_NET_RT_IFLIST */
2245 static void zebra_vxlan_if_vni_dump_vty_json(json_object
*json_if
,
2246 struct zebra_vxlan_vni
*vni
)
2248 json_object_int_add(json_if
, "vxlanId", vni
->vni
);
2249 if (vni
->access_vlan
)
2250 json_object_int_add(json_if
, "accessVlanId", vni
->access_vlan
);
2251 if (vni
->mcast_grp
.s_addr
!= INADDR_ANY
)
2252 json_object_string_addf(json_if
, "mcastGroup", "%pI4",
2256 static void zebra_vxlan_if_vni_hash_dump_vty_json(struct hash_bucket
*bucket
,
2259 json_object
*json_if
;
2260 struct zebra_vxlan_vni
*vni
;
2262 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
2263 json_if
= (json_object
*)ctxt
;
2265 zebra_vxlan_if_vni_dump_vty_json(json_if
, vni
);
2268 static void zebra_vxlan_if_dump_vty_json(json_object
*json_if
,
2269 struct zebra_if
*zebra_if
)
2271 struct zebra_l2info_vxlan
*vxlan_info
;
2272 struct zebra_vxlan_vni_info
*vni_info
;
2274 vxlan_info
= &zebra_if
->l2info
.vxl
;
2275 vni_info
= &vxlan_info
->vni_info
;
2277 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
2278 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2279 &vxlan_info
->vtep_ip
);
2281 if (vxlan_info
->ifindex_link
&& (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
2282 struct interface
*ifp
;
2284 ifp
= if_lookup_by_index_per_ns(
2285 zebra_ns_lookup(vxlan_info
->link_nsid
),
2286 vxlan_info
->ifindex_link
);
2287 json_object_string_add(json_if
, "linkInterface",
2288 ifp
== NULL
? "Unknown" : ifp
->name
);
2290 if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if
)) {
2291 zebra_vxlan_if_vni_dump_vty_json(json_if
, &vni_info
->vni
);
2293 hash_iterate(vni_info
->vni_table
,
2294 zebra_vxlan_if_vni_hash_dump_vty_json
, json_if
);
2298 static void if_dump_vty_json(struct vty
*vty
, struct interface
*ifp
,
2301 struct connected
*connected
;
2302 struct nbr_connected
*nbr_connected
;
2303 struct listnode
*node
;
2304 struct route_node
*rn
;
2305 struct zebra_if
*zebra_if
;
2306 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
2308 json_object
*json_if
;
2309 json_object
*json_addrs
;
2311 json_if
= json_object_new_object();
2312 json_object_object_add(json
, ifp
->name
, json_if
);
2314 if (if_is_up(ifp
)) {
2315 json_object_string_add(json_if
, "administrativeStatus", "up");
2317 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
2318 json_object_string_add(json_if
, "operationalStatus",
2319 if_is_running(ifp
) ? "up"
2321 json_object_boolean_add(json_if
, "linkDetection", true);
2323 json_object_boolean_add(json_if
, "linkDetection",
2327 json_object_string_add(json_if
, "administrativeStatus", "down");
2330 zebra_if
= ifp
->info
;
2332 json_object_int_add(json_if
, "linkUps", zebra_if
->up_count
);
2333 json_object_int_add(json_if
, "linkDowns", zebra_if
->down_count
);
2334 if (zebra_if
->up_last
[0])
2335 json_object_string_add(json_if
, "lastLinkUp",
2337 if (zebra_if
->down_last
[0])
2338 json_object_string_add(json_if
, "lastLinkDown",
2339 zebra_if
->down_last
);
2341 zebra_ptm_show_status(vty
, json
, ifp
);
2343 json_object_string_add(json_if
, "vrfName", ifp
->vrf
->name
);
2346 json_object_string_add(json_if
, "description", ifp
->desc
);
2348 json_object_string_add(json_if
, "OsDescription",
2351 json_object_boolean_add(json_if
, "mplsEnabled", zebra_if
->mpls
);
2352 json_object_boolean_add(json_if
, "linkDown", zebra_if
->linkdown
);
2353 json_object_boolean_add(json_if
, "linkDownV6", zebra_if
->linkdownv6
);
2354 json_object_boolean_add(json_if
, "mcForwardingV4",
2355 zebra_if
->v4mcast_on
);
2356 json_object_boolean_add(json_if
, "mcForwardingV6",
2357 zebra_if
->v6mcast_on
);
2359 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
2360 json_object_boolean_add(json_if
, "pseudoInterface", true);
2362 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2363 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2367 json_object_boolean_add(json_if
, "pseudoInterface", false);
2368 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2369 json_object_int_add(json_if
, "metric", ifp
->metric
);
2370 json_object_int_add(json_if
, "mtu", ifp
->mtu
);
2371 if (ifp
->mtu6
!= ifp
->mtu
)
2372 json_object_int_add(json_if
, "mtu6", ifp
->mtu6
);
2373 json_object_int_add(json_if
, "speed", ifp
->speed
);
2374 json_object_string_add(json_if
, "flags", if_flag_dump(ifp
->flags
));
2376 /* Hardware address. */
2377 json_object_string_add(json_if
, "type", if_link_type_str(ifp
->ll_type
));
2378 if (ifp
->hw_addr_len
!= 0) {
2382 for (int i
= 0; i
< ifp
->hw_addr_len
; i
++) {
2383 snprintf(buf
, sizeof(buf
), "%s%02x", i
== 0 ? "" : ":",
2385 strlcat(hwbuf
, buf
, sizeof(hwbuf
));
2387 json_object_string_add(json_if
, "hardwareAddress", hwbuf
);
2390 /* Bandwidth in Mbps */
2391 if (ifp
->bandwidth
!= 0)
2392 json_object_int_add(json_if
, "bandwidth", ifp
->bandwidth
);
2396 json_addrs
= json_object_new_array();
2397 json_object_object_add(json_if
, "ipAddresses", json_addrs
);
2399 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
2403 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
2405 connected_dump_vty(vty
, json_addrs
, connected
);
2408 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
2409 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2410 && (connected
->address
->family
== AF_INET6
))
2411 connected_dump_vty(vty
, json_addrs
, connected
);
2414 json_object_string_add(json_if
, "interfaceType",
2415 zebra_ziftype_2str(zebra_if
->zif_type
));
2416 json_object_string_add(
2417 json_if
, "interfaceSlaveType",
2418 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
2420 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
2421 struct zebra_l2info_bridge
*bridge_info
;
2423 bridge_info
= &zebra_if
->l2info
.br
;
2424 json_object_boolean_add(json_if
, "bridgeVlanAware",
2425 bridge_info
->bridge
.vlan_aware
);
2426 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2427 struct zebra_l2info_vlan
*vlan_info
;
2429 vlan_info
= &zebra_if
->l2info
.vl
;
2430 json_object_int_add(json_if
, "vlanId", vlan_info
->vid
);
2431 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2432 zebra_vxlan_if_dump_vty_json(json_if
, zebra_if
);
2434 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2435 struct zebra_l2info_gre
*gre_info
;
2437 gre_info
= &zebra_if
->l2info
.gre
;
2438 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2439 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2440 &gre_info
->vtep_ip
);
2441 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2442 json_object_string_addf(
2443 json_if
, "vtepRemoteIp", "%pI4",
2444 &gre_info
->vtep_ip_remote
);
2446 if (gre_info
->ifindex_link
2447 && (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2448 struct interface
*ifp
;
2450 ifp
= if_lookup_by_index_per_ns(
2451 zebra_ns_lookup(gre_info
->link_nsid
),
2452 gre_info
->ifindex_link
);
2453 json_object_string_add(json_if
, "linkInterface",
2454 ifp
== NULL
? "Unknown"
2459 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2460 struct zebra_l2info_brslave
*br_slave
;
2462 br_slave
= &zebra_if
->brslave_info
;
2463 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2464 if (br_slave
->br_if
)
2465 json_object_string_add(json_if
,
2467 br_slave
->br_if
->name
);
2469 json_object_int_add(json_if
, "masterIfindex",
2470 br_slave
->bridge_ifindex
);
2474 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2475 struct zebra_l2info_bondslave
*bond_slave
;
2477 bond_slave
= &zebra_if
->bondslave_info
;
2478 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2479 if (bond_slave
->bond_if
)
2480 json_object_string_add(
2481 json_if
, "masterInterface",
2482 bond_slave
->bond_if
->name
);
2484 json_object_int_add(json_if
, "masterIfindex",
2485 bond_slave
->bond_ifindex
);
2489 json_object_boolean_add(
2490 json_if
, "lacpBypass",
2491 CHECK_FLAG(zebra_if
->flags
, ZIF_FLAG_LACP_BYPASS
));
2493 zebra_evpn_if_es_print(vty
, json_if
, zebra_if
);
2495 if (if_is_protodown_applicable(ifp
)) {
2496 json_object_string_add(
2497 json_if
, "protodown",
2498 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off");
2499 if (zebra_if
->protodown_rc
)
2500 json_object_string_add(
2501 json_if
, "protodownReason",
2502 zebra_protodown_rc_str(zebra_if
->protodown_rc
,
2503 pd_buf
, sizeof(pd_buf
)));
2506 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2508 json_object_string_add(json_if
, "parentInterface",
2509 zebra_if
->link
->name
);
2511 json_object_int_add(json_if
, "parentIfindex",
2512 zebra_if
->link_ifindex
);
2515 if (HAS_LINK_PARAMS(ifp
)) {
2516 struct if_link_params
*iflp
= ifp
->link_params
;
2517 json_object
*json_te
;
2519 json_te
= json_object_new_object();
2520 json_object_object_add(
2521 json_if
, "trafficEngineeringLinkParameters", json_te
);
2523 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2524 json_object_int_add(json_te
, "teMetric",
2526 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2527 json_object_double_add(json_te
, "maximumBandwidth",
2529 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2530 json_object_double_add(json_te
,
2531 "maximumReservableBandwidth",
2533 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2534 json_object
*json_bws
;
2536 json_bws
= json_object_new_object();
2537 json_object_object_add(json_te
, "unreservedBandwidth",
2539 for (unsigned int i
= 0; i
< MAX_CLASS_TYPE
; ++i
) {
2542 snprintf(buf_ct
, sizeof(buf_ct
), "classType%u",
2544 json_object_double_add(json_bws
, buf_ct
,
2549 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2550 json_object_int_add(json_te
, "administrativeGroup",
2552 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2553 json_object_int_add(json_te
, "linkDelayAverage",
2555 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2556 json_object_int_add(json_te
, "linkDelayMinimum",
2558 json_object_int_add(json_te
, "linkDelayMaximum",
2562 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2563 json_object_int_add(json_te
, "linkDelayVariation",
2565 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2566 json_object_double_add(json_te
, "linkPacketLoss",
2568 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2569 json_object_double_add(json_te
, "availableBandwidth",
2571 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2572 json_object_double_add(json_te
, "residualBandwidth",
2574 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2575 json_object_double_add(json_te
, "utilizedBandwidth",
2577 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2578 json_object_string_addf(json_te
, "neighborAsbrIp",
2579 "%pI4", &iflp
->rmt_ip
);
2580 json_object_int_add(json_te
, "neighborAsbrAs", iflp
->rmt_as
);
2583 if (listhead(ifp
->nbr_connected
)) {
2584 json_object
*json_nbr_addrs
;
2586 json_nbr_addrs
= json_object_new_array();
2587 json_object_object_add(json_if
, "neighborIpAddresses",
2590 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
2592 nbr_connected_dump_vty(vty
, json_nbr_addrs
,
2596 #ifdef HAVE_PROC_NET_DEV
2597 json_object_int_add(json_if
, "inputPackets", stats
.rx_packets
);
2598 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.rx_bytes
);
2599 json_object_int_add(json_if
, "inputDropped", ifp
->stats
.rx_dropped
);
2600 json_object_int_add(json_if
, "inputMulticastPackets",
2601 ifp
->stats
.rx_multicast
);
2602 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.rx_errors
);
2603 json_object_int_add(json_if
, "inputLengthErrors",
2604 ifp
->stats
.rx_length_errors
);
2605 json_object_int_add(json_if
, "inputOverrunErrors",
2606 ifp
->stats
.rx_over_errors
);
2607 json_object_int_add(json_if
, "inputCrcErrors",
2608 ifp
->stats
.rx_crc_errors
);
2609 json_object_int_add(json_if
, "inputFrameErrors",
2610 ifp
->stats
.rx_frame_errors
);
2611 json_object_int_add(json_if
, "inputFifoErrors",
2612 ifp
->stats
.rx_fifo_errors
);
2613 json_object_int_add(json_if
, "inputMissedErrors",
2614 ifp
->stats
.rx_missed_errors
);
2615 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.tx_packets
);
2616 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.tx_bytes
);
2617 json_object_int_add(json_if
, "outputDroppedPackets",
2618 ifp
->stats
.tx_dropped
);
2619 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.tx_errors
);
2620 json_object_int_add(json_if
, "outputAbortedErrors",
2621 ifp
->stats
.tx_aborted_errors
);
2622 json_object_int_add(json_if
, "outputCarrierErrors",
2623 ifp
->stats
.tx_carrier_errors
);
2624 json_object_int_add(json_if
, "outputFifoErrors",
2625 ifp
->stats
.tx_fifo_errors
);
2626 json_object_int_add(json_if
, "outputHeartbeatErrors",
2627 ifp
->stats
.tx_heartbeat_errors
);
2628 json_object_int_add(json_if
, "outputWindowErrors",
2629 ifp
->stats
.tx_window_errors
);
2630 json_object_int_add(json_if
, "collisions", ifp
->stats
.collisions
);
2631 #endif /* HAVE_PROC_NET_DEV */
2633 #ifdef HAVE_NET_RT_IFLIST
2634 json_object_int_add(json_if
, "inputPackets", ifp
->stats
.ifi_ipackets
);
2635 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.ifi_ibytes
);
2636 json_object_int_add(json_if
, "inputDropd", ifp
->stats
.ifi_iqdrops
);
2637 json_object_int_add(json_if
, "inputMulticastPackets",
2638 ifp
->stats
.ifi_imcasts
);
2639 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.ifi_ierrors
);
2640 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.ifi_opackets
);
2641 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.ifi_obytes
);
2642 json_object_int_add(json_if
, "outputMulticastPackets",
2643 ifp
->stats
.ifi_omcasts
);
2644 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.ifi_oerrors
);
2645 json_object_int_add(json_if
, "collisions", ifp
->stats
.ifi_collisions
);
2646 #endif /* HAVE_NET_RT_IFLIST */
2649 static void interface_update_stats(void)
2651 #ifdef HAVE_PROC_NET_DEV
2652 /* If system has interface statistics via proc file system, update
2654 ifstat_update_proc();
2655 #endif /* HAVE_PROC_NET_DEV */
2656 #ifdef HAVE_NET_RT_IFLIST
2657 ifstat_update_sysctl();
2658 #endif /* HAVE_NET_RT_IFLIST */
2661 #include "zebra/interface_clippy.c"
2662 /* Show all interfaces to vty. */
2663 DEFPY(show_interface
, show_interface_cmd
,
2664 "show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
2666 "Interface status and configuration\n"
2668 "Interface status and configuration summary\n"
2672 struct interface
*ifp
;
2673 json_object
*json
= NULL
;
2675 interface_update_stats();
2677 vrf
= vrf_lookup_by_name(vrf_name
);
2680 vty_out(vty
, "{}\n");
2682 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2687 json
= json_object_new_object();
2691 ifs_dump_brief_vty_json(json
, vrf
);
2693 ifs_dump_brief_vty(vty
, vrf
);
2695 FOR_ALL_INTERFACES (vrf
, ifp
) {
2697 if_dump_vty_json(vty
, ifp
, json
);
2699 if_dump_vty(vty
, ifp
);
2704 vty_json(vty
, json
);
2710 /* Show all interfaces to vty. */
2711 DEFPY (show_interface_vrf_all
,
2712 show_interface_vrf_all_cmd
,
2713 "show interface [vrf all] [brief$brief] [json$uj]",
2715 "Interface status and configuration\n"
2716 VRF_ALL_CMD_HELP_STR
2717 "Interface status and configuration summary\n"
2721 struct interface
*ifp
;
2722 json_object
*json
= NULL
;
2724 interface_update_stats();
2727 json
= json_object_new_object();
2729 /* All interface print. */
2730 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2733 ifs_dump_brief_vty_json(json
, vrf
);
2735 ifs_dump_brief_vty(vty
, vrf
);
2737 FOR_ALL_INTERFACES (vrf
, ifp
) {
2739 if_dump_vty_json(vty
, ifp
, json
);
2741 if_dump_vty(vty
, ifp
);
2747 vty_json(vty
, json
);
2752 /* Show specified interface to vty. */
2754 DEFPY (show_interface_name_vrf
,
2755 show_interface_name_vrf_cmd
,
2756 "show interface IFNAME$ifname vrf NAME$vrf_name [json$uj]",
2758 "Interface status and configuration\n"
2763 struct interface
*ifp
;
2765 json_object
*json
= NULL
;
2767 interface_update_stats();
2769 vrf
= vrf_lookup_by_name(vrf_name
);
2772 vty_out(vty
, "{}\n");
2774 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2778 ifp
= if_lookup_by_name_vrf(ifname
, vrf
);
2781 vty_out(vty
, "{}\n");
2783 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2788 json
= json_object_new_object();
2791 if_dump_vty_json(vty
, ifp
, json
);
2793 if_dump_vty(vty
, ifp
);
2796 vty_json(vty
, json
);
2801 /* Show specified interface to vty. */
2802 DEFPY (show_interface_name_vrf_all
,
2803 show_interface_name_vrf_all_cmd
,
2804 "show interface IFNAME$ifname [vrf all] [json$uj]",
2806 "Interface status and configuration\n"
2808 VRF_ALL_CMD_HELP_STR
2811 struct interface
*ifp
= NULL
;
2812 struct interface
*ifptmp
;
2814 json_object
*json
= NULL
;
2817 interface_update_stats();
2819 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2820 ifptmp
= if_lookup_by_name_vrf(ifname
, vrf
);
2824 if (!vrf_is_backend_netns())
2831 vty_out(vty
, "{}\n");
2833 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2838 vty_out(vty
, "{}\n");
2841 "%% There are multiple interfaces with name %s\n",
2843 vty_out(vty
, "%% You must specify the VRF name\n");
2849 json
= json_object_new_object();
2852 if_dump_vty_json(vty
, ifp
, json
);
2854 if_dump_vty(vty
, ifp
);
2857 vty_json(vty
, json
);
2862 static void if_show_description(struct vty
*vty
, struct vrf
*vrf
)
2864 struct interface
*ifp
;
2866 vty_out(vty
, "Interface Status Protocol Description\n");
2867 FOR_ALL_INTERFACES (vrf
, ifp
) {
2869 struct zebra_if
*zif
;
2874 len
= vty_out(vty
, "%s", ifp
->name
);
2875 vty_out(vty
, "%*s", (16 - len
), " ");
2877 if (if_is_up(ifp
)) {
2878 vty_out(vty
, "up ");
2879 if (CHECK_FLAG(ifp
->status
,
2880 ZEBRA_INTERFACE_LINKDETECTION
)) {
2881 if (if_is_running(ifp
))
2882 vty_out(vty
, "up ");
2884 vty_out(vty
, "down ");
2886 vty_out(vty
, "unknown ");
2889 vty_out(vty
, "down down ");
2894 vty_out(vty
, "%s", ifp
->desc
);
2897 if (zif
&& zif
->desc
) {
2898 vty_out(vty
, "%s%s",
2909 DEFUN (show_interface_desc
,
2910 show_interface_desc_cmd
,
2911 "show interface description vrf NAME",
2913 "Interface status and configuration\n"
2914 "Interface description\n"
2919 vrf
= vrf_lookup_by_name(argv
[4]->arg
);
2921 vty_out(vty
, "%% VRF %s not found\n", argv
[4]->arg
);
2925 if_show_description(vty
, vrf
);
2931 DEFUN (show_interface_desc_vrf_all
,
2932 show_interface_desc_vrf_all_cmd
,
2933 "show interface description [vrf all]",
2935 "Interface status and configuration\n"
2936 "Interface description\n"
2937 VRF_ALL_CMD_HELP_STR
)
2941 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2942 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
2943 vty_out(vty
, "\n\tVRF %s(%u)\n\n", VRF_LOGNAME(vrf
),
2945 if_show_description(vty
, vrf
);
2951 int if_multicast_set(struct interface
*ifp
)
2953 struct zebra_if
*if_data
;
2955 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2956 if (if_set_flags(ifp
, IFF_MULTICAST
) < 0) {
2957 zlog_debug("Can't set multicast flag on interface %s",
2963 if_data
= ifp
->info
;
2964 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
2972 "Set multicast flag to interface\n")
2974 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2976 struct zebra_if
*if_data
;
2978 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2979 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
2981 vty_out(vty
, "Can't set multicast flag\n");
2982 return CMD_WARNING_CONFIG_FAILED
;
2986 if_data
= ifp
->info
;
2987 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
2997 "Set mpls to be on for the interface\n")
2999 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3000 struct zebra_if
*if_data
= ifp
->info
;
3003 dplane_intf_mpls_modify_state(ifp
, false);
3004 if_data
->mpls
= IF_ZEBRA_DATA_UNSPEC
;
3006 dplane_intf_mpls_modify_state(ifp
, true);
3007 if_data
->mpls
= IF_ZEBRA_DATA_ON
;
3013 int if_multicast_unset(struct interface
*ifp
)
3015 struct zebra_if
*if_data
;
3017 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3018 if (if_unset_flags(ifp
, IFF_MULTICAST
) < 0) {
3019 zlog_debug("Can't unset multicast flag on interface %s",
3025 if_data
= ifp
->info
;
3026 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
3031 DEFUN (no_multicast
,
3035 "Unset multicast flag to interface\n")
3037 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3039 struct zebra_if
*if_data
;
3041 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3042 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
3044 vty_out(vty
, "Can't unset multicast flag\n");
3045 return CMD_WARNING_CONFIG_FAILED
;
3049 if_data
= ifp
->info
;
3050 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
3055 int if_linkdetect(struct interface
*ifp
, bool detect
)
3057 int if_was_operative
;
3059 if_was_operative
= if_is_no_ptm_operative(ifp
);
3061 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3063 /* When linkdetection is enabled, if might come down */
3064 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
3067 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3069 /* Interface may come up after disabling link detection */
3070 if (if_is_operative(ifp
) && !if_was_operative
)
3073 /* FIXME: Will defer status change forwarding if interface
3074 does not come down! */
3078 DEFUN(linkdetect
, linkdetect_cmd
, "link-detect",
3079 "Enable link detection on interface\n")
3081 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3083 if_linkdetect(ifp
, true);
3089 DEFUN (no_linkdetect
,
3093 "Disable link detection on interface\n")
3095 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3097 if_linkdetect(ifp
, false);
3102 int if_shutdown(struct interface
*ifp
)
3104 struct zebra_if
*if_data
;
3106 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3107 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3109 if (if_unset_flags(ifp
, IFF_UP
) < 0) {
3110 zlog_debug("Can't shutdown interface %s", ifp
->name
);
3115 if_data
= ifp
->info
;
3116 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3124 "Shutdown the selected interface\n")
3126 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3128 struct zebra_if
*if_data
;
3130 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3131 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3133 ret
= if_unset_flags(ifp
, IFF_UP
);
3135 vty_out(vty
, "Can't shutdown interface\n");
3136 return CMD_WARNING_CONFIG_FAILED
;
3140 if_data
= ifp
->info
;
3141 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3146 int if_no_shutdown(struct interface
*ifp
)
3148 struct zebra_if
*if_data
;
3150 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3151 if (if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
) < 0) {
3152 zlog_debug("Can't up interface %s", ifp
->name
);
3157 /* Some addresses (in particular, IPv6 addresses on Linux) get
3158 * removed when the interface goes down. They need to be
3161 if_addr_wakeup(ifp
);
3164 if_data
= ifp
->info
;
3165 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3170 DEFUN (no_shutdown_if
,
3174 "Shutdown the selected interface\n")
3176 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3178 struct zebra_if
*if_data
;
3180 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3181 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3183 vty_out(vty
, "Can't up interface\n");
3184 return CMD_WARNING_CONFIG_FAILED
;
3188 /* Some addresses (in particular, IPv6 addresses on Linux) get
3189 * removed when the interface goes down. They need to be
3192 if_addr_wakeup(ifp
);
3195 if_data
= ifp
->info
;
3196 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3201 DEFUN (bandwidth_if
,
3203 "bandwidth (1-100000)",
3204 "Set bandwidth informational parameter\n"
3205 "Bandwidth in megabits\n")
3208 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3209 unsigned int bandwidth
;
3211 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
3213 /* bandwidth range is <1-100000> */
3214 if (bandwidth
< 1 || bandwidth
> 100000) {
3215 vty_out(vty
, "Bandwidth is invalid\n");
3216 return CMD_WARNING_CONFIG_FAILED
;
3219 ifp
->bandwidth
= bandwidth
;
3221 /* force protocols to recalculate routes due to cost change */
3222 if (if_is_operative(ifp
))
3223 zebra_interface_up_update(ifp
);
3228 DEFUN (no_bandwidth_if
,
3229 no_bandwidth_if_cmd
,
3230 "no bandwidth [(1-100000)]",
3232 "Set bandwidth informational parameter\n"
3233 "Bandwidth in megabits\n")
3235 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3239 /* force protocols to recalculate routes due to cost change */
3240 if (if_is_operative(ifp
))
3241 zebra_interface_up_update(ifp
);
3247 struct cmd_node link_params_node
= {
3248 .name
= "link-params",
3249 .node
= LINK_PARAMS_NODE
,
3250 .parent_node
= INTERFACE_NODE
,
3251 .prompt
= "%s(config-link-params)# ",
3255 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
3256 uint32_t type
, uint32_t value
)
3258 /* Update field as needed */
3259 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
3261 SET_PARAM(ifp
->link_params
, type
);
3263 /* force protocols to update LINK STATE due to parameters change
3265 if (if_is_operative(ifp
))
3266 zebra_interface_parameters_update(ifp
);
3269 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
3270 uint32_t type
, float value
)
3273 /* Update field as needed */
3274 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
3276 SET_PARAM(ifp
->link_params
, type
);
3278 /* force protocols to update LINK STATE due to parameters change
3280 if (if_is_operative(ifp
))
3281 zebra_interface_parameters_update(ifp
);
3285 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
3287 if (ifp
->link_params
== NULL
)
3291 UNSET_PARAM(ifp
->link_params
, type
);
3293 /* force protocols to update LINK STATE due to parameters change */
3294 if (if_is_operative(ifp
))
3295 zebra_interface_parameters_update(ifp
);
3298 DEFUN_NOSH (link_params
,
3303 /* vty->qobj_index stays the same @ interface pointer */
3304 vty
->node
= LINK_PARAMS_NODE
;
3309 DEFUN_NOSH (exit_link_params
,
3310 exit_link_params_cmd
,
3312 "Exit from Link Params configuration mode\n")
3314 if (vty
->node
== LINK_PARAMS_NODE
)
3315 vty
->node
= INTERFACE_NODE
;
3319 /* Specific Traffic Engineering parameters commands */
3320 DEFUN (link_params_enable
,
3321 link_params_enable_cmd
,
3323 "Activate link parameters on this interface\n")
3325 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3327 /* This command could be issue at startup, when activate MPLS TE */
3328 /* on a new interface or after a ON / OFF / ON toggle */
3329 /* In all case, TE parameters are reset to their default factory */
3330 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3332 "Link-params: enable TE link parameters on interface %s",
3335 if (!if_link_params_get(ifp
))
3336 if_link_params_enable(ifp
);
3338 /* force protocols to update LINK STATE due to parameters change */
3339 if (if_is_operative(ifp
))
3340 zebra_interface_parameters_update(ifp
);
3345 DEFUN (no_link_params_enable
,
3346 no_link_params_enable_cmd
,
3349 "Disable link parameters on this interface\n")
3351 char xpath
[XPATH_MAXLEN
];
3353 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3355 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3356 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
3359 if_link_params_free(ifp
);
3362 xpath
, sizeof(xpath
),
3363 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
3365 if (yang_dnode_exists(running_config
->dnode
, xpath
))
3366 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
3368 ret
= nb_cli_apply_changes(vty
, NULL
);
3370 if (ret
!= CMD_SUCCESS
)
3373 /* force protocols to update LINK STATE due to parameters change */
3374 if (if_is_operative(ifp
))
3375 zebra_interface_parameters_update(ifp
);
3380 /* STANDARD TE metrics */
3381 DEFUN (link_params_metric
,
3382 link_params_metric_cmd
,
3383 "metric (0-4294967295)",
3384 "Link metric for MPLS-TE purpose\n"
3385 "Metric value in decimal\n")
3388 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3389 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3392 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3395 iflp
= if_link_params_enable(ifp
);
3397 /* Update TE metric if needed */
3398 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
3403 DEFUN (no_link_params_metric
,
3404 no_link_params_metric_cmd
,
3407 "Disable Link Metric on this interface\n")
3409 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3411 /* Unset TE Metric */
3412 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
3417 DEFUN (link_params_maxbw
,
3418 link_params_maxbw_cmd
,
3420 "Maximum bandwidth that can be used\n"
3421 "Bytes/second (IEEE floating point format)\n")
3423 int idx_bandwidth
= 1;
3424 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3425 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3429 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3430 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
3431 safe_strerror(errno
));
3432 return CMD_WARNING_CONFIG_FAILED
;
3435 /* Check that Maximum bandwidth is not lower than other bandwidth
3437 if (iflp
&& ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0]) ||
3438 (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2]) ||
3439 (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4]) ||
3440 (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6]) ||
3441 (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
) ||
3442 (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
))) {
3444 "Maximum Bandwidth could not be lower than others bandwidth\n");
3445 return CMD_WARNING_CONFIG_FAILED
;
3449 iflp
= if_link_params_enable(ifp
);
3451 /* Update Maximum Bandwidth if needed */
3452 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
3457 DEFUN (link_params_max_rsv_bw
,
3458 link_params_max_rsv_bw_cmd
,
3459 "max-rsv-bw BANDWIDTH",
3460 "Maximum bandwidth that may be reserved\n"
3461 "Bytes/second (IEEE floating point format)\n")
3463 int idx_bandwidth
= 1;
3464 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3465 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3468 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3469 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
3470 safe_strerror(errno
));
3471 return CMD_WARNING_CONFIG_FAILED
;
3474 /* Check that bandwidth is not greater than maximum bandwidth parameter
3476 if (iflp
&& bw
> iflp
->max_bw
) {
3478 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3480 return CMD_WARNING_CONFIG_FAILED
;
3484 iflp
= if_link_params_enable(ifp
);
3486 /* Update Maximum Reservable Bandwidth if needed */
3487 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
3492 DEFUN (link_params_unrsv_bw
,
3493 link_params_unrsv_bw_cmd
,
3494 "unrsv-bw (0-7) BANDWIDTH",
3495 "Unreserved bandwidth at each priority level\n"
3497 "Bytes/second (IEEE floating point format)\n")
3500 int idx_bandwidth
= 2;
3501 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3502 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3506 /* We don't have to consider about range check here. */
3507 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
3508 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3509 safe_strerror(errno
));
3510 return CMD_WARNING_CONFIG_FAILED
;
3513 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3514 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3515 safe_strerror(errno
));
3516 return CMD_WARNING_CONFIG_FAILED
;
3519 /* Check that bandwidth is not greater than maximum bandwidth parameter
3521 if (iflp
&& bw
> iflp
->max_bw
) {
3523 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3525 return CMD_WARNING_CONFIG_FAILED
;
3529 iflp
= if_link_params_enable(ifp
);
3531 /* Update Unreserved Bandwidth if needed */
3532 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
3538 DEFPY_YANG(link_params_admin_grp
, link_params_admin_grp_cmd
,
3539 "admin-grp BITPATTERN",
3540 "Administrative group membership\n"
3541 "32-bit Hexadecimal value (e.g. 0xa1)\n")
3543 char xpath
[XPATH_MAXLEN
];
3544 int idx_bitpattern
= 1;
3545 unsigned long value
;
3548 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3551 xpath
, sizeof(xpath
),
3552 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
3554 if (yang_dnode_exists(running_config
->dnode
, xpath
)) {
3556 "cannot use the admin-grp command when affinity is set\n");
3557 return CMD_WARNING_CONFIG_FAILED
;
3560 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
3561 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
3562 safe_strerror(errno
));
3563 return CMD_WARNING_CONFIG_FAILED
;
3566 if (value
> 0xFFFFFFFF) {
3567 vty_out(vty
, "value must be not be superior to 0xFFFFFFFF\n");
3568 return CMD_WARNING_CONFIG_FAILED
;
3571 snprintf(value_str
, sizeof(value_str
), "%ld", value
);
3573 nb_cli_enqueue_change(
3574 vty
, "./frr-zebra:zebra/link-params/legacy-admin-group",
3575 NB_OP_MODIFY
, value_str
);
3577 return nb_cli_apply_changes(vty
, NULL
);
3580 DEFPY_YANG(no_link_params_admin_grp
, no_link_params_admin_grp_cmd
,
3582 NO_STR
"Disable Administrative group membership on this interface\n")
3584 nb_cli_enqueue_change(
3585 vty
, "./frr-zebra:zebra/link-params/legacy-admin-group",
3586 NB_OP_DESTROY
, NULL
);
3588 return nb_cli_apply_changes(vty
, NULL
);
3591 /* RFC5392 & RFC5316: INTER-AS */
3592 DEFUN (link_params_inter_as
,
3593 link_params_inter_as_cmd
,
3594 "neighbor A.B.C.D as (1-4294967295)",
3595 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
3596 "Remote IP address in dot decimal A.B.C.D\n"
3597 "Remote AS number\n"
3598 "AS number in the range <1-4294967295>\n")
3603 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3604 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3605 struct in_addr addr
;
3608 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
3609 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
3610 return CMD_WARNING_CONFIG_FAILED
;
3614 iflp
= if_link_params_enable(ifp
);
3616 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3618 /* Update Remote IP and Remote AS fields if needed */
3619 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
3620 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
3623 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
3624 SET_PARAM(iflp
, LP_RMT_AS
);
3626 /* force protocols to update LINK STATE due to parameters change
3628 if (if_is_operative(ifp
))
3629 zebra_interface_parameters_update(ifp
);
3634 DEFUN (no_link_params_inter_as
,
3635 no_link_params_inter_as_cmd
,
3638 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
3640 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3641 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3646 /* Reset Remote IP and AS neighbor */
3648 iflp
->rmt_ip
.s_addr
= 0;
3649 UNSET_PARAM(iflp
, LP_RMT_AS
);
3651 /* force protocols to update LINK STATE due to parameters change */
3652 if (if_is_operative(ifp
))
3653 zebra_interface_parameters_update(ifp
);
3658 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
3659 * draft-ietf-isis-metric-extensions-07.txt */
3660 DEFUN (link_params_delay
,
3661 link_params_delay_cmd
,
3662 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
3663 "Unidirectional Average Link Delay\n"
3664 "Average delay in micro-second as decimal (0...16777215)\n"
3666 "Minimum delay in micro-second as decimal (0...16777215)\n"
3668 "Maximum delay in micro-second as decimal (0...16777215)\n")
3670 /* Get and Check new delay values */
3671 uint32_t delay
= 0, low
= 0, high
= 0;
3672 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
3674 low
= strtoul(argv
[3]->arg
, NULL
, 10);
3675 high
= strtoul(argv
[5]->arg
, NULL
, 10);
3678 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3679 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3684 * Check new delay value against old Min and Max delays if set
3686 * RFC 7471 Section 4.2.7:
3687 * It is possible for min delay and max delay to be
3690 * Therefore, it is also allowed that the average
3691 * delay be equal to the min delay or max delay.
3693 if (iflp
&& IS_PARAM_SET(iflp
, LP_MM_DELAY
) &&
3694 (delay
< iflp
->min_delay
|| delay
> iflp
->max_delay
)) {
3696 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3697 iflp
->min_delay
, iflp
->max_delay
);
3698 return CMD_WARNING_CONFIG_FAILED
;
3702 iflp
= if_link_params_enable(ifp
);
3704 /* Update delay if value is not set or change */
3705 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
3706 iflp
->av_delay
= delay
;
3707 SET_PARAM(iflp
, LP_DELAY
);
3710 /* Unset Min and Max delays if already set */
3711 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3712 iflp
->min_delay
= 0;
3713 iflp
->max_delay
= 0;
3714 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3719 * Check new delays value coherency. See above note
3720 * regarding average delay equal to min/max allowed
3722 if (delay
< low
|| delay
> high
) {
3724 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3726 return CMD_WARNING_CONFIG_FAILED
;
3730 iflp
= if_link_params_enable(ifp
);
3732 /* Update Delays if needed */
3733 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
3734 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
3735 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
3736 || iflp
->max_delay
!= high
) {
3737 iflp
->av_delay
= delay
;
3738 SET_PARAM(iflp
, LP_DELAY
);
3739 iflp
->min_delay
= low
;
3740 iflp
->max_delay
= high
;
3741 SET_PARAM(iflp
, LP_MM_DELAY
);
3746 /* force protocols to update LINK STATE due to parameters change */
3747 if (update
== 1 && if_is_operative(ifp
))
3748 zebra_interface_parameters_update(ifp
);
3753 DEFUN (no_link_params_delay
,
3754 no_link_params_delay_cmd
,
3757 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
3759 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3760 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3767 UNSET_PARAM(iflp
, LP_DELAY
);
3768 iflp
->min_delay
= 0;
3769 iflp
->max_delay
= 0;
3770 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3772 /* force protocols to update LINK STATE due to parameters change */
3773 if (if_is_operative(ifp
))
3774 zebra_interface_parameters_update(ifp
);
3779 DEFUN (link_params_delay_var
,
3780 link_params_delay_var_cmd
,
3781 "delay-variation (0-16777215)",
3782 "Unidirectional Link Delay Variation\n"
3783 "delay variation in micro-second as decimal (0...16777215)\n")
3786 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3787 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3790 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3793 iflp
= if_link_params_enable(ifp
);
3795 /* Update Delay Variation if needed */
3796 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
3801 DEFUN (no_link_params_delay_var
,
3802 no_link_params_delay_var_cmd
,
3803 "no delay-variation",
3805 "Disable Unidirectional Delay Variation on this interface\n")
3807 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3809 /* Unset Delay Variation */
3810 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
3815 DEFUN (link_params_pkt_loss
,
3816 link_params_pkt_loss_cmd
,
3817 "packet-loss PERCENTAGE",
3818 "Unidirectional Link Packet Loss\n"
3819 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
3821 int idx_percentage
= 1;
3822 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3823 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3826 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
3827 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
3828 safe_strerror(errno
));
3829 return CMD_WARNING_CONFIG_FAILED
;
3832 if (fval
> MAX_PKT_LOSS
)
3833 fval
= MAX_PKT_LOSS
;
3836 iflp
= if_link_params_enable(ifp
);
3838 /* Update Packet Loss if needed */
3839 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
3844 DEFUN (no_link_params_pkt_loss
,
3845 no_link_params_pkt_loss_cmd
,
3848 "Disable Unidirectional Link Packet Loss on this interface\n")
3850 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3852 /* Unset Packet Loss */
3853 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
3858 DEFUN (link_params_res_bw
,
3859 link_params_res_bw_cmd
,
3861 "Unidirectional Residual Bandwidth\n"
3862 "Bytes/second (IEEE floating point format)\n")
3864 int idx_bandwidth
= 1;
3865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3866 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3869 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3870 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
3871 safe_strerror(errno
));
3872 return CMD_WARNING_CONFIG_FAILED
;
3875 /* Check that bandwidth is not greater than maximum bandwidth parameter
3877 if (iflp
&& bw
> iflp
->max_bw
) {
3879 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3881 return CMD_WARNING_CONFIG_FAILED
;
3885 iflp
= if_link_params_enable(ifp
);
3887 /* Update Residual Bandwidth if needed */
3888 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
3893 DEFUN (no_link_params_res_bw
,
3894 no_link_params_res_bw_cmd
,
3897 "Disable Unidirectional Residual Bandwidth on this interface\n")
3899 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3901 /* Unset Residual Bandwidth */
3902 link_param_cmd_unset(ifp
, LP_RES_BW
);
3907 DEFUN (link_params_ava_bw
,
3908 link_params_ava_bw_cmd
,
3910 "Unidirectional Available Bandwidth\n"
3911 "Bytes/second (IEEE floating point format)\n")
3913 int idx_bandwidth
= 1;
3914 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3915 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3918 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3919 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
3920 safe_strerror(errno
));
3921 return CMD_WARNING_CONFIG_FAILED
;
3924 /* Check that bandwidth is not greater than maximum bandwidth parameter
3926 if (iflp
&& bw
> iflp
->max_bw
) {
3928 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3930 return CMD_WARNING_CONFIG_FAILED
;
3934 iflp
= if_link_params_enable(ifp
);
3936 /* Update Residual Bandwidth if needed */
3937 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
3942 DEFUN (no_link_params_ava_bw
,
3943 no_link_params_ava_bw_cmd
,
3946 "Disable Unidirectional Available Bandwidth on this interface\n")
3948 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3950 /* Unset Available Bandwidth */
3951 link_param_cmd_unset(ifp
, LP_AVA_BW
);
3956 DEFUN (link_params_use_bw
,
3957 link_params_use_bw_cmd
,
3959 "Unidirectional Utilised Bandwidth\n"
3960 "Bytes/second (IEEE floating point format)\n")
3962 int idx_bandwidth
= 1;
3963 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3964 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3967 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3968 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
3969 safe_strerror(errno
));
3970 return CMD_WARNING_CONFIG_FAILED
;
3973 /* Check that bandwidth is not greater than maximum bandwidth parameter
3975 if (iflp
&& bw
> iflp
->max_bw
) {
3977 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3979 return CMD_WARNING_CONFIG_FAILED
;
3983 iflp
= if_link_params_enable(ifp
);
3985 /* Update Utilized Bandwidth if needed */
3986 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
3991 DEFUN (no_link_params_use_bw
,
3992 no_link_params_use_bw_cmd
,
3995 "Disable Unidirectional Utilised Bandwidth on this interface\n")
3997 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3999 /* Unset Utilised Bandwidth */
4000 link_param_cmd_unset(ifp
, LP_USE_BW
);
4005 static int ag_change(struct vty
*vty
, int argc
, struct cmd_token
**argv
,
4006 const char *xpath
, bool no
, int start_idx
)
4008 for (int i
= start_idx
; i
< argc
; i
++)
4009 nb_cli_enqueue_change(vty
, xpath
,
4010 no
? NB_OP_DESTROY
: NB_OP_CREATE
,
4012 return nb_cli_apply_changes(vty
, NULL
);
4017 * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity
4019 DEFPY_YANG(link_params_affinity
, link_params_affinity_cmd
,
4020 "[no] affinity NAME...",
4022 "Interface affinities\n"
4025 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4026 char xpath
[XPATH_MAXLEN
];
4029 xpath
, sizeof(xpath
),
4030 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/legacy-admin-group",
4032 if (yang_dnode_exists(running_config
->dnode
, xpath
)) {
4034 "cannot use the affinity command when admin-grp is set\n");
4035 return CMD_WARNING_CONFIG_FAILED
;
4038 return ag_change(vty
, argc
, argv
,
4039 "./frr-zebra:zebra/link-params/affinities/affinity",
4046 * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity-mode
4048 DEFPY_YANG(link_params_affinity_mode
, link_params_affinity_mode_cmd
,
4049 "affinity-mode <standard|extended|both>$affmode",
4050 "Interface affinity mode\n"
4051 "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
4052 "Extended Admin-Group only RFC7308\n"
4053 "Standard and extended Admin-Group format\n")
4055 const char *xpath
= "./frr-zebra:zebra/link-params/affinity-mode";
4057 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, affmode
);
4059 return nb_cli_apply_changes(vty
, NULL
);
4062 DEFPY_YANG(no_link_params_affinity_mode
, no_link_params_affinity_mode_cmd
,
4063 "no affinity-mode [<standard|extended|both>]",
4065 "Interface affinity mode\n"
4066 "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
4067 "Extended Admin-Group only RFC7308\n"
4068 "Standard and extended Admin-Group format\n")
4070 const char *xpath
= "./frr-zebra:zebra/link-params/affinity-mode";
4072 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "standard");
4074 return nb_cli_apply_changes(vty
, NULL
);
4077 static int ag_iter_cb(const struct lyd_node
*dnode
, void *arg
)
4079 struct vty
*vty
= (struct vty
*)arg
;
4081 vty_out(vty
, " %s", yang_dnode_get_string(dnode
, "."));
4082 return YANG_ITER_CONTINUE
;
4085 void cli_show_legacy_admin_group(struct vty
*vty
, const struct lyd_node
*dnode
,
4088 if (!yang_dnode_exists(dnode
, "./legacy-admin-group"))
4091 vty_out(vty
, " admin-group 0x%x\n",
4092 yang_dnode_get_uint32(dnode
, "./legacy-admin-group"));
4095 void cli_show_affinity_mode(struct vty
*vty
, const struct lyd_node
*dnode
,
4098 enum affinity_mode affinity_mode
= yang_dnode_get_enum(dnode
, ".");
4100 if (affinity_mode
== AFFINITY_MODE_STANDARD
)
4101 vty_out(vty
, " affinity-mode standard\n");
4102 else if (affinity_mode
== AFFINITY_MODE_BOTH
)
4103 vty_out(vty
, " affinity-mode both\n");
4106 void cli_show_affinity(struct vty
*vty
, const struct lyd_node
*dnode
,
4109 if (!yang_dnode_exists(dnode
, "./affinity"))
4112 vty_out(vty
, " affinity");
4113 yang_dnode_iterate(ag_iter_cb
, vty
, dnode
, "./affinity");
4117 int if_ip_address_install(struct interface
*ifp
, struct prefix
*prefix
,
4118 const char *label
, struct prefix
*pp
)
4120 struct zebra_if
*if_data
;
4121 struct prefix_ipv4 lp
;
4122 struct prefix_ipv4
*p
;
4123 struct connected
*ifc
;
4124 enum zebra_dplane_result dplane_res
;
4126 if_data
= ifp
->info
;
4128 lp
.family
= prefix
->family
;
4129 lp
.prefix
= prefix
->u
.prefix4
;
4130 lp
.prefixlen
= prefix
->prefixlen
;
4131 apply_mask_ipv4(&lp
);
4133 ifc
= connected_check_ptp(ifp
, &lp
, pp
? pp
: NULL
);
4135 ifc
= connected_new();
4139 p
= prefix_ipv4_new();
4141 ifc
->address
= (struct prefix
*)p
;
4144 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
4145 p
= prefix_ipv4_new();
4146 *p
= *(struct prefix_ipv4
*)pp
;
4147 ifc
->destination
= (struct prefix
*)p
;
4152 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4154 /* Add to linked list. */
4155 listnode_add(ifp
->connected
, ifc
);
4158 /* This address is configured from zebra. */
4159 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4160 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4162 /* In case of this route need to install kernel. */
4163 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4164 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4165 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4166 /* Some system need to up the interface to set IP address. */
4167 if (!if_is_up(ifp
)) {
4168 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4172 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4173 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4175 "dplane can't set interface IP address: %s.",
4176 dplane_res2str(dplane_res
));
4180 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4181 /* The address will be advertised to zebra clients when the
4183 * from the kernel has been received.
4184 * It will also be added to the subnet chain list, then. */
4190 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
4191 const char *addr_str
, const char *peer_str
,
4194 struct zebra_if
*if_data
;
4195 struct prefix_ipv4 lp
, pp
;
4196 struct connected
*ifc
;
4197 struct prefix_ipv4
*p
;
4199 enum zebra_dplane_result dplane_res
;
4201 if_data
= ifp
->info
;
4203 ret
= str2prefix_ipv4(addr_str
, &lp
);
4205 vty_out(vty
, "%% Malformed address \n");
4206 return CMD_WARNING_CONFIG_FAILED
;
4209 if (ipv4_martian(&lp
.prefix
)) {
4210 vty_out(vty
, "%% Invalid address\n");
4211 return CMD_WARNING_CONFIG_FAILED
;
4215 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4217 "%% Local prefix length for P-t-P address must be /32\n");
4218 return CMD_WARNING_CONFIG_FAILED
;
4221 ret
= str2prefix_ipv4(peer_str
, &pp
);
4223 vty_out(vty
, "%% Malformed peer address\n");
4224 return CMD_WARNING_CONFIG_FAILED
;
4228 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4230 ifc
= connected_new();
4234 p
= prefix_ipv4_new();
4236 ifc
->address
= (struct prefix
*)p
;
4239 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
4240 p
= prefix_ipv4_new();
4242 ifc
->destination
= (struct prefix
*)p
;
4247 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4249 /* Add to linked list. */
4250 listnode_add(ifp
->connected
, ifc
);
4253 /* This address is configured from zebra. */
4254 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4255 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4257 /* In case of this route need to install kernel. */
4258 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4259 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4260 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4261 /* Some system need to up the interface to set IP address. */
4262 if (!if_is_up(ifp
)) {
4263 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4267 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4268 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4269 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4270 dplane_res2str(dplane_res
));
4271 return CMD_WARNING_CONFIG_FAILED
;
4274 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4275 /* The address will be advertised to zebra clients when the
4277 * from the kernel has been received.
4278 * It will also be added to the subnet chain list, then. */
4284 int if_ip_address_uinstall(struct interface
*ifp
, struct prefix
*prefix
)
4286 struct connected
*ifc
= NULL
;
4287 enum zebra_dplane_result dplane_res
;
4289 if (prefix
->family
== AF_INET
) {
4290 /* Check current interface address. */
4291 ifc
= connected_check_ptp(ifp
, prefix
, NULL
);
4293 zlog_debug("interface %s Can't find address",
4298 } else if (prefix
->family
== AF_INET6
) {
4299 /* Check current interface address. */
4300 ifc
= connected_check(ifp
, prefix
);
4304 zlog_debug("interface %s Can't find address", ifp
->name
);
4307 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4309 /* This is not real address or interface is not active. */
4310 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4311 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4312 listnode_delete(ifp
->connected
, ifc
);
4313 connected_free(&ifc
);
4314 return CMD_WARNING_CONFIG_FAILED
;
4317 /* This is real route. */
4318 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4319 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4320 zlog_debug("Can't unset interface IP address: %s.",
4321 dplane_res2str(dplane_res
));
4324 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4329 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4330 const char *addr_str
, const char *peer_str
,
4333 struct prefix_ipv4 lp
, pp
;
4334 struct connected
*ifc
;
4336 enum zebra_dplane_result dplane_res
;
4338 /* Convert to prefix structure. */
4339 ret
= str2prefix_ipv4(addr_str
, &lp
);
4341 vty_out(vty
, "%% Malformed address \n");
4342 return CMD_WARNING_CONFIG_FAILED
;
4346 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4348 "%% Local prefix length for P-t-P address must be /32\n");
4349 return CMD_WARNING_CONFIG_FAILED
;
4352 ret
= str2prefix_ipv4(peer_str
, &pp
);
4354 vty_out(vty
, "%% Malformed peer address\n");
4355 return CMD_WARNING_CONFIG_FAILED
;
4359 /* Check current interface address. */
4360 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4362 vty_out(vty
, "%% Can't find address\n");
4363 return CMD_WARNING_CONFIG_FAILED
;
4366 /* This is not configured address. */
4367 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4368 return CMD_WARNING_CONFIG_FAILED
;
4370 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4372 /* This is not real address or interface is not active. */
4373 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4374 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4375 listnode_delete(ifp
->connected
, ifc
);
4376 connected_free(&ifc
);
4377 return CMD_WARNING_CONFIG_FAILED
;
4380 /* This is real route. */
4381 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4382 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4383 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4384 dplane_res2str(dplane_res
));
4385 return CMD_WARNING_CONFIG_FAILED
;
4387 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4388 /* we will receive a kernel notification about this route being removed.
4389 * this will trigger its removal from the connected list. */
4395 "ip address A.B.C.D/M",
4396 "Interface Internet Protocol config commands\n"
4397 "Set the IP address of an interface\n"
4398 "IP address (e.g. 10.0.0.1/8)\n")
4400 int idx_ipv4_prefixlen
= 2;
4401 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4402 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4406 DEFUN (no_ip_address
,
4408 "no ip address A.B.C.D/M",
4410 "Interface Internet Protocol config commands\n"
4411 "Set the IP address of an interface\n"
4412 "IP Address (e.g. 10.0.0.1/8)\n")
4414 int idx_ipv4_prefixlen
= 3;
4415 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4416 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4420 DEFUN(ip_address_peer
,
4421 ip_address_peer_cmd
,
4422 "ip address A.B.C.D peer A.B.C.D/M",
4423 "Interface Internet Protocol config commands\n"
4424 "Set the IP address of an interface\n"
4425 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4426 "Specify P-t-P address\n"
4427 "Peer IP address (e.g. 10.0.0.1/8)\n")
4429 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4430 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
4433 DEFUN(no_ip_address_peer
,
4434 no_ip_address_peer_cmd
,
4435 "no ip address A.B.C.D peer A.B.C.D/M",
4437 "Interface Internet Protocol config commands\n"
4438 "Set the IP address of an interface\n"
4439 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4440 "Specify P-t-P address\n"
4441 "Peer IP address (e.g. 10.0.0.1/8)\n")
4443 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4444 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
4448 DEFUN (ip_address_label
,
4449 ip_address_label_cmd
,
4450 "ip address A.B.C.D/M label LINE",
4451 "Interface Internet Protocol config commands\n"
4452 "Set the IP address of an interface\n"
4453 "IP address (e.g. 10.0.0.1/8)\n"
4454 "Label of this address\n"
4457 int idx_ipv4_prefixlen
= 2;
4459 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4460 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4461 argv
[idx_line
]->arg
);
4464 DEFUN (no_ip_address_label
,
4465 no_ip_address_label_cmd
,
4466 "no ip address A.B.C.D/M label LINE",
4468 "Interface Internet Protocol config commands\n"
4469 "Set the IP address of an interface\n"
4470 "IP address (e.g. 10.0.0.1/8)\n"
4471 "Label of this address\n"
4474 int idx_ipv4_prefixlen
= 3;
4476 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4477 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4478 NULL
, argv
[idx_line
]->arg
);
4480 #endif /* HAVE_NETLINK */
4482 int if_ipv6_address_install(struct interface
*ifp
, struct prefix
*prefix
,
4485 struct zebra_if
*if_data
;
4486 struct prefix_ipv6 cp
;
4487 struct connected
*ifc
;
4488 struct prefix_ipv6
*p
;
4489 enum zebra_dplane_result dplane_res
;
4491 if_data
= ifp
->info
;
4493 cp
.family
= prefix
->family
;
4494 cp
.prefixlen
= prefix
->prefixlen
;
4495 cp
.prefix
= prefix
->u
.prefix6
;
4496 apply_mask_ipv6(&cp
);
4498 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4500 ifc
= connected_new();
4504 p
= prefix_ipv6_new();
4506 ifc
->address
= (struct prefix
*)p
;
4510 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4512 /* Add to linked list. */
4513 listnode_add(ifp
->connected
, ifc
);
4516 /* This address is configured from zebra. */
4517 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4518 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4520 /* In case of this route need to install kernel. */
4521 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4522 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4523 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4524 /* Some system need to up the interface to set IP address. */
4525 if (!if_is_up(ifp
)) {
4526 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4530 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4531 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4533 "dplane can't set interface IP address: %s.",
4534 dplane_res2str(dplane_res
));
4538 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4539 /* The address will be advertised to zebra clients when the
4541 * from the kernel has been received. */
4547 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
4548 const char *addr_str
, const char *peer_str
,
4551 struct zebra_if
*if_data
;
4552 struct prefix_ipv6 cp
;
4553 struct connected
*ifc
;
4554 struct prefix_ipv6
*p
;
4556 enum zebra_dplane_result dplane_res
;
4558 if_data
= ifp
->info
;
4560 ret
= str2prefix_ipv6(addr_str
, &cp
);
4562 vty_out(vty
, "%% Malformed address \n");
4563 return CMD_WARNING_CONFIG_FAILED
;
4566 if (ipv6_martian(&cp
.prefix
)) {
4567 vty_out(vty
, "%% Invalid address\n");
4568 return CMD_WARNING_CONFIG_FAILED
;
4571 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4573 ifc
= connected_new();
4577 p
= prefix_ipv6_new();
4579 ifc
->address
= (struct prefix
*)p
;
4583 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4585 /* Add to linked list. */
4586 listnode_add(ifp
->connected
, ifc
);
4589 /* This address is configured from zebra. */
4590 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4591 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4593 /* In case of this route need to install kernel. */
4594 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4595 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4596 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4597 /* Some system need to up the interface to set IP address. */
4598 if (!if_is_up(ifp
)) {
4599 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4603 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4604 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4605 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4606 dplane_res2str(dplane_res
));
4607 return CMD_WARNING_CONFIG_FAILED
;
4610 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4611 /* The address will be advertised to zebra clients when the
4613 * from the kernel has been received. */
4619 /* Return true if an ipv6 address is configured on ifp */
4620 int ipv6_address_configured(struct interface
*ifp
)
4622 struct connected
*connected
;
4623 struct listnode
*node
;
4625 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
4626 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
4627 && (connected
->address
->family
== AF_INET6
))
4633 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4634 const char *addr_str
, const char *peer_str
,
4637 struct prefix_ipv6 cp
;
4638 struct connected
*ifc
;
4640 enum zebra_dplane_result dplane_res
;
4642 /* Convert to prefix structure. */
4643 ret
= str2prefix_ipv6(addr_str
, &cp
);
4645 vty_out(vty
, "%% Malformed address \n");
4646 return CMD_WARNING_CONFIG_FAILED
;
4649 /* Check current interface address. */
4650 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4652 vty_out(vty
, "%% Can't find address\n");
4653 return CMD_WARNING_CONFIG_FAILED
;
4656 /* This is not configured address. */
4657 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4658 return CMD_WARNING_CONFIG_FAILED
;
4660 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4662 /* This is not real address or interface is not active. */
4663 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4664 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4665 listnode_delete(ifp
->connected
, ifc
);
4666 connected_free(&ifc
);
4667 return CMD_WARNING_CONFIG_FAILED
;
4670 /* This is real route. */
4671 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4672 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4673 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4674 dplane_res2str(dplane_res
));
4675 return CMD_WARNING_CONFIG_FAILED
;
4678 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4679 /* This information will be propagated to the zclients when the
4680 * kernel notification is received. */
4684 DEFUN (ipv6_address
,
4686 "ipv6 address X:X::X:X/M",
4687 "Interface IPv6 config commands\n"
4688 "Set the IP address of an interface\n"
4689 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4691 int idx_ipv6_prefixlen
= 2;
4692 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4693 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4697 DEFUN (no_ipv6_address
,
4698 no_ipv6_address_cmd
,
4699 "no ipv6 address X:X::X:X/M",
4701 "Interface IPv6 config commands\n"
4702 "Set the IP address of an interface\n"
4703 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4705 int idx_ipv6_prefixlen
= 3;
4706 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4707 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4711 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
4713 const struct lyd_node
*dnode
;
4714 char xpath
[XPATH_MAXLEN
];
4717 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
4720 struct if_link_params
*iflp
= ifp
->link_params
;
4722 vty_out(vty
, " link-params\n");
4723 vty_out(vty
, " enable\n");
4724 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
4725 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
4726 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
4727 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
4728 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
4729 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
4730 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
4731 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
4732 for (i
= 0; i
< 8; i
++)
4733 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
4734 vty_out(vty
, " unrsv-bw %d %g\n", i
,
4739 xpath
, sizeof(xpath
),
4740 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params",
4742 dnode
= yang_dnode_get(running_config
->dnode
, xpath
);
4744 nb_cli_show_dnode_cmds(vty
, dnode
, false);
4746 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
4747 vty_out(vty
, " delay %u", iflp
->av_delay
);
4748 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
4749 vty_out(vty
, " min %u", iflp
->min_delay
);
4750 vty_out(vty
, " max %u", iflp
->max_delay
);
4754 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
4755 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
4756 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
4757 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
4758 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
4759 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
4760 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
4761 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
4762 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
4763 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
4764 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
4765 vty_out(vty
, " neighbor %pI4 as %u\n", &iflp
->rmt_ip
,
4768 vty_out(vty
, " exit-link-params\n");
4772 static int if_config_write(struct vty
*vty
)
4775 struct interface
*ifp
;
4777 zebra_ptm_write(vty
);
4779 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
4780 FOR_ALL_INTERFACES (vrf
, ifp
) {
4781 struct zebra_if
*if_data
;
4782 struct listnode
*addrnode
;
4783 struct connected
*ifc
;
4786 if_data
= ifp
->info
;
4788 if_vty_config_start(vty
, ifp
);
4791 if (if_data
->shutdown
== IF_ZEBRA_DATA_ON
)
4792 vty_out(vty
, " shutdown\n");
4794 zebra_ptm_if_write(vty
, if_data
);
4798 vty_out(vty
, " description %s\n", ifp
->desc
);
4800 /* Assign bandwidth here to avoid unnecessary interface
4802 while processing config script */
4803 if (ifp
->bandwidth
!= 0)
4804 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
4806 if (!CHECK_FLAG(ifp
->status
,
4807 ZEBRA_INTERFACE_LINKDETECTION
))
4808 vty_out(vty
, " no link-detect\n");
4810 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
4812 if (CHECK_FLAG(ifc
->conf
,
4813 ZEBRA_IFC_CONFIGURED
)) {
4814 char buf
[INET6_ADDRSTRLEN
];
4816 vty_out(vty
, " ip%s address %s",
4817 p
->family
== AF_INET
? ""
4819 inet_ntop(p
->family
,
4822 if (CONNECTED_PEER(ifc
)) {
4823 p
= ifc
->destination
;
4824 vty_out(vty
, " peer %s",
4825 inet_ntop(p
->family
,
4830 vty_out(vty
, "/%d", p
->prefixlen
);
4833 vty_out(vty
, " label %s",
4841 if (if_data
->multicast
!= IF_ZEBRA_DATA_UNSPEC
)
4842 vty_out(vty
, " %smulticast\n",
4843 if_data
->multicast
==
4847 if (if_data
->mpls
== IF_ZEBRA_DATA_ON
)
4848 vty_out(vty
, " mpls enable\n");
4851 hook_call(zebra_if_config_wr
, vty
, ifp
);
4852 zebra_evpn_mh_if_write(vty
, ifp
);
4853 link_params_config_write(vty
, ifp
);
4855 if_vty_config_end(vty
);
4860 /* Allocate and initialize interface vector. */
4861 void zebra_if_init(void)
4863 /* Initialize interface and new hook. */
4864 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
4865 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
4867 /* Install configuration write function. */
4868 if_cmd_init(if_config_write
);
4869 install_node(&link_params_node
);
4871 * This is *intentionally* setting this to NULL, signaling
4872 * that interface creation for zebra acts differently
4874 if_zapi_callbacks(NULL
, NULL
, NULL
, NULL
);
4876 install_element(VIEW_NODE
, &show_interface_cmd
);
4877 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
4878 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
4879 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
4881 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
4882 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
4883 install_element(INTERFACE_NODE
, &multicast_cmd
);
4884 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
4885 install_element(INTERFACE_NODE
, &mpls_cmd
);
4886 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
4887 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
4888 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
4889 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
4890 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
4891 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
4892 install_element(INTERFACE_NODE
, &ip_address_cmd
);
4893 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
4894 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
4895 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
4896 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
4897 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
4899 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
4900 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
4901 #endif /* HAVE_NETLINK */
4902 install_element(INTERFACE_NODE
, &link_params_cmd
);
4903 install_default(LINK_PARAMS_NODE
);
4904 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
4905 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
4906 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
4907 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
4908 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
4909 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
4910 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
4911 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
4912 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
4913 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
4914 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
4915 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
4916 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
4917 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
4918 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
4919 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
4920 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
4921 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
4922 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
4923 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
4924 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
4925 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
4926 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
4927 install_element(LINK_PARAMS_NODE
, &link_params_affinity_cmd
);
4928 install_element(LINK_PARAMS_NODE
, &link_params_affinity_mode_cmd
);
4929 install_element(LINK_PARAMS_NODE
, &no_link_params_affinity_mode_cmd
);
4930 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4932 /* setup EVPN MH elements */
4933 zebra_evpn_interface_init();