3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "lib_errors.h"
27 #include "sockunion.h"
32 #include "connected.h"
37 #include "zebra/rtadv.h"
39 #include "zebra_vrf.h"
40 #include "zebra/interface.h"
41 #include "zebra/rib.h"
43 #include "zebra/zebra_router.h"
44 #include "zebra/redistribute.h"
45 #include "zebra/debug.h"
46 #include "zebra/irdp.h"
47 #include "zebra/zebra_ptm.h"
48 #include "zebra/rt_netlink.h"
49 #include "zebra/if_netlink.h"
50 #include "zebra/interface.h"
51 #include "zebra/zebra_vxlan.h"
52 #include "zebra/zebra_errors.h"
53 #include "zebra/zebra_evpn_mh.h"
55 DEFINE_MTYPE_STATIC(ZEBRA
, ZINFO
, "Zebra Interface Information");
57 #define ZEBRA_PTM_SUPPORT
59 DEFINE_HOOK(zebra_if_extra_info
, (struct vty
* vty
, struct interface
*ifp
),
61 DEFINE_HOOK(zebra_if_config_wr
, (struct vty
* vty
, struct interface
*ifp
),
64 DEFINE_MTYPE(ZEBRA
, ZIF_DESC
, "Intf desc");
66 static void if_down_del_nbr_connected(struct interface
*ifp
);
68 static void if_zebra_speed_update(struct thread
*thread
)
70 struct interface
*ifp
= THREAD_ARG(thread
);
71 struct zebra_if
*zif
= ifp
->info
;
76 new_speed
= kernel_get_speed(ifp
, &error
);
78 /* error may indicate vrf not available or
79 * interfaces not available.
80 * note that loopback & virtual interfaces can return 0 as speed
85 if (new_speed
!= ifp
->speed
) {
86 zlog_info("%s: %s old speed: %u new speed: %u", __func__
,
87 ifp
->name
, ifp
->speed
, new_speed
);
88 ifp
->speed
= new_speed
;
93 if (changed
|| new_speed
== UINT32_MAX
) {
94 #define SPEED_UPDATE_SLEEP_TIME 5
95 #define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
97 * Some interfaces never actually have an associated speed
98 * with them ( I am looking at you bridges ).
99 * So instead of iterating forever, let's give the
100 * system 4 minutes to try to figure out the speed
101 * if after that it it's probably never going to become
103 * Since I don't know all the wonderful types of interfaces
104 * that may come into existence in the future I am going
105 * to not update the system to keep track of that. This
106 * is far simpler to just stop trying after 4 minutes
108 if (new_speed
== UINT32_MAX
&&
109 zif
->speed_update_count
== SPEED_UPDATE_COUNT_MAX
)
112 zif
->speed_update_count
++;
113 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
,
114 SPEED_UPDATE_SLEEP_TIME
, &zif
->speed_update
);
115 thread_ignore_late_timer(zif
->speed_update
);
119 static void zebra_if_node_destroy(route_table_delegate_t
*delegate
,
120 struct route_table
*table
,
121 struct route_node
*node
)
124 list_delete((struct list
**)&node
->info
);
125 route_node_destroy(delegate
, table
, node
);
128 static void zebra_if_nhg_dependents_free(struct zebra_if
*zebra_if
)
130 nhg_connected_tree_free(&zebra_if
->nhg_dependents
);
133 static void zebra_if_nhg_dependents_init(struct zebra_if
*zebra_if
)
135 nhg_connected_tree_init(&zebra_if
->nhg_dependents
);
139 route_table_delegate_t zebra_if_table_delegate
= {
140 .create_node
= route_node_create
,
141 .destroy_node
= zebra_if_node_destroy
};
143 /* Called when new interface is added. */
144 static int if_zebra_new_hook(struct interface
*ifp
)
146 struct zebra_if
*zebra_if
;
148 zebra_if
= XCALLOC(MTYPE_ZINFO
, sizeof(struct zebra_if
));
151 zebra_if
->multicast
= IF_ZEBRA_DATA_UNSPEC
;
152 zebra_if
->shutdown
= IF_ZEBRA_DATA_OFF
;
154 zebra_if_nhg_dependents_init(zebra_if
);
156 zebra_ptm_if_init(zebra_if
);
158 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
160 rtadv_if_init(zebra_if
);
162 memset(&zebra_if
->neigh_mac
[0], 0, 6);
164 /* Initialize installed address chains tree. */
165 zebra_if
->ipv4_subnets
=
166 route_table_init_with_delegate(&zebra_if_table_delegate
);
168 ifp
->info
= zebra_if
;
171 * Some platforms are telling us that the interface is
172 * up and ready to go. When we check the speed we
173 * sometimes get the wrong value. Wait a couple
174 * of seconds and ask again. Hopefully it's all settled
177 zebra_if
->speed_update_count
= 0;
178 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
179 &zebra_if
->speed_update
);
180 thread_ignore_late_timer(zebra_if
->speed_update
);
185 static void if_nhg_dependents_check_valid(struct nhg_hash_entry
*nhe
)
187 zebra_nhg_check_valid(nhe
);
190 static void if_down_nhg_dependents(const struct interface
*ifp
)
192 struct nhg_connected
*rb_node_dep
= NULL
;
193 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
195 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
)
196 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
199 static void if_nhg_dependents_release(const struct interface
*ifp
)
201 struct nhg_connected
*rb_node_dep
= NULL
;
202 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
204 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
) {
205 rb_node_dep
->nhe
->ifp
= NULL
; /* Null it out */
206 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
210 /* Called when interface is deleted. */
211 static int if_zebra_delete_hook(struct interface
*ifp
)
213 struct zebra_if
*zebra_if
;
216 zebra_if
= ifp
->info
;
218 /* If we set protodown, clear our reason now from the kernel */
219 if (ZEBRA_IF_IS_PROTODOWN(zebra_if
) && zebra_if
->protodown_rc
&&
220 !ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zebra_if
))
221 zebra_if_update_protodown_rc(ifp
, true,
222 (zebra_if
->protodown_rc
&
223 ~ZEBRA_PROTODOWN_ALL
));
225 /* Free installed address chains tree. */
226 if (zebra_if
->ipv4_subnets
)
227 route_table_finish(zebra_if
->ipv4_subnets
);
229 rtadv_if_fini(zebra_if
);
231 zebra_evpn_if_cleanup(zebra_if
);
232 zebra_evpn_mac_ifp_del(ifp
);
234 if_nhg_dependents_release(ifp
);
235 zebra_if_nhg_dependents_free(zebra_if
);
237 XFREE(MTYPE_ZIF_DESC
, zebra_if
->desc
);
239 THREAD_OFF(zebra_if
->speed_update
);
241 XFREE(MTYPE_ZINFO
, zebra_if
);
247 /* Build the table key */
248 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
251 p
->prefixlen
= IPV4_MAX_BITLEN
;
252 p
->u
.prefix4
.s_addr
= ifindex
;
255 /* Link an interface in a per NS interface tree */
256 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
259 struct route_node
*rn
;
261 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
264 if_build_key(ifp
->ifindex
, &p
);
265 rn
= route_node_get(ns
->if_table
, &p
);
267 ifp
= (struct interface
*)rn
->info
;
268 route_unlock_node(rn
); /* get */
278 /* Delete a VRF. This is called in vrf_terminate(). */
279 void if_unlink_per_ns(struct interface
*ifp
)
281 ifp
->node
->info
= NULL
;
282 route_unlock_node(ifp
->node
);
286 /* Look up an interface by identifier within a NS */
287 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
291 struct route_node
*rn
;
292 struct interface
*ifp
= NULL
;
294 if_build_key(ifindex
, &p
);
295 rn
= route_node_lookup(ns
->if_table
, &p
);
297 ifp
= (struct interface
*)rn
->info
;
298 route_unlock_node(rn
); /* lookup */
303 /* Look up an interface by name within a NS */
304 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
307 struct route_node
*rn
;
308 struct interface
*ifp
;
310 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
311 ifp
= (struct interface
*)rn
->info
;
312 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0) {
313 route_unlock_node(rn
);
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 /* Reset some zebra interface params to default values. */
809 zif
->zif_type
= ZEBRA_IF_OTHER
;
810 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
811 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
812 memset(&zif
->brslave_info
, 0,
813 sizeof(struct zebra_l2info_brslave
));
814 zebra_evpn_if_cleanup(zif
);
815 zebra_evpn_mac_ifp_del(ifp
);
818 if (!ifp
->configured
) {
819 if (IS_ZEBRA_DEBUG_KERNEL
)
820 zlog_debug("interface %s is being deleted from the system",
826 /* VRF change for an interface */
827 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
831 old_vrf_id
= ifp
->vrf
->vrf_id
;
833 /* Uninstall connected routes. */
834 if_uninstall_connected(ifp
);
836 /* Delete any IPv4 neighbors created to implement RFC 5549 */
837 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
839 /* Delete all neighbor addresses learnt through IPv6 RA */
840 if_down_del_nbr_connected(ifp
);
842 /* Send out notification on interface VRF change. */
843 /* This is to issue an UPDATE or a DELETE, as appropriate. */
844 zebra_interface_vrf_update_del(ifp
, vrf_id
);
847 if_update_to_new_vrf(ifp
, vrf_id
);
849 /* Send out notification on interface VRF change. */
850 /* This is to issue an ADD, if needed. */
851 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
854 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
856 mac
[0] = address
->s6_addr
[8] ^ 0x02;
857 mac
[1] = address
->s6_addr
[9];
858 mac
[2] = address
->s6_addr
[10];
859 mac
[3] = address
->s6_addr
[13];
860 mac
[4] = address
->s6_addr
[14];
861 mac
[5] = address
->s6_addr
[15];
864 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
866 struct in6_addr
*address
,
869 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
870 struct zebra_if
*zif
= ifp
->info
;
871 char buf
[16] = "169.254.0.1";
872 struct in_addr ipv4_ll
;
875 inet_pton(AF_INET
, buf
, &ipv4_ll
);
877 ns_id
= zvrf
->zns
->ns_id
;
880 * Remove and re-add any existing neighbor entry for this address,
881 * since Netlink doesn't currently offer update message types.
883 kernel_neigh_update(0, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
, mac
, 6,
884 ns_id
, AF_INET
, true);
886 /* Add new neighbor entry.
888 * We force installation even if current neighbor entry is the same.
889 * Since this function is used to refresh our MAC entries after an
890 * interface flap, if we don't force in our custom entries with their
891 * state set to PERMANENT or REACHABLE then the kernel will attempt to
892 * resolve our leftover entries, fail, mark them unreachable and then
893 * they'll be useless to us.
896 kernel_neigh_update(add
, ifp
->ifindex
, (void *)&ipv4_ll
.s_addr
,
897 mac
, 6, ns_id
, AF_INET
, true);
899 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
902 * We need to note whether or not we originated a v6
903 * neighbor entry for this interface. So that when
904 * someone unwisely accidentally deletes this entry
905 * we can shove it back in.
907 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
908 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
910 zvrf
->neigh_updates
++;
913 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
914 struct in6_addr
*address
, int add
)
919 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
920 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
923 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface
*ifp
)
925 if (listhead(ifp
->nbr_connected
)) {
926 struct nbr_connected
*nbr_connected
;
927 struct listnode
*node
;
929 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
931 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
932 ifp
, &nbr_connected
->address
->u
.prefix6
, 1);
936 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
938 if (listhead(ifp
->nbr_connected
)) {
939 struct nbr_connected
*nbr_connected
;
940 struct listnode
*node
;
942 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
944 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
945 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
949 static void if_down_del_nbr_connected(struct interface
*ifp
)
951 struct nbr_connected
*nbr_connected
;
952 struct listnode
*node
, *nnode
;
954 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
956 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
957 nbr_connected_free(nbr_connected
);
961 void if_nhg_dependents_add(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
964 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
966 nhg_connected_tree_add_nhe(&zif
->nhg_dependents
, nhe
);
970 void if_nhg_dependents_del(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
973 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
975 nhg_connected_tree_del_nhe(&zif
->nhg_dependents
, nhe
);
979 unsigned int if_nhg_dependents_count(const struct interface
*ifp
)
982 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
984 return nhg_connected_tree_count(&zif
->nhg_dependents
);
991 bool if_nhg_dependents_is_empty(const struct interface
*ifp
)
994 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
996 return nhg_connected_tree_is_empty(&zif
->nhg_dependents
);
1002 /* Interface is up. */
1003 void if_up(struct interface
*ifp
, bool install_connected
)
1005 struct zebra_if
*zif
;
1006 struct interface
*link_if
;
1007 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
1011 frr_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
1013 /* Notify the protocol daemons. */
1014 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
1015 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
1016 "%s: interface %s hasn't passed ptm check",
1017 __func__
, ifp
->name
);
1020 zebra_interface_up_update(ifp
);
1022 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
1026 /* Install connected routes to the kernel. */
1027 if (install_connected
)
1028 if_install_connected(ifp
);
1030 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1031 * are checked to see if (remote) neighbor entries need to be installed
1032 * on them for ARP suppression.
1034 if (IS_ZEBRA_IF_VXLAN(ifp
))
1035 zebra_vxlan_if_up(ifp
);
1036 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1038 zebra_vxlan_svi_up(ifp
, link_if
);
1039 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1040 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1043 zebra_vxlan_svi_up(ifp
, link_if
);
1044 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1045 zebra_vxlan_macvlan_up(ifp
);
1048 if (zif
->es_info
.es
)
1049 zebra_evpn_es_if_oper_state_change(zif
, true /*up*/);
1051 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1052 zebra_evpn_mh_uplink_oper_update(zif
);
1054 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 0,
1055 &zif
->speed_update
);
1056 thread_ignore_late_timer(zif
->speed_update
);
1059 /* Interface goes down. We have to manage different behavior of based
1061 void if_down(struct interface
*ifp
)
1063 struct zebra_if
*zif
;
1064 struct interface
*link_if
;
1065 struct zebra_vrf
*zvrf
= ifp
->vrf
->info
;
1069 frr_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
1071 if_down_nhg_dependents(ifp
);
1073 /* Handle interface down for specific types for EVPN. Non-VxLAN
1075 * are checked to see if (remote) neighbor entries need to be purged
1076 * for ARP suppression.
1078 if (IS_ZEBRA_IF_VXLAN(ifp
))
1079 zebra_vxlan_if_down(ifp
);
1080 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1082 zebra_vxlan_svi_down(ifp
, link_if
);
1083 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1084 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1087 zebra_vxlan_svi_down(ifp
, link_if
);
1088 } else if (IS_ZEBRA_IF_MACVLAN(ifp
)) {
1089 zebra_vxlan_macvlan_down(ifp
);
1092 if (zif
->es_info
.es
)
1093 zebra_evpn_es_if_oper_state_change(zif
, false /*up*/);
1095 if (zif
->flags
& ZIF_FLAG_EVPN_MH_UPLINK
)
1096 zebra_evpn_mh_uplink_oper_update(zif
);
1098 /* Notify to the protocol daemons. */
1099 zebra_interface_down_update(ifp
);
1101 /* Uninstall connected routes from the kernel. */
1102 if_uninstall_connected(ifp
);
1104 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
1106 /* Delete all neighbor addresses learnt through IPv6 RA */
1107 if_down_del_nbr_connected(ifp
);
1110 void if_refresh(struct interface
*ifp
)
1117 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1120 struct zebra_if
*zif
;
1122 if (IS_ZEBRA_IF_VETH(ifp
))
1124 zif
= (struct zebra_if
*)ifp
->info
;
1125 zif
->link_ifindex
= link_ifindex
;
1126 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1131 * during initial link dump kernel does not order lower devices before
1132 * upper devices so we need to fixup link dependencies at the end of dump
1134 void zebra_if_update_all_links(struct zebra_ns
*zns
)
1136 struct route_node
*rn
;
1137 struct interface
*ifp
;
1138 struct zebra_if
*zif
;
1140 if (IS_ZEBRA_DEBUG_KERNEL
)
1141 zlog_info("fixup link dependencies");
1143 for (rn
= route_top(zns
->if_table
); rn
; rn
= route_next(rn
)) {
1144 ifp
= (struct interface
*)rn
->info
;
1148 /* update bond-member to bond linkages */
1149 if ((IS_ZEBRA_IF_BOND_SLAVE(ifp
))
1150 && (zif
->bondslave_info
.bond_ifindex
!= IFINDEX_INTERNAL
)
1151 && !zif
->bondslave_info
.bond_if
) {
1152 if (IS_ZEBRA_DEBUG_EVPN_MH_ES
|| IS_ZEBRA_DEBUG_KERNEL
)
1153 zlog_debug("bond mbr %s map to bond %d",
1155 zif
->bondslave_info
.bond_ifindex
);
1156 zebra_l2_map_slave_to_bond(zif
, ifp
->vrf
->vrf_id
);
1159 /* update SVI linkages */
1160 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1161 zif
->link
= if_lookup_by_index_per_ns(
1162 zns
, zif
->link_ifindex
);
1163 if (IS_ZEBRA_DEBUG_KERNEL
)
1164 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1165 ifp
->name
, ifp
->ifindex
,
1166 zif
->link
?zif
->link
->name
:"unk",
1170 /* Update VLAN<=>SVI map */
1171 if (IS_ZEBRA_IF_VLAN(ifp
))
1172 zebra_evpn_acc_bd_svi_set(zif
, NULL
,
1173 !!if_is_operative(ifp
));
1177 static bool if_ignore_set_protodown(const struct interface
*ifp
, bool new_down
,
1178 uint32_t new_protodown_rc
)
1180 struct zebra_if
*zif
;
1181 bool old_down
, old_set_down
, old_unset_down
;
1185 /* Current state as we know it */
1186 old_down
= !!(ZEBRA_IF_IS_PROTODOWN(zif
));
1187 old_set_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1188 old_unset_down
= !!CHECK_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1190 if (new_protodown_rc
== zif
->protodown_rc
) {
1191 /* Early return if already down & reason bitfield matches */
1192 if (new_down
== old_down
) {
1193 if (IS_ZEBRA_DEBUG_KERNEL
)
1195 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already set (reason bitfield: old 0x%x new 0x%x)",
1196 new_down
? "on" : "off", ifp
->name
,
1197 ifp
->ifindex
, new_down
? "on" : "off",
1198 zif
->protodown_rc
, new_protodown_rc
);
1203 /* Early return if already set queued & reason bitfield matches
1205 if (new_down
&& old_set_down
) {
1206 if (IS_ZEBRA_DEBUG_KERNEL
)
1208 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already queued to dplane (reason bitfield: old 0x%x new 0x%x)",
1209 new_down
? "on" : "off", ifp
->name
,
1210 ifp
->ifindex
, new_down
? "on" : "off",
1211 zif
->protodown_rc
, new_protodown_rc
);
1216 /* Early return if already unset queued & reason bitfield
1218 if (!new_down
&& old_unset_down
) {
1219 if (IS_ZEBRA_DEBUG_KERNEL
)
1221 "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)",
1222 new_down
? "on" : "off", ifp
->name
,
1223 ifp
->ifindex
, new_down
? "on" : "off",
1224 zif
->protodown_rc
, new_protodown_rc
);
1233 int zebra_if_update_protodown_rc(struct interface
*ifp
, bool new_down
,
1234 uint32_t new_protodown_rc
)
1236 struct zebra_if
*zif
;
1240 /* Check if we already have this state or it's queued */
1241 if (if_ignore_set_protodown(ifp
, new_down
, new_protodown_rc
))
1245 "Setting protodown %s - interface %s (%u): reason bitfield change from 0x%x --> 0x%x",
1246 new_down
? "on" : "off", ifp
->name
, ifp
->ifindex
,
1247 zif
->protodown_rc
, new_protodown_rc
);
1249 zif
->protodown_rc
= new_protodown_rc
;
1252 SET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1254 SET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1257 dplane_intf_update(ifp
);
1259 zlog_warn("Protodown is not supported on this platform");
1264 int zebra_if_set_protodown(struct interface
*ifp
, bool new_down
,
1265 enum protodown_reasons new_reason
)
1267 struct zebra_if
*zif
;
1268 uint32_t new_protodown_rc
;
1273 new_protodown_rc
= zif
->protodown_rc
| new_reason
;
1275 new_protodown_rc
= zif
->protodown_rc
& ~new_reason
;
1277 return zebra_if_update_protodown_rc(ifp
, new_down
, new_protodown_rc
);
1281 * Handle an interface events based on info in a dplane context object.
1282 * This runs in the main pthread, using the info in the context object to
1283 * modify an interface.
1285 static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx
*ctx
,
1286 struct interface
*ifp
)
1289 const char *label
= NULL
;
1290 uint32_t metric
= METRIC_MAX
;
1291 const struct prefix
*addr
, *dest
= NULL
;
1292 enum dplane_op_e op
;
1294 op
= dplane_ctx_get_op(ctx
);
1295 addr
= dplane_ctx_get_intf_addr(ctx
);
1297 if (IS_ZEBRA_DEBUG_KERNEL
)
1298 zlog_debug("%s: %s: ifindex %s(%u), addr %pFX", __func__
,
1299 dplane_op2str(dplane_ctx_get_op(ctx
)), ifp
->name
,
1300 ifp
->ifindex
, addr
);
1302 /* Is there a peer or broadcast address? */
1303 dest
= dplane_ctx_get_intf_dest(ctx
);
1304 if (dest
->prefixlen
== 0)
1307 if (dplane_ctx_intf_is_connected(ctx
))
1308 SET_FLAG(flags
, ZEBRA_IFA_PEER
);
1311 if (dplane_ctx_intf_is_secondary(ctx
))
1312 SET_FLAG(flags
, ZEBRA_IFA_SECONDARY
);
1315 if (dplane_ctx_intf_has_label(ctx
))
1316 label
= dplane_ctx_get_intf_label(ctx
);
1318 if (label
&& strcmp(ifp
->name
, label
) == 0)
1321 metric
= dplane_ctx_get_intf_metric(ctx
);
1323 /* Register interface address to the interface. */
1324 if (addr
->family
== AF_INET
) {
1325 if (op
== DPLANE_OP_INTF_ADDR_ADD
)
1327 ifp
, flags
, &addr
->u
.prefix4
, addr
->prefixlen
,
1328 dest
? &dest
->u
.prefix4
: NULL
, label
, metric
);
1329 else if (CHECK_FLAG(flags
, ZEBRA_IFA_PEER
)) {
1330 /* Delete with a peer address */
1331 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1335 connected_delete_ipv4(ifp
, flags
, &addr
->u
.prefix4
,
1336 addr
->prefixlen
, NULL
);
1339 if (addr
->family
== AF_INET6
) {
1340 if (op
== DPLANE_OP_INTF_ADDR_ADD
) {
1341 connected_add_ipv6(ifp
, flags
, &addr
->u
.prefix6
,
1342 dest
? &dest
->u
.prefix6
: NULL
,
1343 addr
->prefixlen
, label
, metric
);
1345 connected_delete_ipv6(ifp
, &addr
->u
.prefix6
, NULL
,
1350 * Linux kernel does not send route delete on interface down/addr del
1351 * so we have to re-process routes it owns (i.e. kernel routes)
1353 if (op
!= DPLANE_OP_INTF_ADDR_ADD
)
1354 rib_update(RIB_UPDATE_KERNEL
);
1357 static void zebra_if_update_ctx(struct zebra_dplane_ctx
*ctx
,
1358 struct interface
*ifp
)
1360 enum zebra_dplane_result dp_res
;
1361 struct zebra_if
*zif
;
1365 dp_res
= dplane_ctx_get_status(ctx
);
1366 pd_reason_val
= dplane_ctx_get_intf_pd_reason_val(ctx
);
1367 down
= dplane_ctx_intf_is_protodown(ctx
);
1369 if (IS_ZEBRA_DEBUG_KERNEL
)
1370 zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason %d",
1371 __func__
, dplane_op2str(dplane_ctx_get_op(ctx
)),
1372 ifp
->name
, ifp
->ifindex
, down
? "on" : "off",
1377 if (IS_ZEBRA_DEBUG_KERNEL
)
1378 zlog_debug("%s: if %s(%u) zebra info pointer is NULL",
1379 __func__
, ifp
->name
, ifp
->ifindex
);
1383 if (dp_res
!= ZEBRA_DPLANE_REQUEST_SUCCESS
) {
1384 if (IS_ZEBRA_DEBUG_KERNEL
)
1385 zlog_debug("%s: if %s(%u) dplane update failed",
1386 __func__
, ifp
->name
, ifp
->ifindex
);
1390 /* Update our info */
1391 COND_FLAG(zif
->flags
, ZIF_FLAG_PROTODOWN
, down
);
1394 /* Clear our dplane flags */
1395 UNSET_FLAG(zif
->flags
, ZIF_FLAG_SET_PROTODOWN
);
1396 UNSET_FLAG(zif
->flags
, ZIF_FLAG_UNSET_PROTODOWN
);
1400 * Handle netconf change from a dplane context object; runs in the main
1401 * pthread so it can update zebra data structs.
1403 static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx
*ctx
,
1404 struct interface
*ifp
,
1407 struct zebra_if
*zif
= NULL
;
1409 enum dplane_netconf_status_e mpls
, mcast_on
, linkdown
;
1410 bool *mcast_set
, *linkdown_set
;
1412 afi
= dplane_ctx_get_afi(ctx
);
1413 mpls
= dplane_ctx_get_netconf_mpls(ctx
);
1414 linkdown
= dplane_ctx_get_netconf_linkdown(ctx
);
1415 mcast_on
= dplane_ctx_get_netconf_mcast(ctx
);
1417 if (ifindex
== DPLANE_NETCONF_IFINDEX_ALL
) {
1418 if (afi
== AFI_IP
) {
1419 mcast_set
= &zrouter
.all_mc_forwardingv4
;
1420 linkdown_set
= &zrouter
.all_linkdownv4
;
1422 mcast_set
= &zrouter
.all_mc_forwardingv6
;
1423 linkdown_set
= &zrouter
.all_linkdownv6
;
1425 } else if (ifindex
== DPLANE_NETCONF_IFINDEX_DEFAULT
) {
1426 if (afi
== AFI_IP
) {
1427 mcast_set
= &zrouter
.default_mc_forwardingv4
;
1428 linkdown_set
= &zrouter
.default_linkdownv4
;
1430 mcast_set
= &zrouter
.default_mc_forwardingv6
;
1431 linkdown_set
= &zrouter
.default_linkdownv6
;
1434 zif
= ifp
? ifp
->info
: NULL
;
1436 if (IS_ZEBRA_DEBUG_KERNEL
)
1438 "%s: if %s(%u) zebra info pointer is NULL",
1439 __func__
, ifp
->name
, ifp
->ifindex
);
1442 if (afi
== AFI_IP
) {
1443 mcast_set
= &zif
->v4mcast_on
;
1444 linkdown_set
= &zif
->linkdown
;
1446 mcast_set
= &zif
->v6mcast_on
;
1447 linkdown_set
= &zif
->linkdownv6
;
1451 * mpls netconf data is neither v4 or v6 it's AF_MPLS!
1453 if (mpls
== DPLANE_NETCONF_STATUS_ENABLED
) {
1455 zebra_mpls_turned_on();
1456 } else if (mpls
== DPLANE_NETCONF_STATUS_DISABLED
)
1460 if (linkdown
== DPLANE_NETCONF_STATUS_ENABLED
)
1461 *linkdown_set
= true;
1462 else if (linkdown
== DPLANE_NETCONF_STATUS_DISABLED
)
1463 *linkdown_set
= false;
1465 if (mcast_on
== DPLANE_NETCONF_STATUS_ENABLED
)
1467 else if (mcast_on
== DPLANE_NETCONF_STATUS_DISABLED
)
1470 if (IS_ZEBRA_DEBUG_KERNEL
)
1472 "%s: afi: %d if %s, ifindex %d, mpls %s mc_forwarding: %s linkdown %s",
1473 __func__
, afi
, ifp
? ifp
->name
: "Global",
1474 ifp
? ifp
->ifindex
: ifindex
,
1475 (zif
? (zif
->mpls
? "ON" : "OFF") : "OFF"),
1476 (*mcast_set
? "ON" : "OFF"),
1477 (*linkdown_set
? "ON" : "OFF"));
1480 void zebra_if_dplane_result(struct zebra_dplane_ctx
*ctx
)
1482 struct zebra_ns
*zns
;
1483 struct interface
*ifp
;
1485 enum dplane_op_e op
;
1486 enum zebra_dplane_result dp_res
;
1489 ns_id
= dplane_ctx_get_ns_id(ctx
);
1490 dp_res
= dplane_ctx_get_status(ctx
);
1491 op
= dplane_ctx_get_op(ctx
);
1492 ifindex
= dplane_ctx_get_ifindex(ctx
);
1494 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL
|| IS_ZEBRA_DEBUG_KERNEL
)
1495 zlog_debug("Intf dplane ctx %p, op %s, ifindex (%u), result %s",
1496 ctx
, dplane_op2str(op
), ifindex
,
1497 dplane_res2str(dp_res
));
1499 zns
= zebra_ns_lookup(ns_id
);
1501 /* No ns - deleted maybe? */
1502 if (IS_ZEBRA_DEBUG_KERNEL
)
1503 zlog_debug("%s: can't find zns id %u", __func__
, ns_id
);
1508 ifp
= if_lookup_by_index_per_ns(zns
, ifindex
);
1510 if (op
!= DPLANE_OP_INTF_NETCONFIG
||
1511 (ifindex
!= -1 && ifindex
!= -2)) {
1512 if (IS_ZEBRA_DEBUG_KERNEL
)
1514 "%s: can't find ifp at nsid %u index %d",
1515 __func__
, ns_id
, ifindex
);
1522 case DPLANE_OP_INTF_ADDR_ADD
:
1523 case DPLANE_OP_INTF_ADDR_DEL
:
1524 zebra_if_addr_update_ctx(ctx
, ifp
);
1527 case DPLANE_OP_INTF_INSTALL
:
1528 case DPLANE_OP_INTF_UPDATE
:
1529 case DPLANE_OP_INTF_DELETE
:
1530 zebra_if_update_ctx(ctx
, ifp
);
1533 case DPLANE_OP_INTF_NETCONFIG
:
1534 zebra_if_netconf_update_ctx(ctx
, ifp
, ifindex
);
1537 case DPLANE_OP_ROUTE_INSTALL
:
1538 case DPLANE_OP_ROUTE_UPDATE
:
1539 case DPLANE_OP_ROUTE_DELETE
:
1540 case DPLANE_OP_NH_DELETE
:
1541 case DPLANE_OP_NH_INSTALL
:
1542 case DPLANE_OP_NH_UPDATE
:
1543 case DPLANE_OP_ROUTE_NOTIFY
:
1544 case DPLANE_OP_LSP_INSTALL
:
1545 case DPLANE_OP_LSP_UPDATE
:
1546 case DPLANE_OP_LSP_DELETE
:
1547 case DPLANE_OP_LSP_NOTIFY
:
1548 case DPLANE_OP_PW_INSTALL
:
1549 case DPLANE_OP_PW_UNINSTALL
:
1550 case DPLANE_OP_SYS_ROUTE_ADD
:
1551 case DPLANE_OP_SYS_ROUTE_DELETE
:
1552 case DPLANE_OP_ADDR_INSTALL
:
1553 case DPLANE_OP_ADDR_UNINSTALL
:
1554 case DPLANE_OP_MAC_INSTALL
:
1555 case DPLANE_OP_MAC_DELETE
:
1556 case DPLANE_OP_NEIGH_INSTALL
:
1557 case DPLANE_OP_NEIGH_UPDATE
:
1558 case DPLANE_OP_NEIGH_DELETE
:
1559 case DPLANE_OP_NEIGH_IP_INSTALL
:
1560 case DPLANE_OP_NEIGH_IP_DELETE
:
1561 case DPLANE_OP_VTEP_ADD
:
1562 case DPLANE_OP_VTEP_DELETE
:
1563 case DPLANE_OP_RULE_ADD
:
1564 case DPLANE_OP_RULE_DELETE
:
1565 case DPLANE_OP_RULE_UPDATE
:
1566 case DPLANE_OP_NEIGH_DISCOVER
:
1567 case DPLANE_OP_BR_PORT_UPDATE
:
1568 case DPLANE_OP_NONE
:
1569 case DPLANE_OP_IPTABLE_ADD
:
1570 case DPLANE_OP_IPTABLE_DELETE
:
1571 case DPLANE_OP_IPSET_ADD
:
1572 case DPLANE_OP_IPSET_DELETE
:
1573 case DPLANE_OP_IPSET_ENTRY_ADD
:
1574 case DPLANE_OP_IPSET_ENTRY_DELETE
:
1575 case DPLANE_OP_NEIGH_TABLE_UPDATE
:
1576 case DPLANE_OP_GRE_SET
:
1577 case DPLANE_OP_TC_QDISC_INSTALL
:
1578 case DPLANE_OP_TC_QDISC_UNINSTALL
:
1579 case DPLANE_OP_TC_CLASS_ADD
:
1580 case DPLANE_OP_TC_CLASS_DELETE
:
1581 case DPLANE_OP_TC_CLASS_UPDATE
:
1582 case DPLANE_OP_TC_FILTER_ADD
:
1583 case DPLANE_OP_TC_FILTER_DELETE
:
1584 case DPLANE_OP_TC_FILTER_UPDATE
:
1585 break; /* should never hit here */
1589 /* Dump if address information to vty. */
1590 static void connected_dump_vty(struct vty
*vty
, json_object
*json
,
1591 struct connected
*connected
)
1594 json_object
*json_addr
= NULL
;
1596 /* Print interface address. */
1597 p
= connected
->address
;
1600 json_addr
= json_object_new_object();
1601 json_object_array_add(json
, json_addr
);
1602 json_object_string_addf(json_addr
, "address", "%pFX", p
);
1604 vty_out(vty
, " %s %pFX", prefix_family_str(p
), p
);
1607 /* If there is destination address, print it. */
1608 if (CONNECTED_PEER(connected
) && connected
->destination
) {
1610 json_object_string_addf(json_addr
, "peer", "%pFX",
1611 connected
->destination
);
1613 vty_out(vty
, " peer %pFX", connected
->destination
);
1618 json_object_boolean_add(
1619 json_addr
, "secondary",
1620 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
));
1621 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1622 vty_out(vty
, " secondary");
1625 json_object_boolean_add(
1626 json_addr
, "unnumbered",
1627 CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
));
1628 else if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1629 vty_out(vty
, " unnumbered");
1631 if (connected
->label
) {
1633 json_object_string_add(json_addr
, "label",
1636 vty_out(vty
, " %s", connected
->label
);
1643 /* Dump interface neighbor address information to vty. */
1644 static void nbr_connected_dump_vty(struct vty
*vty
, json_object
*json
,
1645 struct nbr_connected
*connected
)
1648 char buf
[PREFIX2STR_BUFFER
];
1650 /* Print interface address. */
1651 p
= connected
->address
;
1653 json_array_string_add(json
, prefix2str(p
, buf
, sizeof(buf
)));
1655 vty_out(vty
, " %s %pFX\n", prefix_family_str(p
), p
);
1659 zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type
)
1661 switch (zif_slave_type
) {
1662 case ZEBRA_IF_SLAVE_BRIDGE
:
1664 case ZEBRA_IF_SLAVE_VRF
:
1666 case ZEBRA_IF_SLAVE_BOND
:
1668 case ZEBRA_IF_SLAVE_OTHER
:
1670 case ZEBRA_IF_SLAVE_NONE
:
1676 static const char *zebra_ziftype_2str(enum zebra_iftype zif_type
)
1679 case ZEBRA_IF_OTHER
:
1682 case ZEBRA_IF_BRIDGE
:
1688 case ZEBRA_IF_VXLAN
:
1700 case ZEBRA_IF_BOND_SLAVE
:
1701 return "bond_slave";
1703 case ZEBRA_IF_MACVLAN
:
1714 /* Interface's brief information print out to vty interface. */
1715 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1717 struct connected
*connected
;
1718 struct listnode
*node
;
1719 struct route_node
*rn
;
1720 struct zebra_if
*zebra_if
;
1722 struct interface
*ifp
;
1723 bool print_header
= true;
1725 FOR_ALL_INTERFACES (vrf
, ifp
) {
1726 bool first_pfx_printed
= false;
1729 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1730 "Status", "VRF", "Addresses");
1731 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1732 "------", "---", "---------");
1733 print_header
= false; /* We have at least 1 iface */
1735 zebra_if
= ifp
->info
;
1737 vty_out(vty
, "%-16s", ifp
->name
);
1740 vty_out(vty
, "%-8s", "up");
1742 vty_out(vty
, "%-8s", "down");
1744 vty_out(vty
, "%-16s", vrf
->name
);
1746 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1747 rn
= route_next(rn
)) {
1750 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1752 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1754 if (!CHECK_FLAG(connected
->flags
,
1755 ZEBRA_IFA_SECONDARY
)) {
1756 p
= connected
->address
;
1757 if (first_pfx_printed
) {
1758 /* padding to prepare row only
1760 vty_out(vty
, "%-40s", "");
1763 vty_out(vty
, "%pFX\n", p
);
1767 vty_out(vty
, "%pFX\n", p
);
1769 first_pfx_printed
= true;
1775 uint32_t v6_list_size
= 0;
1776 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1777 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1778 && (connected
->address
->family
== AF_INET6
))
1781 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1782 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1783 && !CHECK_FLAG(connected
->flags
,
1784 ZEBRA_IFA_SECONDARY
)
1785 && (connected
->address
->family
== AF_INET6
)) {
1786 p
= connected
->address
;
1787 /* Don't print link local pfx */
1788 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1789 if (first_pfx_printed
) {
1790 /* padding to prepare row only
1792 vty_out(vty
, "%-40s", "");
1793 if (v6_list_size
> 1)
1795 vty_out(vty
, "%pFX\n", p
);
1797 if (v6_list_size
> 1)
1799 vty_out(vty
, "%pFX\n", p
);
1801 first_pfx_printed
= true;
1806 if (!first_pfx_printed
)
1812 static void ifs_dump_brief_vty_json(json_object
*json
, struct vrf
*vrf
)
1814 struct connected
*connected
;
1815 struct listnode
*node
;
1816 struct interface
*ifp
;
1818 FOR_ALL_INTERFACES (vrf
, ifp
) {
1819 json_object
*json_if
;
1820 json_object
*json_addrs
;
1822 json_if
= json_object_new_object();
1823 json_object_object_add(json
, ifp
->name
, json_if
);
1825 json_object_string_add(json_if
, "status",
1826 if_is_up(ifp
) ? "up" : "down");
1827 json_object_string_add(json_if
, "vrfName", vrf
->name
);
1829 json_addrs
= json_object_new_array();
1830 json_object_object_add(json_if
, "addresses", json_addrs
);
1831 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1832 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1833 && !CHECK_FLAG(connected
->flags
,
1834 ZEBRA_IFA_SECONDARY
)
1835 && !(connected
->address
->family
== AF_INET6
1836 && IN6_IS_ADDR_LINKLOCAL(
1837 &connected
->address
->u
.prefix6
))) {
1838 char buf
[PREFIX2STR_BUFFER
];
1840 json_array_string_add(
1842 prefix2str(connected
->address
, buf
,
1849 const char *zebra_protodown_rc_str(uint32_t protodown_rc
, char *pd_buf
,
1850 uint32_t pd_buf_len
)
1855 strlcat(pd_buf
, "(", pd_buf_len
);
1857 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EXTERNAL
))
1858 strlcat(pd_buf
, "external,", pd_buf_len
);
1860 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY
))
1861 strlcat(pd_buf
, "startup-delay,", pd_buf_len
);
1863 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
))
1864 strlcat(pd_buf
, "uplinks-down,", pd_buf_len
);
1866 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_VRRP
))
1867 strlcat(pd_buf
, "vrrp,", pd_buf_len
);
1869 if (CHECK_FLAG(protodown_rc
, ZEBRA_PROTODOWN_SHARP
))
1870 strlcat(pd_buf
, "sharp,", pd_buf_len
);
1872 len
= strnlen(pd_buf
, pd_buf_len
);
1874 /* Remove trailing comma */
1875 if (pd_buf
[len
- 1] == ',')
1876 pd_buf
[len
- 1] = '\0';
1878 strlcat(pd_buf
, ")", pd_buf_len
);
1883 static inline bool if_is_protodown_applicable(struct interface
*ifp
)
1885 if (IS_ZEBRA_IF_BOND(ifp
))
1891 /* Interface's information print out to vty interface. */
1892 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1894 struct connected
*connected
;
1895 struct nbr_connected
*nbr_connected
;
1896 struct listnode
*node
;
1897 struct route_node
*rn
;
1898 struct zebra_if
*zebra_if
;
1899 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
1901 zebra_if
= ifp
->info
;
1903 vty_out(vty
, "Interface %s is ", ifp
->name
);
1904 if (if_is_up(ifp
)) {
1905 vty_out(vty
, "up, line protocol ");
1907 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1908 if (if_is_running(ifp
))
1909 vty_out(vty
, "is up\n");
1911 vty_out(vty
, "is down\n");
1913 vty_out(vty
, "detection is disabled\n");
1916 vty_out(vty
, "down\n");
1919 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1920 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1921 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1922 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1924 zebra_ptm_show_status(vty
, NULL
, ifp
);
1926 vty_out(vty
, " vrf: %s\n", ifp
->vrf
->name
);
1929 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1931 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1933 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1934 vty_out(vty
, " pseudo interface\n");
1936 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1937 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
1941 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
1942 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
1943 if (ifp
->mtu6
!= ifp
->mtu
)
1944 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
1945 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
1948 vty_out(vty
, " MPLS enabled\n");
1950 if (zebra_if
->linkdown
)
1951 vty_out(vty
, " Ignore all v4 routes with linkdown\n");
1952 if (zebra_if
->linkdownv6
)
1953 vty_out(vty
, " Ignore all v6 routes with linkdown\n");
1955 if (zebra_if
->v4mcast_on
)
1956 vty_out(vty
, " v4 Multicast forwarding is on\n");
1957 if (zebra_if
->v6mcast_on
)
1958 vty_out(vty
, " v6 Multicast forwarding is on\n");
1960 /* Hardware address. */
1961 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
1962 if (ifp
->hw_addr_len
!= 0) {
1965 vty_out(vty
, " HWaddr: ");
1966 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
1967 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
1972 /* Bandwidth in Mbps */
1973 if (ifp
->bandwidth
!= 0) {
1974 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
1978 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
1982 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1984 connected_dump_vty(vty
, NULL
, connected
);
1987 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1988 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1989 && (connected
->address
->family
== AF_INET6
))
1990 connected_dump_vty(vty
, NULL
, connected
);
1993 vty_out(vty
, " Interface Type %s\n",
1994 zebra_ziftype_2str(zebra_if
->zif_type
));
1995 vty_out(vty
, " Interface Slave Type %s\n",
1996 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
1998 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1999 struct zebra_l2info_bridge
*bridge_info
;
2001 bridge_info
= &zebra_if
->l2info
.br
;
2002 vty_out(vty
, " Bridge VLAN-aware: %s\n",
2003 bridge_info
->vlan_aware
? "yes" : "no");
2004 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2005 struct zebra_l2info_vlan
*vlan_info
;
2007 vlan_info
= &zebra_if
->l2info
.vl
;
2008 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
2009 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2010 struct zebra_l2info_vxlan
*vxlan_info
;
2012 vxlan_info
= &zebra_if
->l2info
.vxl
;
2013 vty_out(vty
, " VxLAN Id %u", vxlan_info
->vni
);
2014 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
2015 vty_out(vty
, " VTEP IP: %pI4",
2016 &vxlan_info
->vtep_ip
);
2017 if (vxlan_info
->access_vlan
)
2018 vty_out(vty
, " Access VLAN Id %u\n",
2019 vxlan_info
->access_vlan
);
2020 if (vxlan_info
->mcast_grp
.s_addr
!= INADDR_ANY
)
2021 vty_out(vty
, " Mcast Group %pI4",
2022 &vxlan_info
->mcast_grp
);
2023 if (vxlan_info
->ifindex_link
&&
2024 (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
2025 struct interface
*ifp
;
2027 ifp
= if_lookup_by_index_per_ns(
2028 zebra_ns_lookup(vxlan_info
->link_nsid
),
2029 vxlan_info
->ifindex_link
);
2030 vty_out(vty
, " Link Interface %s",
2031 ifp
== NULL
? "Unknown" :
2035 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2036 struct zebra_l2info_gre
*gre_info
;
2038 gre_info
= &zebra_if
->l2info
.gre
;
2039 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2040 vty_out(vty
, " VTEP IP: %pI4", &gre_info
->vtep_ip
);
2041 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2042 vty_out(vty
, " , remote %pI4",
2043 &gre_info
->vtep_ip_remote
);
2046 if (gre_info
->ifindex_link
&&
2047 (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2048 struct interface
*ifp
;
2050 ifp
= if_lookup_by_index_per_ns(
2051 zebra_ns_lookup(gre_info
->link_nsid
),
2052 gre_info
->ifindex_link
);
2053 vty_out(vty
, " Link Interface %s\n",
2054 ifp
== NULL
? "Unknown" :
2059 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2060 struct zebra_l2info_brslave
*br_slave
;
2062 br_slave
= &zebra_if
->brslave_info
;
2063 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2064 if (br_slave
->br_if
)
2065 vty_out(vty
, " Master interface: %s\n",
2066 br_slave
->br_if
->name
);
2068 vty_out(vty
, " Master ifindex: %u\n",
2069 br_slave
->bridge_ifindex
);
2073 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2074 struct zebra_l2info_bondslave
*bond_slave
;
2076 bond_slave
= &zebra_if
->bondslave_info
;
2077 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2078 if (bond_slave
->bond_if
)
2079 vty_out(vty
, " Master interface: %s\n",
2080 bond_slave
->bond_if
->name
);
2082 vty_out(vty
, " Master ifindex: %u\n",
2083 bond_slave
->bond_ifindex
);
2087 if (zebra_if
->flags
& ZIF_FLAG_LACP_BYPASS
)
2088 vty_out(vty
, " LACP bypass: on\n");
2090 zebra_evpn_if_es_print(vty
, NULL
, zebra_if
);
2091 vty_out(vty
, " protodown: %s %s\n",
2092 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off",
2093 if_is_protodown_applicable(ifp
) ? "" : "(n/a)");
2094 if (zebra_if
->protodown_rc
)
2095 vty_out(vty
, " protodown reasons: %s\n",
2096 zebra_protodown_rc_str(zebra_if
->protodown_rc
, pd_buf
,
2099 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2101 vty_out(vty
, " Parent interface: %s\n", zebra_if
->link
->name
);
2103 vty_out(vty
, " Parent ifindex: %d\n", zebra_if
->link_ifindex
);
2106 if (HAS_LINK_PARAMS(ifp
)) {
2108 struct if_link_params
*iflp
= ifp
->link_params
;
2109 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
2110 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2111 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
2112 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2113 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
2115 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2117 " Maximum Reservable Bandwidth %g (Byte/s)\n",
2119 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2121 " Unreserved Bandwidth per Class Type in Byte/s:\n");
2122 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
2124 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
2125 i
, iflp
->unrsv_bw
[i
], i
+ 1,
2126 iflp
->unrsv_bw
[i
+ 1]);
2129 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2130 vty_out(vty
, " Administrative Group:%u\n",
2132 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2133 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
2135 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2136 vty_out(vty
, " Min: %u (micro-sec.)",
2138 vty_out(vty
, " Max: %u (micro-sec.)",
2143 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2145 " Link Delay Variation %u (micro-sec.)\n",
2147 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2148 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
2150 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2151 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
2153 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2154 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
2156 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2157 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
2159 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2160 vty_out(vty
, " Neighbor ASBR IP: %pI4 AS: %u \n",
2161 &iflp
->rmt_ip
, iflp
->rmt_as
);
2164 hook_call(zebra_if_extra_info
, vty
, ifp
);
2166 if (listhead(ifp
->nbr_connected
))
2167 vty_out(vty
, " Neighbor address(s):\n");
2168 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
2169 nbr_connected_dump_vty(vty
, NULL
, nbr_connected
);
2171 #ifdef HAVE_PROC_NET_DEV
2172 /* Statistics print out using proc file system. */
2174 " %lu input packets (%lu multicast), %lu bytes, %lu dropped\n",
2175 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
2176 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
2179 " %lu input errors, %lu length, %lu overrun, %lu CRC, %lu frame\n",
2180 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
2181 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
2182 ifp
->stats
.rx_frame_errors
);
2184 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
2185 ifp
->stats
.rx_missed_errors
);
2187 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
2188 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
2189 ifp
->stats
.tx_dropped
);
2192 " %lu output errors, %lu aborted, %lu carrier, %lu fifo, %lu heartbeat\n",
2193 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
2194 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
2195 ifp
->stats
.tx_heartbeat_errors
);
2197 vty_out(vty
, " %lu window, %lu collisions\n",
2198 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
2199 #endif /* HAVE_PROC_NET_DEV */
2201 #ifdef HAVE_NET_RT_IFLIST
2202 /* Statistics print out using sysctl (). */
2204 " input packets %llu, bytes %llu, dropped %llu, multicast packets %llu\n",
2205 (unsigned long long)ifp
->stats
.ifi_ipackets
,
2206 (unsigned long long)ifp
->stats
.ifi_ibytes
,
2207 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
2208 (unsigned long long)ifp
->stats
.ifi_imcasts
);
2210 vty_out(vty
, " input errors %llu\n",
2211 (unsigned long long)ifp
->stats
.ifi_ierrors
);
2214 " output packets %llu, bytes %llu, multicast packets %llu\n",
2215 (unsigned long long)ifp
->stats
.ifi_opackets
,
2216 (unsigned long long)ifp
->stats
.ifi_obytes
,
2217 (unsigned long long)ifp
->stats
.ifi_omcasts
);
2219 vty_out(vty
, " output errors %llu\n",
2220 (unsigned long long)ifp
->stats
.ifi_oerrors
);
2222 vty_out(vty
, " collisions %llu\n",
2223 (unsigned long long)ifp
->stats
.ifi_collisions
);
2224 #endif /* HAVE_NET_RT_IFLIST */
2227 static void if_dump_vty_json(struct vty
*vty
, struct interface
*ifp
,
2230 struct connected
*connected
;
2231 struct nbr_connected
*nbr_connected
;
2232 struct listnode
*node
;
2233 struct route_node
*rn
;
2234 struct zebra_if
*zebra_if
;
2235 char pd_buf
[ZEBRA_PROTODOWN_RC_STR_LEN
];
2237 json_object
*json_if
;
2238 json_object
*json_addrs
;
2240 json_if
= json_object_new_object();
2241 json_object_object_add(json
, ifp
->name
, json_if
);
2243 if (if_is_up(ifp
)) {
2244 json_object_string_add(json_if
, "administrativeStatus", "up");
2246 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
2247 json_object_string_add(json_if
, "operationalStatus",
2248 if_is_running(ifp
) ? "up"
2250 json_object_boolean_add(json_if
, "linkDetection", true);
2252 json_object_boolean_add(json_if
, "linkDetection",
2256 json_object_string_add(json_if
, "administrativeStatus", "down");
2259 zebra_if
= ifp
->info
;
2261 json_object_int_add(json_if
, "linkUps", zebra_if
->up_count
);
2262 json_object_int_add(json_if
, "linkDowns", zebra_if
->down_count
);
2263 if (zebra_if
->up_last
[0])
2264 json_object_string_add(json_if
, "lastLinkUp",
2266 if (zebra_if
->down_last
[0])
2267 json_object_string_add(json_if
, "lastLinkDown",
2268 zebra_if
->down_last
);
2270 zebra_ptm_show_status(vty
, json
, ifp
);
2272 json_object_string_add(json_if
, "vrfName", ifp
->vrf
->name
);
2275 json_object_string_add(json_if
, "description", ifp
->desc
);
2277 json_object_string_add(json_if
, "OsDescription",
2280 json_object_boolean_add(json_if
, "mplsEnabled", zebra_if
->mpls
);
2281 json_object_boolean_add(json_if
, "linkDown", zebra_if
->linkdown
);
2282 json_object_boolean_add(json_if
, "linkDownV6", zebra_if
->linkdownv6
);
2283 json_object_boolean_add(json_if
, "mcForwardingV4",
2284 zebra_if
->v4mcast_on
);
2285 json_object_boolean_add(json_if
, "mcForwardingV6",
2286 zebra_if
->v6mcast_on
);
2288 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
2289 json_object_boolean_add(json_if
, "pseudoInterface", true);
2291 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2292 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2296 json_object_boolean_add(json_if
, "pseudoInterface", false);
2297 json_object_int_add(json_if
, "index", ifp
->ifindex
);
2298 json_object_int_add(json_if
, "metric", ifp
->metric
);
2299 json_object_int_add(json_if
, "mtu", ifp
->mtu
);
2300 if (ifp
->mtu6
!= ifp
->mtu
)
2301 json_object_int_add(json_if
, "mtu6", ifp
->mtu6
);
2302 json_object_int_add(json_if
, "speed", ifp
->speed
);
2303 json_object_string_add(json_if
, "flags", if_flag_dump(ifp
->flags
));
2305 /* Hardware address. */
2306 json_object_string_add(json_if
, "type", if_link_type_str(ifp
->ll_type
));
2307 if (ifp
->hw_addr_len
!= 0) {
2311 for (int i
= 0; i
< ifp
->hw_addr_len
; i
++) {
2312 snprintf(buf
, sizeof(buf
), "%s%02x", i
== 0 ? "" : ":",
2314 strlcat(hwbuf
, buf
, sizeof(hwbuf
));
2316 json_object_string_add(json_if
, "hardwareAddress", hwbuf
);
2319 /* Bandwidth in Mbps */
2320 if (ifp
->bandwidth
!= 0)
2321 json_object_int_add(json_if
, "bandwidth", ifp
->bandwidth
);
2325 json_addrs
= json_object_new_array();
2326 json_object_object_add(json_if
, "ipAddresses", json_addrs
);
2328 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
2332 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
2334 connected_dump_vty(vty
, json_addrs
, connected
);
2337 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
2338 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2339 && (connected
->address
->family
== AF_INET6
))
2340 connected_dump_vty(vty
, json_addrs
, connected
);
2343 json_object_string_add(json_if
, "interfaceType",
2344 zebra_ziftype_2str(zebra_if
->zif_type
));
2345 json_object_string_add(
2346 json_if
, "interfaceSlaveType",
2347 zebra_zifslavetype_2str(zebra_if
->zif_slave_type
));
2349 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
2350 struct zebra_l2info_bridge
*bridge_info
;
2352 bridge_info
= &zebra_if
->l2info
.br
;
2353 json_object_boolean_add(json_if
, "bridgeVlanAware",
2354 bridge_info
->vlan_aware
);
2355 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
2356 struct zebra_l2info_vlan
*vlan_info
;
2358 vlan_info
= &zebra_if
->l2info
.vl
;
2359 json_object_int_add(json_if
, "vlanId", vlan_info
->vid
);
2360 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
2361 struct zebra_l2info_vxlan
*vxlan_info
;
2363 vxlan_info
= &zebra_if
->l2info
.vxl
;
2364 json_object_int_add(json_if
, "vxlanId", vxlan_info
->vni
);
2365 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
2366 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2367 &vxlan_info
->vtep_ip
);
2368 if (vxlan_info
->access_vlan
)
2369 json_object_int_add(json_if
, "accessVlanId",
2370 vxlan_info
->access_vlan
);
2371 if (vxlan_info
->mcast_grp
.s_addr
!= INADDR_ANY
)
2372 json_object_string_addf(json_if
, "mcastGroup", "%pI4",
2373 &vxlan_info
->mcast_grp
);
2374 if (vxlan_info
->ifindex_link
2375 && (vxlan_info
->link_nsid
!= NS_UNKNOWN
)) {
2376 struct interface
*ifp
;
2378 ifp
= if_lookup_by_index_per_ns(
2379 zebra_ns_lookup(vxlan_info
->link_nsid
),
2380 vxlan_info
->ifindex_link
);
2381 json_object_string_add(json_if
, "linkInterface",
2382 ifp
== NULL
? "Unknown"
2385 } else if (IS_ZEBRA_IF_GRE(ifp
)) {
2386 struct zebra_l2info_gre
*gre_info
;
2388 gre_info
= &zebra_if
->l2info
.gre
;
2389 if (gre_info
->vtep_ip
.s_addr
!= INADDR_ANY
) {
2390 json_object_string_addf(json_if
, "vtepIp", "%pI4",
2391 &gre_info
->vtep_ip
);
2392 if (gre_info
->vtep_ip_remote
.s_addr
!= INADDR_ANY
)
2393 json_object_string_addf(
2394 json_if
, "vtepRemoteIp", "%pI4",
2395 &gre_info
->vtep_ip_remote
);
2397 if (gre_info
->ifindex_link
2398 && (gre_info
->link_nsid
!= NS_UNKNOWN
)) {
2399 struct interface
*ifp
;
2401 ifp
= if_lookup_by_index_per_ns(
2402 zebra_ns_lookup(gre_info
->link_nsid
),
2403 gre_info
->ifindex_link
);
2404 json_object_string_add(json_if
, "linkInterface",
2405 ifp
== NULL
? "Unknown"
2410 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
2411 struct zebra_l2info_brslave
*br_slave
;
2413 br_slave
= &zebra_if
->brslave_info
;
2414 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
2415 if (br_slave
->br_if
)
2416 json_object_string_add(json_if
,
2418 br_slave
->br_if
->name
);
2420 json_object_int_add(json_if
, "masterIfindex",
2421 br_slave
->bridge_ifindex
);
2425 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
2426 struct zebra_l2info_bondslave
*bond_slave
;
2428 bond_slave
= &zebra_if
->bondslave_info
;
2429 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
2430 if (bond_slave
->bond_if
)
2431 json_object_string_add(
2432 json_if
, "masterInterface",
2433 bond_slave
->bond_if
->name
);
2435 json_object_int_add(json_if
, "masterIfindex",
2436 bond_slave
->bond_ifindex
);
2440 json_object_boolean_add(
2441 json_if
, "lacpBypass",
2442 CHECK_FLAG(zebra_if
->flags
, ZIF_FLAG_LACP_BYPASS
));
2444 zebra_evpn_if_es_print(vty
, json_if
, zebra_if
);
2446 if (if_is_protodown_applicable(ifp
)) {
2447 json_object_string_add(
2448 json_if
, "protodown",
2449 (ZEBRA_IF_IS_PROTODOWN(zebra_if
)) ? "on" : "off");
2450 if (zebra_if
->protodown_rc
)
2451 json_object_string_add(
2452 json_if
, "protodownReason",
2453 zebra_protodown_rc_str(zebra_if
->protodown_rc
,
2454 pd_buf
, sizeof(pd_buf
)));
2457 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
2459 json_object_string_add(json_if
, "parentInterface",
2460 zebra_if
->link
->name
);
2462 json_object_int_add(json_if
, "parentIfindex",
2463 zebra_if
->link_ifindex
);
2466 if (HAS_LINK_PARAMS(ifp
)) {
2467 struct if_link_params
*iflp
= ifp
->link_params
;
2468 json_object
*json_te
;
2470 json_te
= json_object_new_object();
2471 json_object_object_add(
2472 json_if
, "trafficEngineeringLinkParameters", json_te
);
2474 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
2475 json_object_int_add(json_te
, "teMetric",
2477 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
2478 json_object_double_add(json_te
, "maximumBandwidth",
2480 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
2481 json_object_double_add(json_te
,
2482 "maximumReservableBandwidth",
2484 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
2485 json_object
*json_bws
;
2487 json_bws
= json_object_new_object();
2488 json_object_object_add(json_te
, "unreservedBandwidth",
2490 for (unsigned int i
= 0; i
< MAX_CLASS_TYPE
; ++i
) {
2493 snprintf(buf_ct
, sizeof(buf_ct
), "classType%u",
2495 json_object_double_add(json_bws
, buf_ct
,
2500 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
2501 json_object_int_add(json_te
, "administrativeGroup",
2503 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
2504 json_object_int_add(json_te
, "linkDelayAverage",
2506 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2507 json_object_int_add(json_te
, "linkDelayMinimum",
2509 json_object_int_add(json_te
, "linkDelayMaximum",
2513 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
2514 json_object_int_add(json_te
, "linkDelayVariation",
2516 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
2517 json_object_double_add(json_te
, "linkPacketLoss",
2519 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
2520 json_object_double_add(json_te
, "availableBandwidth",
2522 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
2523 json_object_double_add(json_te
, "residualBandwidth",
2525 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
2526 json_object_double_add(json_te
, "utilizedBandwidth",
2528 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
2529 json_object_string_addf(json_te
, "neighborAsbrIp",
2530 "%pI4", &iflp
->rmt_ip
);
2531 json_object_int_add(json_te
, "neighborAsbrAs", iflp
->rmt_as
);
2534 if (listhead(ifp
->nbr_connected
)) {
2535 json_object
*json_nbr_addrs
;
2537 json_nbr_addrs
= json_object_new_array();
2538 json_object_object_add(json_if
, "neighborIpAddresses",
2541 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
2543 nbr_connected_dump_vty(vty
, json_nbr_addrs
,
2547 #ifdef HAVE_PROC_NET_DEV
2548 json_object_int_add(json_if
, "inputPackets", stats
.rx_packets
);
2549 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.rx_bytes
);
2550 json_object_int_add(json_if
, "inputDropped", ifp
->stats
.rx_dropped
);
2551 json_object_int_add(json_if
, "inputMulticastPackets",
2552 ifp
->stats
.rx_multicast
);
2553 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.rx_errors
);
2554 json_object_int_add(json_if
, "inputLengthErrors",
2555 ifp
->stats
.rx_length_errors
);
2556 json_object_int_add(json_if
, "inputOverrunErrors",
2557 ifp
->stats
.rx_over_errors
);
2558 json_object_int_add(json_if
, "inputCrcErrors",
2559 ifp
->stats
.rx_crc_errors
);
2560 json_object_int_add(json_if
, "inputFrameErrors",
2561 ifp
->stats
.rx_frame_errors
);
2562 json_object_int_add(json_if
, "inputFifoErrors",
2563 ifp
->stats
.rx_fifo_errors
);
2564 json_object_int_add(json_if
, "inputMissedErrors",
2565 ifp
->stats
.rx_missed_errors
);
2566 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.tx_packets
);
2567 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.tx_bytes
);
2568 json_object_int_add(json_if
, "outputDroppedPackets",
2569 ifp
->stats
.tx_dropped
);
2570 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.tx_errors
);
2571 json_object_int_add(json_if
, "outputAbortedErrors",
2572 ifp
->stats
.tx_aborted_errors
);
2573 json_object_int_add(json_if
, "outputCarrierErrors",
2574 ifp
->stats
.tx_carrier_errors
);
2575 json_object_int_add(json_if
, "outputFifoErrors",
2576 ifp
->stats
.tx_fifo_errors
);
2577 json_object_int_add(json_if
, "outputHeartbeatErrors",
2578 ifp
->stats
.tx_heartbeat_errors
);
2579 json_object_int_add(json_if
, "outputWindowErrors",
2580 ifp
->stats
.tx_window_errors
);
2581 json_object_int_add(json_if
, "collisions", ifp
->stats
.collisions
);
2582 #endif /* HAVE_PROC_NET_DEV */
2584 #ifdef HAVE_NET_RT_IFLIST
2585 json_object_int_add(json_if
, "inputPackets", ifp
->stats
.ifi_ipackets
);
2586 json_object_int_add(json_if
, "inputBytes", ifp
->stats
.ifi_ibytes
);
2587 json_object_int_add(json_if
, "inputDropd", ifp
->stats
.ifi_iqdrops
);
2588 json_object_int_add(json_if
, "inputMulticastPackets",
2589 ifp
->stats
.ifi_imcasts
);
2590 json_object_int_add(json_if
, "inputErrors", ifp
->stats
.ifi_ierrors
);
2591 json_object_int_add(json_if
, "outputPackets", ifp
->stats
.ifi_opackets
);
2592 json_object_int_add(json_if
, "outputBytes", ifp
->stats
.ifi_obytes
);
2593 json_object_int_add(json_if
, "outputMulticastPackets",
2594 ifp
->stats
.ifi_omcasts
);
2595 json_object_int_add(json_if
, "outputErrors", ifp
->stats
.ifi_oerrors
);
2596 json_object_int_add(json_if
, "collisions", ifp
->stats
.ifi_collisions
);
2597 #endif /* HAVE_NET_RT_IFLIST */
2600 static void interface_update_stats(void)
2602 #ifdef HAVE_PROC_NET_DEV
2603 /* If system has interface statistics via proc file system, update
2605 ifstat_update_proc();
2606 #endif /* HAVE_PROC_NET_DEV */
2607 #ifdef HAVE_NET_RT_IFLIST
2608 ifstat_update_sysctl();
2609 #endif /* HAVE_NET_RT_IFLIST */
2612 #include "zebra/interface_clippy.c"
2613 /* Show all interfaces to vty. */
2614 DEFPY(show_interface
, show_interface_cmd
,
2615 "show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
2617 "Interface status and configuration\n"
2619 "Interface status and configuration summary\n"
2623 struct interface
*ifp
;
2624 json_object
*json
= NULL
;
2626 interface_update_stats();
2628 vrf
= vrf_lookup_by_name(vrf_name
);
2631 vty_out(vty
, "{}\n");
2633 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2638 json
= json_object_new_object();
2642 ifs_dump_brief_vty_json(json
, vrf
);
2644 ifs_dump_brief_vty(vty
, vrf
);
2646 FOR_ALL_INTERFACES (vrf
, ifp
) {
2648 if_dump_vty_json(vty
, ifp
, json
);
2650 if_dump_vty(vty
, ifp
);
2655 vty_json(vty
, json
);
2661 /* Show all interfaces to vty. */
2662 DEFPY (show_interface_vrf_all
,
2663 show_interface_vrf_all_cmd
,
2664 "show interface [vrf all] [brief$brief] [json$uj]",
2666 "Interface status and configuration\n"
2667 VRF_ALL_CMD_HELP_STR
2668 "Interface status and configuration summary\n"
2672 struct interface
*ifp
;
2673 json_object
*json
= NULL
;
2675 interface_update_stats();
2678 json
= json_object_new_object();
2680 /* All interface print. */
2681 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2684 ifs_dump_brief_vty_json(json
, vrf
);
2686 ifs_dump_brief_vty(vty
, vrf
);
2688 FOR_ALL_INTERFACES (vrf
, ifp
) {
2690 if_dump_vty_json(vty
, ifp
, json
);
2692 if_dump_vty(vty
, ifp
);
2698 vty_json(vty
, json
);
2703 /* Show specified interface to vty. */
2705 DEFPY (show_interface_name_vrf
,
2706 show_interface_name_vrf_cmd
,
2707 "show interface IFNAME$ifname vrf NAME$vrf_name [json$uj]",
2709 "Interface status and configuration\n"
2714 struct interface
*ifp
;
2716 json_object
*json
= NULL
;
2718 interface_update_stats();
2720 vrf
= vrf_lookup_by_name(vrf_name
);
2723 vty_out(vty
, "{}\n");
2725 vty_out(vty
, "%% VRF %s not found\n", vrf_name
);
2729 ifp
= if_lookup_by_name_vrf(ifname
, vrf
);
2732 vty_out(vty
, "{}\n");
2734 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2739 json
= json_object_new_object();
2742 if_dump_vty_json(vty
, ifp
, json
);
2744 if_dump_vty(vty
, ifp
);
2747 vty_json(vty
, json
);
2752 /* Show specified interface to vty. */
2753 DEFPY (show_interface_name_vrf_all
,
2754 show_interface_name_vrf_all_cmd
,
2755 "show interface IFNAME$ifname [vrf all] [json$uj]",
2757 "Interface status and configuration\n"
2759 VRF_ALL_CMD_HELP_STR
2762 struct interface
*ifp
= NULL
;
2763 struct interface
*ifptmp
;
2765 json_object
*json
= NULL
;
2768 interface_update_stats();
2770 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2771 ifptmp
= if_lookup_by_name_vrf(ifname
, vrf
);
2775 if (!vrf_is_backend_netns())
2782 vty_out(vty
, "{}\n");
2784 vty_out(vty
, "%% Can't find interface %s\n", ifname
);
2789 vty_out(vty
, "{}\n");
2792 "%% There are multiple interfaces with name %s\n",
2794 vty_out(vty
, "%% You must specify the VRF name\n");
2800 json
= json_object_new_object();
2803 if_dump_vty_json(vty
, ifp
, json
);
2805 if_dump_vty(vty
, ifp
);
2808 vty_json(vty
, json
);
2813 static void if_show_description(struct vty
*vty
, struct vrf
*vrf
)
2815 struct interface
*ifp
;
2817 vty_out(vty
, "Interface Status Protocol Description\n");
2818 FOR_ALL_INTERFACES (vrf
, ifp
) {
2820 struct zebra_if
*zif
;
2825 len
= vty_out(vty
, "%s", ifp
->name
);
2826 vty_out(vty
, "%*s", (16 - len
), " ");
2828 if (if_is_up(ifp
)) {
2829 vty_out(vty
, "up ");
2830 if (CHECK_FLAG(ifp
->status
,
2831 ZEBRA_INTERFACE_LINKDETECTION
)) {
2832 if (if_is_running(ifp
))
2833 vty_out(vty
, "up ");
2835 vty_out(vty
, "down ");
2837 vty_out(vty
, "unknown ");
2840 vty_out(vty
, "down down ");
2845 vty_out(vty
, "%s", ifp
->desc
);
2848 if (zif
&& zif
->desc
) {
2849 vty_out(vty
, "%s%s",
2860 DEFUN (show_interface_desc
,
2861 show_interface_desc_cmd
,
2862 "show interface description vrf NAME",
2864 "Interface status and configuration\n"
2865 "Interface description\n"
2870 vrf
= vrf_lookup_by_name(argv
[4]->arg
);
2872 vty_out(vty
, "%% VRF %s not found\n", argv
[4]->arg
);
2876 if_show_description(vty
, vrf
);
2882 DEFUN (show_interface_desc_vrf_all
,
2883 show_interface_desc_vrf_all_cmd
,
2884 "show interface description [vrf all]",
2886 "Interface status and configuration\n"
2887 "Interface description\n"
2888 VRF_ALL_CMD_HELP_STR
)
2892 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2893 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
2894 vty_out(vty
, "\n\tVRF %s(%u)\n\n", VRF_LOGNAME(vrf
),
2896 if_show_description(vty
, vrf
);
2902 int if_multicast_set(struct interface
*ifp
)
2904 struct zebra_if
*if_data
;
2906 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2907 if (if_set_flags(ifp
, IFF_MULTICAST
) < 0) {
2908 zlog_debug("Can't set multicast flag on interface %s",
2914 if_data
= ifp
->info
;
2915 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
2923 "Set multicast flag to interface\n")
2925 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2927 struct zebra_if
*if_data
;
2929 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2930 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
2932 vty_out(vty
, "Can't set multicast flag\n");
2933 return CMD_WARNING_CONFIG_FAILED
;
2937 if_data
= ifp
->info
;
2938 if_data
->multicast
= IF_ZEBRA_DATA_ON
;
2948 "Set mpls to be on for the interface\n")
2950 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2951 struct zebra_if
*if_data
= ifp
->info
;
2954 dplane_intf_mpls_modify_state(ifp
, false);
2955 if_data
->mpls
= IF_ZEBRA_DATA_UNSPEC
;
2957 dplane_intf_mpls_modify_state(ifp
, true);
2958 if_data
->mpls
= IF_ZEBRA_DATA_ON
;
2964 int if_multicast_unset(struct interface
*ifp
)
2966 struct zebra_if
*if_data
;
2968 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2969 if (if_unset_flags(ifp
, IFF_MULTICAST
) < 0) {
2970 zlog_debug("Can't unset multicast flag on interface %s",
2976 if_data
= ifp
->info
;
2977 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
2982 DEFUN (no_multicast
,
2986 "Unset multicast flag to interface\n")
2988 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2990 struct zebra_if
*if_data
;
2992 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2993 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
2995 vty_out(vty
, "Can't unset multicast flag\n");
2996 return CMD_WARNING_CONFIG_FAILED
;
3000 if_data
= ifp
->info
;
3001 if_data
->multicast
= IF_ZEBRA_DATA_OFF
;
3006 int if_linkdetect(struct interface
*ifp
, bool detect
)
3008 int if_was_operative
;
3010 if_was_operative
= if_is_no_ptm_operative(ifp
);
3012 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3014 /* When linkdetection is enabled, if might come down */
3015 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
3018 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
3020 /* Interface may come up after disabling link detection */
3021 if (if_is_operative(ifp
) && !if_was_operative
)
3024 /* FIXME: Will defer status change forwarding if interface
3025 does not come down! */
3029 DEFUN(linkdetect
, linkdetect_cmd
, "link-detect",
3030 "Enable link detection on interface\n")
3032 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3034 if_linkdetect(ifp
, true);
3040 DEFUN (no_linkdetect
,
3044 "Disable link detection on interface\n")
3046 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3048 if_linkdetect(ifp
, false);
3053 int if_shutdown(struct interface
*ifp
)
3055 struct zebra_if
*if_data
;
3057 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3058 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3060 if (if_unset_flags(ifp
, IFF_UP
) < 0) {
3061 zlog_debug("Can't shutdown interface %s", ifp
->name
);
3066 if_data
= ifp
->info
;
3067 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3075 "Shutdown the selected interface\n")
3077 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3079 struct zebra_if
*if_data
;
3081 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3082 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3084 ret
= if_unset_flags(ifp
, IFF_UP
);
3086 vty_out(vty
, "Can't shutdown interface\n");
3087 return CMD_WARNING_CONFIG_FAILED
;
3091 if_data
= ifp
->info
;
3092 if_data
->shutdown
= IF_ZEBRA_DATA_ON
;
3097 int if_no_shutdown(struct interface
*ifp
)
3099 struct zebra_if
*if_data
;
3101 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3102 if (if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
) < 0) {
3103 zlog_debug("Can't up interface %s", ifp
->name
);
3108 /* Some addresses (in particular, IPv6 addresses on Linux) get
3109 * removed when the interface goes down. They need to be
3112 if_addr_wakeup(ifp
);
3115 if_data
= ifp
->info
;
3116 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3121 DEFUN (no_shutdown_if
,
3125 "Shutdown the selected interface\n")
3127 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3129 struct zebra_if
*if_data
;
3131 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
3132 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3134 vty_out(vty
, "Can't up interface\n");
3135 return CMD_WARNING_CONFIG_FAILED
;
3139 /* Some addresses (in particular, IPv6 addresses on Linux) get
3140 * removed when the interface goes down. They need to be
3143 if_addr_wakeup(ifp
);
3146 if_data
= ifp
->info
;
3147 if_data
->shutdown
= IF_ZEBRA_DATA_OFF
;
3152 DEFUN (bandwidth_if
,
3154 "bandwidth (1-100000)",
3155 "Set bandwidth informational parameter\n"
3156 "Bandwidth in megabits\n")
3159 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3160 unsigned int bandwidth
;
3162 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
3164 /* bandwidth range is <1-100000> */
3165 if (bandwidth
< 1 || bandwidth
> 100000) {
3166 vty_out(vty
, "Bandwidth is invalid\n");
3167 return CMD_WARNING_CONFIG_FAILED
;
3170 ifp
->bandwidth
= bandwidth
;
3172 /* force protocols to recalculate routes due to cost change */
3173 if (if_is_operative(ifp
))
3174 zebra_interface_up_update(ifp
);
3179 DEFUN (no_bandwidth_if
,
3180 no_bandwidth_if_cmd
,
3181 "no bandwidth [(1-100000)]",
3183 "Set bandwidth informational parameter\n"
3184 "Bandwidth in megabits\n")
3186 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3190 /* force protocols to recalculate routes due to cost change */
3191 if (if_is_operative(ifp
))
3192 zebra_interface_up_update(ifp
);
3198 struct cmd_node link_params_node
= {
3199 .name
= "link-params",
3200 .node
= LINK_PARAMS_NODE
,
3201 .parent_node
= INTERFACE_NODE
,
3202 .prompt
= "%s(config-link-params)# ",
3206 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
3207 uint32_t type
, uint32_t value
)
3209 /* Update field as needed */
3210 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
3212 SET_PARAM(ifp
->link_params
, type
);
3214 /* force protocols to update LINK STATE due to parameters change
3216 if (if_is_operative(ifp
))
3217 zebra_interface_parameters_update(ifp
);
3220 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
3221 uint32_t type
, float value
)
3224 /* Update field as needed */
3225 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
3227 SET_PARAM(ifp
->link_params
, type
);
3229 /* force protocols to update LINK STATE due to parameters change
3231 if (if_is_operative(ifp
))
3232 zebra_interface_parameters_update(ifp
);
3236 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
3238 if (ifp
->link_params
== NULL
)
3242 UNSET_PARAM(ifp
->link_params
, type
);
3244 /* force protocols to update LINK STATE due to parameters change */
3245 if (if_is_operative(ifp
))
3246 zebra_interface_parameters_update(ifp
);
3249 DEFUN_NOSH (link_params
,
3254 /* vty->qobj_index stays the same @ interface pointer */
3255 vty
->node
= LINK_PARAMS_NODE
;
3260 DEFUN_NOSH (exit_link_params
,
3261 exit_link_params_cmd
,
3263 "Exit from Link Params configuration mode\n")
3265 if (vty
->node
== LINK_PARAMS_NODE
)
3266 vty
->node
= INTERFACE_NODE
;
3270 /* Specific Traffic Engineering parameters commands */
3271 DEFUN (link_params_enable
,
3272 link_params_enable_cmd
,
3274 "Activate link parameters on this interface\n")
3276 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3278 /* This command could be issue at startup, when activate MPLS TE */
3279 /* on a new interface or after a ON / OFF / ON toggle */
3280 /* In all case, TE parameters are reset to their default factory */
3281 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3283 "Link-params: enable TE link parameters on interface %s",
3286 if (!if_link_params_get(ifp
))
3287 if_link_params_enable(ifp
);
3289 /* force protocols to update LINK STATE due to parameters change */
3290 if (if_is_operative(ifp
))
3291 zebra_interface_parameters_update(ifp
);
3296 DEFUN (no_link_params_enable
,
3297 no_link_params_enable_cmd
,
3300 "Disable link parameters on this interface\n")
3302 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3304 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
3305 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
3308 if_link_params_free(ifp
);
3310 /* force protocols to update LINK STATE due to parameters change */
3311 if (if_is_operative(ifp
))
3312 zebra_interface_parameters_update(ifp
);
3317 /* STANDARD TE metrics */
3318 DEFUN (link_params_metric
,
3319 link_params_metric_cmd
,
3320 "metric (0-4294967295)",
3321 "Link metric for MPLS-TE purpose\n"
3322 "Metric value in decimal\n")
3325 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3326 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3329 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3332 iflp
= if_link_params_enable(ifp
);
3334 /* Update TE metric if needed */
3335 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
3340 DEFUN (no_link_params_metric
,
3341 no_link_params_metric_cmd
,
3344 "Disable Link Metric on this interface\n")
3346 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3348 /* Unset TE Metric */
3349 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
3354 DEFUN (link_params_maxbw
,
3355 link_params_maxbw_cmd
,
3357 "Maximum bandwidth that can be used\n"
3358 "Bytes/second (IEEE floating point format)\n")
3360 int idx_bandwidth
= 1;
3361 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3362 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3366 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3367 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
3368 safe_strerror(errno
));
3369 return CMD_WARNING_CONFIG_FAILED
;
3372 /* Check that Maximum bandwidth is not lower than other bandwidth
3374 if (iflp
&& ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0]) ||
3375 (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2]) ||
3376 (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4]) ||
3377 (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6]) ||
3378 (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
) ||
3379 (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
))) {
3381 "Maximum Bandwidth could not be lower than others bandwidth\n");
3382 return CMD_WARNING_CONFIG_FAILED
;
3386 iflp
= if_link_params_enable(ifp
);
3388 /* Update Maximum Bandwidth if needed */
3389 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
3394 DEFUN (link_params_max_rsv_bw
,
3395 link_params_max_rsv_bw_cmd
,
3396 "max-rsv-bw BANDWIDTH",
3397 "Maximum bandwidth that may be reserved\n"
3398 "Bytes/second (IEEE floating point format)\n")
3400 int idx_bandwidth
= 1;
3401 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3402 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3405 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3406 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
3407 safe_strerror(errno
));
3408 return CMD_WARNING_CONFIG_FAILED
;
3411 /* Check that bandwidth is not greater than maximum bandwidth parameter
3413 if (iflp
&& bw
> iflp
->max_bw
) {
3415 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3417 return CMD_WARNING_CONFIG_FAILED
;
3421 iflp
= if_link_params_enable(ifp
);
3423 /* Update Maximum Reservable Bandwidth if needed */
3424 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
3429 DEFUN (link_params_unrsv_bw
,
3430 link_params_unrsv_bw_cmd
,
3431 "unrsv-bw (0-7) BANDWIDTH",
3432 "Unreserved bandwidth at each priority level\n"
3434 "Bytes/second (IEEE floating point format)\n")
3437 int idx_bandwidth
= 2;
3438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3439 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3443 /* We don't have to consider about range check here. */
3444 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
3445 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3446 safe_strerror(errno
));
3447 return CMD_WARNING_CONFIG_FAILED
;
3450 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3451 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
3452 safe_strerror(errno
));
3453 return CMD_WARNING_CONFIG_FAILED
;
3456 /* Check that bandwidth is not greater than maximum bandwidth parameter
3458 if (iflp
&& bw
> iflp
->max_bw
) {
3460 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3462 return CMD_WARNING_CONFIG_FAILED
;
3466 iflp
= if_link_params_enable(ifp
);
3468 /* Update Unreserved Bandwidth if needed */
3469 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
3475 DEFUN (link_params_admin_grp
,
3476 link_params_admin_grp_cmd
,
3477 "admin-grp BITPATTERN",
3478 "Administrative group membership\n"
3479 "32-bit Hexadecimal value (e.g. 0xa1)\n")
3481 int idx_bitpattern
= 1;
3482 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3483 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3484 unsigned long value
;
3486 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
3487 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
3488 safe_strerror(errno
));
3489 return CMD_WARNING_CONFIG_FAILED
;
3493 iflp
= if_link_params_enable(ifp
);
3495 /* Update Administrative Group if needed */
3496 link_param_cmd_set_uint32(ifp
, &iflp
->admin_grp
, LP_ADM_GRP
, value
);
3501 DEFUN (no_link_params_admin_grp
,
3502 no_link_params_admin_grp_cmd
,
3505 "Disable Administrative group membership on this interface\n")
3507 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3509 /* Unset Admin Group */
3510 link_param_cmd_unset(ifp
, LP_ADM_GRP
);
3515 /* RFC5392 & RFC5316: INTER-AS */
3516 DEFUN (link_params_inter_as
,
3517 link_params_inter_as_cmd
,
3518 "neighbor A.B.C.D as (1-4294967295)",
3519 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
3520 "Remote IP address in dot decimal A.B.C.D\n"
3521 "Remote AS number\n"
3522 "AS number in the range <1-4294967295>\n")
3527 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3528 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3529 struct in_addr addr
;
3532 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
3533 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
3534 return CMD_WARNING_CONFIG_FAILED
;
3538 iflp
= if_link_params_enable(ifp
);
3540 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3542 /* Update Remote IP and Remote AS fields if needed */
3543 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
3544 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
3547 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
3548 SET_PARAM(iflp
, LP_RMT_AS
);
3550 /* force protocols to update LINK STATE due to parameters change
3552 if (if_is_operative(ifp
))
3553 zebra_interface_parameters_update(ifp
);
3558 DEFUN (no_link_params_inter_as
,
3559 no_link_params_inter_as_cmd
,
3562 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
3564 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3565 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3570 /* Reset Remote IP and AS neighbor */
3572 iflp
->rmt_ip
.s_addr
= 0;
3573 UNSET_PARAM(iflp
, LP_RMT_AS
);
3575 /* force protocols to update LINK STATE due to parameters change */
3576 if (if_is_operative(ifp
))
3577 zebra_interface_parameters_update(ifp
);
3582 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
3583 * draft-ietf-isis-metric-extensions-07.txt */
3584 DEFUN (link_params_delay
,
3585 link_params_delay_cmd
,
3586 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
3587 "Unidirectional Average Link Delay\n"
3588 "Average delay in micro-second as decimal (0...16777215)\n"
3590 "Minimum delay in micro-second as decimal (0...16777215)\n"
3592 "Maximum delay in micro-second as decimal (0...16777215)\n")
3594 /* Get and Check new delay values */
3595 uint32_t delay
= 0, low
= 0, high
= 0;
3596 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
3598 low
= strtoul(argv
[3]->arg
, NULL
, 10);
3599 high
= strtoul(argv
[5]->arg
, NULL
, 10);
3602 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3603 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3608 * Check new delay value against old Min and Max delays if set
3610 * RFC 7471 Section 4.2.7:
3611 * It is possible for min delay and max delay to be
3614 * Therefore, it is also allowed that the average
3615 * delay be equal to the min delay or max delay.
3617 if (iflp
&& IS_PARAM_SET(iflp
, LP_MM_DELAY
) &&
3618 (delay
< iflp
->min_delay
|| delay
> iflp
->max_delay
)) {
3620 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3621 iflp
->min_delay
, iflp
->max_delay
);
3622 return CMD_WARNING_CONFIG_FAILED
;
3626 iflp
= if_link_params_enable(ifp
);
3628 /* Update delay if value is not set or change */
3629 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
3630 iflp
->av_delay
= delay
;
3631 SET_PARAM(iflp
, LP_DELAY
);
3634 /* Unset Min and Max delays if already set */
3635 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3636 iflp
->min_delay
= 0;
3637 iflp
->max_delay
= 0;
3638 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3643 * Check new delays value coherency. See above note
3644 * regarding average delay equal to min/max allowed
3646 if (delay
< low
|| delay
> high
) {
3648 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3650 return CMD_WARNING_CONFIG_FAILED
;
3654 iflp
= if_link_params_enable(ifp
);
3656 /* Update Delays if needed */
3657 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
3658 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
3659 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
3660 || iflp
->max_delay
!= high
) {
3661 iflp
->av_delay
= delay
;
3662 SET_PARAM(iflp
, LP_DELAY
);
3663 iflp
->min_delay
= low
;
3664 iflp
->max_delay
= high
;
3665 SET_PARAM(iflp
, LP_MM_DELAY
);
3670 /* force protocols to update LINK STATE due to parameters change */
3671 if (update
== 1 && if_is_operative(ifp
))
3672 zebra_interface_parameters_update(ifp
);
3677 DEFUN (no_link_params_delay
,
3678 no_link_params_delay_cmd
,
3681 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
3683 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3684 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3691 UNSET_PARAM(iflp
, LP_DELAY
);
3692 iflp
->min_delay
= 0;
3693 iflp
->max_delay
= 0;
3694 UNSET_PARAM(iflp
, LP_MM_DELAY
);
3696 /* force protocols to update LINK STATE due to parameters change */
3697 if (if_is_operative(ifp
))
3698 zebra_interface_parameters_update(ifp
);
3703 DEFUN (link_params_delay_var
,
3704 link_params_delay_var_cmd
,
3705 "delay-variation (0-16777215)",
3706 "Unidirectional Link Delay Variation\n"
3707 "delay variation in micro-second as decimal (0...16777215)\n")
3710 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3711 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3714 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3717 iflp
= if_link_params_enable(ifp
);
3719 /* Update Delay Variation if needed */
3720 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
3725 DEFUN (no_link_params_delay_var
,
3726 no_link_params_delay_var_cmd
,
3727 "no delay-variation",
3729 "Disable Unidirectional Delay Variation on this interface\n")
3731 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3733 /* Unset Delay Variation */
3734 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
3739 DEFUN (link_params_pkt_loss
,
3740 link_params_pkt_loss_cmd
,
3741 "packet-loss PERCENTAGE",
3742 "Unidirectional Link Packet Loss\n"
3743 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
3745 int idx_percentage
= 1;
3746 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3747 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3750 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
3751 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
3752 safe_strerror(errno
));
3753 return CMD_WARNING_CONFIG_FAILED
;
3756 if (fval
> MAX_PKT_LOSS
)
3757 fval
= MAX_PKT_LOSS
;
3760 iflp
= if_link_params_enable(ifp
);
3762 /* Update Packet Loss if needed */
3763 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
3768 DEFUN (no_link_params_pkt_loss
,
3769 no_link_params_pkt_loss_cmd
,
3772 "Disable Unidirectional Link Packet Loss on this interface\n")
3774 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3776 /* Unset Packet Loss */
3777 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
3782 DEFUN (link_params_res_bw
,
3783 link_params_res_bw_cmd
,
3785 "Unidirectional Residual Bandwidth\n"
3786 "Bytes/second (IEEE floating point format)\n")
3788 int idx_bandwidth
= 1;
3789 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3790 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3793 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3794 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
3795 safe_strerror(errno
));
3796 return CMD_WARNING_CONFIG_FAILED
;
3799 /* Check that bandwidth is not greater than maximum bandwidth parameter
3801 if (iflp
&& bw
> iflp
->max_bw
) {
3803 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3805 return CMD_WARNING_CONFIG_FAILED
;
3809 iflp
= if_link_params_enable(ifp
);
3811 /* Update Residual Bandwidth if needed */
3812 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
3817 DEFUN (no_link_params_res_bw
,
3818 no_link_params_res_bw_cmd
,
3821 "Disable Unidirectional Residual Bandwidth on this interface\n")
3823 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3825 /* Unset Residual Bandwidth */
3826 link_param_cmd_unset(ifp
, LP_RES_BW
);
3831 DEFUN (link_params_ava_bw
,
3832 link_params_ava_bw_cmd
,
3834 "Unidirectional Available Bandwidth\n"
3835 "Bytes/second (IEEE floating point format)\n")
3837 int idx_bandwidth
= 1;
3838 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3839 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3842 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3843 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
3844 safe_strerror(errno
));
3845 return CMD_WARNING_CONFIG_FAILED
;
3848 /* Check that bandwidth is not greater than maximum bandwidth parameter
3850 if (iflp
&& bw
> iflp
->max_bw
) {
3852 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3854 return CMD_WARNING_CONFIG_FAILED
;
3858 iflp
= if_link_params_enable(ifp
);
3860 /* Update Residual Bandwidth if needed */
3861 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
3866 DEFUN (no_link_params_ava_bw
,
3867 no_link_params_ava_bw_cmd
,
3870 "Disable Unidirectional Available Bandwidth on this interface\n")
3872 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3874 /* Unset Available Bandwidth */
3875 link_param_cmd_unset(ifp
, LP_AVA_BW
);
3880 DEFUN (link_params_use_bw
,
3881 link_params_use_bw_cmd
,
3883 "Unidirectional Utilised Bandwidth\n"
3884 "Bytes/second (IEEE floating point format)\n")
3886 int idx_bandwidth
= 1;
3887 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3888 struct if_link_params
*iflp
= if_link_params_get(ifp
);
3891 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
3892 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
3893 safe_strerror(errno
));
3894 return CMD_WARNING_CONFIG_FAILED
;
3897 /* Check that bandwidth is not greater than maximum bandwidth parameter
3899 if (iflp
&& bw
> iflp
->max_bw
) {
3901 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3903 return CMD_WARNING_CONFIG_FAILED
;
3907 iflp
= if_link_params_enable(ifp
);
3909 /* Update Utilized Bandwidth if needed */
3910 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
3915 DEFUN (no_link_params_use_bw
,
3916 no_link_params_use_bw_cmd
,
3919 "Disable Unidirectional Utilised Bandwidth on this interface\n")
3921 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3923 /* Unset Utilised Bandwidth */
3924 link_param_cmd_unset(ifp
, LP_USE_BW
);
3929 int if_ip_address_install(struct interface
*ifp
, struct prefix
*prefix
,
3930 const char *label
, struct prefix
*pp
)
3932 struct zebra_if
*if_data
;
3933 struct prefix_ipv4 lp
;
3934 struct prefix_ipv4
*p
;
3935 struct connected
*ifc
;
3936 enum zebra_dplane_result dplane_res
;
3938 if_data
= ifp
->info
;
3940 lp
.family
= prefix
->family
;
3941 lp
.prefix
= prefix
->u
.prefix4
;
3942 lp
.prefixlen
= prefix
->prefixlen
;
3943 apply_mask_ipv4(&lp
);
3945 ifc
= connected_check_ptp(ifp
, &lp
, pp
? pp
: NULL
);
3947 ifc
= connected_new();
3951 p
= prefix_ipv4_new();
3953 ifc
->address
= (struct prefix
*)p
;
3956 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
3957 p
= prefix_ipv4_new();
3958 *p
= *(struct prefix_ipv4
*)pp
;
3959 ifc
->destination
= (struct prefix
*)p
;
3964 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
3966 /* Add to linked list. */
3967 listnode_add(ifp
->connected
, ifc
);
3970 /* This address is configured from zebra. */
3971 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3972 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3974 /* In case of this route need to install kernel. */
3975 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
3976 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
3977 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
3978 /* Some system need to up the interface to set IP address. */
3979 if (!if_is_up(ifp
)) {
3980 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3984 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
3985 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3987 "dplane can't set interface IP address: %s.",
3988 dplane_res2str(dplane_res
));
3992 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3993 /* The address will be advertised to zebra clients when the
3995 * from the kernel has been received.
3996 * It will also be added to the subnet chain list, then. */
4002 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
4003 const char *addr_str
, const char *peer_str
,
4006 struct zebra_if
*if_data
;
4007 struct prefix_ipv4 lp
, pp
;
4008 struct connected
*ifc
;
4009 struct prefix_ipv4
*p
;
4011 enum zebra_dplane_result dplane_res
;
4013 if_data
= ifp
->info
;
4015 ret
= str2prefix_ipv4(addr_str
, &lp
);
4017 vty_out(vty
, "%% Malformed address \n");
4018 return CMD_WARNING_CONFIG_FAILED
;
4021 if (ipv4_martian(&lp
.prefix
)) {
4022 vty_out(vty
, "%% Invalid address\n");
4023 return CMD_WARNING_CONFIG_FAILED
;
4027 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4029 "%% Local prefix length for P-t-P address must be /32\n");
4030 return CMD_WARNING_CONFIG_FAILED
;
4033 ret
= str2prefix_ipv4(peer_str
, &pp
);
4035 vty_out(vty
, "%% Malformed peer address\n");
4036 return CMD_WARNING_CONFIG_FAILED
;
4040 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4042 ifc
= connected_new();
4046 p
= prefix_ipv4_new();
4048 ifc
->address
= (struct prefix
*)p
;
4051 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
4052 p
= prefix_ipv4_new();
4054 ifc
->destination
= (struct prefix
*)p
;
4059 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4061 /* Add to linked list. */
4062 listnode_add(ifp
->connected
, ifc
);
4065 /* This address is configured from zebra. */
4066 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4067 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4069 /* In case of this route need to install kernel. */
4070 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4071 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4072 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4073 /* Some system need to up the interface to set IP address. */
4074 if (!if_is_up(ifp
)) {
4075 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4079 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4080 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4081 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4082 dplane_res2str(dplane_res
));
4083 return CMD_WARNING_CONFIG_FAILED
;
4086 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4087 /* The address will be advertised to zebra clients when the
4089 * from the kernel has been received.
4090 * It will also be added to the subnet chain list, then. */
4096 int if_ip_address_uinstall(struct interface
*ifp
, struct prefix
*prefix
)
4098 struct connected
*ifc
= NULL
;
4099 enum zebra_dplane_result dplane_res
;
4101 if (prefix
->family
== AF_INET
) {
4102 /* Check current interface address. */
4103 ifc
= connected_check_ptp(ifp
, prefix
, NULL
);
4105 zlog_debug("interface %s Can't find address",
4110 } else if (prefix
->family
== AF_INET6
) {
4111 /* Check current interface address. */
4112 ifc
= connected_check(ifp
, prefix
);
4116 zlog_debug("interface %s Can't find address", ifp
->name
);
4119 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4121 /* This is not real address or interface is not active. */
4122 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4123 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4124 listnode_delete(ifp
->connected
, ifc
);
4125 connected_free(&ifc
);
4126 return CMD_WARNING_CONFIG_FAILED
;
4129 /* This is real route. */
4130 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4131 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4132 zlog_debug("Can't unset interface IP address: %s.",
4133 dplane_res2str(dplane_res
));
4136 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4141 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4142 const char *addr_str
, const char *peer_str
,
4145 struct prefix_ipv4 lp
, pp
;
4146 struct connected
*ifc
;
4148 enum zebra_dplane_result dplane_res
;
4150 /* Convert to prefix structure. */
4151 ret
= str2prefix_ipv4(addr_str
, &lp
);
4153 vty_out(vty
, "%% Malformed address \n");
4154 return CMD_WARNING_CONFIG_FAILED
;
4158 if (lp
.prefixlen
!= IPV4_MAX_BITLEN
) {
4160 "%% Local prefix length for P-t-P address must be /32\n");
4161 return CMD_WARNING_CONFIG_FAILED
;
4164 ret
= str2prefix_ipv4(peer_str
, &pp
);
4166 vty_out(vty
, "%% Malformed peer address\n");
4167 return CMD_WARNING_CONFIG_FAILED
;
4171 /* Check current interface address. */
4172 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
4174 vty_out(vty
, "%% Can't find address\n");
4175 return CMD_WARNING_CONFIG_FAILED
;
4178 /* This is not configured address. */
4179 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4180 return CMD_WARNING_CONFIG_FAILED
;
4182 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4184 /* This is not real address or interface is not active. */
4185 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4186 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4187 listnode_delete(ifp
->connected
, ifc
);
4188 connected_free(&ifc
);
4189 return CMD_WARNING_CONFIG_FAILED
;
4192 /* This is real route. */
4193 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4194 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4195 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4196 dplane_res2str(dplane_res
));
4197 return CMD_WARNING_CONFIG_FAILED
;
4199 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4200 /* we will receive a kernel notification about this route being removed.
4201 * this will trigger its removal from the connected list. */
4207 "ip address A.B.C.D/M",
4208 "Interface Internet Protocol config commands\n"
4209 "Set the IP address of an interface\n"
4210 "IP address (e.g. 10.0.0.1/8)\n")
4212 int idx_ipv4_prefixlen
= 2;
4213 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4214 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4218 DEFUN (no_ip_address
,
4220 "no ip address A.B.C.D/M",
4222 "Interface Internet Protocol config commands\n"
4223 "Set the IP address of an interface\n"
4224 "IP Address (e.g. 10.0.0.1/8)\n")
4226 int idx_ipv4_prefixlen
= 3;
4227 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4228 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4232 DEFUN(ip_address_peer
,
4233 ip_address_peer_cmd
,
4234 "ip address A.B.C.D peer A.B.C.D/M",
4235 "Interface Internet Protocol config commands\n"
4236 "Set the IP address of an interface\n"
4237 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4238 "Specify P-t-P address\n"
4239 "Peer IP address (e.g. 10.0.0.1/8)\n")
4241 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4242 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
4245 DEFUN(no_ip_address_peer
,
4246 no_ip_address_peer_cmd
,
4247 "no ip address A.B.C.D peer A.B.C.D/M",
4249 "Interface Internet Protocol config commands\n"
4250 "Set the IP address of an interface\n"
4251 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4252 "Specify P-t-P address\n"
4253 "Peer IP address (e.g. 10.0.0.1/8)\n")
4255 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4256 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
4260 DEFUN (ip_address_label
,
4261 ip_address_label_cmd
,
4262 "ip address A.B.C.D/M label LINE",
4263 "Interface Internet Protocol config commands\n"
4264 "Set the IP address of an interface\n"
4265 "IP address (e.g. 10.0.0.1/8)\n"
4266 "Label of this address\n"
4269 int idx_ipv4_prefixlen
= 2;
4271 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4272 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
4273 argv
[idx_line
]->arg
);
4276 DEFUN (no_ip_address_label
,
4277 no_ip_address_label_cmd
,
4278 "no ip address A.B.C.D/M label LINE",
4280 "Interface Internet Protocol config commands\n"
4281 "Set the IP address of an interface\n"
4282 "IP address (e.g. 10.0.0.1/8)\n"
4283 "Label of this address\n"
4286 int idx_ipv4_prefixlen
= 3;
4288 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4289 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
4290 NULL
, argv
[idx_line
]->arg
);
4292 #endif /* HAVE_NETLINK */
4294 int if_ipv6_address_install(struct interface
*ifp
, struct prefix
*prefix
,
4297 struct zebra_if
*if_data
;
4298 struct prefix_ipv6 cp
;
4299 struct connected
*ifc
;
4300 struct prefix_ipv6
*p
;
4301 enum zebra_dplane_result dplane_res
;
4303 if_data
= ifp
->info
;
4305 cp
.family
= prefix
->family
;
4306 cp
.prefixlen
= prefix
->prefixlen
;
4307 cp
.prefix
= prefix
->u
.prefix6
;
4308 apply_mask_ipv6(&cp
);
4310 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4312 ifc
= connected_new();
4316 p
= prefix_ipv6_new();
4318 ifc
->address
= (struct prefix
*)p
;
4322 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4324 /* Add to linked list. */
4325 listnode_add(ifp
->connected
, ifc
);
4328 /* This address is configured from zebra. */
4329 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4330 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4332 /* In case of this route need to install kernel. */
4333 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4334 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4335 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4336 /* Some system need to up the interface to set IP address. */
4337 if (!if_is_up(ifp
)) {
4338 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4342 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4343 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4345 "dplane can't set interface IP address: %s.",
4346 dplane_res2str(dplane_res
));
4350 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4351 /* The address will be advertised to zebra clients when the
4353 * from the kernel has been received. */
4359 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
4360 const char *addr_str
, const char *peer_str
,
4363 struct zebra_if
*if_data
;
4364 struct prefix_ipv6 cp
;
4365 struct connected
*ifc
;
4366 struct prefix_ipv6
*p
;
4368 enum zebra_dplane_result dplane_res
;
4370 if_data
= ifp
->info
;
4372 ret
= str2prefix_ipv6(addr_str
, &cp
);
4374 vty_out(vty
, "%% Malformed address \n");
4375 return CMD_WARNING_CONFIG_FAILED
;
4378 if (ipv6_martian(&cp
.prefix
)) {
4379 vty_out(vty
, "%% Invalid address\n");
4380 return CMD_WARNING_CONFIG_FAILED
;
4383 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4385 ifc
= connected_new();
4389 p
= prefix_ipv6_new();
4391 ifc
->address
= (struct prefix
*)p
;
4395 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
4397 /* Add to linked list. */
4398 listnode_add(ifp
->connected
, ifc
);
4401 /* This address is configured from zebra. */
4402 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4403 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4405 /* In case of this route need to install kernel. */
4406 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
) &&
4407 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
) &&
4408 !(if_data
&& if_data
->shutdown
== IF_ZEBRA_DATA_ON
)) {
4409 /* Some system need to up the interface to set IP address. */
4410 if (!if_is_up(ifp
)) {
4411 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
4415 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
4416 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4417 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
4418 dplane_res2str(dplane_res
));
4419 return CMD_WARNING_CONFIG_FAILED
;
4422 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4423 /* The address will be advertised to zebra clients when the
4425 * from the kernel has been received. */
4431 /* Return true if an ipv6 address is configured on ifp */
4432 int ipv6_address_configured(struct interface
*ifp
)
4434 struct connected
*connected
;
4435 struct listnode
*node
;
4437 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
4438 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
4439 && (connected
->address
->family
== AF_INET6
))
4445 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
4446 const char *addr_str
, const char *peer_str
,
4449 struct prefix_ipv6 cp
;
4450 struct connected
*ifc
;
4452 enum zebra_dplane_result dplane_res
;
4454 /* Convert to prefix structure. */
4455 ret
= str2prefix_ipv6(addr_str
, &cp
);
4457 vty_out(vty
, "%% Malformed address \n");
4458 return CMD_WARNING_CONFIG_FAILED
;
4461 /* Check current interface address. */
4462 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
4464 vty_out(vty
, "%% Can't find address\n");
4465 return CMD_WARNING_CONFIG_FAILED
;
4468 /* This is not configured address. */
4469 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
4470 return CMD_WARNING_CONFIG_FAILED
;
4472 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
4474 /* This is not real address or interface is not active. */
4475 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
4476 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
4477 listnode_delete(ifp
->connected
, ifc
);
4478 connected_free(&ifc
);
4479 return CMD_WARNING_CONFIG_FAILED
;
4482 /* This is real route. */
4483 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
4484 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
4485 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
4486 dplane_res2str(dplane_res
));
4487 return CMD_WARNING_CONFIG_FAILED
;
4490 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
4491 /* This information will be propagated to the zclients when the
4492 * kernel notification is received. */
4496 DEFUN (ipv6_address
,
4498 "ipv6 address X:X::X:X/M",
4499 "Interface IPv6 config commands\n"
4500 "Set the IP address of an interface\n"
4501 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4503 int idx_ipv6_prefixlen
= 2;
4504 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4505 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4509 DEFUN (no_ipv6_address
,
4510 no_ipv6_address_cmd
,
4511 "no ipv6 address X:X::X:X/M",
4513 "Interface IPv6 config commands\n"
4514 "Set the IP address of an interface\n"
4515 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4517 int idx_ipv6_prefixlen
= 3;
4518 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4519 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
4523 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
4527 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
4530 struct if_link_params
*iflp
= ifp
->link_params
;
4532 vty_out(vty
, " link-params\n");
4533 vty_out(vty
, " enable\n");
4534 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
4535 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
4536 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
4537 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
4538 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
4539 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
4540 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
4541 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
4542 for (i
= 0; i
< 8; i
++)
4543 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
4544 vty_out(vty
, " unrsv-bw %d %g\n", i
,
4547 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
4548 vty_out(vty
, " admin-grp 0x%x\n", iflp
->admin_grp
);
4549 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
4550 vty_out(vty
, " delay %u", iflp
->av_delay
);
4551 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
4552 vty_out(vty
, " min %u", iflp
->min_delay
);
4553 vty_out(vty
, " max %u", iflp
->max_delay
);
4557 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
4558 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
4559 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
4560 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
4561 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
4562 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
4563 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
4564 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
4565 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
4566 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
4567 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
4568 vty_out(vty
, " neighbor %pI4 as %u\n", &iflp
->rmt_ip
,
4570 vty_out(vty
, " exit-link-params\n");
4574 static int if_config_write(struct vty
*vty
)
4577 struct interface
*ifp
;
4579 zebra_ptm_write(vty
);
4581 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
4582 FOR_ALL_INTERFACES (vrf
, ifp
) {
4583 struct zebra_if
*if_data
;
4584 struct listnode
*addrnode
;
4585 struct connected
*ifc
;
4588 if_data
= ifp
->info
;
4590 if_vty_config_start(vty
, ifp
);
4593 if (if_data
->shutdown
== IF_ZEBRA_DATA_ON
)
4594 vty_out(vty
, " shutdown\n");
4596 zebra_ptm_if_write(vty
, if_data
);
4600 vty_out(vty
, " description %s\n", ifp
->desc
);
4602 /* Assign bandwidth here to avoid unnecessary interface
4604 while processing config script */
4605 if (ifp
->bandwidth
!= 0)
4606 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
4608 if (!CHECK_FLAG(ifp
->status
,
4609 ZEBRA_INTERFACE_LINKDETECTION
))
4610 vty_out(vty
, " no link-detect\n");
4612 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
4614 if (CHECK_FLAG(ifc
->conf
,
4615 ZEBRA_IFC_CONFIGURED
)) {
4616 char buf
[INET6_ADDRSTRLEN
];
4618 vty_out(vty
, " ip%s address %s",
4619 p
->family
== AF_INET
? ""
4621 inet_ntop(p
->family
,
4624 if (CONNECTED_PEER(ifc
)) {
4625 p
= ifc
->destination
;
4626 vty_out(vty
, " peer %s",
4627 inet_ntop(p
->family
,
4632 vty_out(vty
, "/%d", p
->prefixlen
);
4635 vty_out(vty
, " label %s",
4643 if (if_data
->multicast
!= IF_ZEBRA_DATA_UNSPEC
)
4644 vty_out(vty
, " %smulticast\n",
4645 if_data
->multicast
==
4649 if (if_data
->mpls
== IF_ZEBRA_DATA_ON
)
4650 vty_out(vty
, " mpls enable\n");
4653 hook_call(zebra_if_config_wr
, vty
, ifp
);
4654 zebra_evpn_mh_if_write(vty
, ifp
);
4655 link_params_config_write(vty
, ifp
);
4657 if_vty_config_end(vty
);
4662 /* Allocate and initialize interface vector. */
4663 void zebra_if_init(void)
4665 /* Initialize interface and new hook. */
4666 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
4667 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
4669 /* Install configuration write function. */
4670 if_cmd_init(if_config_write
);
4671 install_node(&link_params_node
);
4673 * This is *intentionally* setting this to NULL, signaling
4674 * that interface creation for zebra acts differently
4676 if_zapi_callbacks(NULL
, NULL
, NULL
, NULL
);
4678 install_element(VIEW_NODE
, &show_interface_cmd
);
4679 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
4680 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
4681 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
4683 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
4684 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
4685 install_element(INTERFACE_NODE
, &multicast_cmd
);
4686 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
4687 install_element(INTERFACE_NODE
, &mpls_cmd
);
4688 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
4689 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
4690 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
4691 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
4692 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
4693 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
4694 install_element(INTERFACE_NODE
, &ip_address_cmd
);
4695 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
4696 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
4697 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
4698 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
4699 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
4701 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
4702 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
4703 #endif /* HAVE_NETLINK */
4704 install_element(INTERFACE_NODE
, &link_params_cmd
);
4705 install_default(LINK_PARAMS_NODE
);
4706 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
4707 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
4708 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
4709 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
4710 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
4711 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
4712 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
4713 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
4714 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
4715 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
4716 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
4717 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
4718 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
4719 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
4720 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
4721 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
4722 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
4723 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
4724 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
4725 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
4726 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
4727 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
4728 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
4729 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4731 /* setup EVPN MH elements */
4732 zebra_evpn_interface_init();