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"
31 #include "zebra_memory.h"
33 #include "connected.h"
38 #include "zebra/rtadv.h"
40 #include "zebra_vrf.h"
41 #include "zebra/interface.h"
42 #include "zebra/rib.h"
44 #include "zebra/zebra_router.h"
45 #include "zebra/redistribute.h"
46 #include "zebra/debug.h"
47 #include "zebra/irdp.h"
48 #include "zebra/zebra_ptm.h"
49 #include "zebra/rt_netlink.h"
50 #include "zebra/if_netlink.h"
51 #include "zebra/interface.h"
52 #include "zebra/zebra_vxlan.h"
53 #include "zebra/zebra_errors.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
),
65 static void if_down_del_nbr_connected(struct interface
*ifp
);
67 static int if_zebra_speed_update(struct thread
*thread
)
69 struct interface
*ifp
= THREAD_ARG(thread
);
70 struct zebra_if
*zif
= ifp
->info
;
75 zif
->speed_update
= NULL
;
77 new_speed
= kernel_get_speed(ifp
, &error
);
79 /* error may indicate vrf not available or
80 * interfaces not available.
81 * note that loopback & virtual interfaces can return 0 as speed
86 if (new_speed
!= ifp
->speed
) {
87 zlog_info("%s: %s old speed: %u new speed: %u",
88 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->speed
,
90 ifp
->speed
= new_speed
;
95 if (changed
|| new_speed
== UINT32_MAX
)
96 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 5,
101 static void zebra_if_node_destroy(route_table_delegate_t
*delegate
,
102 struct route_table
*table
,
103 struct route_node
*node
)
106 list_delete((struct list
**)&node
->info
);
107 route_node_destroy(delegate
, table
, node
);
110 static void zebra_if_nhg_dependents_free(struct zebra_if
*zebra_if
)
112 nhg_connected_tree_free(&zebra_if
->nhg_dependents
);
115 static void zebra_if_nhg_dependents_init(struct zebra_if
*zebra_if
)
117 nhg_connected_tree_init(&zebra_if
->nhg_dependents
);
121 route_table_delegate_t zebra_if_table_delegate
= {
122 .create_node
= route_node_create
,
123 .destroy_node
= zebra_if_node_destroy
};
125 /* Called when new interface is added. */
126 static int if_zebra_new_hook(struct interface
*ifp
)
128 struct zebra_if
*zebra_if
;
130 zebra_if
= XCALLOC(MTYPE_ZINFO
, sizeof(struct zebra_if
));
132 zebra_if
->multicast
= IF_ZEBRA_MULTICAST_UNSPEC
;
133 zebra_if
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
135 zebra_if_nhg_dependents_init(zebra_if
);
137 zebra_ptm_if_init(zebra_if
);
139 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
140 #if defined(HAVE_RTADV)
142 /* Set default router advertise values. */
143 struct rtadvconf
*rtadv
;
145 rtadv
= &zebra_if
->rtadv
;
147 rtadv
->AdvSendAdvertisements
= 0;
148 rtadv
->MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
149 rtadv
->MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
150 rtadv
->AdvIntervalTimer
= 0;
151 rtadv
->AdvManagedFlag
= 0;
152 rtadv
->AdvOtherConfigFlag
= 0;
153 rtadv
->AdvHomeAgentFlag
= 0;
154 rtadv
->AdvLinkMTU
= 0;
155 rtadv
->AdvReachableTime
= 0;
156 rtadv
->AdvRetransTimer
= 0;
157 rtadv
->AdvCurHopLimit
= 0;
158 rtadv
->AdvDefaultLifetime
=
159 -1; /* derive from MaxRtrAdvInterval */
160 rtadv
->HomeAgentPreference
= 0;
161 rtadv
->HomeAgentLifetime
=
162 -1; /* derive from AdvDefaultLifetime */
163 rtadv
->AdvIntervalOption
= 0;
164 rtadv
->DefaultPreference
= RTADV_PREF_MEDIUM
;
166 rtadv
->AdvPrefixList
= list_new();
167 rtadv
->AdvRDNSSList
= list_new();
168 rtadv
->AdvDNSSLList
= list_new();
170 #endif /* HAVE_RTADV */
172 memset(&zebra_if
->neigh_mac
[0], 0, 6);
174 /* Initialize installed address chains tree. */
175 zebra_if
->ipv4_subnets
=
176 route_table_init_with_delegate(&zebra_if_table_delegate
);
178 ifp
->info
= zebra_if
;
181 * Some platforms are telling us that the interface is
182 * up and ready to go. When we check the speed we
183 * sometimes get the wrong value. Wait a couple
184 * of seconds and ask again. Hopefully it's all settled
187 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
188 &zebra_if
->speed_update
);
192 static void if_nhg_dependents_check_valid(struct nhg_hash_entry
*nhe
)
194 zebra_nhg_check_valid(nhe
);
195 if (!CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
))
196 /* Assuming uninstalled as well here */
197 UNSET_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
);
200 static void if_down_nhg_dependents(const struct interface
*ifp
)
202 struct nhg_connected
*rb_node_dep
= NULL
;
203 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
205 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
)
206 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
209 static void if_nhg_dependents_release(const struct interface
*ifp
)
211 struct nhg_connected
*rb_node_dep
= NULL
;
212 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
214 frr_each(nhg_connected_tree
, &zif
->nhg_dependents
, rb_node_dep
) {
215 rb_node_dep
->nhe
->ifp
= NULL
; /* Null it out */
216 if_nhg_dependents_check_valid(rb_node_dep
->nhe
);
220 /* Called when interface is deleted. */
221 static int if_zebra_delete_hook(struct interface
*ifp
)
223 struct zebra_if
*zebra_if
;
226 zebra_if
= ifp
->info
;
228 /* Free installed address chains tree. */
229 if (zebra_if
->ipv4_subnets
)
230 route_table_finish(zebra_if
->ipv4_subnets
);
231 #if defined(HAVE_RTADV)
233 struct rtadvconf
*rtadv
;
235 rtadv
= &zebra_if
->rtadv
;
236 list_delete(&rtadv
->AdvPrefixList
);
237 list_delete(&rtadv
->AdvRDNSSList
);
238 list_delete(&rtadv
->AdvDNSSLList
);
239 #endif /* HAVE_RTADV */
241 if_nhg_dependents_release(ifp
);
242 zebra_if_nhg_dependents_free(zebra_if
);
244 XFREE(MTYPE_TMP
, zebra_if
->desc
);
246 THREAD_OFF(zebra_if
->speed_update
);
248 XFREE(MTYPE_ZINFO
, zebra_if
);
254 /* Build the table key */
255 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
258 p
->prefixlen
= IPV4_MAX_BITLEN
;
259 p
->u
.prefix4
.s_addr
= ifindex
;
262 /* Link an interface in a per NS interface tree */
263 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
266 struct route_node
*rn
;
268 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
271 if_build_key(ifp
->ifindex
, &p
);
272 rn
= route_node_get(ns
->if_table
, &p
);
274 ifp
= (struct interface
*)rn
->info
;
275 route_unlock_node(rn
); /* get */
285 /* Delete a VRF. This is called in vrf_terminate(). */
286 void if_unlink_per_ns(struct interface
*ifp
)
288 ifp
->node
->info
= NULL
;
289 route_unlock_node(ifp
->node
);
293 /* Look up an interface by identifier within a NS */
294 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
298 struct route_node
*rn
;
299 struct interface
*ifp
= NULL
;
301 if_build_key(ifindex
, &p
);
302 rn
= route_node_lookup(ns
->if_table
, &p
);
304 ifp
= (struct interface
*)rn
->info
;
305 route_unlock_node(rn
); /* lookup */
310 /* Look up an interface by name within a NS */
311 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
314 struct route_node
*rn
;
315 struct interface
*ifp
;
317 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
318 ifp
= (struct interface
*)rn
->info
;
319 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0) {
320 route_unlock_node(rn
);
328 const char *ifindex2ifname_per_ns(struct zebra_ns
*zns
, unsigned int ifindex
)
330 struct interface
*ifp
;
332 return ((ifp
= if_lookup_by_index_per_ns(zns
, ifindex
)) != NULL
)
337 /* Tie an interface address to its derived subnet list of addresses. */
338 int if_subnet_add(struct interface
*ifp
, struct connected
*ifc
)
340 struct route_node
*rn
;
341 struct zebra_if
*zebra_if
;
343 struct list
*addr_list
;
345 assert(ifp
&& ifp
->info
&& ifc
);
346 zebra_if
= ifp
->info
;
348 /* Get address derived subnet node and associated address list, while
350 address secondary attribute appropriately. */
351 cp
= *CONNECTED_PREFIX(ifc
);
353 rn
= route_node_get(zebra_if
->ipv4_subnets
, &cp
);
355 if ((addr_list
= rn
->info
))
356 SET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
358 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
359 rn
->info
= addr_list
= list_new();
363 /* Tie address at the tail of address list. */
364 listnode_add(addr_list
, ifc
);
366 /* Return list element count. */
367 return (addr_list
->count
);
370 /* Untie an interface address from its derived subnet list of addresses. */
371 int if_subnet_delete(struct interface
*ifp
, struct connected
*ifc
)
373 struct route_node
*rn
;
374 struct zebra_if
*zebra_if
;
375 struct list
*addr_list
;
378 assert(ifp
&& ifp
->info
&& ifc
);
379 zebra_if
= ifp
->info
;
381 cp
= *CONNECTED_PREFIX(ifc
);
384 /* Get address derived subnet node. */
385 rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
);
386 if (!(rn
&& rn
->info
)) {
387 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET
,
388 "Trying to remove an address from an unknown subnet."
389 " (please report this bug)");
392 route_unlock_node(rn
);
394 /* Untie address from subnet's address list. */
395 addr_list
= rn
->info
;
397 /* Deleting an address that is not registered is a bug.
398 * In any case, we shouldn't decrement the lock counter if the address
400 if (!listnode_lookup(addr_list
, ifc
)) {
402 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR
,
403 "Trying to remove an address from a subnet where it is not"
404 " currently registered. (please report this bug)");
408 listnode_delete(addr_list
, ifc
);
409 route_unlock_node(rn
);
411 /* Return list element count, if not empty. */
412 if (addr_list
->count
) {
413 /* If deleted address is primary, mark subsequent one as such
415 if (!CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
417 (struct listnode
*)listhead(addr_list
));
418 zebra_interface_address_delete_update(ifp
, ifc
);
419 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
420 /* XXX: Linux kernel removes all the secondary addresses
422 * address is removed. We could try to work around that,
425 zebra_interface_address_add_update(ifp
, ifc
);
428 return addr_list
->count
;
431 /* Otherwise, free list and route node. */
432 list_delete(&addr_list
);
434 route_unlock_node(rn
);
439 /* if_flags_mangle: A place for hacks that require mangling
440 * or tweaking the interface flags.
442 * ******************** Solaris flags hacks **************************
444 * Solaris IFF_UP flag reflects only the primary interface as the
445 * routing socket only sends IFINFO for the primary interface. Hence
446 * ~IFF_UP does not per se imply all the logical interfaces are also
447 * down - which we only know of as addresses. Instead we must determine
448 * whether the interface really is up or not according to how many
449 * addresses are still attached. (Solaris always sends RTM_DELADDR if
450 * an interface, logical or not, goes ~IFF_UP).
452 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
453 * are addresses left in struct connected, not just the actual underlying
456 * We must hence remember the real state of IFF_UP, which we do in
457 * struct zebra_if.primary_state.
459 * Setting IFF_UP within zebra to administratively shutdown the
460 * interface will affect only the primary interface/address on Solaris.
461 ************************End Solaris flags hacks ***********************
463 static void if_flags_mangle(struct interface
*ifp
, uint64_t *newflags
)
466 struct zebra_if
*zif
= ifp
->info
;
468 zif
->primary_state
= *newflags
& (IFF_UP
& 0xff);
470 if (CHECK_FLAG(zif
->primary_state
, IFF_UP
)
471 || listcount(ifp
->connected
) > 0)
472 SET_FLAG(*newflags
, IFF_UP
);
474 UNSET_FLAG(*newflags
, IFF_UP
);
478 /* Update the flags field of the ifp with the new flag set provided.
479 * Take whatever actions are required for any changes in flags we care
482 * newflags should be the raw value, as obtained from the OS.
484 void if_flags_update(struct interface
*ifp
, uint64_t newflags
)
486 if_flags_mangle(ifp
, &newflags
);
488 if (if_is_no_ptm_operative(ifp
)) {
489 /* operative -> inoperative? */
490 ifp
->flags
= newflags
;
491 if (!if_is_operative(ifp
))
494 /* inoperative -> operative? */
495 ifp
->flags
= newflags
;
496 if (if_is_operative(ifp
))
501 /* Wake up configured address if it is not in current kernel
503 static void if_addr_wakeup(struct interface
*ifp
)
505 struct listnode
*node
, *nnode
;
506 struct connected
*ifc
;
508 enum zebra_dplane_result dplane_res
;
510 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, ifc
)) {
513 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)
514 && !CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)) {
516 if (p
->family
== AF_INET
) {
517 if (!if_is_up(ifp
)) {
518 /* Assume zebra is configured like
522 * ip addr 192.0.2.1/24
525 * As soon as zebra becomes first aware
526 * that gre0 exists in the
527 * kernel, it will set gre0 up and
528 * configure its addresses.
530 * (This may happen at startup when the
531 * interface already exists
532 * or during runtime when the interface
533 * is added to the kernel)
535 * XXX: IRDP code is calling here via
536 * if_add_update - this seems
538 * XXX: RUNNING is not a settable flag
540 * I (paulj) am aware of.
542 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
546 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
548 ZEBRA_DPLANE_REQUEST_FAILURE
) {
550 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
551 "Can't set interface's address: %s",
552 dplane_res2str(dplane_res
));
556 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
557 /* The address will be advertised to zebra
558 * clients when the notification
559 * from the kernel has been received.
560 * It will also be added to the interface's
561 * subnet list then. */
563 if (p
->family
== AF_INET6
) {
564 if (!if_is_up(ifp
)) {
565 /* See long comment above */
566 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
571 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
573 ZEBRA_DPLANE_REQUEST_FAILURE
) {
575 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
576 "Can't set interface's address: %s",
577 dplane_res2str(dplane_res
));
581 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
582 /* The address will be advertised to zebra
583 * clients when the notification
584 * from the kernel has been received. */
590 /* Handle interface addition */
591 void if_add_update(struct interface
*ifp
)
593 struct zebra_if
*if_data
;
594 struct zebra_ns
*zns
;
595 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
597 /* case interface populate before vrf enabled */
601 zns
= zebra_ns_lookup(NS_DEFAULT
);
602 if_link_per_ns(zns
, ifp
);
606 if (if_data
->multicast
== IF_ZEBRA_MULTICAST_ON
)
607 if_set_flags(ifp
, IFF_MULTICAST
);
608 else if (if_data
->multicast
== IF_ZEBRA_MULTICAST_OFF
)
609 if_unset_flags(ifp
, IFF_MULTICAST
);
611 zebra_ptm_if_set_ptm_state(ifp
, if_data
);
613 zebra_interface_add_update(ifp
);
615 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
616 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
618 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
) {
619 if (IS_ZEBRA_DEBUG_KERNEL
)
621 "interface %s vrf %u index %d is shutdown. "
623 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
629 if (IS_ZEBRA_DEBUG_KERNEL
)
631 "interface %s vrf %u index %d becomes active.",
632 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
635 if (IS_ZEBRA_DEBUG_KERNEL
)
636 zlog_debug("interface %s vrf %u index %d is added.",
637 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
641 /* Install connected routes corresponding to an interface. */
642 static void if_install_connected(struct interface
*ifp
)
644 struct listnode
*node
;
645 struct listnode
*next
;
646 struct connected
*ifc
;
648 if (ifp
->connected
) {
649 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
650 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
651 zebra_interface_address_add_update(ifp
, ifc
);
653 connected_up(ifp
, ifc
);
658 /* Uninstall connected routes corresponding to an interface. */
659 static void if_uninstall_connected(struct interface
*ifp
)
661 struct listnode
*node
;
662 struct listnode
*next
;
663 struct connected
*ifc
;
665 if (ifp
->connected
) {
666 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
667 zebra_interface_address_delete_update(ifp
, ifc
);
668 connected_down(ifp
, ifc
);
673 /* Uninstall and delete connected routes corresponding to an interface. */
674 /* TODO - Check why IPv4 handling here is different from install or if_down */
675 static void if_delete_connected(struct interface
*ifp
)
677 struct connected
*ifc
;
679 struct route_node
*rn
;
680 struct zebra_if
*zebra_if
;
681 struct listnode
*node
;
682 struct listnode
*last
= NULL
;
684 zebra_if
= ifp
->info
;
689 while ((node
= (last
? last
->next
: listhead(ifp
->connected
)))) {
690 ifc
= listgetdata(node
);
692 cp
= *CONNECTED_PREFIX(ifc
);
695 if (cp
.family
== AF_INET
696 && (rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
))) {
697 struct listnode
*anode
;
698 struct listnode
*next
;
699 struct listnode
*first
;
700 struct list
*addr_list
;
702 route_unlock_node(rn
);
703 addr_list
= (struct list
*)rn
->info
;
705 /* Remove addresses, secondaries first. */
706 first
= listhead(addr_list
);
708 for (anode
= first
->next
; anode
|| first
;
716 ifc
= listgetdata(anode
);
717 connected_down(ifp
, ifc
);
719 /* XXX: We have to send notifications
720 * here explicitly, because we destroy
721 * the ifc before receiving the
722 * notification about the address being
725 zebra_interface_address_delete_update(
728 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
729 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
731 /* Remove from subnet chain. */
732 list_delete_node(addr_list
, anode
);
733 route_unlock_node(rn
);
735 /* Remove from interface address list
736 * (unconditionally). */
737 if (!CHECK_FLAG(ifc
->conf
,
738 ZEBRA_IFC_CONFIGURED
)) {
739 listnode_delete(ifp
->connected
,
746 /* Free chain list and respective route node. */
747 list_delete(&addr_list
);
749 route_unlock_node(rn
);
750 } else if (cp
.family
== AF_INET6
) {
751 connected_down(ifp
, ifc
);
753 zebra_interface_address_delete_update(ifp
, ifc
);
755 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
756 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
758 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
761 listnode_delete(ifp
->connected
, ifc
);
770 /* Handle an interface delete event */
771 void if_delete_update(struct interface
*ifp
)
773 struct zebra_if
*zif
;
778 "interface %s vrf %u index %d is still up while being deleted.",
779 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
783 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
786 /* Mark interface as inactive */
787 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
789 if (IS_ZEBRA_DEBUG_KERNEL
)
790 zlog_debug("interface %s vrf %u index %d is now inactive.",
791 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
793 /* Delete connected routes from the kernel. */
794 if_delete_connected(ifp
);
796 /* Send out notification on interface delete. */
797 zebra_interface_delete_update(ifp
);
799 if_unlink_per_ns(ifp
);
801 /* Update ifindex after distributing the delete message. This is in
802 case any client needs to have the old value of ifindex available
803 while processing the deletion. Each client daemon is responsible
804 for setting ifindex to IFINDEX_INTERNAL after processing the
805 interface deletion message. */
806 if_set_index(ifp
, IFINDEX_INTERNAL
);
809 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
810 * desired. This operation is not done for netns implementation to avoid
811 * collision with interface with the same name in the default vrf (can
812 * occur with this implementation whereas it is not possible with
815 if (ifp
->vrf_id
&& !vrf_is_backend_netns())
816 if_handle_vrf_change(ifp
, VRF_DEFAULT
);
818 /* Reset some zebra interface params to default values. */
821 zif
->zif_type
= ZEBRA_IF_OTHER
;
822 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
823 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
824 memset(&zif
->brslave_info
, 0,
825 sizeof(struct zebra_l2info_brslave
));
828 if (!ifp
->configured
) {
829 if (IS_ZEBRA_DEBUG_KERNEL
)
830 zlog_debug("interface %s is being deleted from the system",
836 /* VRF change for an interface */
837 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
841 old_vrf_id
= ifp
->vrf_id
;
843 /* Uninstall connected routes. */
844 if_uninstall_connected(ifp
);
846 /* Delete any IPv4 neighbors created to implement RFC 5549 */
847 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
849 /* Delete all neighbor addresses learnt through IPv6 RA */
850 if_down_del_nbr_connected(ifp
);
852 /* Send out notification on interface VRF change. */
853 /* This is to issue an UPDATE or a DELETE, as appropriate. */
854 zebra_interface_vrf_update_del(ifp
, vrf_id
);
857 if_update_to_new_vrf(ifp
, vrf_id
);
859 /* Send out notification on interface VRF change. */
860 /* This is to issue an ADD, if needed. */
861 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
863 /* Install connected routes (in new VRF). */
864 if (if_is_operative(ifp
))
865 if_install_connected(ifp
);
868 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
870 mac
[0] = address
->s6_addr
[8] ^ 0x02;
871 mac
[1] = address
->s6_addr
[9];
872 mac
[2] = address
->s6_addr
[10];
873 mac
[3] = address
->s6_addr
[13];
874 mac
[4] = address
->s6_addr
[14];
875 mac
[5] = address
->s6_addr
[15];
878 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
880 struct in6_addr
*address
,
883 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
884 struct zebra_if
*zif
= ifp
->info
;
885 char buf
[16] = "169.254.0.1";
886 struct in_addr ipv4_ll
;
889 inet_pton(AF_INET
, buf
, &ipv4_ll
);
891 ns_id
= zvrf
->zns
->ns_id
;
894 * Remove and re-add any existing neighbor entry for this address,
895 * since Netlink doesn't currently offer update message types.
897 kernel_neigh_update(0, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6, ns_id
);
899 /* Add new neighbor entry.
901 * We force installation even if current neighbor entry is the same.
902 * Since this function is used to refresh our MAC entries after an
903 * interface flap, if we don't force in our custom entries with their
904 * state set to PERMANENT or REACHABLE then the kernel will attempt to
905 * resolve our leftover entries, fail, mark them unreachable and then
906 * they'll be useless to us.
909 kernel_neigh_update(add
, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6,
912 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
915 * We need to note whether or not we originated a v6
916 * neighbor entry for this interface. So that when
917 * someone unwisely accidently deletes this entry
918 * we can shove it back in.
920 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
921 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
923 zvrf
->neigh_updates
++;
926 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
927 struct in6_addr
*address
, int add
)
932 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
933 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
936 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_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
, 1);
949 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
951 if (listhead(ifp
->nbr_connected
)) {
952 struct nbr_connected
*nbr_connected
;
953 struct listnode
*node
;
955 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
957 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
958 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
962 static void if_down_del_nbr_connected(struct interface
*ifp
)
964 struct nbr_connected
*nbr_connected
;
965 struct listnode
*node
, *nnode
;
967 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
969 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
970 nbr_connected_free(nbr_connected
);
974 void if_nhg_dependents_add(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
977 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
979 nhg_connected_tree_add_nhe(&zif
->nhg_dependents
, nhe
);
983 void if_nhg_dependents_del(struct interface
*ifp
, struct nhg_hash_entry
*nhe
)
986 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
988 nhg_connected_tree_del_nhe(&zif
->nhg_dependents
, nhe
);
992 unsigned int if_nhg_dependents_count(const struct interface
*ifp
)
995 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
997 return nhg_connected_tree_count(&zif
->nhg_dependents
);
1004 bool if_nhg_dependents_is_empty(const struct interface
*ifp
)
1007 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
1009 return nhg_connected_tree_is_empty(&zif
->nhg_dependents
);
1015 /* Interface is up. */
1016 void if_up(struct interface
*ifp
)
1018 struct zebra_if
*zif
;
1019 struct interface
*link_if
;
1020 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1024 quagga_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
1026 /* Notify the protocol daemons. */
1027 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
1028 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
1029 "%s: interface %s hasn't passed ptm check\n",
1030 __func__
, ifp
->name
);
1033 zebra_interface_up_update(ifp
);
1035 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
1037 #if defined(HAVE_RTADV)
1038 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
1039 if (zif
->rtadv
.AdvSendAdvertisements
1040 && (zif
->rtadv
.MaxRtrAdvInterval
>= 1000)) {
1041 zif
->rtadv
.inFastRexmit
= 1;
1042 zif
->rtadv
.NumFastReXmitsRemain
= RTADV_NUM_FAST_REXMITS
;
1046 /* Install connected routes to the kernel. */
1047 if_install_connected(ifp
);
1049 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1050 * are checked to see if (remote) neighbor entries need to be installed
1051 * on them for ARP suppression.
1053 if (IS_ZEBRA_IF_VXLAN(ifp
))
1054 zebra_vxlan_if_up(ifp
);
1055 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1057 zebra_vxlan_svi_up(ifp
, link_if
);
1058 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1059 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1062 zebra_vxlan_svi_up(ifp
, link_if
);
1066 /* Interface goes down. We have to manage different behavior of based
1068 void if_down(struct interface
*ifp
)
1070 struct zebra_if
*zif
;
1071 struct interface
*link_if
;
1072 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1076 quagga_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
1078 if_down_nhg_dependents(ifp
);
1080 /* Handle interface down for specific types for EVPN. Non-VxLAN
1082 * are checked to see if (remote) neighbor entries need to be purged
1083 * for ARP suppression.
1085 if (IS_ZEBRA_IF_VXLAN(ifp
))
1086 zebra_vxlan_if_down(ifp
);
1087 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1089 zebra_vxlan_svi_down(ifp
, link_if
);
1090 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1091 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1094 zebra_vxlan_svi_down(ifp
, link_if
);
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
)
1115 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1118 struct zebra_if
*zif
;
1120 if (IS_ZEBRA_IF_VETH(ifp
))
1122 zif
= (struct zebra_if
*)ifp
->info
;
1123 zif
->link_ifindex
= link_ifindex
;
1124 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1129 * during initial link dump kernel does not order lower devices before
1130 * upper devices so we need to fixup link dependencies at the end of dump
1132 void zebra_if_update_all_links(void)
1134 struct route_node
*rn
;
1135 struct interface
*ifp
;
1136 struct zebra_if
*zif
;
1137 struct zebra_ns
*ns
;
1139 if (IS_ZEBRA_DEBUG_KERNEL
)
1140 zlog_info("fixup link dependencies");
1142 ns
= zebra_ns_lookup(NS_DEFAULT
);
1143 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
1144 ifp
= (struct interface
*)rn
->info
;
1148 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1149 zif
->link
= if_lookup_by_index_per_ns(ns
,
1151 if (IS_ZEBRA_DEBUG_KERNEL
)
1152 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1153 ifp
->name
, ifp
->ifindex
,
1154 zif
->link
?zif
->link
->name
:"unk",
1160 void zebra_if_set_protodown(struct interface
*ifp
, bool down
)
1163 netlink_protodown(ifp
, down
);
1165 zlog_warn("Protodown is not supported on this platform");
1169 /* Output prefix string to vty. */
1170 static int prefix_vty_out(struct vty
*vty
, struct prefix
*p
)
1172 char str
[INET6_ADDRSTRLEN
];
1174 inet_ntop(p
->family
, &p
->u
.prefix
, str
, sizeof(str
));
1175 vty_out(vty
, "%s", str
);
1179 /* Dump if address information to vty. */
1180 static void connected_dump_vty(struct vty
*vty
, struct connected
*connected
)
1184 /* Print interface address. */
1185 p
= connected
->address
;
1186 vty_out(vty
, " %s ", prefix_family_str(p
));
1187 prefix_vty_out(vty
, p
);
1188 vty_out(vty
, "/%d", p
->prefixlen
);
1190 /* If there is destination address, print it. */
1191 if (CONNECTED_PEER(connected
) && connected
->destination
) {
1192 vty_out(vty
, " peer ");
1193 prefix_vty_out(vty
, connected
->destination
);
1194 vty_out(vty
, "/%d", connected
->destination
->prefixlen
);
1197 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1198 vty_out(vty
, " secondary");
1200 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1201 vty_out(vty
, " unnumbered");
1203 if (connected
->label
)
1204 vty_out(vty
, " %s", connected
->label
);
1209 /* Dump interface neighbor address information to vty. */
1210 static void nbr_connected_dump_vty(struct vty
*vty
,
1211 struct nbr_connected
*connected
)
1215 /* Print interface address. */
1216 p
= connected
->address
;
1217 vty_out(vty
, " %s ", prefix_family_str(p
));
1218 prefix_vty_out(vty
, p
);
1219 vty_out(vty
, "/%d", p
->prefixlen
);
1224 static const char *zebra_ziftype_2str(zebra_iftype_t zif_type
)
1227 case ZEBRA_IF_OTHER
:
1231 case ZEBRA_IF_BRIDGE
:
1239 case ZEBRA_IF_VXLAN
:
1254 case ZEBRA_IF_BOND_SLAVE
:
1255 return "bond_slave";
1257 case ZEBRA_IF_MACVLAN
:
1266 /* Interface's brief information print out to vty interface. */
1267 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1269 struct connected
*connected
;
1270 struct listnode
*node
;
1271 struct route_node
*rn
;
1272 struct zebra_if
*zebra_if
;
1274 struct interface
*ifp
;
1275 bool print_header
= true;
1277 FOR_ALL_INTERFACES (vrf
, ifp
) {
1278 char global_pfx
[PREFIX_STRLEN
] = {0};
1279 char buf
[PREFIX_STRLEN
] = {0};
1280 bool first_pfx_printed
= false;
1283 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1284 "Status", "VRF", "Addresses");
1285 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1286 "------", "---", "---------");
1287 print_header
= false; /* We have at least 1 iface */
1289 zebra_if
= ifp
->info
;
1291 vty_out(vty
, "%-16s", ifp
->name
);
1294 vty_out(vty
, "%-8s", "up");
1296 vty_out(vty
, "%-8s", "down");
1298 vty_out(vty
, "%-16s", vrf
->name
);
1300 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1301 rn
= route_next(rn
)) {
1304 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1306 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1308 if (!CHECK_FLAG(connected
->flags
,
1309 ZEBRA_IFA_SECONDARY
)) {
1310 p
= connected
->address
;
1311 prefix2str(p
, buf
, sizeof(buf
));
1312 if (first_pfx_printed
) {
1313 /* padding to prepare row only for ip addr */
1314 vty_out(vty
, "%-40s", "");
1317 vty_out(vty
, "%s\n", buf
);
1321 vty_out(vty
, "%s\n", buf
);
1323 first_pfx_printed
= true;
1329 uint32_t v6_list_size
= 0;
1330 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1331 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1332 && (connected
->address
->family
== AF_INET6
))
1335 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1336 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1337 && !CHECK_FLAG(connected
->flags
,
1338 ZEBRA_IFA_SECONDARY
)
1339 && (connected
->address
->family
== AF_INET6
)) {
1340 p
= connected
->address
;
1341 /* Don't print link local pfx */
1342 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1343 prefix2str(p
, global_pfx
, PREFIX_STRLEN
);
1344 if (first_pfx_printed
) {
1345 /* padding to prepare row only for ip addr */
1346 vty_out(vty
, "%-40s", "");
1347 if (v6_list_size
> 1)
1349 vty_out(vty
, "%s\n", global_pfx
);
1351 if (v6_list_size
> 1)
1353 vty_out(vty
, "%s\n", global_pfx
);
1355 first_pfx_printed
= true;
1360 if (!first_pfx_printed
)
1366 /* Interface's information print out to vty interface. */
1367 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1369 struct connected
*connected
;
1370 struct nbr_connected
*nbr_connected
;
1371 struct listnode
*node
;
1372 struct route_node
*rn
;
1373 struct zebra_if
*zebra_if
;
1376 zebra_if
= ifp
->info
;
1378 vty_out(vty
, "Interface %s is ", ifp
->name
);
1379 if (if_is_up(ifp
)) {
1380 vty_out(vty
, "up, line protocol ");
1382 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1383 if (if_is_running(ifp
))
1384 vty_out(vty
, "is up\n");
1386 vty_out(vty
, "is down\n");
1388 vty_out(vty
, "detection is disabled\n");
1391 vty_out(vty
, "down\n");
1394 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1395 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1396 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1397 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1399 zebra_ptm_show_status(vty
, ifp
);
1401 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
1402 vty_out(vty
, " vrf: %s\n", vrf
->name
);
1405 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1407 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1409 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1410 vty_out(vty
, " pseudo interface\n");
1412 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1413 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
1417 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
1418 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
1419 if (ifp
->mtu6
!= ifp
->mtu
)
1420 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
1421 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
1423 /* Hardware address. */
1424 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
1425 if (ifp
->hw_addr_len
!= 0) {
1428 vty_out(vty
, " HWaddr: ");
1429 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
1430 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
1435 /* Bandwidth in Mbps */
1436 if (ifp
->bandwidth
!= 0) {
1437 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
1441 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
1445 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1447 connected_dump_vty(vty
, connected
);
1450 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1451 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1452 && (connected
->address
->family
== AF_INET6
))
1453 connected_dump_vty(vty
, connected
);
1456 vty_out(vty
, " Interface Type %s\n",
1457 zebra_ziftype_2str(zebra_if
->zif_type
));
1458 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1459 struct zebra_l2info_bridge
*bridge_info
;
1461 bridge_info
= &zebra_if
->l2info
.br
;
1462 vty_out(vty
, " Bridge VLAN-aware: %s\n",
1463 bridge_info
->vlan_aware
? "yes" : "no");
1464 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1465 struct zebra_l2info_vlan
*vlan_info
;
1467 vlan_info
= &zebra_if
->l2info
.vl
;
1468 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
1469 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
1470 struct zebra_l2info_vxlan
*vxlan_info
;
1472 vxlan_info
= &zebra_if
->l2info
.vxl
;
1473 vty_out(vty
, " VxLAN Id %u", vxlan_info
->vni
);
1474 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
1475 vty_out(vty
, " VTEP IP: %s",
1476 inet_ntoa(vxlan_info
->vtep_ip
));
1477 if (vxlan_info
->access_vlan
)
1478 vty_out(vty
, " Access VLAN Id %u\n",
1479 vxlan_info
->access_vlan
);
1480 if (vxlan_info
->mcast_grp
.s_addr
!= INADDR_ANY
)
1481 vty_out(vty
, " Mcast Group %s",
1482 inet_ntoa(vxlan_info
->mcast_grp
));
1486 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
1487 struct zebra_l2info_brslave
*br_slave
;
1489 br_slave
= &zebra_if
->brslave_info
;
1490 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
1491 if (br_slave
->br_if
)
1492 vty_out(vty
, " Master interface: %s\n",
1493 br_slave
->br_if
->name
);
1495 vty_out(vty
, " Master ifindex: %u\n",
1496 br_slave
->bridge_ifindex
);
1500 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
1501 struct zebra_l2info_bondslave
*bond_slave
;
1503 bond_slave
= &zebra_if
->bondslave_info
;
1504 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
1505 if (bond_slave
->bond_if
)
1506 vty_out(vty
, " Master interface: %s\n",
1507 bond_slave
->bond_if
->name
);
1509 vty_out(vty
, " Master ifindex: %u\n",
1510 bond_slave
->bond_ifindex
);
1514 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
1516 vty_out(vty
, " Parent interface: %s\n", zebra_if
->link
->name
);
1518 vty_out(vty
, " Parent ifindex: %d\n", zebra_if
->link_ifindex
);
1521 if (HAS_LINK_PARAMS(ifp
)) {
1523 struct if_link_params
*iflp
= ifp
->link_params
;
1524 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
1525 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
1526 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
1527 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
1528 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
1530 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
1532 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1534 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
1536 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1537 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
1539 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1540 i
, iflp
->unrsv_bw
[i
], i
+ 1,
1541 iflp
->unrsv_bw
[i
+ 1]);
1544 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
1545 vty_out(vty
, " Administrative Group:%u\n",
1547 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
1548 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
1550 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
1551 vty_out(vty
, " Min: %u (micro-sec.)",
1553 vty_out(vty
, " Max: %u (micro-sec.)",
1558 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
1560 " Link Delay Variation %u (micro-sec.)\n",
1562 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
1563 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
1565 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
1566 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
1568 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
1569 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
1571 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
1572 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
1574 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
1575 vty_out(vty
, " Neighbor ASBR IP: %s AS: %u \n",
1576 inet_ntoa(iflp
->rmt_ip
), iflp
->rmt_as
);
1579 hook_call(zebra_if_extra_info
, vty
, ifp
);
1581 if (listhead(ifp
->nbr_connected
))
1582 vty_out(vty
, " Neighbor address(s):\n");
1583 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
1584 nbr_connected_dump_vty(vty
, nbr_connected
);
1586 #ifdef HAVE_PROC_NET_DEV
1587 /* Statistics print out using proc file system. */
1589 " %lu input packets (%lu multicast), %lu bytes, "
1591 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
1592 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
1595 " %lu input errors, %lu length, %lu overrun,"
1596 " %lu CRC, %lu frame\n",
1597 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
1598 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
1599 ifp
->stats
.rx_frame_errors
);
1601 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
1602 ifp
->stats
.rx_missed_errors
);
1604 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
1605 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
1606 ifp
->stats
.tx_dropped
);
1609 " %lu output errors, %lu aborted, %lu carrier,"
1610 " %lu fifo, %lu heartbeat\n",
1611 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
1612 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
1613 ifp
->stats
.tx_heartbeat_errors
);
1615 vty_out(vty
, " %lu window, %lu collisions\n",
1616 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
1617 #endif /* HAVE_PROC_NET_DEV */
1619 #ifdef HAVE_NET_RT_IFLIST
1620 /* Statistics print out using sysctl (). */
1622 " input packets %llu, bytes %llu, dropped %llu,"
1623 " multicast packets %llu\n",
1624 (unsigned long long)ifp
->stats
.ifi_ipackets
,
1625 (unsigned long long)ifp
->stats
.ifi_ibytes
,
1626 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
1627 (unsigned long long)ifp
->stats
.ifi_imcasts
);
1629 vty_out(vty
, " input errors %llu\n",
1630 (unsigned long long)ifp
->stats
.ifi_ierrors
);
1633 " output packets %llu, bytes %llu,"
1634 " multicast packets %llu\n",
1635 (unsigned long long)ifp
->stats
.ifi_opackets
,
1636 (unsigned long long)ifp
->stats
.ifi_obytes
,
1637 (unsigned long long)ifp
->stats
.ifi_omcasts
);
1639 vty_out(vty
, " output errors %llu\n",
1640 (unsigned long long)ifp
->stats
.ifi_oerrors
);
1642 vty_out(vty
, " collisions %llu\n",
1643 (unsigned long long)ifp
->stats
.ifi_collisions
);
1644 #endif /* HAVE_NET_RT_IFLIST */
1647 static void interface_update_stats(void)
1649 #ifdef HAVE_PROC_NET_DEV
1650 /* If system has interface statistics via proc file system, update
1652 ifstat_update_proc();
1653 #endif /* HAVE_PROC_NET_DEV */
1654 #ifdef HAVE_NET_RT_IFLIST
1655 ifstat_update_sysctl();
1656 #endif /* HAVE_NET_RT_IFLIST */
1659 struct cmd_node interface_node
= {INTERFACE_NODE
, "%s(config-if)# ", 1};
1661 #ifndef VTYSH_EXTRACT_PL
1662 #include "zebra/interface_clippy.c"
1664 /* Show all interfaces to vty. */
1665 DEFPY(show_interface
, show_interface_cmd
,
1666 "show interface [vrf NAME$vrf_name] [brief$brief]",
1668 "Interface status and configuration\n"
1670 "Interface status and configuration summary\n")
1673 struct interface
*ifp
;
1674 vrf_id_t vrf_id
= VRF_DEFAULT
;
1676 interface_update_stats();
1679 VRF_GET_ID(vrf_id
, vrf_name
, false);
1681 /* All interface print. */
1682 vrf
= vrf_lookup_by_id(vrf_id
);
1684 ifs_dump_brief_vty(vty
, vrf
);
1686 FOR_ALL_INTERFACES (vrf
, ifp
) {
1687 if_dump_vty(vty
, ifp
);
1695 /* Show all interfaces to vty. */
1696 DEFPY (show_interface_vrf_all
,
1697 show_interface_vrf_all_cmd
,
1698 "show interface vrf all [brief$brief]",
1700 "Interface status and configuration\n"
1701 VRF_ALL_CMD_HELP_STR
1702 "Interface status and configuration summary\n")
1705 struct interface
*ifp
;
1707 interface_update_stats();
1709 /* All interface print. */
1710 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1712 ifs_dump_brief_vty(vty
, vrf
);
1714 FOR_ALL_INTERFACES (vrf
, ifp
)
1715 if_dump_vty(vty
, ifp
);
1722 /* Show specified interface to vty. */
1724 DEFUN (show_interface_name_vrf
,
1725 show_interface_name_vrf_cmd
,
1726 "show interface IFNAME vrf NAME",
1728 "Interface status and configuration\n"
1734 struct interface
*ifp
;
1737 interface_update_stats();
1739 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
1741 /* Specified interface print. */
1742 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1744 vty_out(vty
, "%% Can't find interface %s\n",
1745 argv
[idx_ifname
]->arg
);
1748 if_dump_vty(vty
, ifp
);
1753 /* Show specified interface to vty. */
1754 DEFUN (show_interface_name_vrf_all
,
1755 show_interface_name_vrf_all_cmd
,
1756 "show interface IFNAME [vrf all]",
1758 "Interface status and configuration\n"
1760 VRF_ALL_CMD_HELP_STR
)
1764 struct interface
*ifp
;
1767 interface_update_stats();
1769 /* All interface print. */
1770 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1771 /* Specified interface print. */
1772 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf
->vrf_id
);
1774 if_dump_vty(vty
, ifp
);
1780 vty_out(vty
, "%% Can't find interface %s\n",
1781 argv
[idx_ifname
]->arg
);
1789 static void if_show_description(struct vty
*vty
, vrf_id_t vrf_id
)
1791 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1792 struct interface
*ifp
;
1794 vty_out(vty
, "Interface Status Protocol Description\n");
1795 FOR_ALL_INTERFACES (vrf
, ifp
) {
1797 struct zebra_if
*zif
;
1802 len
= vty_out(vty
, "%s", ifp
->name
);
1803 vty_out(vty
, "%*s", (16 - len
), " ");
1805 if (if_is_up(ifp
)) {
1806 vty_out(vty
, "up ");
1807 if (CHECK_FLAG(ifp
->status
,
1808 ZEBRA_INTERFACE_LINKDETECTION
)) {
1809 if (if_is_running(ifp
))
1810 vty_out(vty
, "up ");
1812 vty_out(vty
, "down ");
1814 vty_out(vty
, "unknown ");
1817 vty_out(vty
, "down down ");
1822 vty_out(vty
, "%s", ifp
->desc
);
1825 if (zif
&& zif
->desc
) {
1826 vty_out(vty
, "%s%s",
1837 DEFUN (show_interface_desc
,
1838 show_interface_desc_cmd
,
1839 "show interface description [vrf NAME]",
1841 "Interface status and configuration\n"
1842 "Interface description\n"
1845 vrf_id_t vrf_id
= VRF_DEFAULT
;
1848 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1850 if_show_description(vty
, vrf_id
);
1856 DEFUN (show_interface_desc_vrf_all
,
1857 show_interface_desc_vrf_all_cmd
,
1858 "show interface description vrf all",
1860 "Interface status and configuration\n"
1861 "Interface description\n"
1862 VRF_ALL_CMD_HELP_STR
)
1866 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1867 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
1868 vty_out(vty
, "\n\tVRF %u\n\n", vrf
->vrf_id
);
1869 if_show_description(vty
, vrf
->vrf_id
);
1878 "Set multicast flag to interface\n")
1880 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1882 struct zebra_if
*if_data
;
1884 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1885 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
1887 vty_out(vty
, "Can't set multicast flag\n");
1888 return CMD_WARNING_CONFIG_FAILED
;
1892 if_data
= ifp
->info
;
1893 if_data
->multicast
= IF_ZEBRA_MULTICAST_ON
;
1898 DEFUN (no_multicast
,
1902 "Unset multicast flag to interface\n")
1904 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1906 struct zebra_if
*if_data
;
1908 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1909 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
1911 vty_out(vty
, "Can't unset multicast flag\n");
1912 return CMD_WARNING_CONFIG_FAILED
;
1916 if_data
= ifp
->info
;
1917 if_data
->multicast
= IF_ZEBRA_MULTICAST_OFF
;
1925 "Enable link detection on interface\n")
1927 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1928 int if_was_operative
;
1930 if_was_operative
= if_is_no_ptm_operative(ifp
);
1931 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1933 /* When linkdetection is enabled, if might come down */
1934 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
1937 /* FIXME: Will defer status change forwarding if interface
1938 does not come down! */
1944 DEFUN (no_linkdetect
,
1948 "Disable link detection on interface\n")
1950 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1951 int if_was_operative
;
1953 if_was_operative
= if_is_no_ptm_operative(ifp
);
1954 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1956 /* Interface may come up after disabling link detection */
1957 if (if_is_operative(ifp
) && !if_was_operative
)
1960 /* FIXME: see linkdetect_cmd */
1968 "Shutdown the selected interface\n")
1970 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1972 struct zebra_if
*if_data
;
1974 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1975 ret
= if_unset_flags(ifp
, IFF_UP
);
1977 vty_out(vty
, "Can't shutdown interface\n");
1978 return CMD_WARNING_CONFIG_FAILED
;
1982 if_data
= ifp
->info
;
1983 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_ON
;
1988 DEFUN (no_shutdown_if
,
1992 "Shutdown the selected interface\n")
1994 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1996 struct zebra_if
*if_data
;
1998 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1999 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
2001 vty_out(vty
, "Can't up interface\n");
2002 return CMD_WARNING_CONFIG_FAILED
;
2006 /* Some addresses (in particular, IPv6 addresses on Linux) get
2007 * removed when the interface goes down. They need to be
2010 if_addr_wakeup(ifp
);
2013 if_data
= ifp
->info
;
2014 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
2019 DEFUN (bandwidth_if
,
2021 "bandwidth (1-100000)",
2022 "Set bandwidth informational parameter\n"
2023 "Bandwidth in megabits\n")
2026 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2027 unsigned int bandwidth
;
2029 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
2031 /* bandwidth range is <1-100000> */
2032 if (bandwidth
< 1 || bandwidth
> 100000) {
2033 vty_out(vty
, "Bandwidth is invalid\n");
2034 return CMD_WARNING_CONFIG_FAILED
;
2037 ifp
->bandwidth
= bandwidth
;
2039 /* force protocols to recalculate routes due to cost change */
2040 if (if_is_operative(ifp
))
2041 zebra_interface_up_update(ifp
);
2046 DEFUN (no_bandwidth_if
,
2047 no_bandwidth_if_cmd
,
2048 "no bandwidth [(1-100000)]",
2050 "Set bandwidth informational parameter\n"
2051 "Bandwidth in megabits\n")
2053 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2057 /* force protocols to recalculate routes due to cost change */
2058 if (if_is_operative(ifp
))
2059 zebra_interface_up_update(ifp
);
2065 struct cmd_node link_params_node
= {
2066 LINK_PARAMS_NODE
, "%s(config-link-params)# ", 1,
2069 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
2070 uint32_t type
, uint32_t value
)
2072 /* Update field as needed */
2073 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
2075 SET_PARAM(ifp
->link_params
, type
);
2077 /* force protocols to update LINK STATE due to parameters change
2079 if (if_is_operative(ifp
))
2080 zebra_interface_parameters_update(ifp
);
2083 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
2084 uint32_t type
, float value
)
2087 /* Update field as needed */
2088 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
2090 SET_PARAM(ifp
->link_params
, type
);
2092 /* force protocols to update LINK STATE due to parameters change
2094 if (if_is_operative(ifp
))
2095 zebra_interface_parameters_update(ifp
);
2099 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
2101 if (ifp
->link_params
== NULL
)
2105 UNSET_PARAM(ifp
->link_params
, type
);
2107 /* force protocols to update LINK STATE due to parameters change */
2108 if (if_is_operative(ifp
))
2109 zebra_interface_parameters_update(ifp
);
2112 DEFUN_NOSH (link_params
,
2117 /* vty->qobj_index stays the same @ interface pointer */
2118 vty
->node
= LINK_PARAMS_NODE
;
2123 DEFUN_NOSH (exit_link_params
,
2124 exit_link_params_cmd
,
2126 "Exit from Link Params configuration mode\n")
2128 if (vty
->node
== LINK_PARAMS_NODE
)
2129 vty
->node
= INTERFACE_NODE
;
2133 /* Specific Traffic Engineering parameters commands */
2134 DEFUN (link_params_enable
,
2135 link_params_enable_cmd
,
2137 "Activate link parameters on this interface\n")
2139 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2141 /* This command could be issue at startup, when activate MPLS TE */
2142 /* on a new interface or after a ON / OFF / ON toggle */
2143 /* In all case, TE parameters are reset to their default factory */
2144 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2146 "Link-params: enable TE link parameters on interface %s",
2149 if (!if_link_params_get(ifp
)) {
2150 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2152 "Link-params: failed to init TE link parameters %s",
2155 return CMD_WARNING_CONFIG_FAILED
;
2158 /* force protocols to update LINK STATE due to parameters change */
2159 if (if_is_operative(ifp
))
2160 zebra_interface_parameters_update(ifp
);
2165 DEFUN (no_link_params_enable
,
2166 no_link_params_enable_cmd
,
2169 "Disable link parameters on this interface\n")
2171 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2173 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2174 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2177 if_link_params_free(ifp
);
2179 /* force protocols to update LINK STATE due to parameters change */
2180 if (if_is_operative(ifp
))
2181 zebra_interface_parameters_update(ifp
);
2186 /* STANDARD TE metrics */
2187 DEFUN (link_params_metric
,
2188 link_params_metric_cmd
,
2189 "metric (0-4294967295)",
2190 "Link metric for MPLS-TE purpose\n"
2191 "Metric value in decimal\n")
2194 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2195 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2198 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2200 /* Update TE metric if needed */
2201 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
2206 DEFUN (no_link_params_metric
,
2207 no_link_params_metric_cmd
,
2210 "Disable Link Metric on this interface\n")
2212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2214 /* Unset TE Metric */
2215 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
2220 DEFUN (link_params_maxbw
,
2221 link_params_maxbw_cmd
,
2223 "Maximum bandwidth that can be used\n"
2224 "Bytes/second (IEEE floating point format)\n")
2226 int idx_bandwidth
= 1;
2227 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2228 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2232 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2233 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
2234 safe_strerror(errno
));
2235 return CMD_WARNING_CONFIG_FAILED
;
2238 /* Check that Maximum bandwidth is not lower than other bandwidth
2240 if ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0])
2241 || (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2])
2242 || (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4])
2243 || (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6])
2244 || (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
)
2245 || (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
)) {
2247 "Maximum Bandwidth could not be lower than others bandwidth\n");
2248 return CMD_WARNING_CONFIG_FAILED
;
2251 /* Update Maximum Bandwidth if needed */
2252 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
2257 DEFUN (link_params_max_rsv_bw
,
2258 link_params_max_rsv_bw_cmd
,
2259 "max-rsv-bw BANDWIDTH",
2260 "Maximum bandwidth that may be reserved\n"
2261 "Bytes/second (IEEE floating point format)\n")
2263 int idx_bandwidth
= 1;
2264 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2265 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2268 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2269 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
2270 safe_strerror(errno
));
2271 return CMD_WARNING_CONFIG_FAILED
;
2274 /* Check that bandwidth is not greater than maximum bandwidth parameter
2276 if (bw
> iflp
->max_bw
) {
2278 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2280 return CMD_WARNING_CONFIG_FAILED
;
2283 /* Update Maximum Reservable Bandwidth if needed */
2284 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
2289 DEFUN (link_params_unrsv_bw
,
2290 link_params_unrsv_bw_cmd
,
2291 "unrsv-bw (0-7) BANDWIDTH",
2292 "Unreserved bandwidth at each priority level\n"
2294 "Bytes/second (IEEE floating point format)\n")
2297 int idx_bandwidth
= 2;
2298 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2299 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2303 /* We don't have to consider about range check here. */
2304 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
2305 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2306 safe_strerror(errno
));
2307 return CMD_WARNING_CONFIG_FAILED
;
2310 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2311 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2312 safe_strerror(errno
));
2313 return CMD_WARNING_CONFIG_FAILED
;
2316 /* Check that bandwidth is not greater than maximum bandwidth parameter
2318 if (bw
> iflp
->max_bw
) {
2320 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2322 return CMD_WARNING_CONFIG_FAILED
;
2325 /* Update Unreserved Bandwidth if needed */
2326 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
2332 DEFUN (link_params_admin_grp
,
2333 link_params_admin_grp_cmd
,
2334 "admin-grp BITPATTERN",
2335 "Administrative group membership\n"
2336 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2338 int idx_bitpattern
= 1;
2339 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2340 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2341 unsigned long value
;
2343 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
2344 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
2345 safe_strerror(errno
));
2346 return CMD_WARNING_CONFIG_FAILED
;
2349 /* Update Administrative Group if needed */
2350 link_param_cmd_set_uint32(ifp
, &iflp
->admin_grp
, LP_ADM_GRP
, value
);
2355 DEFUN (no_link_params_admin_grp
,
2356 no_link_params_admin_grp_cmd
,
2359 "Disable Administrative group membership on this interface\n")
2361 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2363 /* Unset Admin Group */
2364 link_param_cmd_unset(ifp
, LP_ADM_GRP
);
2369 /* RFC5392 & RFC5316: INTER-AS */
2370 DEFUN (link_params_inter_as
,
2371 link_params_inter_as_cmd
,
2372 "neighbor A.B.C.D as (1-4294967295)",
2373 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2374 "Remote IP address in dot decimal A.B.C.D\n"
2375 "Remote AS number\n"
2376 "AS number in the range <1-4294967295>\n")
2381 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2382 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2383 struct in_addr addr
;
2386 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
2387 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
2388 return CMD_WARNING_CONFIG_FAILED
;
2391 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2393 /* Update Remote IP and Remote AS fields if needed */
2394 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
2395 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
2398 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
2399 SET_PARAM(iflp
, LP_RMT_AS
);
2401 /* force protocols to update LINK STATE due to parameters change
2403 if (if_is_operative(ifp
))
2404 zebra_interface_parameters_update(ifp
);
2409 DEFUN (no_link_params_inter_as
,
2410 no_link_params_inter_as_cmd
,
2413 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2415 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2416 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2418 /* Reset Remote IP and AS neighbor */
2420 iflp
->rmt_ip
.s_addr
= 0;
2421 UNSET_PARAM(iflp
, LP_RMT_AS
);
2423 /* force protocols to update LINK STATE due to parameters change */
2424 if (if_is_operative(ifp
))
2425 zebra_interface_parameters_update(ifp
);
2430 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2431 * draft-ietf-isis-metric-extensions-07.txt */
2432 DEFUN (link_params_delay
,
2433 link_params_delay_cmd
,
2434 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2435 "Unidirectional Average Link Delay\n"
2436 "Average delay in micro-second as decimal (0...16777215)\n"
2438 "Minimum delay in micro-second as decimal (0...16777215)\n"
2440 "Maximum delay in micro-second as decimal (0...16777215)\n")
2442 /* Get and Check new delay values */
2443 uint32_t delay
= 0, low
= 0, high
= 0;
2444 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
2446 low
= strtoul(argv
[3]->arg
, NULL
, 10);
2447 high
= strtoul(argv
[5]->arg
, NULL
, 10);
2450 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2451 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2455 /* Check new delay value against old Min and Max delays if set
2457 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)
2458 && (delay
<= iflp
->min_delay
|| delay
>= iflp
->max_delay
)) {
2460 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2461 iflp
->min_delay
, iflp
->max_delay
);
2462 return CMD_WARNING_CONFIG_FAILED
;
2464 /* Update delay if value is not set or change */
2465 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
2466 iflp
->av_delay
= delay
;
2467 SET_PARAM(iflp
, LP_DELAY
);
2470 /* Unset Min and Max delays if already set */
2471 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2472 iflp
->min_delay
= 0;
2473 iflp
->max_delay
= 0;
2474 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2478 /* Check new delays value coherency */
2479 if (delay
<= low
|| delay
>= high
) {
2481 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2483 return CMD_WARNING_CONFIG_FAILED
;
2485 /* Update Delays if needed */
2486 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
2487 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
2488 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
2489 || iflp
->max_delay
!= high
) {
2490 iflp
->av_delay
= delay
;
2491 SET_PARAM(iflp
, LP_DELAY
);
2492 iflp
->min_delay
= low
;
2493 iflp
->max_delay
= high
;
2494 SET_PARAM(iflp
, LP_MM_DELAY
);
2499 /* force protocols to update LINK STATE due to parameters change */
2500 if (update
== 1 && if_is_operative(ifp
))
2501 zebra_interface_parameters_update(ifp
);
2506 DEFUN (no_link_params_delay
,
2507 no_link_params_delay_cmd
,
2510 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2512 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2513 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2517 UNSET_PARAM(iflp
, LP_DELAY
);
2518 iflp
->min_delay
= 0;
2519 iflp
->max_delay
= 0;
2520 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2522 /* force protocols to update LINK STATE due to parameters change */
2523 if (if_is_operative(ifp
))
2524 zebra_interface_parameters_update(ifp
);
2529 DEFUN (link_params_delay_var
,
2530 link_params_delay_var_cmd
,
2531 "delay-variation (0-16777215)",
2532 "Unidirectional Link Delay Variation\n"
2533 "delay variation in micro-second as decimal (0...16777215)\n")
2536 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2537 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2540 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2542 /* Update Delay Variation if needed */
2543 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
2548 DEFUN (no_link_params_delay_var
,
2549 no_link_params_delay_var_cmd
,
2550 "no delay-variation",
2552 "Disable Unidirectional Delay Variation on this interface\n")
2554 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2556 /* Unset Delay Variation */
2557 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
2562 DEFUN (link_params_pkt_loss
,
2563 link_params_pkt_loss_cmd
,
2564 "packet-loss PERCENTAGE",
2565 "Unidirectional Link Packet Loss\n"
2566 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2568 int idx_percentage
= 1;
2569 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2570 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2573 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
2574 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
2575 safe_strerror(errno
));
2576 return CMD_WARNING_CONFIG_FAILED
;
2579 if (fval
> MAX_PKT_LOSS
)
2580 fval
= MAX_PKT_LOSS
;
2582 /* Update Packet Loss if needed */
2583 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
2588 DEFUN (no_link_params_pkt_loss
,
2589 no_link_params_pkt_loss_cmd
,
2592 "Disable Unidirectional Link Packet Loss on this interface\n")
2594 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2596 /* Unset Packet Loss */
2597 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
2602 DEFUN (link_params_res_bw
,
2603 link_params_res_bw_cmd
,
2605 "Unidirectional Residual Bandwidth\n"
2606 "Bytes/second (IEEE floating point format)\n")
2608 int idx_bandwidth
= 1;
2609 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2610 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2613 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2614 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
2615 safe_strerror(errno
));
2616 return CMD_WARNING_CONFIG_FAILED
;
2619 /* Check that bandwidth is not greater than maximum bandwidth parameter
2621 if (bw
> iflp
->max_bw
) {
2623 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2625 return CMD_WARNING_CONFIG_FAILED
;
2628 /* Update Residual Bandwidth if needed */
2629 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
2634 DEFUN (no_link_params_res_bw
,
2635 no_link_params_res_bw_cmd
,
2638 "Disable Unidirectional Residual Bandwidth on this interface\n")
2640 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2642 /* Unset Residual Bandwidth */
2643 link_param_cmd_unset(ifp
, LP_RES_BW
);
2648 DEFUN (link_params_ava_bw
,
2649 link_params_ava_bw_cmd
,
2651 "Unidirectional Available Bandwidth\n"
2652 "Bytes/second (IEEE floating point format)\n")
2654 int idx_bandwidth
= 1;
2655 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2656 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2659 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2660 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
2661 safe_strerror(errno
));
2662 return CMD_WARNING_CONFIG_FAILED
;
2665 /* Check that bandwidth is not greater than maximum bandwidth parameter
2667 if (bw
> iflp
->max_bw
) {
2669 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2671 return CMD_WARNING_CONFIG_FAILED
;
2674 /* Update Residual Bandwidth if needed */
2675 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
2680 DEFUN (no_link_params_ava_bw
,
2681 no_link_params_ava_bw_cmd
,
2684 "Disable Unidirectional Available Bandwidth on this interface\n")
2686 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2688 /* Unset Available Bandwidth */
2689 link_param_cmd_unset(ifp
, LP_AVA_BW
);
2694 DEFUN (link_params_use_bw
,
2695 link_params_use_bw_cmd
,
2697 "Unidirectional Utilised Bandwidth\n"
2698 "Bytes/second (IEEE floating point format)\n")
2700 int idx_bandwidth
= 1;
2701 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2702 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2705 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2706 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
2707 safe_strerror(errno
));
2708 return CMD_WARNING_CONFIG_FAILED
;
2711 /* Check that bandwidth is not greater than maximum bandwidth parameter
2713 if (bw
> iflp
->max_bw
) {
2715 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2717 return CMD_WARNING_CONFIG_FAILED
;
2720 /* Update Utilized Bandwidth if needed */
2721 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
2726 DEFUN (no_link_params_use_bw
,
2727 no_link_params_use_bw_cmd
,
2730 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2732 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2734 /* Unset Utilised Bandwidth */
2735 link_param_cmd_unset(ifp
, LP_USE_BW
);
2740 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
2741 const char *addr_str
, const char *peer_str
,
2744 struct zebra_if
*if_data
;
2745 struct prefix_ipv4 lp
, pp
;
2746 struct connected
*ifc
;
2747 struct prefix_ipv4
*p
;
2749 enum zebra_dplane_result dplane_res
;
2751 if_data
= ifp
->info
;
2753 ret
= str2prefix_ipv4(addr_str
, &lp
);
2755 vty_out(vty
, "%% Malformed address \n");
2756 return CMD_WARNING_CONFIG_FAILED
;
2759 if (ipv4_martian(&lp
.prefix
)) {
2760 vty_out(vty
, "%% Invalid address\n");
2761 return CMD_WARNING_CONFIG_FAILED
;
2765 if (lp
.prefixlen
!= 32) {
2767 "%% Local prefix length for P-t-P address must be /32\n");
2768 return CMD_WARNING_CONFIG_FAILED
;
2771 ret
= str2prefix_ipv4(peer_str
, &pp
);
2773 vty_out(vty
, "%% Malformed peer address\n");
2774 return CMD_WARNING_CONFIG_FAILED
;
2778 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2780 ifc
= connected_new();
2784 p
= prefix_ipv4_new();
2786 ifc
->address
= (struct prefix
*)p
;
2789 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
2790 p
= prefix_ipv4_new();
2792 ifc
->destination
= (struct prefix
*)p
;
2797 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
2799 /* Add to linked list. */
2800 listnode_add(ifp
->connected
, ifc
);
2803 /* This address is configured from zebra. */
2804 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2805 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2807 /* In case of this route need to install kernel. */
2808 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2809 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
2810 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
2811 /* Some system need to up the interface to set IP address. */
2812 if (!if_is_up(ifp
)) {
2813 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
2817 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
2818 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2819 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
2820 dplane_res2str(dplane_res
));
2821 return CMD_WARNING_CONFIG_FAILED
;
2824 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2825 /* The address will be advertised to zebra clients when the
2827 * from the kernel has been received.
2828 * It will also be added to the subnet chain list, then. */
2834 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
2835 const char *addr_str
, const char *peer_str
,
2838 struct prefix_ipv4 lp
, pp
;
2839 struct connected
*ifc
;
2841 enum zebra_dplane_result dplane_res
;
2843 /* Convert to prefix structure. */
2844 ret
= str2prefix_ipv4(addr_str
, &lp
);
2846 vty_out(vty
, "%% Malformed address \n");
2847 return CMD_WARNING_CONFIG_FAILED
;
2851 if (lp
.prefixlen
!= 32) {
2853 "%% Local prefix length for P-t-P address must be /32\n");
2854 return CMD_WARNING_CONFIG_FAILED
;
2857 ret
= str2prefix_ipv4(peer_str
, &pp
);
2859 vty_out(vty
, "%% Malformed peer address\n");
2860 return CMD_WARNING_CONFIG_FAILED
;
2864 /* Check current interface address. */
2865 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2867 vty_out(vty
, "%% Can't find address\n");
2868 return CMD_WARNING_CONFIG_FAILED
;
2871 /* This is not configured address. */
2872 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2873 return CMD_WARNING_CONFIG_FAILED
;
2875 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2877 /* This is not real address or interface is not active. */
2878 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2879 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2880 listnode_delete(ifp
->connected
, ifc
);
2881 connected_free(ifc
);
2882 return CMD_WARNING_CONFIG_FAILED
;
2885 /* This is real route. */
2886 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
2887 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2888 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
2889 dplane_res2str(dplane_res
));
2890 return CMD_WARNING_CONFIG_FAILED
;
2892 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2893 /* we will receive a kernel notification about this route being removed.
2894 * this will trigger its removal from the connected list. */
2900 "ip address A.B.C.D/M",
2901 "Interface Internet Protocol config commands\n"
2902 "Set the IP address of an interface\n"
2903 "IP address (e.g. 10.0.0.1/8)\n")
2905 int idx_ipv4_prefixlen
= 2;
2906 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2907 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2911 DEFUN (no_ip_address
,
2913 "no ip address A.B.C.D/M",
2915 "Interface Internet Protocol config commands\n"
2916 "Set the IP address of an interface\n"
2917 "IP Address (e.g. 10.0.0.1/8)\n")
2919 int idx_ipv4_prefixlen
= 3;
2920 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2921 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2925 DEFUN(ip_address_peer
,
2926 ip_address_peer_cmd
,
2927 "ip address A.B.C.D peer A.B.C.D/M",
2928 "Interface Internet Protocol config commands\n"
2929 "Set the IP address of an interface\n"
2930 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2931 "Specify P-t-P address\n"
2932 "Peer IP address (e.g. 10.0.0.1/8)\n")
2934 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2935 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
2938 DEFUN(no_ip_address_peer
,
2939 no_ip_address_peer_cmd
,
2940 "no ip address A.B.C.D peer A.B.C.D/M",
2942 "Interface Internet Protocol config commands\n"
2943 "Set the IP address of an interface\n"
2944 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2945 "Specify P-t-P address\n"
2946 "Peer IP address (e.g. 10.0.0.1/8)\n")
2948 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2949 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
2953 DEFUN (ip_address_label
,
2954 ip_address_label_cmd
,
2955 "ip address A.B.C.D/M label LINE",
2956 "Interface Internet Protocol config commands\n"
2957 "Set the IP address of an interface\n"
2958 "IP address (e.g. 10.0.0.1/8)\n"
2959 "Label of this address\n"
2962 int idx_ipv4_prefixlen
= 2;
2964 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2965 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2966 argv
[idx_line
]->arg
);
2969 DEFUN (no_ip_address_label
,
2970 no_ip_address_label_cmd
,
2971 "no ip address A.B.C.D/M label LINE",
2973 "Interface Internet Protocol config commands\n"
2974 "Set the IP address of an interface\n"
2975 "IP address (e.g. 10.0.0.1/8)\n"
2976 "Label of this address\n"
2979 int idx_ipv4_prefixlen
= 3;
2981 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2982 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2983 NULL
, argv
[idx_line
]->arg
);
2985 #endif /* HAVE_NETLINK */
2987 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
2988 const char *addr_str
, const char *peer_str
,
2991 struct zebra_if
*if_data
;
2992 struct prefix_ipv6 cp
;
2993 struct connected
*ifc
;
2994 struct prefix_ipv6
*p
;
2996 enum zebra_dplane_result dplane_res
;
2998 if_data
= ifp
->info
;
3000 ret
= str2prefix_ipv6(addr_str
, &cp
);
3002 vty_out(vty
, "%% Malformed address \n");
3003 return CMD_WARNING_CONFIG_FAILED
;
3006 if (ipv6_martian(&cp
.prefix
)) {
3007 vty_out(vty
, "%% Invalid address\n");
3008 return CMD_WARNING_CONFIG_FAILED
;
3011 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
3013 ifc
= connected_new();
3017 p
= prefix_ipv6_new();
3019 ifc
->address
= (struct prefix
*)p
;
3023 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
3025 /* Add to linked list. */
3026 listnode_add(ifp
->connected
, ifc
);
3029 /* This address is configured from zebra. */
3030 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3031 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3033 /* In case of this route need to install kernel. */
3034 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
3035 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
3036 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
3037 /* Some system need to up the interface to set IP address. */
3038 if (!if_is_up(ifp
)) {
3039 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3043 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
3044 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3045 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
3046 dplane_res2str(dplane_res
));
3047 return CMD_WARNING_CONFIG_FAILED
;
3050 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3051 /* The address will be advertised to zebra clients when the
3053 * from the kernel has been received. */
3059 /* Return true if an ipv6 address is configured on ifp */
3060 int ipv6_address_configured(struct interface
*ifp
)
3062 struct connected
*connected
;
3063 struct listnode
*node
;
3065 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
3066 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
3067 && (connected
->address
->family
== AF_INET6
))
3073 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
3074 const char *addr_str
, const char *peer_str
,
3077 struct prefix_ipv6 cp
;
3078 struct connected
*ifc
;
3080 enum zebra_dplane_result dplane_res
;
3082 /* Convert to prefix structure. */
3083 ret
= str2prefix_ipv6(addr_str
, &cp
);
3085 vty_out(vty
, "%% Malformed address \n");
3086 return CMD_WARNING_CONFIG_FAILED
;
3089 /* Check current interface address. */
3090 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
3092 vty_out(vty
, "%% Can't find address\n");
3093 return CMD_WARNING_CONFIG_FAILED
;
3096 /* This is not configured address. */
3097 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3098 return CMD_WARNING_CONFIG_FAILED
;
3100 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3102 /* This is not real address or interface is not active. */
3103 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
3104 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3105 listnode_delete(ifp
->connected
, ifc
);
3106 connected_free(ifc
);
3107 return CMD_WARNING_CONFIG_FAILED
;
3110 /* This is real route. */
3111 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
3112 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3113 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
3114 dplane_res2str(dplane_res
));
3115 return CMD_WARNING_CONFIG_FAILED
;
3118 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3119 /* This information will be propagated to the zclients when the
3120 * kernel notification is received. */
3124 DEFUN (ipv6_address
,
3126 "ipv6 address X:X::X:X/M",
3127 "Interface IPv6 config commands\n"
3128 "Set the IP address of an interface\n"
3129 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3131 int idx_ipv6_prefixlen
= 2;
3132 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3133 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3137 DEFUN (no_ipv6_address
,
3138 no_ipv6_address_cmd
,
3139 "no ipv6 address X:X::X:X/M",
3141 "Interface IPv6 config commands\n"
3142 "Set the IP address of an interface\n"
3143 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3145 int idx_ipv6_prefixlen
= 3;
3146 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3147 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3151 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
3155 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
3158 struct if_link_params
*iflp
= ifp
->link_params
;
3160 vty_out(vty
, " link-params\n");
3161 vty_out(vty
, " enable\n");
3162 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
3163 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
3164 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
3165 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
3166 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
3167 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
3168 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
3169 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
3170 for (i
= 0; i
< 8; i
++)
3171 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
3172 vty_out(vty
, " unrsv-bw %d %g\n", i
,
3175 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
3176 vty_out(vty
, " admin-grp 0x%x\n", iflp
->admin_grp
);
3177 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
3178 vty_out(vty
, " delay %u", iflp
->av_delay
);
3179 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3180 vty_out(vty
, " min %u", iflp
->min_delay
);
3181 vty_out(vty
, " max %u", iflp
->max_delay
);
3185 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
3186 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
3187 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
3188 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
3189 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
3190 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
3191 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
3192 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
3193 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
3194 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
3195 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
3196 vty_out(vty
, " neighbor %s as %u\n", inet_ntoa(iflp
->rmt_ip
),
3198 vty_out(vty
, " exit-link-params\n");
3202 static int if_config_write(struct vty
*vty
)
3205 struct interface
*ifp
;
3207 zebra_ptm_write(vty
);
3209 RB_FOREACH (vrf0
, vrf_name_head
, &vrfs_by_name
)
3210 FOR_ALL_INTERFACES (vrf0
, ifp
) {
3211 struct zebra_if
*if_data
;
3212 struct listnode
*addrnode
;
3213 struct connected
*ifc
;
3217 if_data
= ifp
->info
;
3218 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
3220 if (ifp
->vrf_id
== VRF_DEFAULT
)
3221 vty_frame(vty
, "interface %s\n", ifp
->name
);
3223 vty_frame(vty
, "interface %s vrf %s\n",
3224 ifp
->name
, vrf
->name
);
3227 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)
3228 vty_out(vty
, " shutdown\n");
3230 zebra_ptm_if_write(vty
, if_data
);
3234 vty_out(vty
, " description %s\n", ifp
->desc
);
3236 /* Assign bandwidth here to avoid unnecessary interface
3238 while processing config script */
3239 if (ifp
->bandwidth
!= 0)
3240 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
3242 if (!CHECK_FLAG(ifp
->status
,
3243 ZEBRA_INTERFACE_LINKDETECTION
))
3244 vty_out(vty
, " no link-detect\n");
3246 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
3248 if (CHECK_FLAG(ifc
->conf
,
3249 ZEBRA_IFC_CONFIGURED
)) {
3250 char buf
[INET6_ADDRSTRLEN
];
3252 vty_out(vty
, " ip%s address %s",
3253 p
->family
== AF_INET
? ""
3255 inet_ntop(p
->family
,
3258 if (CONNECTED_PEER(ifc
)) {
3259 p
= ifc
->destination
;
3260 vty_out(vty
, " peer %s",
3261 inet_ntop(p
->family
,
3266 vty_out(vty
, "/%d", p
->prefixlen
);
3269 vty_out(vty
, " label %s",
3277 if (if_data
->multicast
3278 != IF_ZEBRA_MULTICAST_UNSPEC
)
3279 vty_out(vty
, " %smulticast\n",
3281 == IF_ZEBRA_MULTICAST_ON
3286 hook_call(zebra_if_config_wr
, vty
, ifp
);
3288 link_params_config_write(vty
, ifp
);
3290 vty_endframe(vty
, "!\n");
3295 /* Allocate and initialize interface vector. */
3296 void zebra_if_init(void)
3298 /* Initialize interface and new hook. */
3299 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
3300 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
3302 /* Install configuration write function. */
3303 install_node(&interface_node
, if_config_write
);
3304 install_node(&link_params_node
, NULL
);
3307 * This is *intentionally* setting this to NULL, signaling
3308 * that interface creation for zebra acts differently
3310 if_zapi_callbacks(NULL
, NULL
, NULL
, NULL
);
3312 install_element(VIEW_NODE
, &show_interface_cmd
);
3313 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
3314 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
3315 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
3317 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
3318 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
3319 install_element(INTERFACE_NODE
, &multicast_cmd
);
3320 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
3321 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
3322 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
3323 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
3324 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
3325 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
3326 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
3327 install_element(INTERFACE_NODE
, &ip_address_cmd
);
3328 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
3329 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
3330 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
3331 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
3332 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
3334 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
3335 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
3336 #endif /* HAVE_NETLINK */
3337 install_element(INTERFACE_NODE
, &link_params_cmd
);
3338 install_default(LINK_PARAMS_NODE
);
3339 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
3340 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
3341 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
3342 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
3343 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
3344 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
3345 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
3346 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
3347 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
3348 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
3349 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
3350 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
3351 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
3352 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
3353 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
3354 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
3355 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
3356 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
3357 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
3358 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
3359 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
3360 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
3361 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
3362 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);