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 event
*thread
)
56 struct interface
*ifp
= EVENT_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 event_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
,
100 SPEED_UPDATE_SLEEP_TIME
, &zif
->speed_update
);
101 event_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
->link_nsid
= NS_UNKNOWN
;
142 zebra_if_nhg_dependents_init(zebra_if
);
144 zebra_ptm_if_init(zebra_if
);
146 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
148 rtadv_if_init(zebra_if
);
150 memset(&zebra_if
->neigh_mac
[0], 0, 6);
152 /* Initialize installed address chains tree. */
153 zebra_if
->ipv4_subnets
=
154 route_table_init_with_delegate(&zebra_if_table_delegate
);
156 ifp
->info
= zebra_if
;
159 * Some platforms are telling us that the interface is
160 * up and ready to go. When we check the speed we
161 * sometimes get the wrong value. Wait a couple
162 * of seconds and ask again. Hopefully it's all settled
165 zebra_if
->speed_update_count
= 0;
166 event_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
167 &zebra_if
->speed_update
);
168 event_ignore_late_timer(zebra_if
->speed_update
);
173 static void if_nhg_dependents_check_valid(struct nhg_hash_entry
*nhe
)
175 zebra_nhg_check_valid(nhe
);
178 static void if_down_nhg_dependents(const struct interface
*ifp
)
180 struct nhg_connected
*rb_node_dep
= NULL
;
181 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
183 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
)
184 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
187 static void if_nhg_dependents_release(const struct interface
*ifp
)
189 struct nhg_connected
*rb_node_dep
= NULL
;
190 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
192 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
) {
193 rb_node_dep
->nhe
->ifp
= NULL
; /* Null it out */
194 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
198 /* Called when interface is deleted. */
199 static int if_zebra_delete_hook(struct interface
*ifp
)
201 struct zebra_if
*zebra_if
;
204 zebra_if
= ifp
->info
;
206 /* If we set protodown, clear our reason now from the kernel */
207 if (ZEBRA_IF_IS_PROTODOWN(zebra_if
) && zebra_if
->protodown_rc
&&
208 !ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zebra_if
))
209 zebra_if_update_protodown_rc(ifp
, true,
210 (zebra_if
->protodown_rc
&
211 ~ZEBRA_PROTODOWN_ALL
));
213 /* Free installed address chains tree. */
214 if (zebra_if
->ipv4_subnets
)
215 route_table_finish(zebra_if
->ipv4_subnets
);
217 rtadv_if_fini(zebra_if
);
219 zebra_l2_bridge_if_cleanup(ifp
);
220 zebra_evpn_if_cleanup(zebra_if
);
221 zebra_evpn_mac_ifp_del(ifp
);
223 if_nhg_dependents_release(ifp
);
224 zebra_if_nhg_dependents_free(zebra_if
);
226 XFREE(MTYPE_ZIF_DESC
, zebra_if
->desc
);
228 EVENT_OFF(zebra_if
->speed_update
);
230 XFREE(MTYPE_ZINFO
, zebra_if
);
236 /* Build the table key */
237 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
240 p
->prefixlen
= IPV4_MAX_BITLEN
;
241 p
->u
.prefix4
.s_addr
= ifindex
;
244 /* Link an interface in a per NS interface tree */
245 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
248 struct route_node
*rn
;
250 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
253 if_build_key(ifp
->ifindex
, &p
);
254 rn
= route_node_get(ns
->if_table
, &p
);
256 ifp
= (struct interface
*)rn
->info
;
257 route_unlock_node(rn
); /* get */
267 /* Delete a VRF. This is called in vrf_terminate(). */
268 void if_unlink_per_ns(struct interface
*ifp
)
273 ifp
->node
->info
= NULL
;
274 route_unlock_node(ifp
->node
);
278 /* Look up an interface by identifier within a NS */
279 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
283 struct route_node
*rn
;
284 struct interface
*ifp
= NULL
;
286 if_build_key(ifindex
, &p
);
287 rn
= route_node_lookup(ns
->if_table
, &p
);
289 ifp
= (struct interface
*)rn
->info
;
290 route_unlock_node(rn
); /* lookup */
295 /* Look up an interface by name within a NS */
296 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
299 struct route_node
*rn
;
300 struct interface
*ifp
;
302 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
303 ifp
= (struct interface
*)rn
->info
;
304 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0) {
305 route_unlock_node(rn
);
313 struct interface
*if_lookup_by_index_per_nsid(ns_id_t ns_id
, uint32_t ifindex
)
315 struct zebra_ns
*zns
;
317 zns
= zebra_ns_lookup(ns_id
);
318 return zns
? if_lookup_by_index_per_ns(zns
, ifindex
) : NULL
;
321 const char *ifindex2ifname_per_ns(struct zebra_ns
*zns
, unsigned int ifindex
)
323 struct interface
*ifp
;
325 return ((ifp
= if_lookup_by_index_per_ns(zns
, ifindex
)) != NULL
)
330 /* Tie an interface address to its derived subnet list of addresses. */
331 int if_subnet_add(struct interface
*ifp
, struct connected
*ifc
)
333 struct route_node
*rn
;
334 struct zebra_if
*zebra_if
;
336 struct list
*addr_list
;
338 assert(ifp
&& ifp
->info
&& ifc
);
339 zebra_if
= ifp
->info
;
341 /* Get address derived subnet node and associated address list, while
343 address secondary attribute appropriately. */
344 cp
= *CONNECTED_PREFIX(ifc
);
346 rn
= route_node_get(zebra_if
->ipv4_subnets
, &cp
);
348 if ((addr_list
= rn
->info
))
349 SET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
351 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
352 rn
->info
= addr_list
= list_new();
356 /* Tie address at the tail of address list. */
357 listnode_add(addr_list
, ifc
);
359 /* Return list element count. */
360 return (addr_list
->count
);
363 /* Untie an interface address from its derived subnet list of addresses. */
364 int if_subnet_delete(struct interface
*ifp
, struct connected
*ifc
)
366 struct route_node
*rn
;
367 struct zebra_if
*zebra_if
;
368 struct list
*addr_list
;
371 assert(ifp
&& ifp
->info
&& ifc
);
372 zebra_if
= ifp
->info
;
374 cp
= *CONNECTED_PREFIX(ifc
);
377 /* Get address derived subnet node. */
378 rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
);
379 if (!(rn
&& rn
->info
)) {
380 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET
,
381 "Trying to remove an address from an unknown subnet. (please report this bug)");
384 route_unlock_node(rn
);
386 /* Untie address from subnet's address list. */
387 addr_list
= rn
->info
;
389 /* Deleting an address that is not registered is a bug.
390 * In any case, we shouldn't decrement the lock counter if the address
392 if (!listnode_lookup(addr_list
, ifc
)) {
394 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR
,
395 "Trying to remove an address from a subnet where it is not currently registered. (please report this bug)");
399 listnode_delete(addr_list
, ifc
);
400 route_unlock_node(rn
);
402 /* Return list element count, if not empty. */
403 if (addr_list
->count
) {
404 /* If deleted address is primary, mark subsequent one as such
406 if (!CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
408 (struct listnode
*)listhead(addr_list
));
409 zebra_interface_address_delete_update(ifp
, ifc
);
410 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
411 /* XXX: Linux kernel removes all the secondary addresses
413 * address is removed. We could try to work around that,
416 zebra_interface_address_add_update(ifp
, ifc
);
419 return addr_list
->count
;
422 /* Otherwise, free list and route node. */
423 list_delete(&addr_list
);
425 route_unlock_node(rn
);
430 /* if_flags_mangle: A place for hacks that require mangling
431 * or tweaking the interface flags.
433 * ******************** Solaris flags hacks **************************
435 * Solaris IFF_UP flag reflects only the primary interface as the
436 * routing socket only sends IFINFO for the primary interface. Hence
437 * ~IFF_UP does not per se imply all the logical interfaces are also
438 * down - which we only know of as addresses. Instead we must determine
439 * whether the interface really is up or not according to how many
440 * addresses are still attached. (Solaris always sends RTM_DELADDR if
441 * an interface, logical or not, goes ~IFF_UP).
443 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
444 * are addresses left in struct connected, not just the actual underlying
447 * We must hence remember the real state of IFF_UP, which we do in
448 * struct zebra_if.primary_state.
450 * Setting IFF_UP within zebra to administratively shutdown the
451 * interface will affect only the primary interface/address on Solaris.
452 ************************End Solaris flags hacks ***********************
454 static void if_flags_mangle(struct interface
*ifp
, uint64_t *newflags
)
459 /* Update the flags field of the ifp with the new flag set provided.
460 * Take whatever actions are required for any changes in flags we care
463 * newflags should be the raw value, as obtained from the OS.
465 void if_flags_update(struct interface
*ifp
, uint64_t newflags
)
467 if_flags_mangle(ifp
, &newflags
);
469 if (if_is_no_ptm_operative(ifp
)) {
470 /* operative -> inoperative? */
471 ifp
->flags
= newflags
;
472 if (!if_is_operative(ifp
))
475 /* inoperative -> operative? */
476 ifp
->flags
= newflags
;
477 if (if_is_operative(ifp
))
482 /* Wake up configured address if it is not in current kernel
484 void if_addr_wakeup(struct interface
*ifp
)
486 struct listnode
*node
, *nnode
;
487 struct connected
*ifc
;
489 enum zebra_dplane_result dplane_res
;
491 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, ifc
)) {
494 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)
495 && !CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)) {
497 if (p
->family
== AF_INET
) {
498 if (!if_is_up(ifp
)) {
499 /* Assume zebra is configured like
503 * ip addr 192.0.2.1/24
506 * As soon as zebra becomes first aware
507 * that gre0 exists in the
508 * kernel, it will set gre0 up and
509 * configure its addresses.
511 * (This may happen at startup when the
512 * interface already exists
513 * or during runtime when the interface
514 * is added to the kernel)
516 * XXX: IRDP code is calling here via
517 * if_add_update - this seems
519 * XXX: RUNNING is not a settable flag
521 * I (paulj) am aware of.
523 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
527 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
529 ZEBRA_DPLANE_REQUEST_FAILURE
) {
531 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
532 "Can't set interface's address: %s",
533 dplane_res2str(dplane_res
));
537 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
538 /* The address will be advertised to zebra
539 * clients when the notification
540 * from the kernel has been received.
541 * It will also be added to the interface's
542 * subnet list then. */
544 if (p
->family
== AF_INET6
) {
545 if (!if_is_up(ifp
)) {
546 /* See long comment above */
547 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
552 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
554 ZEBRA_DPLANE_REQUEST_FAILURE
) {
556 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
557 "Can't set interface's address: %s",
558 dplane_res2str(dplane_res
));
562 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
563 /* The address will be advertised to zebra
564 * clients when the notification
565 * from the kernel has been received. */
571 /* Handle interface addition */
572 void if_add_update(struct interface
*ifp
)
574 struct zebra_if
*if_data
;
575 struct zebra_ns
*zns
;
576 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
578 /* case interface populate before vrf enabled */
582 zns
= zebra_ns_lookup(NS_DEFAULT
);
583 if_link_per_ns(zns
, ifp
);
587 if (if_data
->multicast
== IF_ZEBRA_DATA_ON
)
588 if_set_flags(ifp
, IFF_MULTICAST
);
589 else if (if_data
->multicast
== IF_ZEBRA_DATA_OFF
)
590 if_unset_flags(ifp
, IFF_MULTICAST
);
592 zebra_ptm_if_set_ptm_state(ifp
, if_data
);
594 zebra_interface_add_update(ifp
);
596 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
597 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
599 if (if_data
->shutdown
== IF_ZEBRA_DATA_ON
) {
600 if (IS_ZEBRA_DEBUG_KERNEL
) {
602 "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.",
603 ifp
->name
, ifp
->vrf
->name
,
604 ifp
->vrf
->vrf_id
, ifp
->ifindex
);
612 if (IS_ZEBRA_DEBUG_KERNEL
)
614 "interface %s vrf %s(%u) index %d becomes active.",
615 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
619 if (IS_ZEBRA_DEBUG_KERNEL
)
620 zlog_debug("interface %s vrf %s(%u) index %d is added.",
621 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
626 /* Install connected routes corresponding to an interface. */
627 static void if_install_connected(struct interface
*ifp
)
629 struct listnode
*node
;
630 struct listnode
*next
;
631 struct connected
*ifc
;
633 if (ifp
->connected
) {
634 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
635 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
636 zebra_interface_address_add_update(ifp
, ifc
);
638 connected_up(ifp
, ifc
);
643 /* Uninstall connected routes corresponding to an interface. */
644 static void if_uninstall_connected(struct interface
*ifp
)
646 struct listnode
*node
;
647 struct listnode
*next
;
648 struct connected
*ifc
;
650 if (ifp
->connected
) {
651 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
652 zebra_interface_address_delete_update(ifp
, ifc
);
653 connected_down(ifp
, ifc
);
658 /* Uninstall and delete connected routes corresponding to an interface. */
659 /* TODO - Check why IPv4 handling here is different from install or if_down */
660 static void if_delete_connected(struct interface
*ifp
)
662 struct connected
*ifc
;
664 struct route_node
*rn
;
665 struct zebra_if
*zebra_if
;
666 struct listnode
*node
;
667 struct listnode
*last
= NULL
;
669 zebra_if
= ifp
->info
;
674 while ((node
= (last
? last
->next
: listhead(ifp
->connected
)))) {
675 ifc
= listgetdata(node
);
677 cp
= *CONNECTED_PREFIX(ifc
);
680 if (cp
.family
== AF_INET
681 && (rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
))) {
682 struct listnode
*anode
;
683 struct listnode
*next
;
684 struct listnode
*first
;
685 struct list
*addr_list
;
687 route_unlock_node(rn
);
688 addr_list
= (struct list
*)rn
->info
;
690 /* Remove addresses, secondaries first. */
691 first
= listhead(addr_list
);
693 for (anode
= first
->next
; anode
|| first
;
701 ifc
= listgetdata(anode
);
702 connected_down(ifp
, ifc
);
704 /* XXX: We have to send notifications
705 * here explicitly, because we destroy
706 * the ifc before receiving the
707 * notification about the address being
710 zebra_interface_address_delete_update(
713 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
714 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
716 /* Remove from subnet chain. */
717 list_delete_node(addr_list
, anode
);
718 route_unlock_node(rn
);
720 /* Remove from interface address list
721 * (unconditionally). */
722 if (!CHECK_FLAG(ifc
->conf
,
723 ZEBRA_IFC_CONFIGURED
)) {
724 listnode_delete(ifp
->connected
,
726 connected_free(&ifc
);
731 /* Free chain list and respective route node. */
732 list_delete(&addr_list
);
734 route_unlock_node(rn
);
735 } else if (cp
.family
== AF_INET6
) {
736 connected_down(ifp
, ifc
);
738 zebra_interface_address_delete_update(ifp
, ifc
);
740 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
741 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
743 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
746 listnode_delete(ifp
->connected
, ifc
);
747 connected_free(&ifc
);
755 /* Handle an interface delete event */
756 void if_delete_update(struct interface
**pifp
)
758 struct zebra_if
*zif
;
759 struct interface
*ifp
= *pifp
;
764 "interface %s vrf %s(%u) index %d is still up while being deleted.",
765 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
770 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
773 /* Mark interface as inactive */
774 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
776 if (IS_ZEBRA_DEBUG_KERNEL
)
777 zlog_debug("interface %s vrf %s(%u) index %d is now inactive.",
778 ifp
->name
, ifp
->vrf
->name
, ifp
->vrf
->vrf_id
,
781 /* Delete connected routes from the kernel. */
782 if_delete_connected(ifp
);
784 /* Send out notification on interface delete. */
785 zebra_interface_delete_update(ifp
);
787 if_unlink_per_ns(ifp
);
789 /* Update ifindex after distributing the delete message. This is in
790 case any client needs to have the old value of ifindex available
791 while processing the deletion. Each client daemon is responsible
792 for setting ifindex to IFINDEX_INTERNAL after processing the
793 interface deletion message. */
794 if_set_index(ifp
, IFINDEX_INTERNAL
);
797 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
798 * desired. This operation is not done for netns implementation to avoid
799 * collision with interface with the same name in the default vrf (can
800 * occur with this implementation whereas it is not possible with
803 if (ifp
->vrf
->vrf_id
&& !vrf_is_backend_netns())
804 if_handle_vrf_change(ifp
, VRF_DEFAULT
);
806 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
);
808 /* Reset some zebra interface params to default values. */
811 zebra_evpn_if_cleanup(zif
);
812 zif
->zif_type
= ZEBRA_IF_OTHER
;
813 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
814 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
815 memset(&zif
->brslave_info
, 0,
816 sizeof(struct zebra_l2info_brslave
));
817 zebra_evpn_mac_ifp_del(ifp
);
820 if (!ifp
->configured
) {
821 if (IS_ZEBRA_DEBUG_KERNEL
)
822 zlog_debug("interface %s is being deleted from the system",
828 /* VRF change for an interface */
829 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
833 old_vrf_id
= ifp
->vrf
->vrf_id
;
835 /* Uninstall connected routes. */
836 if_uninstall_connected(ifp
);
838 /* Delete any IPv4 neighbors created to implement RFC 5549 */
839 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
841 /* Delete all neighbor addresses learnt through IPv6 RA */
842 if_down_del_nbr_connected(ifp
);
844 /* Send out notification on interface VRF change. */
845 /* This is to issue an UPDATE or a DELETE, as appropriate. */
846 zebra_interface_vrf_update_del(ifp
, vrf_id
);
852 if_update_to_new_vrf(ifp
, vrf_id
);
854 /* Send out notification on interface VRF change. */
855 /* This is to issue an ADD, if needed. */
856 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
859 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
861 mac
[0] = address
->s6_addr
[8] ^ 0x02;
862 mac
[1] = address
->s6_addr
[9];
863 mac
[2] = address
->s6_addr
[10];
864 mac
[3] = address
->s6_addr
[13];
865 mac
[4] = address
->s6_addr
[14];
866 mac
[5] = address
->s6_addr
[15];
869 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
871 struct in6_addr
*address
,
874 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
875 struct zebra_if
*zif
= ifp
->info
;
876 char buf
[16] = "169.254.0.1";
877 struct in_addr ipv4_ll
;
880 inet_pton(AF_INET
, buf
, &ipv4_ll
);
882 ns_id
= zvrf
->zns
->ns_id
;
885 * Remove and re-add any existing neighbor entry for this address,
886 * since Netlink doesn't currently offer update message types.
888 kernel_neigh_update(0, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
, mac
, 6,
889 ns_id
, AF_INET
, true);
891 /* Add new neighbor entry.
893 * We force installation even if current neighbor entry is the same.
894 * Since this function is used to refresh our MAC entries after an
895 * interface flap, if we don't force in our custom entries with their
896 * state set to PERMANENT or REACHABLE then the kernel will attempt to
897 * resolve our leftover entries, fail, mark them unreachable and then
898 * they'll be useless to us.
901 kernel_neigh_update(add
, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
,
902 mac
, 6, ns_id
, AF_INET
, true);
904 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
907 * We need to note whether or not we originated a v6
908 * neighbor entry for this interface. So that when
909 * someone unwisely accidentally deletes this entry
910 * we can shove it back in.
912 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
913 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
915 zvrf
->neigh_updates
++;
918 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
919 struct in6_addr
*address
, int add
)
924 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
925 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
928 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface
*ifp
)
930 if (listhead(ifp
->nbr_connected
)) {
931 struct nbr_connected
*nbr_connected
;
932 struct listnode
*node
;
934 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
936 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
937 ifp
, &nbr_connected
->address
->u
.prefix6
, 1);
941 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
943 if (listhead(ifp
->nbr_connected
)) {
944 struct nbr_connected
*nbr_connected
;
945 struct listnode
*node
;
947 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
949 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
950 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
954 static void if_down_del_nbr_connected(struct interface
*ifp
)
956 struct nbr_connected
*nbr_connected
;
957 struct listnode
*node
, *nnode
;
959 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
961 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
962 nbr_connected_free(nbr_connected
);
966 void if_nhg_dependents_add(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
969 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
971 nhg_connected_tree_add_nhe(&zif
->nhg_dependents
, nhe
);
975 void if_nhg_dependents_del(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
978 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
980 nhg_connected_tree_del_nhe(&zif
->nhg_dependents
, nhe
);
984 unsigned int if_nhg_dependents_count(const struct interface
*ifp
)
987 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
989 return nhg_connected_tree_count(&zif
->nhg_dependents
);
996 bool if_nhg_dependents_is_empty(const struct interface
*ifp
)
999 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
1001 return nhg_connected_tree_is_empty(&zif
->nhg_dependents
);
1007 /* Interface is up. */
1008 void if_up(struct interface
*ifp
, bool install_connected
)
1010 struct zebra_if
*zif
;
1011 struct interface
*link_if
;
1015 frr_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
1017 /* Notify the protocol daemons. */
1018 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
1019 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
1020 "%s: interface %s hasn't passed ptm check",
1021 __func__
, ifp
->name
);
1024 zebra_interface_up_update(ifp
);
1026 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
1030 /* Install connected routes to the kernel. */
1031 if (install_connected
)
1032 if_install_connected(ifp
);
1034 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1035 * are checked to see if (remote) neighbor entries need to be installed
1036 * on them for ARP suppression.
1038 if (IS_ZEBRA_IF_VXLAN(ifp
))
1039 zebra_vxlan_if_up(ifp
);
1040 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1042 zebra_vxlan_svi_up(ifp
, link_if
);
1043 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1044 link_if
= zif
->link
;
1046 zebra_vxlan_svi_up(ifp
, link_if
);
1047 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1048 zebra_vxlan_macvlan_up(ifp
);
1051 if (zif
->es_info
.es
)
1052 zebra_evpn_es_if_oper_state_change(zif
, true /*up*/);
1054 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1055 zebra_evpn_mh_uplink_oper_update(zif
);
1057 event_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 0,
1058 &zif
->speed_update
);
1059 event_ignore_late_timer(zif
->speed_update
);
1062 /* Interface goes down. We have to manage different behavior of based
1064 void if_down(struct interface
*ifp
)
1066 struct zebra_if
*zif
;
1067 struct interface
*link_if
;
1071 frr_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
1073 if_down_nhg_dependents(ifp
);
1075 /* Handle interface down for specific types for EVPN. Non-VxLAN
1077 * are checked to see if (remote) neighbor entries need to be purged
1078 * for ARP suppression.
1080 if (IS_ZEBRA_IF_VXLAN(ifp
))
1081 zebra_vxlan_if_down(ifp
);
1082 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1084 zebra_vxlan_svi_down(ifp
, link_if
);
1085 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1086 link_if
= zif
->link
;
1088 zebra_vxlan_svi_down(ifp
, link_if
);
1089 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1090 zebra_vxlan_macvlan_down(ifp
);
1093 if (zif
->es_info
.es
)
1094 zebra_evpn_es_if_oper_state_change(zif
, false /*up*/);
1096 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1097 zebra_evpn_mh_uplink_oper_update(zif
);
1099 /* Notify to the protocol daemons. */
1100 zebra_interface_down_update(ifp
);
1102 /* Uninstall connected routes from the kernel. */
1103 if_uninstall_connected(ifp
);
1105 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
1107 /* Delete all neighbor addresses learnt through IPv6 RA */
1108 if_down_del_nbr_connected(ifp
);
1111 void if_refresh(struct interface
*ifp
)
1118 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1121 struct zebra_if
*zif
;
1123 if (IS_ZEBRA_IF_VETH(ifp
))
1125 zif
= (struct zebra_if
*)ifp
->info
;
1126 zif
->link_nsid
= ns_id
;
1127 zif
->link_ifindex
= link_ifindex
;
1128 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1133 * during initial link dump kernel does not order lower devices before
1134 * upper devices so we need to fixup link dependencies at the end of dump
1136 void zebra_if_update_all_links(struct zebra_ns
*zns
)
1138 struct route_node
*rn
;
1139 struct interface
*ifp
;
1140 struct zebra_if
*zif
;
1142 if (IS_ZEBRA_DEBUG_KERNEL
)
1143 zlog_info("fixup link dependencies");
1145 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1146 ifp
= (struct interface
*)rn
->info
;
1150 /* update bond-member to bond linkages */
1151 if ((IS_ZEBRA_IF_BOND_SLAVE(ifp
))
1152 && (zif
->bondslave_info
.bond_ifindex
!= IFINDEX_INTERNAL
)
1153 && !zif
->bondslave_info
.bond_if
) {
1154 if (IS_ZEBRA_DEBUG_EVPN_MH_ES
|| IS_ZEBRA_DEBUG_KERNEL
)
1155 zlog_debug("bond mbr %s map to bond %d",
1157 zif
->bondslave_info
.bond_ifindex
);
1158 zebra_l2_map_slave_to_bond(zif
, ifp
->vrf
->vrf_id
);
1161 /* update SVI linkages */
1162 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1163 zif
->link
= if_lookup_by_index_per_nsid(
1164 zif
->link_nsid
, zif
->link_ifindex
);
1165 if (IS_ZEBRA_DEBUG_KERNEL
)
1166 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1167 ifp
->name
, ifp
->ifindex
,
1168 zif
->link
?zif
->link
->name
:"unk",
1172 /* Update VLAN<=>SVI map */
1173 if (IS_ZEBRA_IF_VLAN(ifp
))
1174 zebra_evpn_acc_bd_svi_set(zif
, NULL
,
1175 !!if_is_operative(ifp
));
1179 static bool if_ignore_set_protodown(const struct interface
*ifp
, bool new_down
,
1180 uint32_t new_protodown_rc
)
1182 struct zebra_if
*zif
;
1183 bool old_down
, old_set_down
, old_unset_down
;
1187 /* Current state as we know it */
1188 old_down
= !!(ZEBRA_IF_IS_PROTODOWN(zif
));
1189 old_set_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1190 old_unset_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1192 if (new_protodown_rc
== zif
->protodown_rc
) {
1193 /* Early return if already down & reason bitfield matches */
1194 if (new_down
== old_down
) {
1195 if (IS_ZEBRA_DEBUG_KERNEL
)
1197 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already set (reason bitfield: old 0x%x new 0x%x)",
1198 new_down
? "on" : "off", ifp
->name
,
1199 ifp
->ifindex
, new_down
? "on" : "off",
1200 zif
->protodown_rc
, new_protodown_rc
);
1205 /* Early return if already set queued & reason bitfield matches
1207 if (new_down
&& old_set_down
) {
1208 if (IS_ZEBRA_DEBUG_KERNEL
)
1210 "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)",
1211 new_down
? "on" : "off", ifp
->name
,
1212 ifp
->ifindex
, new_down
? "on" : "off",
1213 zif
->protodown_rc
, new_protodown_rc
);
1218 /* Early return if already unset queued & reason bitfield
1220 if (!new_down
&& old_unset_down
) {
1221 if (IS_ZEBRA_DEBUG_KERNEL
)
1223 "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)",
1224 new_down
? "on" : "off", ifp
->name
,
1225 ifp
->ifindex
, new_down
? "on" : "off",
1226 zif
->protodown_rc
, new_protodown_rc
);
1235 int zebra_if_update_protodown_rc(struct interface
*ifp
, bool new_down
,
1236 uint32_t new_protodown_rc
)
1238 struct zebra_if
*zif
;
1242 /* Check if we already have this state or it's queued */
1243 if (if_ignore_set_protodown(ifp
, new_down
, new_protodown_rc
))
1247 "Setting protodown %s - interface %s (%u): reason bitfield change from 0x%x --> 0x%x",
1248 new_down
? "on" : "off", ifp
->name
, ifp
->ifindex
,
1249 zif
->protodown_rc
, new_protodown_rc
);
1251 zif
->protodown_rc
= new_protodown_rc
;
1254 SET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1256 SET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1259 dplane_intf_update(ifp
);
1261 zlog_warn("Protodown is not supported on this platform");
1266 int zebra_if_set_protodown(struct interface
*ifp
, bool new_down
,
1267 enum protodown_reasons new_reason
)
1269 struct zebra_if
*zif
;
1270 uint32_t new_protodown_rc
;
1275 new_protodown_rc
= zif
->protodown_rc
| new_reason
;
1277 new_protodown_rc
= zif
->protodown_rc
& ~new_reason
;
1279 return zebra_if_update_protodown_rc(ifp
, new_down
, new_protodown_rc
);
1283 * Handle an interface events based on info in a dplane context object.
1284 * This runs in the main pthread, using the info in the context object to
1285 * modify an interface.
1287 static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx
*ctx
,
1288 struct interface
*ifp
)
1291 const char *label
= NULL
;
1292 uint32_t metric
= METRIC_MAX
;
1293 const struct prefix
*addr
, *dest
= NULL
;
1294 enum dplane_op_e op
;
1296 op
= dplane_ctx_get_op(ctx
);
1297 addr
= dplane_ctx_get_intf_addr(ctx
);
1299 if (IS_ZEBRA_DEBUG_KERNEL
)
1300 zlog_debug("%s: %s: ifindex %s(%u), addr %pFX", __func__
,
1301 dplane_op2str(dplane_ctx_get_op(ctx
)), ifp
->name
,
1302 ifp
->ifindex
, addr
);
1304 /* Is there a peer or broadcast address? */
1305 dest
= dplane_ctx_get_intf_dest(ctx
);
1306 if (dest
->prefixlen
== 0)
1309 if (dplane_ctx_intf_is_connected(ctx
))
1310 SET_FLAG(flags
, ZEBRA_IFA_PEER
);
1313 if (dplane_ctx_intf_is_secondary(ctx
))
1314 SET_FLAG(flags
, ZEBRA_IFA_SECONDARY
);
1317 if (dplane_ctx_intf_has_label(ctx
))
1318 label
= dplane_ctx_get_intf_label(ctx
);
1320 if (label
&& strcmp(ifp
->name
, label
) == 0)
1323 metric
= dplane_ctx_get_intf_metric(ctx
);
1325 /* Register interface address to the interface. */
1326 if (addr
->family
== AF_INET
) {
1327 if (op
== DPLANE_OP_INTF_ADDR_ADD
)
1329 ifp
, flags
, &addr
->u
.prefix4
, addr
->prefixlen
,
1330 dest
? &dest
->u
.prefix4
: NULL
, label
, metric
);
1331 else if (CHECK_FLAG(flags
, ZEBRA_IFA_PEER
)) {
1332 /* Delete with a peer address */
1333 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1337 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1338 addr
->prefixlen
, NULL
);
1341 if (addr
->family
== AF_INET6
) {
1342 if (op
== DPLANE_OP_INTF_ADDR_ADD
) {
1343 connected_add_ipv6(ifp
, flags
, &addr
->u
.prefix6
,
1344 dest
? &dest
->u
.prefix6
: NULL
,
1345 addr
->prefixlen
, label
, metric
);
1347 connected_delete_ipv6(ifp
, &addr
->u
.prefix6
, NULL
,
1352 * Linux kernel does not send route delete on interface down/addr del
1353 * so we have to re-process routes it owns (i.e. kernel routes)
1355 if (op
!= DPLANE_OP_INTF_ADDR_ADD
)
1356 rib_update(RIB_UPDATE_KERNEL
);
1359 static void zebra_if_update_ctx(struct zebra_dplane_ctx
*ctx
,
1360 struct interface
*ifp
)
1362 enum zebra_dplane_result dp_res
;
1363 struct zebra_if
*zif
;
1367 dp_res
= dplane_ctx_get_status(ctx
);
1368 pd_reason_val
= dplane_ctx_get_intf_pd_reason_val(ctx
);
1369 down
= dplane_ctx_intf_is_protodown(ctx
);
1371 if (IS_ZEBRA_DEBUG_KERNEL
)
1372 zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason %d",
1373 __func__
, dplane_op2str(dplane_ctx_get_op(ctx
)),
1374 ifp
->name
, ifp
->ifindex
, down
? "on" : "off",
1379 if (IS_ZEBRA_DEBUG_KERNEL
)
1380 zlog_debug("%s: if %s(%u) zebra info pointer is NULL",
1381 __func__
, ifp
->name
, ifp
->ifindex
);
1385 if (dp_res
!= ZEBRA_DPLANE_REQUEST_SUCCESS
) {
1386 if (IS_ZEBRA_DEBUG_KERNEL
)
1387 zlog_debug("%s: if %s(%u) dplane update failed",
1388 __func__
, ifp
->name
, ifp
->ifindex
);
1392 /* Update our info */
1393 COND_FLAG(zif
->flags
, ZIF_FLAG_PROTODOWN
, down
);
1396 /* Clear our dplane flags */
1397 UNSET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1398 UNSET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1402 * Handle netconf change from a dplane context object; runs in the main
1403 * pthread so it can update zebra data structs.
1405 static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx
*ctx
,
1406 struct interface
*ifp
,
1409 struct zebra_if
*zif
= NULL
;
1411 enum dplane_netconf_status_e mpls
, mcast_on
, linkdown
;
1412 bool *mcast_set
, *linkdown_set
;
1414 afi
= dplane_ctx_get_afi(ctx
);
1415 mpls
= dplane_ctx_get_netconf_mpls(ctx
);
1416 linkdown
= dplane_ctx_get_netconf_linkdown(ctx
);
1417 mcast_on
= dplane_ctx_get_netconf_mcast(ctx
);
1419 if (ifindex
== DPLANE_NETCONF_IFINDEX_ALL
) {
1420 if (afi
== AFI_IP
) {
1421 mcast_set
= &zrouter
.all_mc_forwardingv4
;
1422 linkdown_set
= &zrouter
.all_linkdownv4
;
1424 mcast_set
= &zrouter
.all_mc_forwardingv6
;
1425 linkdown_set
= &zrouter
.all_linkdownv6
;
1427 } else if (ifindex
== DPLANE_NETCONF_IFINDEX_DEFAULT
) {
1428 if (afi
== AFI_IP
) {
1429 mcast_set
= &zrouter
.default_mc_forwardingv4
;
1430 linkdown_set
= &zrouter
.default_linkdownv4
;
1432 mcast_set
= &zrouter
.default_mc_forwardingv6
;
1433 linkdown_set
= &zrouter
.default_linkdownv6
;
1436 zif
= ifp
? ifp
->info
: NULL
;
1438 if (IS_ZEBRA_DEBUG_KERNEL
)
1440 "%s: if %s(%u) zebra info pointer is NULL",
1441 __func__
, ifp
? ifp
->name
: "(null)",
1442 ifp
? ifp
->ifindex
: ifindex
);
1445 if (afi
== AFI_IP
) {
1446 mcast_set
= &zif
->v4mcast_on
;
1447 linkdown_set
= &zif
->linkdown
;
1449 mcast_set
= &zif
->v6mcast_on
;
1450 linkdown_set
= &zif
->linkdownv6
;
1454 * mpls netconf data is neither v4 or v6 it's AF_MPLS!
1456 if (mpls
== DPLANE_NETCONF_STATUS_ENABLED
) {
1458 zebra_mpls_turned_on();
1459 } else if (mpls
== DPLANE_NETCONF_STATUS_DISABLED
)
1463 if (linkdown
== DPLANE_NETCONF_STATUS_ENABLED
)
1464 *linkdown_set
= true;
1465 else if (linkdown
== DPLANE_NETCONF_STATUS_DISABLED
)
1466 *linkdown_set
= false;
1468 if (mcast_on
== DPLANE_NETCONF_STATUS_ENABLED
)
1470 else if (mcast_on
== DPLANE_NETCONF_STATUS_DISABLED
)
1473 if (IS_ZEBRA_DEBUG_KERNEL
)
1475 "%s: afi: %d if %s, ifindex %d, mpls %s mc_forwarding: %s linkdown %s",
1476 __func__
, afi
, ifp
? ifp
->name
: "Global",
1477 ifp
? ifp
->ifindex
: ifindex
,
1478 (zif
? (zif
->mpls
? "ON" : "OFF") : "OFF"),
1479 (*mcast_set
? "ON" : "OFF"),
1480 (*linkdown_set
? "ON" : "OFF"));
1483 void zebra_if_dplane_result(struct zebra_dplane_ctx
*ctx
)
1485 struct zebra_ns
*zns
;
1486 struct interface
*ifp
;
1488 enum dplane_op_e op
;
1489 enum zebra_dplane_result dp_res
;
1492 ns_id
= dplane_ctx_get_ns_id(ctx
);
1493 dp_res
= dplane_ctx_get_status(ctx
);
1494 op
= dplane_ctx_get_op(ctx
);
1495 ifindex
= dplane_ctx_get_ifindex(ctx
);
1497 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
|| IS_ZEBRA_DEBUG_KERNEL
)
1498 zlog_debug("Intf dplane ctx %p, op %s, ifindex (%u), result %s",
1499 ctx
, dplane_op2str(op
), ifindex
,
1500 dplane_res2str(dp_res
));
1502 zns
= zebra_ns_lookup(ns_id
);
1504 /* No ns - deleted maybe? */
1505 if (IS_ZEBRA_DEBUG_KERNEL
)
1506 zlog_debug("%s: can't find zns id %u", __func__
, ns_id
);
1511 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
1513 if (op
!= DPLANE_OP_INTF_NETCONFIG
||
1514 (ifindex
!= -1 && ifindex
!= -2)) {
1515 if (IS_ZEBRA_DEBUG_KERNEL
)
1517 "%s: can't find ifp at nsid %u index %d",
1518 __func__
, ns_id
, ifindex
);
1525 case DPLANE_OP_INTF_ADDR_ADD
:
1526 case DPLANE_OP_INTF_ADDR_DEL
:
1527 zebra_if_addr_update_ctx(ctx
, ifp
);
1530 case DPLANE_OP_INTF_INSTALL
:
1531 case DPLANE_OP_INTF_UPDATE
:
1532 case DPLANE_OP_INTF_DELETE
:
1533 zebra_if_update_ctx(ctx
, ifp
);
1536 case DPLANE_OP_INTF_NETCONFIG
:
1537 zebra_if_netconf_update_ctx(ctx
, ifp
, ifindex
);
1540 case DPLANE_OP_ROUTE_INSTALL
:
1541 case DPLANE_OP_ROUTE_UPDATE
:
1542 case DPLANE_OP_ROUTE_DELETE
:
1543 case DPLANE_OP_NH_DELETE
:
1544 case DPLANE_OP_NH_INSTALL
:
1545 case DPLANE_OP_NH_UPDATE
:
1546 case DPLANE_OP_ROUTE_NOTIFY
:
1547 case DPLANE_OP_LSP_INSTALL
:
1548 case DPLANE_OP_LSP_UPDATE
:
1549 case DPLANE_OP_LSP_DELETE
:
1550 case DPLANE_OP_LSP_NOTIFY
:
1551 case DPLANE_OP_PW_INSTALL
:
1552 case DPLANE_OP_PW_UNINSTALL
:
1553 case DPLANE_OP_SYS_ROUTE_ADD
:
1554 case DPLANE_OP_SYS_ROUTE_DELETE
:
1555 case DPLANE_OP_ADDR_INSTALL
:
1556 case DPLANE_OP_ADDR_UNINSTALL
:
1557 case DPLANE_OP_MAC_INSTALL
:
1558 case DPLANE_OP_MAC_DELETE
:
1559 case DPLANE_OP_NEIGH_INSTALL
:
1560 case DPLANE_OP_NEIGH_UPDATE
:
1561 case DPLANE_OP_NEIGH_DELETE
:
1562 case DPLANE_OP_NEIGH_IP_INSTALL
:
1563 case DPLANE_OP_NEIGH_IP_DELETE
:
1564 case DPLANE_OP_VTEP_ADD
:
1565 case DPLANE_OP_VTEP_DELETE
:
1566 case DPLANE_OP_RULE_ADD
:
1567 case DPLANE_OP_RULE_DELETE
:
1568 case DPLANE_OP_RULE_UPDATE
:
1569 case DPLANE_OP_NEIGH_DISCOVER
:
1570 case DPLANE_OP_BR_PORT_UPDATE
:
1571 case DPLANE_OP_NONE
:
1572 case DPLANE_OP_IPTABLE_ADD
:
1573 case DPLANE_OP_IPTABLE_DELETE
:
1574 case DPLANE_OP_IPSET_ADD
:
1575 case DPLANE_OP_IPSET_DELETE
:
1576 case DPLANE_OP_IPSET_ENTRY_ADD
:
1577 case DPLANE_OP_IPSET_ENTRY_DELETE
:
1578 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
1579 case DPLANE_OP_GRE_SET
:
1580 case DPLANE_OP_TC_QDISC_INSTALL
:
1581 case DPLANE_OP_TC_QDISC_UNINSTALL
:
1582 case DPLANE_OP_TC_CLASS_ADD
:
1583 case DPLANE_OP_TC_CLASS_DELETE
:
1584 case DPLANE_OP_TC_CLASS_UPDATE
:
1585 case DPLANE_OP_TC_FILTER_ADD
:
1586 case DPLANE_OP_TC_FILTER_DELETE
:
1587 case DPLANE_OP_TC_FILTER_UPDATE
:
1588 break; /* should never hit here */
1592 /* Dump if address information to vty. */
1593 static void connected_dump_vty(struct vty
*vty
, json_object
*json
,
1594 struct connected
*connected
)
1597 json_object
*json_addr
= NULL
;
1599 /* Print interface address. */
1600 p
= connected
->address
;
1603 json_addr
= json_object_new_object();
1604 json_object_array_add(json
, json_addr
);
1605 json_object_string_addf(json_addr
, "address", "%pFX", p
);
1607 vty_out(vty
, " %s %pFX", prefix_family_str(p
), p
);
1610 /* If there is destination address, print it. */
1611 if (CONNECTED_PEER(connected
) && connected
->destination
) {
1613 json_object_string_addf(json_addr
, "peer", "%pFX",
1614 connected
->destination
);
1616 vty_out(vty
, " peer %pFX", connected
->destination
);
1621 json_object_boolean_add(
1622 json_addr
, "secondary",
1623 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
));
1624 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1625 vty_out(vty
, " secondary");
1628 json_object_boolean_add(
1629 json_addr
, "unnumbered",
1630 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
));
1631 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1632 vty_out(vty
, " unnumbered");
1634 if (connected
->label
) {
1636 json_object_string_add(json_addr
, "label",
1639 vty_out(vty
, " %s", connected
->label
);
1646 /* Dump interface neighbor address information to vty. */
1647 static void nbr_connected_dump_vty(struct vty
*vty
, json_object
*json
,
1648 struct nbr_connected
*connected
)
1651 char buf
[PREFIX2STR_BUFFER
];
1653 /* Print interface address. */
1654 p
= connected
->address
;
1656 json_array_string_add(json
, prefix2str(p
, buf
, sizeof(buf
)));
1658 vty_out(vty
, " %s %pFX\n", prefix_family_str(p
), p
);
1662 zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type
)
1664 switch (zif_slave_type
) {
1665 case ZEBRA_IF_SLAVE_BRIDGE
:
1667 case ZEBRA_IF_SLAVE_VRF
:
1669 case ZEBRA_IF_SLAVE_BOND
:
1671 case ZEBRA_IF_SLAVE_OTHER
:
1673 case ZEBRA_IF_SLAVE_NONE
:
1679 static const char *zebra_ziftype_2str(enum zebra_iftype zif_type
)
1682 case ZEBRA_IF_OTHER
:
1685 case ZEBRA_IF_BRIDGE
:
1691 case ZEBRA_IF_VXLAN
:
1703 case ZEBRA_IF_BOND_SLAVE
:
1704 return "bond_slave";
1706 case ZEBRA_IF_MACVLAN
:
1717 /* Interface's brief information print out to vty interface. */
1718 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1720 struct connected
*connected
;
1721 struct listnode
*node
;
1722 struct route_node
*rn
;
1723 struct zebra_if
*zebra_if
;
1725 struct interface
*ifp
;
1726 bool print_header
= true;
1728 FOR_ALL_INTERFACES (vrf
, ifp
) {
1729 bool first_pfx_printed
= false;
1732 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1733 "Status", "VRF", "Addresses");
1734 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1735 "------", "---", "---------");
1736 print_header
= false; /* We have at least 1 iface */
1738 zebra_if
= ifp
->info
;
1740 vty_out(vty
, "%-16s", ifp
->name
);
1743 vty_out(vty
, "%-8s", "up");
1745 vty_out(vty
, "%-8s", "down");
1747 vty_out(vty
, "%-16s", vrf
->name
);
1749 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1750 rn
= route_next(rn
)) {
1753 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1755 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1757 if (!CHECK_FLAG(connected
->flags
,
1758 ZEBRA_IFA_SECONDARY
)) {
1759 p
= connected
->address
;
1760 if (first_pfx_printed
) {
1761 /* padding to prepare row only
1763 vty_out(vty
, "%-40s", "");
1766 vty_out(vty
, "%pFX\n", p
);
1770 vty_out(vty
, "%pFX\n", p
);
1772 first_pfx_printed
= true;
1778 uint32_t v6_list_size
= 0;
1779 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1780 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1781 && (connected
->address
->family
== AF_INET6
))
1784 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1785 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1786 && !CHECK_FLAG(connected
->flags
,
1787 ZEBRA_IFA_SECONDARY
)
1788 && (connected
->address
->family
== AF_INET6
)) {
1789 p
= connected
->address
;
1790 /* Don't print link local pfx */
1791 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1792 if (first_pfx_printed
) {
1793 /* padding to prepare row only
1795 vty_out(vty
, "%-40s", "");
1796 if (v6_list_size
> 1)
1798 vty_out(vty
, "%pFX\n", p
);
1800 if (v6_list_size
> 1)
1802 vty_out(vty
, "%pFX\n", p
);
1804 first_pfx_printed
= true;
1809 if (!first_pfx_printed
)
1815 static void ifs_dump_brief_vty_json(json_object
*json
, struct vrf
*vrf
)
1817 struct connected
*connected
;
1818 struct listnode
*node
;
1819 struct interface
*ifp
;
1821 FOR_ALL_INTERFACES (vrf
, ifp
) {
1822 json_object
*json_if
;
1823 json_object
*json_addrs
;
1825 json_if
= json_object_new_object();
1826 json_object_object_add(json
, ifp
->name
, json_if
);
1828 json_object_string_add(json_if
, "status",
1829 if_is_up(ifp
) ? "up" : "down");
1830 json_object_string_add(json_if
, "vrfName", vrf
->name
);
1832 json_addrs
= json_object_new_array();
1833 json_object_object_add(json_if
, "addresses", json_addrs
);
1834 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1835 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1836 && !CHECK_FLAG(connected
->flags
,
1837 ZEBRA_IFA_SECONDARY
)
1838 && !(connected
->address
->family
== AF_INET6
1839 && IN6_IS_ADDR_LINKLOCAL(
1840 &connected
->address
->u
.prefix6
))) {
1841 char buf
[PREFIX2STR_BUFFER
];
1843 json_array_string_add(
1845 prefix2str(connected
->address
, buf
,
1852 const char *zebra_protodown_rc_str(uint32_t protodown_rc
, char *pd_buf
,
1853 uint32_t pd_buf_len
)
1858 strlcat(pd_buf
, "(", pd_buf_len
);
1860 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EXTERNAL
))
1861 strlcat(pd_buf
, "external,", pd_buf_len
);
1863 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY
))
1864 strlcat(pd_buf
, "startup-delay,", pd_buf_len
);
1866 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
))
1867 strlcat(pd_buf
, "uplinks-down,", pd_buf_len
);
1869 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_VRRP
))
1870 strlcat(pd_buf
, "vrrp,", pd_buf_len
);
1872 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_SHARP
))
1873 strlcat(pd_buf
, "sharp,", pd_buf_len
);
1875 len
= strnlen(pd_buf
, pd_buf_len
);
1877 /* Remove trailing comma */
1878 if (pd_buf
[len
- 1] == ',')
1879 pd_buf
[len
- 1] = '\0';
1881 strlcat(pd_buf
, ")", pd_buf_len
);
1886 static inline bool if_is_protodown_applicable(struct interface
*ifp
)
1888 if (IS_ZEBRA_IF_BOND(ifp
))
1894 static void zebra_vxlan_if_vni_dump_vty(struct vty
*vty
,
1895 struct zebra_vxlan_vni
*vni
)
1897 char str
[INET6_ADDRSTRLEN
];
1899 vty_out(vty
, " VxLAN Id %u", vni
->vni
);
1900 if (vni
->access_vlan
)
1901 vty_out(vty
, " Access VLAN Id %u\n", vni
->access_vlan
);
1903 if (vni
->mcast_grp
.s_addr
!= INADDR_ANY
)
1904 vty_out(vty
, " Mcast Group %s",
1905 inet_ntop(AF_INET
, &vni
->mcast_grp
, str
, sizeof(str
)));
1908 static void zebra_vxlan_if_vni_hash_dump_vty(struct hash_bucket
*bucket
,
1912 struct zebra_vxlan_vni
*vni
;
1914 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
1915 vty
= (struct vty
*)ctxt
;
1917 zebra_vxlan_if_vni_dump_vty(vty
, vni
);
1920 static void zebra_vxlan_if_dump_vty(struct vty
*vty
, struct zebra_if
*zebra_if
)
1922 struct zebra_l2info_vxlan
*vxlan_info
;
1923 struct zebra_vxlan_vni_info
*vni_info
;
1925 vxlan_info
= &zebra_if
->l2info
.vxl
;
1926 vni_info
= &vxlan_info
->vni_info
;
1928 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
1929 vty_out(vty
, " VTEP IP: %pI4", &vxlan_info
->vtep_ip
);
1931 if (vxlan_info
->ifindex_link
&& (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
1932 struct interface
*ifp
;
1934 ifp
= if_lookup_by_index_per_ns(
1935 zebra_ns_lookup(vxlan_info
->link_nsid
),
1936 vxlan_info
->ifindex_link
);
1937 vty_out(vty
, " Link Interface %s",
1938 ifp
== NULL
? "Unknown" : ifp
->name
);
1941 if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if
)) {
1942 zebra_vxlan_if_vni_dump_vty(vty
, &vni_info
->vni
);
1944 hash_iterate(vni_info
->vni_table
,
1945 zebra_vxlan_if_vni_hash_dump_vty
, vty
);
1951 /* Interface's information print out to vty interface. */
1952 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1954 struct connected
*connected
;
1955 struct nbr_connected
*nbr_connected
;
1956 struct listnode
*node
;
1957 struct route_node
*rn
;
1958 struct zebra_if
*zebra_if
;
1959 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
1961 zebra_if
= ifp
->info
;
1963 vty_out(vty
, "Interface %s is ", ifp
->name
);
1964 if (if_is_up(ifp
)) {
1965 vty_out(vty
, "up, line protocol ");
1967 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1968 if (if_is_running(ifp
))
1969 vty_out(vty
, "is up\n");
1971 vty_out(vty
, "is down\n");
1973 vty_out(vty
, "detection is disabled\n");
1976 vty_out(vty
, "down\n");
1979 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1980 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1981 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1982 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1984 zebra_ptm_show_status(vty
, NULL
, ifp
);
1986 vty_out(vty
, " vrf: %s\n", ifp
->vrf
->name
);
1989 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1991 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1993 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1994 vty_out(vty
, " pseudo interface\n");
1996 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1997 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
2001 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
2002 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
2003 if (ifp
->mtu6
!= ifp
->mtu
)
2004 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
2005 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
2008 vty_out(vty
, " MPLS enabled\n");
2010 if (zebra_if
->linkdown
)
2011 vty_out(vty
, " Ignore all v4 routes with linkdown\n");
2012 if (zebra_if
->linkdownv6
)
2013 vty_out(vty
, " Ignore all v6 routes with linkdown\n");
2015 if (zebra_if
->v4mcast_on
)
2016 vty_out(vty
, " v4 Multicast forwarding is on\n");
2017 if (zebra_if
->v6mcast_on
)
2018 vty_out(vty
, " v6 Multicast forwarding is on\n");
2020 /* Hardware address. */
2021 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
2022 if (ifp
->hw_addr_len
!= 0) {
2025 vty_out(vty
, " HWaddr: ");
2026 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
2027 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
2032 /* Bandwidth in Mbps */
2033 if (ifp
->bandwidth
!= 0) {
2034 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
2038 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
2042 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
2044 connected_dump_vty(vty
, NULL
, connected
);
2047 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
2048 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2049 && (connected
->address
->family
== AF_INET6
))
2050 connected_dump_vty(vty
, NULL
, connected
);
2053 vty_out(vty
, " Interface Type %s\n",
2054 zebra_ziftype_2str(zebra_if
->zif_type
));
2055 vty_out(vty
, " Interface Slave Type %s\n",
2056 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
2058 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
2059 vty_out(vty
, " Bridge VLAN-aware: %s\n",
2060 IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zebra_if
) ? "yes" : "no");
2061 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2062 struct zebra_l2info_vlan
*vlan_info
;
2064 vlan_info
= &zebra_if
->l2info
.vl
;
2065 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
2066 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2067 zebra_vxlan_if_dump_vty(vty
, zebra_if
);
2068 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2069 struct zebra_l2info_gre
*gre_info
;
2071 gre_info
= &zebra_if
->l2info
.gre
;
2072 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2073 vty_out(vty
, " VTEP IP: %pI4", &gre_info
->vtep_ip
);
2074 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2075 vty_out(vty
, " , remote %pI4",
2076 &gre_info
->vtep_ip_remote
);
2079 if (gre_info
->ifindex_link
&&
2080 (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2081 struct interface
*ifp
;
2083 ifp
= if_lookup_by_index_per_ns(
2084 zebra_ns_lookup(gre_info
->link_nsid
),
2085 gre_info
->ifindex_link
);
2086 vty_out(vty
, " Link Interface %s\n",
2087 ifp
== NULL
? "Unknown" :
2092 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2093 struct zebra_l2info_brslave
*br_slave
;
2095 br_slave
= &zebra_if
->brslave_info
;
2096 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2097 if (br_slave
->br_if
)
2098 vty_out(vty
, " Master interface: %s\n",
2099 br_slave
->br_if
->name
);
2101 vty_out(vty
, " Master ifindex: %u\n",
2102 br_slave
->bridge_ifindex
);
2106 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2107 struct zebra_l2info_bondslave
*bond_slave
;
2109 bond_slave
= &zebra_if
->bondslave_info
;
2110 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2111 if (bond_slave
->bond_if
)
2112 vty_out(vty
, " Master interface: %s\n",
2113 bond_slave
->bond_if
->name
);
2115 vty_out(vty
, " Master ifindex: %u\n",
2116 bond_slave
->bond_ifindex
);
2120 if (zebra_if
->flags
& ZIF_FLAG_LACP_BYPASS
)
2121 vty_out(vty
, " LACP bypass: on\n");
2123 zebra_evpn_if_es_print(vty
, NULL
, zebra_if
);
2124 vty_out(vty
, " protodown: %s %s\n",
2125 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off",
2126 if_is_protodown_applicable(ifp
) ? "" : "(n/a)");
2127 if (zebra_if
->protodown_rc
)
2128 vty_out(vty
, " protodown reasons: %s\n",
2129 zebra_protodown_rc_str(zebra_if
->protodown_rc
, pd_buf
,
2132 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2134 vty_out(vty
, " Parent interface: %s\n", zebra_if
->link
->name
);
2136 vty_out(vty
, " Parent ifindex: %d\n", zebra_if
->link_ifindex
);
2139 if (HAS_LINK_PARAMS(ifp
)) {
2141 struct if_link_params
*iflp
= ifp
->link_params
;
2142 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
2143 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2144 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
2145 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2146 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
2148 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2150 " Maximum Reservable Bandwidth %g (Byte/s)\n",
2152 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2154 " Unreserved Bandwidth per Class Type in Byte/s:\n");
2155 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
2157 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
2158 i
, iflp
->unrsv_bw
[i
], i
+ 1,
2159 iflp
->unrsv_bw
[i
+ 1]);
2162 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2163 vty_out(vty
, " Administrative Group:%u\n",
2165 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2166 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
2168 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2169 vty_out(vty
, " Min: %u (micro-sec.)",
2171 vty_out(vty
, " Max: %u (micro-sec.)",
2176 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2178 " Link Delay Variation %u (micro-sec.)\n",
2180 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2181 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
2183 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2184 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
2186 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2187 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
2189 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2190 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
2192 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2193 vty_out(vty
, " Neighbor ASBR IP: %pI4 AS: %u \n",
2194 &iflp
->rmt_ip
, iflp
->rmt_as
);
2197 hook_call(zebra_if_extra_info
, vty
, ifp
);
2199 if (listhead(ifp
->nbr_connected
))
2200 vty_out(vty
, " Neighbor address(s):\n");
2201 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
2202 nbr_connected_dump_vty(vty
, NULL
, nbr_connected
);
2204 #ifdef HAVE_PROC_NET_DEV
2205 /* Statistics print out using proc file system. */
2207 " %lu input packets (%lu multicast), %lu bytes, %lu dropped\n",
2208 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
2209 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
2212 " %lu input errors, %lu length, %lu overrun, %lu CRC, %lu frame\n",
2213 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
2214 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
2215 ifp
->stats
.rx_frame_errors
);
2217 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
2218 ifp
->stats
.rx_missed_errors
);
2220 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
2221 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
2222 ifp
->stats
.tx_dropped
);
2225 " %lu output errors, %lu aborted, %lu carrier, %lu fifo, %lu heartbeat\n",
2226 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
2227 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
2228 ifp
->stats
.tx_heartbeat_errors
);
2230 vty_out(vty
, " %lu window, %lu collisions\n",
2231 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
2232 #endif /* HAVE_PROC_NET_DEV */
2234 #ifdef HAVE_NET_RT_IFLIST
2235 /* Statistics print out using sysctl (). */
2237 " input packets %llu, bytes %llu, dropped %llu, multicast packets %llu\n",
2238 (unsigned long long)ifp
->stats
.ifi_ipackets
,
2239 (unsigned long long)ifp
->stats
.ifi_ibytes
,
2240 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
2241 (unsigned long long)ifp
->stats
.ifi_imcasts
);
2243 vty_out(vty
, " input errors %llu\n",
2244 (unsigned long long)ifp
->stats
.ifi_ierrors
);
2247 " output packets %llu, bytes %llu, multicast packets %llu\n",
2248 (unsigned long long)ifp
->stats
.ifi_opackets
,
2249 (unsigned long long)ifp
->stats
.ifi_obytes
,
2250 (unsigned long long)ifp
->stats
.ifi_omcasts
);
2252 vty_out(vty
, " output errors %llu\n",
2253 (unsigned long long)ifp
->stats
.ifi_oerrors
);
2255 vty_out(vty
, " collisions %llu\n",
2256 (unsigned long long)ifp
->stats
.ifi_collisions
);
2257 #endif /* HAVE_NET_RT_IFLIST */
2260 static void zebra_vxlan_if_vni_dump_vty_json(json_object
*json_if
,
2261 struct zebra_vxlan_vni
*vni
)
2263 json_object_int_add(json_if
, "vxlanId", vni
->vni
);
2264 if (vni
->access_vlan
)
2265 json_object_int_add(json_if
, "accessVlanId", vni
->access_vlan
);
2266 if (vni
->mcast_grp
.s_addr
!= INADDR_ANY
)
2267 json_object_string_addf(json_if
, "mcastGroup", "%pI4",
2271 static void zebra_vxlan_if_vni_hash_dump_vty_json(struct hash_bucket
*bucket
,
2274 json_object
*json_if
;
2275 struct zebra_vxlan_vni
*vni
;
2277 vni
= (struct zebra_vxlan_vni
*)bucket
->data
;
2278 json_if
= (json_object
*)ctxt
;
2280 zebra_vxlan_if_vni_dump_vty_json(json_if
, vni
);
2283 static void zebra_vxlan_if_dump_vty_json(json_object
*json_if
,
2284 struct zebra_if
*zebra_if
)
2286 struct zebra_l2info_vxlan
*vxlan_info
;
2287 struct zebra_vxlan_vni_info
*vni_info
;
2289 vxlan_info
= &zebra_if
->l2info
.vxl
;
2290 vni_info
= &vxlan_info
->vni_info
;
2292 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
2293 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2294 &vxlan_info
->vtep_ip
);
2296 if (vxlan_info
->ifindex_link
&& (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
2297 struct interface
*ifp
;
2299 ifp
= if_lookup_by_index_per_ns(
2300 zebra_ns_lookup(vxlan_info
->link_nsid
),
2301 vxlan_info
->ifindex_link
);
2302 json_object_string_add(json_if
, "linkInterface",
2303 ifp
== NULL
? "Unknown" : ifp
->name
);
2305 if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if
)) {
2306 zebra_vxlan_if_vni_dump_vty_json(json_if
, &vni_info
->vni
);
2308 hash_iterate(vni_info
->vni_table
,
2309 zebra_vxlan_if_vni_hash_dump_vty_json
, json_if
);
2313 static void if_dump_vty_json(struct vty
*vty
, struct interface
*ifp
,
2316 struct connected
*connected
;
2317 struct nbr_connected
*nbr_connected
;
2318 struct listnode
*node
;
2319 struct route_node
*rn
;
2320 struct zebra_if
*zebra_if
;
2321 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
2323 json_object
*json_if
;
2324 json_object
*json_addrs
;
2326 json_if
= json_object_new_object();
2327 json_object_object_add(json
, ifp
->name
, json_if
);
2329 if (if_is_up(ifp
)) {
2330 json_object_string_add(json_if
, "administrativeStatus", "up");
2332 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
2333 json_object_string_add(json_if
, "operationalStatus",
2334 if_is_running(ifp
) ? "up"
2336 json_object_boolean_add(json_if
, "linkDetection", true);
2338 json_object_boolean_add(json_if
, "linkDetection",
2342 json_object_string_add(json_if
, "administrativeStatus", "down");
2345 zebra_if
= ifp
->info
;
2347 json_object_int_add(json_if
, "linkUps", zebra_if
->up_count
);
2348 json_object_int_add(json_if
, "linkDowns", zebra_if
->down_count
);
2349 if (zebra_if
->up_last
[0])
2350 json_object_string_add(json_if
, "lastLinkUp",
2352 if (zebra_if
->down_last
[0])
2353 json_object_string_add(json_if
, "lastLinkDown",
2354 zebra_if
->down_last
);
2356 zebra_ptm_show_status(vty
, json
, ifp
);
2358 json_object_string_add(json_if
, "vrfName", ifp
->vrf
->name
);
2361 json_object_string_add(json_if
, "description", ifp
->desc
);
2363 json_object_string_add(json_if
, "OsDescription",
2366 json_object_boolean_add(json_if
, "mplsEnabled", zebra_if
->mpls
);
2367 json_object_boolean_add(json_if
, "linkDown", zebra_if
->linkdown
);
2368 json_object_boolean_add(json_if
, "linkDownV6", zebra_if
->linkdownv6
);
2369 json_object_boolean_add(json_if
, "mcForwardingV4",
2370 zebra_if
->v4mcast_on
);
2371 json_object_boolean_add(json_if
, "mcForwardingV6",
2372 zebra_if
->v6mcast_on
);
2374 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
2375 json_object_boolean_add(json_if
, "pseudoInterface", true);
2377 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2378 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2382 json_object_boolean_add(json_if
, "pseudoInterface", false);
2383 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2384 json_object_int_add(json_if
, "metric", ifp
->metric
);
2385 json_object_int_add(json_if
, "mtu", ifp
->mtu
);
2386 if (ifp
->mtu6
!= ifp
->mtu
)
2387 json_object_int_add(json_if
, "mtu6", ifp
->mtu6
);
2388 json_object_int_add(json_if
, "speed", ifp
->speed
);
2389 json_object_string_add(json_if
, "flags", if_flag_dump(ifp
->flags
));
2391 /* Hardware address. */
2392 json_object_string_add(json_if
, "type", if_link_type_str(ifp
->ll_type
));
2393 if (ifp
->hw_addr_len
!= 0) {
2397 for (int i
= 0; i
< ifp
->hw_addr_len
; i
++) {
2398 snprintf(buf
, sizeof(buf
), "%s%02x", i
== 0 ? "" : ":",
2400 strlcat(hwbuf
, buf
, sizeof(hwbuf
));
2402 json_object_string_add(json_if
, "hardwareAddress", hwbuf
);
2405 /* Bandwidth in Mbps */
2406 if (ifp
->bandwidth
!= 0)
2407 json_object_int_add(json_if
, "bandwidth", ifp
->bandwidth
);
2411 json_addrs
= json_object_new_array();
2412 json_object_object_add(json_if
, "ipAddresses", json_addrs
);
2414 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
2418 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
2420 connected_dump_vty(vty
, json_addrs
, connected
);
2423 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
2424 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2425 && (connected
->address
->family
== AF_INET6
))
2426 connected_dump_vty(vty
, json_addrs
, connected
);
2429 json_object_string_add(json_if
, "interfaceType",
2430 zebra_ziftype_2str(zebra_if
->zif_type
));
2431 json_object_string_add(
2432 json_if
, "interfaceSlaveType",
2433 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
2435 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
2436 struct zebra_l2info_bridge
*bridge_info
;
2438 bridge_info
= &zebra_if
->l2info
.br
;
2439 json_object_boolean_add(json_if
, "bridgeVlanAware",
2440 bridge_info
->bridge
.vlan_aware
);
2441 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2442 struct zebra_l2info_vlan
*vlan_info
;
2444 vlan_info
= &zebra_if
->l2info
.vl
;
2445 json_object_int_add(json_if
, "vlanId", vlan_info
->vid
);
2446 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2447 zebra_vxlan_if_dump_vty_json(json_if
, zebra_if
);
2449 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2450 struct zebra_l2info_gre
*gre_info
;
2452 gre_info
= &zebra_if
->l2info
.gre
;
2453 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2454 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2455 &gre_info
->vtep_ip
);
2456 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2457 json_object_string_addf(
2458 json_if
, "vtepRemoteIp", "%pI4",
2459 &gre_info
->vtep_ip_remote
);
2461 if (gre_info
->ifindex_link
2462 && (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2463 struct interface
*ifp
;
2465 ifp
= if_lookup_by_index_per_ns(
2466 zebra_ns_lookup(gre_info
->link_nsid
),
2467 gre_info
->ifindex_link
);
2468 json_object_string_add(json_if
, "linkInterface",
2469 ifp
== NULL
? "Unknown"
2474 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2475 struct zebra_l2info_brslave
*br_slave
;
2477 br_slave
= &zebra_if
->brslave_info
;
2478 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2479 if (br_slave
->br_if
)
2480 json_object_string_add(json_if
,
2482 br_slave
->br_if
->name
);
2484 json_object_int_add(json_if
, "masterIfindex",
2485 br_slave
->bridge_ifindex
);
2489 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2490 struct zebra_l2info_bondslave
*bond_slave
;
2492 bond_slave
= &zebra_if
->bondslave_info
;
2493 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2494 if (bond_slave
->bond_if
)
2495 json_object_string_add(
2496 json_if
, "masterInterface",
2497 bond_slave
->bond_if
->name
);
2499 json_object_int_add(json_if
, "masterIfindex",
2500 bond_slave
->bond_ifindex
);
2504 json_object_boolean_add(
2505 json_if
, "lacpBypass",
2506 CHECK_FLAG(zebra_if
->flags
, ZIF_FLAG_LACP_BYPASS
));
2508 zebra_evpn_if_es_print(vty
, json_if
, zebra_if
);
2510 if (if_is_protodown_applicable(ifp
)) {
2511 json_object_string_add(
2512 json_if
, "protodown",
2513 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off");
2514 if (zebra_if
->protodown_rc
)
2515 json_object_string_add(
2516 json_if
, "protodownReason",
2517 zebra_protodown_rc_str(zebra_if
->protodown_rc
,
2518 pd_buf
, sizeof(pd_buf
)));
2521 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2523 json_object_string_add(json_if
, "parentInterface",
2524 zebra_if
->link
->name
);
2526 json_object_int_add(json_if
, "parentIfindex",
2527 zebra_if
->link_ifindex
);
2530 if (HAS_LINK_PARAMS(ifp
)) {
2531 struct if_link_params
*iflp
= ifp
->link_params
;
2532 json_object
*json_te
;
2534 json_te
= json_object_new_object();
2535 json_object_object_add(
2536 json_if
, "trafficEngineeringLinkParameters", json_te
);
2538 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2539 json_object_int_add(json_te
, "teMetric",
2541 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2542 json_object_double_add(json_te
, "maximumBandwidth",
2544 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2545 json_object_double_add(json_te
,
2546 "maximumReservableBandwidth",
2548 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2549 json_object
*json_bws
;
2551 json_bws
= json_object_new_object();
2552 json_object_object_add(json_te
, "unreservedBandwidth",
2554 for (unsigned int i
= 0; i
< MAX_CLASS_TYPE
; ++i
) {
2557 snprintf(buf_ct
, sizeof(buf_ct
), "classType%u",
2559 json_object_double_add(json_bws
, buf_ct
,
2564 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2565 json_object_int_add(json_te
, "administrativeGroup",
2567 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2568 json_object_int_add(json_te
, "linkDelayAverage",
2570 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2571 json_object_int_add(json_te
, "linkDelayMinimum",
2573 json_object_int_add(json_te
, "linkDelayMaximum",
2577 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2578 json_object_int_add(json_te
, "linkDelayVariation",
2580 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2581 json_object_double_add(json_te
, "linkPacketLoss",
2583 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2584 json_object_double_add(json_te
, "availableBandwidth",
2586 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2587 json_object_double_add(json_te
, "residualBandwidth",
2589 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2590 json_object_double_add(json_te
, "utilizedBandwidth",
2592 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2593 json_object_string_addf(json_te
, "neighborAsbrIp",
2594 "%pI4", &iflp
->rmt_ip
);
2595 json_object_int_add(json_te
, "neighborAsbrAs", iflp
->rmt_as
);
2598 if (listhead(ifp
->nbr_connected
)) {
2599 json_object
*json_nbr_addrs
;
2601 json_nbr_addrs
= json_object_new_array();
2602 json_object_object_add(json_if
, "neighborIpAddresses",
2605 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
2607 nbr_connected_dump_vty(vty
, json_nbr_addrs
,
2611 #ifdef HAVE_PROC_NET_DEV
2612 json_object_int_add(json_if
, "inputPackets", stats
.rx_packets
);
2613 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.rx_bytes
);
2614 json_object_int_add(json_if
, "inputDropped", ifp
->stats
.rx_dropped
);
2615 json_object_int_add(json_if
, "inputMulticastPackets",
2616 ifp
->stats
.rx_multicast
);
2617 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.rx_errors
);
2618 json_object_int_add(json_if
, "inputLengthErrors",
2619 ifp
->stats
.rx_length_errors
);
2620 json_object_int_add(json_if
, "inputOverrunErrors",
2621 ifp
->stats
.rx_over_errors
);
2622 json_object_int_add(json_if
, "inputCrcErrors",
2623 ifp
->stats
.rx_crc_errors
);
2624 json_object_int_add(json_if
, "inputFrameErrors",
2625 ifp
->stats
.rx_frame_errors
);
2626 json_object_int_add(json_if
, "inputFifoErrors",
2627 ifp
->stats
.rx_fifo_errors
);
2628 json_object_int_add(json_if
, "inputMissedErrors",
2629 ifp
->stats
.rx_missed_errors
);
2630 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.tx_packets
);
2631 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.tx_bytes
);
2632 json_object_int_add(json_if
, "outputDroppedPackets",
2633 ifp
->stats
.tx_dropped
);
2634 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.tx_errors
);
2635 json_object_int_add(json_if
, "outputAbortedErrors",
2636 ifp
->stats
.tx_aborted_errors
);
2637 json_object_int_add(json_if
, "outputCarrierErrors",
2638 ifp
->stats
.tx_carrier_errors
);
2639 json_object_int_add(json_if
, "outputFifoErrors",
2640 ifp
->stats
.tx_fifo_errors
);
2641 json_object_int_add(json_if
, "outputHeartbeatErrors",
2642 ifp
->stats
.tx_heartbeat_errors
);
2643 json_object_int_add(json_if
, "outputWindowErrors",
2644 ifp
->stats
.tx_window_errors
);
2645 json_object_int_add(json_if
, "collisions", ifp
->stats
.collisions
);
2646 #endif /* HAVE_PROC_NET_DEV */
2648 #ifdef HAVE_NET_RT_IFLIST
2649 json_object_int_add(json_if
, "inputPackets", ifp
->stats
.ifi_ipackets
);
2650 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.ifi_ibytes
);
2651 json_object_int_add(json_if
, "inputDropd", ifp
->stats
.ifi_iqdrops
);
2652 json_object_int_add(json_if
, "inputMulticastPackets",
2653 ifp
->stats
.ifi_imcasts
);
2654 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.ifi_ierrors
);
2655 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.ifi_opackets
);
2656 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.ifi_obytes
);
2657 json_object_int_add(json_if
, "outputMulticastPackets",
2658 ifp
->stats
.ifi_omcasts
);
2659 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.ifi_oerrors
);
2660 json_object_int_add(json_if
, "collisions", ifp
->stats
.ifi_collisions
);
2661 #endif /* HAVE_NET_RT_IFLIST */
2664 static void interface_update_stats(void)
2666 #ifdef HAVE_PROC_NET_DEV
2667 /* If system has interface statistics via proc file system, update
2669 ifstat_update_proc();
2670 #endif /* HAVE_PROC_NET_DEV */
2671 #ifdef HAVE_NET_RT_IFLIST
2672 ifstat_update_sysctl();
2673 #endif /* HAVE_NET_RT_IFLIST */
2676 #include "zebra/interface_clippy.c"
2677 /* Show all interfaces to vty. */
2678 DEFPY(show_interface
, show_interface_cmd
,
2679 "show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
2681 "Interface status and configuration\n"
2683 "Interface status and configuration summary\n"
2687 struct interface
*ifp
;
2688 json_object
*json
= NULL
;
2690 interface_update_stats();
2692 vrf
= vrf_lookup_by_name(vrf_name
);
2695 vty_out(vty
, "{}\n");
2697 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2702 json
= json_object_new_object();
2706 ifs_dump_brief_vty_json(json
, vrf
);
2708 ifs_dump_brief_vty(vty
, vrf
);
2710 FOR_ALL_INTERFACES (vrf
, ifp
) {
2712 if_dump_vty_json(vty
, ifp
, json
);
2714 if_dump_vty(vty
, ifp
);
2719 vty_json(vty
, json
);
2725 /* Show all interfaces to vty. */
2726 DEFPY (show_interface_vrf_all
,
2727 show_interface_vrf_all_cmd
,
2728 "show interface [vrf all] [brief$brief] [json$uj]",
2730 "Interface status and configuration\n"
2731 VRF_ALL_CMD_HELP_STR
2732 "Interface status and configuration summary\n"
2736 struct interface
*ifp
;
2737 json_object
*json
= NULL
;
2739 interface_update_stats();
2742 json
= json_object_new_object();
2744 /* All interface print. */
2745 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2748 ifs_dump_brief_vty_json(json
, vrf
);
2750 ifs_dump_brief_vty(vty
, vrf
);
2752 FOR_ALL_INTERFACES (vrf
, ifp
) {
2754 if_dump_vty_json(vty
, ifp
, json
);
2756 if_dump_vty(vty
, ifp
);
2762 vty_json(vty
, json
);
2767 /* Show specified interface to vty. */
2769 DEFPY (show_interface_name_vrf
,
2770 show_interface_name_vrf_cmd
,
2771 "show interface IFNAME$ifname vrf NAME$vrf_name [json$uj]",
2773 "Interface status and configuration\n"
2778 struct interface
*ifp
;
2780 json_object
*json
= NULL
;
2782 interface_update_stats();
2784 vrf
= vrf_lookup_by_name(vrf_name
);
2787 vty_out(vty
, "{}\n");
2789 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2793 ifp
= if_lookup_by_name_vrf(ifname
, vrf
);
2796 vty_out(vty
, "{}\n");
2798 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2803 json
= json_object_new_object();
2806 if_dump_vty_json(vty
, ifp
, json
);
2808 if_dump_vty(vty
, ifp
);
2811 vty_json(vty
, json
);
2816 /* Show specified interface to vty. */
2817 DEFPY (show_interface_name_vrf_all
,
2818 show_interface_name_vrf_all_cmd
,
2819 "show interface IFNAME$ifname [vrf all] [json$uj]",
2821 "Interface status and configuration\n"
2823 VRF_ALL_CMD_HELP_STR
2826 struct interface
*ifp
= NULL
;
2827 struct interface
*ifptmp
;
2829 json_object
*json
= NULL
;
2832 interface_update_stats();
2834 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2835 ifptmp
= if_lookup_by_name_vrf(ifname
, vrf
);
2839 if (!vrf_is_backend_netns())
2846 vty_out(vty
, "{}\n");
2848 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2853 vty_out(vty
, "{}\n");
2856 "%% There are multiple interfaces with name %s\n",
2858 vty_out(vty
, "%% You must specify the VRF name\n");
2864 json
= json_object_new_object();
2867 if_dump_vty_json(vty
, ifp
, json
);
2869 if_dump_vty(vty
, ifp
);
2872 vty_json(vty
, json
);
2877 static void if_show_description(struct vty
*vty
, struct vrf
*vrf
)
2879 struct interface
*ifp
;
2881 vty_out(vty
, "Interface Status Protocol Description\n");
2882 FOR_ALL_INTERFACES (vrf
, ifp
) {
2884 struct zebra_if
*zif
;
2889 len
= vty_out(vty
, "%s", ifp
->name
);
2890 vty_out(vty
, "%*s", (16 - len
), " ");
2892 if (if_is_up(ifp
)) {
2893 vty_out(vty
, "up ");
2894 if (CHECK_FLAG(ifp
->status
,
2895 ZEBRA_INTERFACE_LINKDETECTION
)) {
2896 if (if_is_running(ifp
))
2897 vty_out(vty
, "up ");
2899 vty_out(vty
, "down ");
2901 vty_out(vty
, "unknown ");
2904 vty_out(vty
, "down down ");
2909 vty_out(vty
, "%s", ifp
->desc
);
2912 if (zif
&& zif
->desc
) {
2913 vty_out(vty
, "%s%s",
2924 DEFUN (show_interface_desc
,
2925 show_interface_desc_cmd
,
2926 "show interface description vrf NAME",
2928 "Interface status and configuration\n"
2929 "Interface description\n"
2934 vrf
= vrf_lookup_by_name(argv
[4]->arg
);
2936 vty_out(vty
, "%% VRF %s not found\n", argv
[4]->arg
);
2940 if_show_description(vty
, vrf
);
2946 DEFUN (show_interface_desc_vrf_all
,
2947 show_interface_desc_vrf_all_cmd
,
2948 "show interface description [vrf all]",
2950 "Interface status and configuration\n"
2951 "Interface description\n"
2952 VRF_ALL_CMD_HELP_STR
)
2956 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2957 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
2958 vty_out(vty
, "\n\tVRF %s(%u)\n\n", VRF_LOGNAME(vrf
),
2960 if_show_description(vty
, vrf
);
2966 int if_multicast_set(struct interface
*ifp
)
2968 struct zebra_if
*if_data
;
2970 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2971 if (if_set_flags(ifp
, IFF_MULTICAST
) < 0) {
2972 zlog_debug("Can't set multicast flag on interface %s",
2978 if_data
= ifp
->info
;
2979 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
2987 "Set multicast flag to interface\n")
2989 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2991 struct zebra_if
*if_data
;
2993 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2994 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
2996 vty_out(vty
, "Can't set multicast flag\n");
2997 return CMD_WARNING_CONFIG_FAILED
;
3001 if_data
= ifp
->info
;
3002 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
3012 "Set mpls to be on for the interface\n")
3014 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3015 struct zebra_if
*if_data
= ifp
->info
;
3018 dplane_intf_mpls_modify_state(ifp
, false);
3019 if_data
->mpls
= IF_ZEBRA_DATA_UNSPEC
;
3021 dplane_intf_mpls_modify_state(ifp
, true);
3022 if_data
->mpls
= IF_ZEBRA_DATA_ON
;
3028 int if_multicast_unset(struct interface
*ifp
)
3030 struct zebra_if
*if_data
;
3032 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3033 if (if_unset_flags(ifp
, IFF_MULTICAST
) < 0) {
3034 zlog_debug("Can't unset multicast flag on interface %s",
3040 if_data
= ifp
->info
;
3041 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
3046 DEFUN (no_multicast
,
3050 "Unset multicast flag to interface\n")
3052 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3054 struct zebra_if
*if_data
;
3056 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3057 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
3059 vty_out(vty
, "Can't unset multicast flag\n");
3060 return CMD_WARNING_CONFIG_FAILED
;
3064 if_data
= ifp
->info
;
3065 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
3070 int if_linkdetect(struct interface
*ifp
, bool detect
)
3072 int if_was_operative
;
3074 if_was_operative
= if_is_no_ptm_operative(ifp
);
3076 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3078 /* When linkdetection is enabled, if might come down */
3079 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
3082 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3084 /* Interface may come up after disabling link detection */
3085 if (if_is_operative(ifp
) && !if_was_operative
)
3088 /* FIXME: Will defer status change forwarding if interface
3089 does not come down! */
3093 DEFUN(linkdetect
, linkdetect_cmd
, "link-detect",
3094 "Enable link detection on interface\n")
3096 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3098 if_linkdetect(ifp
, true);
3104 DEFUN (no_linkdetect
,
3108 "Disable link detection on interface\n")
3110 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3112 if_linkdetect(ifp
, false);
3117 int if_shutdown(struct interface
*ifp
)
3119 struct zebra_if
*if_data
;
3121 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3122 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3124 if (if_unset_flags(ifp
, IFF_UP
) < 0) {
3125 zlog_debug("Can't shutdown interface %s", ifp
->name
);
3130 if_data
= ifp
->info
;
3131 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3139 "Shutdown the selected interface\n")
3141 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3143 struct zebra_if
*if_data
;
3145 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3146 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3148 ret
= if_unset_flags(ifp
, IFF_UP
);
3150 vty_out(vty
, "Can't shutdown interface\n");
3151 return CMD_WARNING_CONFIG_FAILED
;
3155 if_data
= ifp
->info
;
3156 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3161 int if_no_shutdown(struct interface
*ifp
)
3163 struct zebra_if
*if_data
;
3165 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3166 if (if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
) < 0) {
3167 zlog_debug("Can't up interface %s", ifp
->name
);
3172 /* Some addresses (in particular, IPv6 addresses on Linux) get
3173 * removed when the interface goes down. They need to be
3176 if_addr_wakeup(ifp
);
3179 if_data
= ifp
->info
;
3180 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3185 DEFUN (no_shutdown_if
,
3189 "Shutdown the selected interface\n")
3191 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3193 struct zebra_if
*if_data
;
3195 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3196 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3198 vty_out(vty
, "Can't up interface\n");
3199 return CMD_WARNING_CONFIG_FAILED
;
3203 /* Some addresses (in particular, IPv6 addresses on Linux) get
3204 * removed when the interface goes down. They need to be
3207 if_addr_wakeup(ifp
);
3210 if_data
= ifp
->info
;
3211 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3216 DEFUN (bandwidth_if
,
3218 "bandwidth (1-100000)",
3219 "Set bandwidth informational parameter\n"
3220 "Bandwidth in megabits\n")
3223 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3224 unsigned int bandwidth
;
3226 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
3228 /* bandwidth range is <1-100000> */
3229 if (bandwidth
< 1 || bandwidth
> 100000) {
3230 vty_out(vty
, "Bandwidth is invalid\n");
3231 return CMD_WARNING_CONFIG_FAILED
;
3234 ifp
->bandwidth
= bandwidth
;
3236 /* force protocols to recalculate routes due to cost change */
3237 if (if_is_operative(ifp
))
3238 zebra_interface_up_update(ifp
);
3243 DEFUN (no_bandwidth_if
,
3244 no_bandwidth_if_cmd
,
3245 "no bandwidth [(1-100000)]",
3247 "Set bandwidth informational parameter\n"
3248 "Bandwidth in megabits\n")
3250 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3254 /* force protocols to recalculate routes due to cost change */
3255 if (if_is_operative(ifp
))
3256 zebra_interface_up_update(ifp
);
3262 struct cmd_node link_params_node
= {
3263 .name
= "link-params",
3264 .node
= LINK_PARAMS_NODE
,
3265 .parent_node
= INTERFACE_NODE
,
3266 .prompt
= "%s(config-link-params)# ",
3270 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
3271 uint32_t type
, uint32_t 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
);
3284 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
3285 uint32_t type
, float value
)
3288 /* Update field as needed */
3289 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
3291 SET_PARAM(ifp
->link_params
, type
);
3293 /* force protocols to update LINK STATE due to parameters change
3295 if (if_is_operative(ifp
))
3296 zebra_interface_parameters_update(ifp
);
3300 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
3302 if (ifp
->link_params
== NULL
)
3306 UNSET_PARAM(ifp
->link_params
, type
);
3308 /* force protocols to update LINK STATE due to parameters change */
3309 if (if_is_operative(ifp
))
3310 zebra_interface_parameters_update(ifp
);
3313 DEFUN_NOSH (link_params
,
3318 /* vty->qobj_index stays the same @ interface pointer */
3319 vty
->node
= LINK_PARAMS_NODE
;
3324 DEFUN_NOSH (exit_link_params
,
3325 exit_link_params_cmd
,
3327 "Exit from Link Params configuration mode\n")
3329 if (vty
->node
== LINK_PARAMS_NODE
)
3330 vty
->node
= INTERFACE_NODE
;
3334 /* Specific Traffic Engineering parameters commands */
3335 DEFUN (link_params_enable
,
3336 link_params_enable_cmd
,
3338 "Activate link parameters on this interface\n")
3340 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3342 /* This command could be issue at startup, when activate MPLS TE */
3343 /* on a new interface or after a ON / OFF / ON toggle */
3344 /* In all case, TE parameters are reset to their default factory */
3345 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3347 "Link-params: enable TE link parameters on interface %s",
3350 if (!if_link_params_get(ifp
))
3351 if_link_params_enable(ifp
);
3353 /* force protocols to update LINK STATE due to parameters change */
3354 if (if_is_operative(ifp
))
3355 zebra_interface_parameters_update(ifp
);
3360 DEFUN (no_link_params_enable
,
3361 no_link_params_enable_cmd
,
3364 "Disable link parameters on this interface\n")
3366 char xpath
[XPATH_MAXLEN
];
3368 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3370 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3371 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
3374 if_link_params_free(ifp
);
3377 xpath
, sizeof(xpath
),
3378 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
3380 if (yang_dnode_exists(running_config
->dnode
, xpath
))
3381 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
3383 ret
= nb_cli_apply_changes(vty
, NULL
);
3385 if (ret
!= CMD_SUCCESS
)
3388 /* force protocols to update LINK STATE due to parameters change */
3389 if (if_is_operative(ifp
))
3390 zebra_interface_parameters_update(ifp
);
3395 /* STANDARD TE metrics */
3396 DEFUN (link_params_metric
,
3397 link_params_metric_cmd
,
3398 "metric (0-4294967295)",
3399 "Link metric for MPLS-TE purpose\n"
3400 "Metric value in decimal\n")
3403 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3404 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3407 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3410 iflp
= if_link_params_enable(ifp
);
3412 /* Update TE metric if needed */
3413 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
3418 DEFUN (no_link_params_metric
,
3419 no_link_params_metric_cmd
,
3422 "Disable Link Metric on this interface\n")
3424 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3426 /* Unset TE Metric */
3427 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
3432 DEFUN (link_params_maxbw
,
3433 link_params_maxbw_cmd
,
3435 "Maximum bandwidth that can be used\n"
3436 "Bytes/second (IEEE floating point format)\n")
3438 int idx_bandwidth
= 1;
3439 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3440 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3444 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3445 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
3446 safe_strerror(errno
));
3447 return CMD_WARNING_CONFIG_FAILED
;
3450 /* Check that Maximum bandwidth is not lower than other bandwidth
3452 if (iflp
&& ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0]) ||
3453 (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2]) ||
3454 (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4]) ||
3455 (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6]) ||
3456 (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
) ||
3457 (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
))) {
3459 "Maximum Bandwidth could not be lower than others bandwidth\n");
3460 return CMD_WARNING_CONFIG_FAILED
;
3464 iflp
= if_link_params_enable(ifp
);
3466 /* Update Maximum Bandwidth if needed */
3467 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
3472 DEFUN (link_params_max_rsv_bw
,
3473 link_params_max_rsv_bw_cmd
,
3474 "max-rsv-bw BANDWIDTH",
3475 "Maximum bandwidth that may be reserved\n"
3476 "Bytes/second (IEEE floating point format)\n")
3478 int idx_bandwidth
= 1;
3479 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3480 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3483 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3484 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
3485 safe_strerror(errno
));
3486 return CMD_WARNING_CONFIG_FAILED
;
3489 /* Check that bandwidth is not greater than maximum bandwidth parameter
3491 if (iflp
&& bw
> iflp
->max_bw
) {
3493 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3495 return CMD_WARNING_CONFIG_FAILED
;
3499 iflp
= if_link_params_enable(ifp
);
3501 /* Update Maximum Reservable Bandwidth if needed */
3502 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
3507 DEFUN (link_params_unrsv_bw
,
3508 link_params_unrsv_bw_cmd
,
3509 "unrsv-bw (0-7) BANDWIDTH",
3510 "Unreserved bandwidth at each priority level\n"
3512 "Bytes/second (IEEE floating point format)\n")
3515 int idx_bandwidth
= 2;
3516 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3517 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3521 /* We don't have to consider about range check here. */
3522 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
3523 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3524 safe_strerror(errno
));
3525 return CMD_WARNING_CONFIG_FAILED
;
3528 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3529 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3530 safe_strerror(errno
));
3531 return CMD_WARNING_CONFIG_FAILED
;
3534 /* Check that bandwidth is not greater than maximum bandwidth parameter
3536 if (iflp
&& bw
> iflp
->max_bw
) {
3538 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3540 return CMD_WARNING_CONFIG_FAILED
;
3544 iflp
= if_link_params_enable(ifp
);
3546 /* Update Unreserved Bandwidth if needed */
3547 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
3553 DEFPY_YANG(link_params_admin_grp
, link_params_admin_grp_cmd
,
3554 "admin-grp BITPATTERN",
3555 "Administrative group membership\n"
3556 "32-bit Hexadecimal value (e.g. 0xa1)\n")
3558 char xpath
[XPATH_MAXLEN
];
3559 int idx_bitpattern
= 1;
3560 unsigned long value
;
3563 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3566 xpath
, sizeof(xpath
),
3567 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
3569 if (yang_dnode_exists(running_config
->dnode
, xpath
)) {
3571 "cannot use the admin-grp command when affinity is set\n");
3572 return CMD_WARNING_CONFIG_FAILED
;
3575 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
3576 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
3577 safe_strerror(errno
));
3578 return CMD_WARNING_CONFIG_FAILED
;
3581 if (value
> 0xFFFFFFFF) {
3582 vty_out(vty
, "value must be not be superior to 0xFFFFFFFF\n");
3583 return CMD_WARNING_CONFIG_FAILED
;
3586 snprintf(value_str
, sizeof(value_str
), "%ld", value
);
3588 nb_cli_enqueue_change(
3589 vty
, "./frr-zebra:zebra/link-params/legacy-admin-group",
3590 NB_OP_MODIFY
, value_str
);
3592 return nb_cli_apply_changes(vty
, NULL
);
3595 DEFPY_YANG(no_link_params_admin_grp
, no_link_params_admin_grp_cmd
,
3597 NO_STR
"Disable Administrative group membership on this interface\n")
3599 nb_cli_enqueue_change(
3600 vty
, "./frr-zebra:zebra/link-params/legacy-admin-group",
3601 NB_OP_DESTROY
, NULL
);
3603 return nb_cli_apply_changes(vty
, NULL
);
3606 /* RFC5392 & RFC5316: INTER-AS */
3607 DEFUN (link_params_inter_as
,
3608 link_params_inter_as_cmd
,
3609 "neighbor A.B.C.D as (1-4294967295)",
3610 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
3611 "Remote IP address in dot decimal A.B.C.D\n"
3612 "Remote AS number\n"
3613 "AS number in the range <1-4294967295>\n")
3618 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3619 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3620 struct in_addr addr
;
3623 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
3624 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
3625 return CMD_WARNING_CONFIG_FAILED
;
3629 iflp
= if_link_params_enable(ifp
);
3631 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3633 /* Update Remote IP and Remote AS fields if needed */
3634 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
3635 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
3638 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
3639 SET_PARAM(iflp
, LP_RMT_AS
);
3641 /* force protocols to update LINK STATE due to parameters change
3643 if (if_is_operative(ifp
))
3644 zebra_interface_parameters_update(ifp
);
3649 DEFUN (no_link_params_inter_as
,
3650 no_link_params_inter_as_cmd
,
3653 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
3655 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3656 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3661 /* Reset Remote IP and AS neighbor */
3663 iflp
->rmt_ip
.s_addr
= 0;
3664 UNSET_PARAM(iflp
, LP_RMT_AS
);
3666 /* force protocols to update LINK STATE due to parameters change */
3667 if (if_is_operative(ifp
))
3668 zebra_interface_parameters_update(ifp
);
3673 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
3674 * draft-ietf-isis-metric-extensions-07.txt */
3675 DEFUN (link_params_delay
,
3676 link_params_delay_cmd
,
3677 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
3678 "Unidirectional Average Link Delay\n"
3679 "Average delay in micro-second as decimal (0...16777215)\n"
3681 "Minimum delay in micro-second as decimal (0...16777215)\n"
3683 "Maximum delay in micro-second as decimal (0...16777215)\n")
3685 /* Get and Check new delay values */
3686 uint32_t delay
= 0, low
= 0, high
= 0;
3687 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
3689 low
= strtoul(argv
[3]->arg
, NULL
, 10);
3690 high
= strtoul(argv
[5]->arg
, NULL
, 10);
3693 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3694 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3699 * Check new delay value against old Min and Max delays if set
3701 * RFC 7471 Section 4.2.7:
3702 * It is possible for min delay and max delay to be
3705 * Therefore, it is also allowed that the average
3706 * delay be equal to the min delay or max delay.
3708 if (iflp
&& IS_PARAM_SET(iflp
, LP_MM_DELAY
) &&
3709 (delay
< iflp
->min_delay
|| delay
> iflp
->max_delay
)) {
3711 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3712 iflp
->min_delay
, iflp
->max_delay
);
3713 return CMD_WARNING_CONFIG_FAILED
;
3717 iflp
= if_link_params_enable(ifp
);
3719 /* Update delay if value is not set or change */
3720 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
3721 iflp
->av_delay
= delay
;
3722 SET_PARAM(iflp
, LP_DELAY
);
3725 /* Unset Min and Max delays if already set */
3726 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3727 iflp
->min_delay
= 0;
3728 iflp
->max_delay
= 0;
3729 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3734 * Check new delays value coherency. See above note
3735 * regarding average delay equal to min/max allowed
3737 if (delay
< low
|| delay
> high
) {
3739 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3741 return CMD_WARNING_CONFIG_FAILED
;
3745 iflp
= if_link_params_enable(ifp
);
3747 /* Update Delays if needed */
3748 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
3749 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
3750 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
3751 || iflp
->max_delay
!= high
) {
3752 iflp
->av_delay
= delay
;
3753 SET_PARAM(iflp
, LP_DELAY
);
3754 iflp
->min_delay
= low
;
3755 iflp
->max_delay
= high
;
3756 SET_PARAM(iflp
, LP_MM_DELAY
);
3761 /* force protocols to update LINK STATE due to parameters change */
3762 if (update
== 1 && if_is_operative(ifp
))
3763 zebra_interface_parameters_update(ifp
);
3768 DEFUN (no_link_params_delay
,
3769 no_link_params_delay_cmd
,
3772 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
3774 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3775 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3782 UNSET_PARAM(iflp
, LP_DELAY
);
3783 iflp
->min_delay
= 0;
3784 iflp
->max_delay
= 0;
3785 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3787 /* force protocols to update LINK STATE due to parameters change */
3788 if (if_is_operative(ifp
))
3789 zebra_interface_parameters_update(ifp
);
3794 DEFUN (link_params_delay_var
,
3795 link_params_delay_var_cmd
,
3796 "delay-variation (0-16777215)",
3797 "Unidirectional Link Delay Variation\n"
3798 "delay variation in micro-second as decimal (0...16777215)\n")
3801 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3802 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3805 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3808 iflp
= if_link_params_enable(ifp
);
3810 /* Update Delay Variation if needed */
3811 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
3816 DEFUN (no_link_params_delay_var
,
3817 no_link_params_delay_var_cmd
,
3818 "no delay-variation",
3820 "Disable Unidirectional Delay Variation on this interface\n")
3822 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3824 /* Unset Delay Variation */
3825 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
3830 DEFUN (link_params_pkt_loss
,
3831 link_params_pkt_loss_cmd
,
3832 "packet-loss PERCENTAGE",
3833 "Unidirectional Link Packet Loss\n"
3834 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
3836 int idx_percentage
= 1;
3837 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3838 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3841 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
3842 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
3843 safe_strerror(errno
));
3844 return CMD_WARNING_CONFIG_FAILED
;
3847 if (fval
> MAX_PKT_LOSS
)
3848 fval
= MAX_PKT_LOSS
;
3851 iflp
= if_link_params_enable(ifp
);
3853 /* Update Packet Loss if needed */
3854 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
3859 DEFUN (no_link_params_pkt_loss
,
3860 no_link_params_pkt_loss_cmd
,
3863 "Disable Unidirectional Link Packet Loss on this interface\n")
3865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3867 /* Unset Packet Loss */
3868 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
3873 DEFUN (link_params_res_bw
,
3874 link_params_res_bw_cmd
,
3876 "Unidirectional Residual Bandwidth\n"
3877 "Bytes/second (IEEE floating point format)\n")
3879 int idx_bandwidth
= 1;
3880 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3881 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3884 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3885 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
3886 safe_strerror(errno
));
3887 return CMD_WARNING_CONFIG_FAILED
;
3890 /* Check that bandwidth is not greater than maximum bandwidth parameter
3892 if (iflp
&& bw
> iflp
->max_bw
) {
3894 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3896 return CMD_WARNING_CONFIG_FAILED
;
3900 iflp
= if_link_params_enable(ifp
);
3902 /* Update Residual Bandwidth if needed */
3903 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
3908 DEFUN (no_link_params_res_bw
,
3909 no_link_params_res_bw_cmd
,
3912 "Disable Unidirectional Residual Bandwidth on this interface\n")
3914 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3916 /* Unset Residual Bandwidth */
3917 link_param_cmd_unset(ifp
, LP_RES_BW
);
3922 DEFUN (link_params_ava_bw
,
3923 link_params_ava_bw_cmd
,
3925 "Unidirectional Available Bandwidth\n"
3926 "Bytes/second (IEEE floating point format)\n")
3928 int idx_bandwidth
= 1;
3929 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3930 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3933 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3934 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
3935 safe_strerror(errno
));
3936 return CMD_WARNING_CONFIG_FAILED
;
3939 /* Check that bandwidth is not greater than maximum bandwidth parameter
3941 if (iflp
&& bw
> iflp
->max_bw
) {
3943 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3945 return CMD_WARNING_CONFIG_FAILED
;
3949 iflp
= if_link_params_enable(ifp
);
3951 /* Update Residual Bandwidth if needed */
3952 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
3957 DEFUN (no_link_params_ava_bw
,
3958 no_link_params_ava_bw_cmd
,
3961 "Disable Unidirectional Available Bandwidth on this interface\n")
3963 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3965 /* Unset Available Bandwidth */
3966 link_param_cmd_unset(ifp
, LP_AVA_BW
);
3971 DEFUN (link_params_use_bw
,
3972 link_params_use_bw_cmd
,
3974 "Unidirectional Utilised Bandwidth\n"
3975 "Bytes/second (IEEE floating point format)\n")
3977 int idx_bandwidth
= 1;
3978 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3979 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3982 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3983 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
3984 safe_strerror(errno
));
3985 return CMD_WARNING_CONFIG_FAILED
;
3988 /* Check that bandwidth is not greater than maximum bandwidth parameter
3990 if (iflp
&& bw
> iflp
->max_bw
) {
3992 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3994 return CMD_WARNING_CONFIG_FAILED
;
3998 iflp
= if_link_params_enable(ifp
);
4000 /* Update Utilized Bandwidth if needed */
4001 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
4006 DEFUN (no_link_params_use_bw
,
4007 no_link_params_use_bw_cmd
,
4010 "Disable Unidirectional Utilised Bandwidth on this interface\n")
4012 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4014 /* Unset Utilised Bandwidth */
4015 link_param_cmd_unset(ifp
, LP_USE_BW
);
4020 static int ag_change(struct vty
*vty
, int argc
, struct cmd_token
**argv
,
4021 const char *xpath
, bool no
, int start_idx
)
4023 for (int i
= start_idx
; i
< argc
; i
++)
4024 nb_cli_enqueue_change(vty
, xpath
,
4025 no
? NB_OP_DESTROY
: NB_OP_CREATE
,
4027 return nb_cli_apply_changes(vty
, NULL
);
4032 * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity
4034 DEFPY_YANG(link_params_affinity
, link_params_affinity_cmd
,
4035 "[no] affinity NAME...",
4037 "Interface affinities\n"
4040 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4041 char xpath
[XPATH_MAXLEN
];
4044 xpath
, sizeof(xpath
),
4045 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/legacy-admin-group",
4047 if (yang_dnode_exists(running_config
->dnode
, xpath
)) {
4049 "cannot use the affinity command when admin-grp is set\n");
4050 return CMD_WARNING_CONFIG_FAILED
;
4053 return ag_change(vty
, argc
, argv
,
4054 "./frr-zebra:zebra/link-params/affinities/affinity",
4061 * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity-mode
4063 DEFPY_YANG(link_params_affinity_mode
, link_params_affinity_mode_cmd
,
4064 "affinity-mode <standard|extended|both>$affmode",
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
, affmode
);
4074 return nb_cli_apply_changes(vty
, NULL
);
4077 DEFPY_YANG(no_link_params_affinity_mode
, no_link_params_affinity_mode_cmd
,
4078 "no affinity-mode [<standard|extended|both>]",
4080 "Interface affinity mode\n"
4081 "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
4082 "Extended Admin-Group only RFC7308\n"
4083 "Standard and extended Admin-Group format\n")
4085 const char *xpath
= "./frr-zebra:zebra/link-params/affinity-mode";
4087 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "standard");
4089 return nb_cli_apply_changes(vty
, NULL
);
4092 static int ag_iter_cb(const struct lyd_node
*dnode
, void *arg
)
4094 struct vty
*vty
= (struct vty
*)arg
;
4096 vty_out(vty
, " %s", yang_dnode_get_string(dnode
, "."));
4097 return YANG_ITER_CONTINUE
;
4100 void cli_show_legacy_admin_group(struct vty
*vty
, const struct lyd_node
*dnode
,
4103 if (!yang_dnode_exists(dnode
, "./legacy-admin-group"))
4106 vty_out(vty
, " admin-group 0x%x\n",
4107 yang_dnode_get_uint32(dnode
, "./legacy-admin-group"));
4110 void cli_show_affinity_mode(struct vty
*vty
, const struct lyd_node
*dnode
,
4113 enum affinity_mode affinity_mode
= yang_dnode_get_enum(dnode
, ".");
4115 if (affinity_mode
== AFFINITY_MODE_STANDARD
)
4116 vty_out(vty
, " affinity-mode standard\n");
4117 else if (affinity_mode
== AFFINITY_MODE_BOTH
)
4118 vty_out(vty
, " affinity-mode both\n");
4121 void cli_show_affinity(struct vty
*vty
, const struct lyd_node
*dnode
,
4124 if (!yang_dnode_exists(dnode
, "./affinity"))
4127 vty_out(vty
, " affinity");
4128 yang_dnode_iterate(ag_iter_cb
, vty
, dnode
, "./affinity");
4132 int if_ip_address_install(struct interface
*ifp
, struct prefix
*prefix
,
4133 const char *label
, struct prefix
*pp
)
4135 struct zebra_if
*if_data
;
4136 struct prefix_ipv4 lp
;
4137 struct prefix_ipv4
*p
;
4138 struct connected
*ifc
;
4139 enum zebra_dplane_result dplane_res
;
4141 if_data
= ifp
->info
;
4143 lp
.family
= prefix
->family
;
4144 lp
.prefix
= prefix
->u
.prefix4
;
4145 lp
.prefixlen
= prefix
->prefixlen
;
4146 apply_mask_ipv4(&lp
);
4148 ifc
= connected_check_ptp(ifp
, &lp
, pp
? pp
: NULL
);
4150 ifc
= connected_new();
4154 p
= prefix_ipv4_new();
4156 ifc
->address
= (struct prefix
*)p
;
4159 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
4160 p
= prefix_ipv4_new();
4161 *p
= *(struct prefix_ipv4
*)pp
;
4162 ifc
->destination
= (struct prefix
*)p
;
4167 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4169 /* Add to linked list. */
4170 listnode_add(ifp
->connected
, ifc
);
4173 /* This address is configured from zebra. */
4174 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4175 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4177 /* In case of this route need to install kernel. */
4178 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4179 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4180 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4181 /* Some system need to up the interface to set IP address. */
4182 if (!if_is_up(ifp
)) {
4183 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4187 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4188 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4190 "dplane can't set interface IP address: %s.",
4191 dplane_res2str(dplane_res
));
4195 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4196 /* The address will be advertised to zebra clients when the
4198 * from the kernel has been received.
4199 * It will also be added to the subnet chain list, then. */
4205 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
4206 const char *addr_str
, const char *peer_str
,
4209 struct zebra_if
*if_data
;
4210 struct prefix_ipv4 lp
, pp
;
4211 struct connected
*ifc
;
4212 struct prefix_ipv4
*p
;
4214 enum zebra_dplane_result dplane_res
;
4216 if_data
= ifp
->info
;
4218 ret
= str2prefix_ipv4(addr_str
, &lp
);
4220 vty_out(vty
, "%% Malformed address \n");
4221 return CMD_WARNING_CONFIG_FAILED
;
4224 if (ipv4_martian(&lp
.prefix
)) {
4225 vty_out(vty
, "%% Invalid address\n");
4226 return CMD_WARNING_CONFIG_FAILED
;
4230 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4232 "%% Local prefix length for P-t-P address must be /32\n");
4233 return CMD_WARNING_CONFIG_FAILED
;
4236 ret
= str2prefix_ipv4(peer_str
, &pp
);
4238 vty_out(vty
, "%% Malformed peer address\n");
4239 return CMD_WARNING_CONFIG_FAILED
;
4243 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4245 ifc
= connected_new();
4249 p
= prefix_ipv4_new();
4251 ifc
->address
= (struct prefix
*)p
;
4254 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
4255 p
= prefix_ipv4_new();
4257 ifc
->destination
= (struct prefix
*)p
;
4262 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4264 /* Add to linked list. */
4265 listnode_add(ifp
->connected
, ifc
);
4268 /* This address is configured from zebra. */
4269 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4270 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4272 /* In case of this route need to install kernel. */
4273 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4274 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4275 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4276 /* Some system need to up the interface to set IP address. */
4277 if (!if_is_up(ifp
)) {
4278 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4282 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4283 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4284 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4285 dplane_res2str(dplane_res
));
4286 return CMD_WARNING_CONFIG_FAILED
;
4289 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4290 /* The address will be advertised to zebra clients when the
4292 * from the kernel has been received.
4293 * It will also be added to the subnet chain list, then. */
4299 int if_ip_address_uinstall(struct interface
*ifp
, struct prefix
*prefix
)
4301 struct connected
*ifc
= NULL
;
4302 enum zebra_dplane_result dplane_res
;
4304 if (prefix
->family
== AF_INET
) {
4305 /* Check current interface address. */
4306 ifc
= connected_check_ptp(ifp
, prefix
, NULL
);
4308 zlog_debug("interface %s Can't find address",
4313 } else if (prefix
->family
== AF_INET6
) {
4314 /* Check current interface address. */
4315 ifc
= connected_check(ifp
, prefix
);
4319 zlog_debug("interface %s Can't find address", ifp
->name
);
4322 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4324 /* This is not real address or interface is not active. */
4325 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4326 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4327 listnode_delete(ifp
->connected
, ifc
);
4328 connected_free(&ifc
);
4329 return CMD_WARNING_CONFIG_FAILED
;
4332 /* This is real route. */
4333 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4334 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4335 zlog_debug("Can't unset interface IP address: %s.",
4336 dplane_res2str(dplane_res
));
4339 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4344 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4345 const char *addr_str
, const char *peer_str
,
4348 struct prefix_ipv4 lp
, pp
;
4349 struct connected
*ifc
;
4351 enum zebra_dplane_result dplane_res
;
4353 /* Convert to prefix structure. */
4354 ret
= str2prefix_ipv4(addr_str
, &lp
);
4356 vty_out(vty
, "%% Malformed address \n");
4357 return CMD_WARNING_CONFIG_FAILED
;
4361 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4363 "%% Local prefix length for P-t-P address must be /32\n");
4364 return CMD_WARNING_CONFIG_FAILED
;
4367 ret
= str2prefix_ipv4(peer_str
, &pp
);
4369 vty_out(vty
, "%% Malformed peer address\n");
4370 return CMD_WARNING_CONFIG_FAILED
;
4374 /* Check current interface address. */
4375 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4377 vty_out(vty
, "%% Can't find address\n");
4378 return CMD_WARNING_CONFIG_FAILED
;
4381 /* This is not configured address. */
4382 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4383 return CMD_WARNING_CONFIG_FAILED
;
4385 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4387 /* This is not real address or interface is not active. */
4388 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4389 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4390 listnode_delete(ifp
->connected
, ifc
);
4391 connected_free(&ifc
);
4392 return CMD_WARNING_CONFIG_FAILED
;
4395 /* This is real route. */
4396 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4397 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4398 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4399 dplane_res2str(dplane_res
));
4400 return CMD_WARNING_CONFIG_FAILED
;
4402 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4403 /* we will receive a kernel notification about this route being removed.
4404 * this will trigger its removal from the connected list. */
4410 "ip address A.B.C.D/M",
4411 "Interface Internet Protocol config commands\n"
4412 "Set the IP address of an interface\n"
4413 "IP address (e.g. 10.0.0.1/8)\n")
4415 int idx_ipv4_prefixlen
= 2;
4416 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4417 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4421 DEFUN (no_ip_address
,
4423 "no ip address A.B.C.D/M",
4425 "Interface Internet Protocol config commands\n"
4426 "Set the IP address of an interface\n"
4427 "IP Address (e.g. 10.0.0.1/8)\n")
4429 int idx_ipv4_prefixlen
= 3;
4430 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4431 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4435 DEFUN(ip_address_peer
,
4436 ip_address_peer_cmd
,
4437 "ip address A.B.C.D peer A.B.C.D/M",
4438 "Interface Internet Protocol config commands\n"
4439 "Set the IP address of an interface\n"
4440 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4441 "Specify P-t-P address\n"
4442 "Peer IP address (e.g. 10.0.0.1/8)\n")
4444 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4445 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
4448 DEFUN(no_ip_address_peer
,
4449 no_ip_address_peer_cmd
,
4450 "no ip address A.B.C.D peer A.B.C.D/M",
4452 "Interface Internet Protocol config commands\n"
4453 "Set the IP address of an interface\n"
4454 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4455 "Specify P-t-P address\n"
4456 "Peer IP address (e.g. 10.0.0.1/8)\n")
4458 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4459 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
4463 DEFUN (ip_address_label
,
4464 ip_address_label_cmd
,
4465 "ip address A.B.C.D/M label LINE",
4466 "Interface Internet Protocol config commands\n"
4467 "Set the IP address of an interface\n"
4468 "IP address (e.g. 10.0.0.1/8)\n"
4469 "Label of this address\n"
4472 int idx_ipv4_prefixlen
= 2;
4474 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4475 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4476 argv
[idx_line
]->arg
);
4479 DEFUN (no_ip_address_label
,
4480 no_ip_address_label_cmd
,
4481 "no ip address A.B.C.D/M label LINE",
4483 "Interface Internet Protocol config commands\n"
4484 "Set the IP address of an interface\n"
4485 "IP address (e.g. 10.0.0.1/8)\n"
4486 "Label of this address\n"
4489 int idx_ipv4_prefixlen
= 3;
4491 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4492 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4493 NULL
, argv
[idx_line
]->arg
);
4495 #endif /* HAVE_NETLINK */
4497 int if_ipv6_address_install(struct interface
*ifp
, struct prefix
*prefix
,
4500 struct zebra_if
*if_data
;
4501 struct prefix_ipv6 cp
;
4502 struct connected
*ifc
;
4503 struct prefix_ipv6
*p
;
4504 enum zebra_dplane_result dplane_res
;
4506 if_data
= ifp
->info
;
4508 cp
.family
= prefix
->family
;
4509 cp
.prefixlen
= prefix
->prefixlen
;
4510 cp
.prefix
= prefix
->u
.prefix6
;
4511 apply_mask_ipv6(&cp
);
4513 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4515 ifc
= connected_new();
4519 p
= prefix_ipv6_new();
4521 ifc
->address
= (struct prefix
*)p
;
4525 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4527 /* Add to linked list. */
4528 listnode_add(ifp
->connected
, ifc
);
4531 /* This address is configured from zebra. */
4532 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4533 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4535 /* In case of this route need to install kernel. */
4536 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4537 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4538 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4539 /* Some system need to up the interface to set IP address. */
4540 if (!if_is_up(ifp
)) {
4541 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4545 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4546 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4548 "dplane can't set interface IP address: %s.",
4549 dplane_res2str(dplane_res
));
4553 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4554 /* The address will be advertised to zebra clients when the
4556 * from the kernel has been received. */
4562 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
4563 const char *addr_str
, const char *peer_str
,
4566 struct zebra_if
*if_data
;
4567 struct prefix_ipv6 cp
;
4568 struct connected
*ifc
;
4569 struct prefix_ipv6
*p
;
4571 enum zebra_dplane_result dplane_res
;
4573 if_data
= ifp
->info
;
4575 ret
= str2prefix_ipv6(addr_str
, &cp
);
4577 vty_out(vty
, "%% Malformed address \n");
4578 return CMD_WARNING_CONFIG_FAILED
;
4581 if (ipv6_martian(&cp
.prefix
)) {
4582 vty_out(vty
, "%% Invalid address\n");
4583 return CMD_WARNING_CONFIG_FAILED
;
4586 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4588 ifc
= connected_new();
4592 p
= prefix_ipv6_new();
4594 ifc
->address
= (struct prefix
*)p
;
4598 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4600 /* Add to linked list. */
4601 listnode_add(ifp
->connected
, ifc
);
4604 /* This address is configured from zebra. */
4605 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4606 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4608 /* In case of this route need to install kernel. */
4609 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4610 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4611 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4612 /* Some system need to up the interface to set IP address. */
4613 if (!if_is_up(ifp
)) {
4614 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4618 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4619 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4620 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4621 dplane_res2str(dplane_res
));
4622 return CMD_WARNING_CONFIG_FAILED
;
4625 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4626 /* The address will be advertised to zebra clients when the
4628 * from the kernel has been received. */
4634 /* Return true if an ipv6 address is configured on ifp */
4635 int ipv6_address_configured(struct interface
*ifp
)
4637 struct connected
*connected
;
4638 struct listnode
*node
;
4640 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
4641 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
4642 && (connected
->address
->family
== AF_INET6
))
4648 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4649 const char *addr_str
, const char *peer_str
,
4652 struct prefix_ipv6 cp
;
4653 struct connected
*ifc
;
4655 enum zebra_dplane_result dplane_res
;
4657 /* Convert to prefix structure. */
4658 ret
= str2prefix_ipv6(addr_str
, &cp
);
4660 vty_out(vty
, "%% Malformed address \n");
4661 return CMD_WARNING_CONFIG_FAILED
;
4664 /* Check current interface address. */
4665 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4667 vty_out(vty
, "%% Can't find address\n");
4668 return CMD_WARNING_CONFIG_FAILED
;
4671 /* This is not configured address. */
4672 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4673 return CMD_WARNING_CONFIG_FAILED
;
4675 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4677 /* This is not real address or interface is not active. */
4678 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4679 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4680 listnode_delete(ifp
->connected
, ifc
);
4681 connected_free(&ifc
);
4682 return CMD_WARNING_CONFIG_FAILED
;
4685 /* This is real route. */
4686 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4687 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4688 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4689 dplane_res2str(dplane_res
));
4690 return CMD_WARNING_CONFIG_FAILED
;
4693 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4694 /* This information will be propagated to the zclients when the
4695 * kernel notification is received. */
4699 DEFUN (ipv6_address
,
4701 "ipv6 address X:X::X:X/M",
4702 "Interface IPv6 config commands\n"
4703 "Set the IP address of an interface\n"
4704 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4706 int idx_ipv6_prefixlen
= 2;
4707 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4708 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4712 DEFUN (no_ipv6_address
,
4713 no_ipv6_address_cmd
,
4714 "no ipv6 address X:X::X:X/M",
4716 "Interface IPv6 config commands\n"
4717 "Set the IP address of an interface\n"
4718 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4720 int idx_ipv6_prefixlen
= 3;
4721 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4722 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4726 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
4728 const struct lyd_node
*dnode
;
4729 char xpath
[XPATH_MAXLEN
];
4732 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
4735 struct if_link_params
*iflp
= ifp
->link_params
;
4737 vty_out(vty
, " link-params\n");
4738 vty_out(vty
, " enable\n");
4739 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
4740 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
4741 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
4742 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
4743 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
4744 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
4745 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
4746 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
4747 for (i
= 0; i
< 8; i
++)
4748 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
4749 vty_out(vty
, " unrsv-bw %d %g\n", i
,
4754 xpath
, sizeof(xpath
),
4755 "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params",
4757 dnode
= yang_dnode_get(running_config
->dnode
, xpath
);
4759 nb_cli_show_dnode_cmds(vty
, dnode
, false);
4761 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
4762 vty_out(vty
, " delay %u", iflp
->av_delay
);
4763 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
4764 vty_out(vty
, " min %u", iflp
->min_delay
);
4765 vty_out(vty
, " max %u", iflp
->max_delay
);
4769 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
4770 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
4771 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
4772 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
4773 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
4774 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
4775 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
4776 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
4777 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
4778 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
4779 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
4780 vty_out(vty
, " neighbor %pI4 as %u\n", &iflp
->rmt_ip
,
4783 vty_out(vty
, " exit-link-params\n");
4787 static int if_config_write(struct vty
*vty
)
4790 struct interface
*ifp
;
4792 zebra_ptm_write(vty
);
4794 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
4795 FOR_ALL_INTERFACES (vrf
, ifp
) {
4796 struct zebra_if
*if_data
;
4797 struct listnode
*addrnode
;
4798 struct connected
*ifc
;
4801 if_data
= ifp
->info
;
4803 if_vty_config_start(vty
, ifp
);
4806 if (if_data
->shutdown
== IF_ZEBRA_DATA_ON
)
4807 vty_out(vty
, " shutdown\n");
4809 zebra_ptm_if_write(vty
, if_data
);
4813 vty_out(vty
, " description %s\n", ifp
->desc
);
4815 /* Assign bandwidth here to avoid unnecessary interface
4817 while processing config script */
4818 if (ifp
->bandwidth
!= 0)
4819 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
4821 if (!CHECK_FLAG(ifp
->status
,
4822 ZEBRA_INTERFACE_LINKDETECTION
))
4823 vty_out(vty
, " no link-detect\n");
4825 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
4827 if (CHECK_FLAG(ifc
->conf
,
4828 ZEBRA_IFC_CONFIGURED
)) {
4829 char buf
[INET6_ADDRSTRLEN
];
4831 vty_out(vty
, " ip%s address %s",
4832 p
->family
== AF_INET
? ""
4834 inet_ntop(p
->family
,
4837 if (CONNECTED_PEER(ifc
)) {
4838 p
= ifc
->destination
;
4839 vty_out(vty
, " peer %s",
4840 inet_ntop(p
->family
,
4845 vty_out(vty
, "/%d", p
->prefixlen
);
4848 vty_out(vty
, " label %s",
4856 if (if_data
->multicast
!= IF_ZEBRA_DATA_UNSPEC
)
4857 vty_out(vty
, " %smulticast\n",
4858 if_data
->multicast
==
4862 if (if_data
->mpls
== IF_ZEBRA_DATA_ON
)
4863 vty_out(vty
, " mpls enable\n");
4866 hook_call(zebra_if_config_wr
, vty
, ifp
);
4867 zebra_evpn_mh_if_write(vty
, ifp
);
4868 link_params_config_write(vty
, ifp
);
4870 if_vty_config_end(vty
);
4875 /* Allocate and initialize interface vector. */
4876 void zebra_if_init(void)
4878 /* Initialize interface and new hook. */
4879 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
4880 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
4882 /* Install configuration write function. */
4883 if_cmd_init(if_config_write
);
4884 install_node(&link_params_node
);
4886 * This is *intentionally* setting this to NULL, signaling
4887 * that interface creation for zebra acts differently
4889 if_zapi_callbacks(NULL
, NULL
, NULL
, NULL
);
4891 install_element(VIEW_NODE
, &show_interface_cmd
);
4892 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
4893 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
4894 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
4896 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
4897 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
4898 install_element(INTERFACE_NODE
, &multicast_cmd
);
4899 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
4900 install_element(INTERFACE_NODE
, &mpls_cmd
);
4901 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
4902 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
4903 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
4904 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
4905 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
4906 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
4907 install_element(INTERFACE_NODE
, &ip_address_cmd
);
4908 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
4909 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
4910 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
4911 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
4912 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
4914 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
4915 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
4916 #endif /* HAVE_NETLINK */
4917 install_element(INTERFACE_NODE
, &link_params_cmd
);
4918 install_default(LINK_PARAMS_NODE
);
4919 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
4920 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
4921 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
4922 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
4923 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
4924 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
4925 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
4926 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
4927 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
4928 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
4929 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
4930 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
4931 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
4932 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
4933 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
4934 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
4935 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
4936 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
4937 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
4938 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
4939 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
4940 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
4941 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
4942 install_element(LINK_PARAMS_NODE
, &link_params_affinity_cmd
);
4943 install_element(LINK_PARAMS_NODE
, &link_params_affinity_mode_cmd
);
4944 install_element(LINK_PARAMS_NODE
, &no_link_params_affinity_mode_cmd
);
4945 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4947 /* setup EVPN MH elements */
4948 zebra_evpn_interface_init();