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")
56 DEFINE_MTYPE_STATIC(ZEBRA
, NHE_CONNECTED
, "Nexthops Connected")
58 #define ZEBRA_PTM_SUPPORT
60 DEFINE_HOOK(zebra_if_extra_info
, (struct vty
* vty
, struct interface
*ifp
),
62 DEFINE_HOOK(zebra_if_config_wr
, (struct vty
* vty
, struct interface
*ifp
),
66 static void if_down_del_nbr_connected(struct interface
*ifp
);
68 static int if_zebra_speed_update(struct thread
*thread
)
70 struct interface
*ifp
= THREAD_ARG(thread
);
71 struct zebra_if
*zif
= ifp
->info
;
76 zif
->speed_update
= NULL
;
78 new_speed
= kernel_get_speed(ifp
, &error
);
80 /* error may indicate vrf not available or
81 * interfaces not available.
82 * note that loopback & virtual interfaces can return 0 as speed
87 if (new_speed
!= ifp
->speed
) {
88 zlog_info("%s: %s old speed: %u new speed: %u",
89 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->speed
,
91 ifp
->speed
= new_speed
;
96 if (changed
|| new_speed
== UINT32_MAX
)
97 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 5,
102 static void zebra_if_node_destroy(route_table_delegate_t
*delegate
,
103 struct route_table
*table
,
104 struct route_node
*node
)
107 list_delete((struct list
**)&node
->info
);
108 route_node_destroy(delegate
, table
, node
);
111 route_table_delegate_t zebra_if_table_delegate
= {
112 .create_node
= route_node_create
,
113 .destroy_node
= zebra_if_node_destroy
};
115 /* Called when new interface is added. */
116 static int if_zebra_new_hook(struct interface
*ifp
)
118 struct zebra_if
*zebra_if
;
120 zebra_if
= XCALLOC(MTYPE_ZINFO
, sizeof(struct zebra_if
));
122 zebra_if
->multicast
= IF_ZEBRA_MULTICAST_UNSPEC
;
123 zebra_if
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
125 zebra_if
->nhe_connected
= list_new();
126 zebra_if
->nhe_connected
->del
= (void (*)(void *))nhe_connected_free
;
128 zebra_ptm_if_init(zebra_if
);
130 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
131 #if defined(HAVE_RTADV)
133 /* Set default router advertise values. */
134 struct rtadvconf
*rtadv
;
136 rtadv
= &zebra_if
->rtadv
;
138 rtadv
->AdvSendAdvertisements
= 0;
139 rtadv
->MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
140 rtadv
->MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
141 rtadv
->AdvIntervalTimer
= 0;
142 rtadv
->AdvManagedFlag
= 0;
143 rtadv
->AdvOtherConfigFlag
= 0;
144 rtadv
->AdvHomeAgentFlag
= 0;
145 rtadv
->AdvLinkMTU
= 0;
146 rtadv
->AdvReachableTime
= 0;
147 rtadv
->AdvRetransTimer
= 0;
148 rtadv
->AdvCurHopLimit
= 0;
149 rtadv
->AdvDefaultLifetime
=
150 -1; /* derive from MaxRtrAdvInterval */
151 rtadv
->HomeAgentPreference
= 0;
152 rtadv
->HomeAgentLifetime
=
153 -1; /* derive from AdvDefaultLifetime */
154 rtadv
->AdvIntervalOption
= 0;
155 rtadv
->DefaultPreference
= RTADV_PREF_MEDIUM
;
157 rtadv
->AdvPrefixList
= list_new();
158 rtadv
->AdvRDNSSList
= list_new();
159 rtadv
->AdvDNSSLList
= list_new();
161 #endif /* HAVE_RTADV */
163 memset(&zebra_if
->neigh_mac
[0], 0, 6);
165 /* Initialize installed address chains tree. */
166 zebra_if
->ipv4_subnets
=
167 route_table_init_with_delegate(&zebra_if_table_delegate
);
169 ifp
->info
= zebra_if
;
172 * Some platforms are telling us that the interface is
173 * up and ready to go. When we check the speed we
174 * sometimes get the wrong value. Wait a couple
175 * of seconds and ask again. Hopefully it's all settled
178 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
179 &zebra_if
->speed_update
);
183 /* Called when interface is deleted. */
184 static int if_zebra_delete_hook(struct interface
*ifp
)
186 struct zebra_if
*zebra_if
;
189 zebra_if
= ifp
->info
;
191 /* Free installed address chains tree. */
192 if (zebra_if
->ipv4_subnets
)
193 route_table_finish(zebra_if
->ipv4_subnets
);
194 #if defined(HAVE_RTADV)
196 struct rtadvconf
*rtadv
;
198 rtadv
= &zebra_if
->rtadv
;
199 list_delete(&rtadv
->AdvPrefixList
);
200 list_delete(&rtadv
->AdvRDNSSList
);
201 list_delete(&rtadv
->AdvDNSSLList
);
202 #endif /* HAVE_RTADV */
204 list_delete(&zebra_if
->nhe_connected
);
206 XFREE(MTYPE_TMP
, zebra_if
->desc
);
207 THREAD_OFF(zebra_if
->speed_update
);
209 XFREE(MTYPE_ZINFO
, zebra_if
);
215 /* Build the table key */
216 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
219 p
->prefixlen
= IPV4_MAX_BITLEN
;
220 p
->u
.prefix4
.s_addr
= ifindex
;
223 /* Link an interface in a per NS interface tree */
224 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
227 struct route_node
*rn
;
229 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
232 if_build_key(ifp
->ifindex
, &p
);
233 rn
= route_node_get(ns
->if_table
, &p
);
235 ifp
= (struct interface
*)rn
->info
;
236 route_unlock_node(rn
); /* get */
246 /* Delete a VRF. This is called in vrf_terminate(). */
247 void if_unlink_per_ns(struct interface
*ifp
)
249 ifp
->node
->info
= NULL
;
250 route_unlock_node(ifp
->node
);
254 /* Look up an interface by identifier within a NS */
255 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
259 struct route_node
*rn
;
260 struct interface
*ifp
= NULL
;
262 if_build_key(ifindex
, &p
);
263 rn
= route_node_lookup(ns
->if_table
, &p
);
265 ifp
= (struct interface
*)rn
->info
;
266 route_unlock_node(rn
); /* lookup */
271 /* Look up an interface by name within a NS */
272 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
275 struct route_node
*rn
;
276 struct interface
*ifp
;
278 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
279 ifp
= (struct interface
*)rn
->info
;
280 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0) {
281 route_unlock_node(rn
);
289 const char *ifindex2ifname_per_ns(struct zebra_ns
*zns
, unsigned int ifindex
)
291 struct interface
*ifp
;
293 return ((ifp
= if_lookup_by_index_per_ns(zns
, ifindex
)) != NULL
)
298 /* Tie an interface address to its derived subnet list of addresses. */
299 int if_subnet_add(struct interface
*ifp
, struct connected
*ifc
)
301 struct route_node
*rn
;
302 struct zebra_if
*zebra_if
;
304 struct list
*addr_list
;
306 assert(ifp
&& ifp
->info
&& ifc
);
307 zebra_if
= ifp
->info
;
309 /* Get address derived subnet node and associated address list, while
311 address secondary attribute appropriately. */
312 cp
= *CONNECTED_PREFIX(ifc
);
314 rn
= route_node_get(zebra_if
->ipv4_subnets
, &cp
);
316 if ((addr_list
= rn
->info
))
317 SET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
319 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
320 rn
->info
= addr_list
= list_new();
324 /* Tie address at the tail of address list. */
325 listnode_add(addr_list
, ifc
);
327 /* Return list element count. */
328 return (addr_list
->count
);
331 /* Untie an interface address from its derived subnet list of addresses. */
332 int if_subnet_delete(struct interface
*ifp
, struct connected
*ifc
)
334 struct route_node
*rn
;
335 struct zebra_if
*zebra_if
;
336 struct list
*addr_list
;
339 assert(ifp
&& ifp
->info
&& ifc
);
340 zebra_if
= ifp
->info
;
342 cp
= *CONNECTED_PREFIX(ifc
);
345 /* Get address derived subnet node. */
346 rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
);
347 if (!(rn
&& rn
->info
)) {
348 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET
,
349 "Trying to remove an address from an unknown subnet."
350 " (please report this bug)");
353 route_unlock_node(rn
);
355 /* Untie address from subnet's address list. */
356 addr_list
= rn
->info
;
358 /* Deleting an address that is not registered is a bug.
359 * In any case, we shouldn't decrement the lock counter if the address
361 if (!listnode_lookup(addr_list
, ifc
)) {
363 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR
,
364 "Trying to remove an address from a subnet where it is not"
365 " currently registered. (please report this bug)");
369 listnode_delete(addr_list
, ifc
);
370 route_unlock_node(rn
);
372 /* Return list element count, if not empty. */
373 if (addr_list
->count
) {
374 /* If deleted address is primary, mark subsequent one as such
376 if (!CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
378 (struct listnode
*)listhead(addr_list
));
379 zebra_interface_address_delete_update(ifp
, ifc
);
380 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
381 /* XXX: Linux kernel removes all the secondary addresses
383 * address is removed. We could try to work around that,
386 zebra_interface_address_add_update(ifp
, ifc
);
389 return addr_list
->count
;
392 /* Otherwise, free list and route node. */
393 list_delete(&addr_list
);
395 route_unlock_node(rn
);
400 /* if_flags_mangle: A place for hacks that require mangling
401 * or tweaking the interface flags.
403 * ******************** Solaris flags hacks **************************
405 * Solaris IFF_UP flag reflects only the primary interface as the
406 * routing socket only sends IFINFO for the primary interface. Hence
407 * ~IFF_UP does not per se imply all the logical interfaces are also
408 * down - which we only know of as addresses. Instead we must determine
409 * whether the interface really is up or not according to how many
410 * addresses are still attached. (Solaris always sends RTM_DELADDR if
411 * an interface, logical or not, goes ~IFF_UP).
413 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
414 * are addresses left in struct connected, not just the actual underlying
417 * We must hence remember the real state of IFF_UP, which we do in
418 * struct zebra_if.primary_state.
420 * Setting IFF_UP within zebra to administratively shutdown the
421 * interface will affect only the primary interface/address on Solaris.
422 ************************End Solaris flags hacks ***********************
424 static void if_flags_mangle(struct interface
*ifp
, uint64_t *newflags
)
427 struct zebra_if
*zif
= ifp
->info
;
429 zif
->primary_state
= *newflags
& (IFF_UP
& 0xff);
431 if (CHECK_FLAG(zif
->primary_state
, IFF_UP
)
432 || listcount(ifp
->connected
) > 0)
433 SET_FLAG(*newflags
, IFF_UP
);
435 UNSET_FLAG(*newflags
, IFF_UP
);
439 /* Update the flags field of the ifp with the new flag set provided.
440 * Take whatever actions are required for any changes in flags we care
443 * newflags should be the raw value, as obtained from the OS.
445 void if_flags_update(struct interface
*ifp
, uint64_t newflags
)
447 if_flags_mangle(ifp
, &newflags
);
449 if (if_is_no_ptm_operative(ifp
)) {
450 /* operative -> inoperative? */
451 ifp
->flags
= newflags
;
452 if (!if_is_operative(ifp
))
455 /* inoperative -> operative? */
456 ifp
->flags
= newflags
;
457 if (if_is_operative(ifp
))
462 /* Wake up configured address if it is not in current kernel
464 static void if_addr_wakeup(struct interface
*ifp
)
466 struct listnode
*node
, *nnode
;
467 struct connected
*ifc
;
469 enum zebra_dplane_result dplane_res
;
471 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, ifc
)) {
474 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)
475 && !CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)) {
477 if (p
->family
== AF_INET
) {
478 if (!if_is_up(ifp
)) {
479 /* Assume zebra is configured like
483 * ip addr 192.0.2.1/24
486 * As soon as zebra becomes first aware
487 * that gre0 exists in the
488 * kernel, it will set gre0 up and
489 * configure its addresses.
491 * (This may happen at startup when the
492 * interface already exists
493 * or during runtime when the interface
494 * is added to the kernel)
496 * XXX: IRDP code is calling here via
497 * if_add_update - this seems
499 * XXX: RUNNING is not a settable flag
501 * I (paulj) am aware of.
503 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
507 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
509 ZEBRA_DPLANE_REQUEST_FAILURE
) {
511 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
512 "Can't set interface's address: %s",
513 dplane_res2str(dplane_res
));
517 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
518 /* The address will be advertised to zebra
519 * clients when the notification
520 * from the kernel has been received.
521 * It will also be added to the interface's
522 * subnet list then. */
524 if (p
->family
== AF_INET6
) {
525 if (!if_is_up(ifp
)) {
526 /* See long comment above */
527 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
532 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
534 ZEBRA_DPLANE_REQUEST_FAILURE
) {
536 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
537 "Can't set interface's address: %s",
538 dplane_res2str(dplane_res
));
542 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
543 /* The address will be advertised to zebra
544 * clients when the notification
545 * from the kernel has been received. */
551 /* Handle interface addition */
552 void if_add_update(struct interface
*ifp
)
554 struct zebra_if
*if_data
;
555 struct zebra_ns
*zns
;
556 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
558 /* case interface populate before vrf enabled */
562 zns
= zebra_ns_lookup(NS_DEFAULT
);
563 if_link_per_ns(zns
, ifp
);
567 if (if_data
->multicast
== IF_ZEBRA_MULTICAST_ON
)
568 if_set_flags(ifp
, IFF_MULTICAST
);
569 else if (if_data
->multicast
== IF_ZEBRA_MULTICAST_OFF
)
570 if_unset_flags(ifp
, IFF_MULTICAST
);
572 zebra_ptm_if_set_ptm_state(ifp
, if_data
);
574 zebra_interface_add_update(ifp
);
576 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
577 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
579 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
) {
580 if (IS_ZEBRA_DEBUG_KERNEL
)
582 "interface %s vrf %u index %d is shutdown. "
584 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
590 if (IS_ZEBRA_DEBUG_KERNEL
)
592 "interface %s vrf %u index %d becomes active.",
593 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
596 if (IS_ZEBRA_DEBUG_KERNEL
)
597 zlog_debug("interface %s vrf %u index %d is added.",
598 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
602 /* Install connected routes corresponding to an interface. */
603 static void if_install_connected(struct interface
*ifp
)
605 struct listnode
*node
;
606 struct listnode
*next
;
607 struct connected
*ifc
;
609 if (ifp
->connected
) {
610 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
611 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
612 zebra_interface_address_add_update(ifp
, ifc
);
614 connected_up(ifp
, ifc
);
619 /* Uninstall connected routes corresponding to an interface. */
620 static void if_uninstall_connected(struct interface
*ifp
)
622 struct listnode
*node
;
623 struct listnode
*next
;
624 struct connected
*ifc
;
626 if (ifp
->connected
) {
627 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
628 zebra_interface_address_delete_update(ifp
, ifc
);
629 connected_down(ifp
, ifc
);
634 /* Uninstall and delete connected routes corresponding to an interface. */
635 /* TODO - Check why IPv4 handling here is different from install or if_down */
636 static void if_delete_connected(struct interface
*ifp
)
638 struct connected
*ifc
;
640 struct route_node
*rn
;
641 struct zebra_if
*zebra_if
;
642 struct listnode
*node
;
643 struct listnode
*last
= NULL
;
645 zebra_if
= ifp
->info
;
650 while ((node
= (last
? last
->next
: listhead(ifp
->connected
)))) {
651 ifc
= listgetdata(node
);
653 cp
= *CONNECTED_PREFIX(ifc
);
656 if (cp
.family
== AF_INET
657 && (rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
))) {
658 struct listnode
*anode
;
659 struct listnode
*next
;
660 struct listnode
*first
;
661 struct list
*addr_list
;
663 route_unlock_node(rn
);
664 addr_list
= (struct list
*)rn
->info
;
666 /* Remove addresses, secondaries first. */
667 first
= listhead(addr_list
);
669 for (anode
= first
->next
; anode
|| first
;
677 ifc
= listgetdata(anode
);
678 connected_down(ifp
, ifc
);
680 /* XXX: We have to send notifications
681 * here explicitly, because we destroy
682 * the ifc before receiving the
683 * notification about the address being
686 zebra_interface_address_delete_update(
689 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
690 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
692 /* Remove from subnet chain. */
693 list_delete_node(addr_list
, anode
);
694 route_unlock_node(rn
);
696 /* Remove from interface address list
697 * (unconditionally). */
698 if (!CHECK_FLAG(ifc
->conf
,
699 ZEBRA_IFC_CONFIGURED
)) {
700 listnode_delete(ifp
->connected
,
707 /* Free chain list and respective route node. */
708 list_delete(&addr_list
);
710 route_unlock_node(rn
);
711 } else if (cp
.family
== AF_INET6
) {
712 connected_down(ifp
, ifc
);
714 zebra_interface_address_delete_update(ifp
, ifc
);
716 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
717 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
719 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
722 listnode_delete(ifp
->connected
, ifc
);
731 /* Handle an interface delete event */
732 void if_delete_update(struct interface
*ifp
)
734 struct zebra_if
*zif
;
739 "interface %s vrf %u index %d is still up while being deleted.",
740 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
744 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
747 /* Mark interface as inactive */
748 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
750 if (IS_ZEBRA_DEBUG_KERNEL
)
751 zlog_debug("interface %s vrf %u index %d is now inactive.",
752 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
754 /* Delete connected routes from the kernel. */
755 if_delete_connected(ifp
);
757 /* Send out notification on interface delete. */
758 zebra_interface_delete_update(ifp
);
760 if_unlink_per_ns(ifp
);
762 /* Update ifindex after distributing the delete message. This is in
763 case any client needs to have the old value of ifindex available
764 while processing the deletion. Each client daemon is responsible
765 for setting ifindex to IFINDEX_INTERNAL after processing the
766 interface deletion message. */
767 if_set_index(ifp
, IFINDEX_INTERNAL
);
770 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
771 * desired. This operation is not done for netns implementation to avoid
772 * collision with interface with the same name in the default vrf (can
773 * occur with this implementation whereas it is not possible with
776 if (ifp
->vrf_id
&& !vrf_is_backend_netns())
777 if_handle_vrf_change(ifp
, VRF_DEFAULT
);
779 /* Reset some zebra interface params to default values. */
782 zif
->zif_type
= ZEBRA_IF_OTHER
;
783 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
784 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
785 memset(&zif
->brslave_info
, 0,
786 sizeof(struct zebra_l2info_brslave
));
789 if (!ifp
->configured
) {
790 if (IS_ZEBRA_DEBUG_KERNEL
)
791 zlog_debug("interface %s is being deleted from the system",
797 /* VRF change for an interface */
798 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
802 old_vrf_id
= ifp
->vrf_id
;
804 /* Uninstall connected routes. */
805 if_uninstall_connected(ifp
);
807 /* Delete any IPv4 neighbors created to implement RFC 5549 */
808 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
810 /* Delete all neighbor addresses learnt through IPv6 RA */
811 if_down_del_nbr_connected(ifp
);
813 /* Send out notification on interface VRF change. */
814 /* This is to issue an UPDATE or a DELETE, as appropriate. */
815 zebra_interface_vrf_update_del(ifp
, vrf_id
);
818 if_update_to_new_vrf(ifp
, vrf_id
);
820 /* Send out notification on interface VRF change. */
821 /* This is to issue an ADD, if needed. */
822 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
824 /* Install connected routes (in new VRF). */
825 if (if_is_operative(ifp
))
826 if_install_connected(ifp
);
829 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
831 mac
[0] = address
->s6_addr
[8] ^ 0x02;
832 mac
[1] = address
->s6_addr
[9];
833 mac
[2] = address
->s6_addr
[10];
834 mac
[3] = address
->s6_addr
[13];
835 mac
[4] = address
->s6_addr
[14];
836 mac
[5] = address
->s6_addr
[15];
839 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
841 struct in6_addr
*address
,
844 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
845 struct zebra_if
*zif
= ifp
->info
;
846 char buf
[16] = "169.254.0.1";
847 struct in_addr ipv4_ll
;
850 inet_pton(AF_INET
, buf
, &ipv4_ll
);
852 ns_id
= zvrf
->zns
->ns_id
;
855 * Remove and re-add any existing neighbor entry for this address,
856 * since Netlink doesn't currently offer update message types.
858 kernel_neigh_update(0, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6, ns_id
);
860 /* Add new neighbor entry.
862 * We force installation even if current neighbor entry is the same.
863 * Since this function is used to refresh our MAC entries after an
864 * interface flap, if we don't force in our custom entries with their
865 * state set to PERMANENT or REACHABLE then the kernel will attempt to
866 * resolve our leftover entries, fail, mark them unreachable and then
867 * they'll be useless to us.
870 kernel_neigh_update(add
, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6,
873 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
876 * We need to note whether or not we originated a v6
877 * neighbor entry for this interface. So that when
878 * someone unwisely accidently deletes this entry
879 * we can shove it back in.
881 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
882 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
884 zvrf
->neigh_updates
++;
887 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
888 struct in6_addr
*address
, int add
)
893 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
894 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
897 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface
*ifp
)
899 if (listhead(ifp
->nbr_connected
)) {
900 struct nbr_connected
*nbr_connected
;
901 struct listnode
*node
;
903 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
905 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
906 ifp
, &nbr_connected
->address
->u
.prefix6
, 1);
910 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
912 if (listhead(ifp
->nbr_connected
)) {
913 struct nbr_connected
*nbr_connected
;
914 struct listnode
*node
;
916 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
918 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
919 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
923 static void if_down_del_nbr_connected(struct interface
*ifp
)
925 struct nbr_connected
*nbr_connected
;
926 struct listnode
*node
, *nnode
;
928 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
930 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
931 nbr_connected_free(nbr_connected
);
936 * nhe_connected_add() - Add the nexthop entry to the interfaces connected list
938 * @ifp: Interface to add to
939 * @nhe: Nexthop hash entry to add
941 * Return: nhe_connected struct created and added
943 struct nhe_connected
*nhe_connected_add(struct interface
*ifp
,
944 struct nhg_hash_entry
*nhe
)
946 struct nhe_connected
*if_nhec
= NULL
;
947 struct zebra_if
*zif
= (struct zebra_if
*)ifp
->info
;
949 if_nhec
= nhe_connected_new();
955 /* Add connected nexthop to the interface */
956 listnode_add(zif
->nhe_connected
, if_nhec
);
961 * nhe_connected() - Allocate nhe connected structure
963 * Return: Allocated nhe_connected structure
965 struct nhe_connected
*nhe_connected_new(void)
967 return XCALLOC(MTYPE_NHE_CONNECTED
, sizeof(struct nhe_connected
));
971 * nhe_connected_free() - Free nhe_connected structure
973 * @nhe_connected: nhe_connected structure to free
975 void nhe_connected_free(struct nhe_connected
*connected
)
977 XFREE(MTYPE_NHE_CONNECTED
, connected
);
980 /* Interface is up. */
981 void if_up(struct interface
*ifp
)
983 struct zebra_if
*zif
;
984 struct interface
*link_if
;
985 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
989 quagga_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
991 /* Notify the protocol daemons. */
992 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
993 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
994 "%s: interface %s hasn't passed ptm check\n",
995 __func__
, ifp
->name
);
998 zebra_interface_up_update(ifp
);
1000 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
1002 #if defined(HAVE_RTADV)
1003 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
1004 if (zif
->rtadv
.AdvSendAdvertisements
1005 && (zif
->rtadv
.MaxRtrAdvInterval
>= 1000)) {
1006 zif
->rtadv
.inFastRexmit
= 1;
1007 zif
->rtadv
.NumFastReXmitsRemain
= RTADV_NUM_FAST_REXMITS
;
1011 /* Install connected routes to the kernel. */
1012 if_install_connected(ifp
);
1014 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1015 * are checked to see if (remote) neighbor entries need to be installed
1016 * on them for ARP suppression.
1018 if (IS_ZEBRA_IF_VXLAN(ifp
))
1019 zebra_vxlan_if_up(ifp
);
1020 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1022 zebra_vxlan_svi_up(ifp
, link_if
);
1023 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1024 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1027 zebra_vxlan_svi_up(ifp
, link_if
);
1031 /* Interface goes down. We have to manage different behavior of based
1033 void if_down(struct interface
*ifp
)
1035 struct zebra_if
*zif
;
1036 struct interface
*link_if
;
1037 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
1041 quagga_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
1043 /* Handle interface down for specific types for EVPN. Non-VxLAN
1045 * are checked to see if (remote) neighbor entries need to be purged
1046 * for ARP suppression.
1048 if (IS_ZEBRA_IF_VXLAN(ifp
))
1049 zebra_vxlan_if_down(ifp
);
1050 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1052 zebra_vxlan_svi_down(ifp
, link_if
);
1053 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1054 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
1057 zebra_vxlan_svi_down(ifp
, link_if
);
1061 /* Notify to the protocol daemons. */
1062 zebra_interface_down_update(ifp
);
1064 /* Uninstall connected routes from the kernel. */
1065 if_uninstall_connected(ifp
);
1067 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
1069 /* Delete all neighbor addresses learnt through IPv6 RA */
1070 if_down_del_nbr_connected(ifp
);
1073 void if_refresh(struct interface
*ifp
)
1078 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1081 struct zebra_if
*zif
;
1083 if (IS_ZEBRA_IF_VETH(ifp
))
1085 zif
= (struct zebra_if
*)ifp
->info
;
1086 zif
->link_ifindex
= link_ifindex
;
1087 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1092 * during initial link dump kernel does not order lower devices before
1093 * upper devices so we need to fixup link dependencies at the end of dump
1095 void zebra_if_update_all_links(void)
1097 struct route_node
*rn
;
1098 struct interface
*ifp
;
1099 struct zebra_if
*zif
;
1100 struct zebra_ns
*ns
;
1102 if (IS_ZEBRA_DEBUG_KERNEL
)
1103 zlog_info("fixup link dependencies");
1105 ns
= zebra_ns_lookup(NS_DEFAULT
);
1106 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
1107 ifp
= (struct interface
*)rn
->info
;
1111 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1112 zif
->link
= if_lookup_by_index_per_ns(ns
,
1114 if (IS_ZEBRA_DEBUG_KERNEL
)
1115 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1116 ifp
->name
, ifp
->ifindex
,
1117 zif
->link
?zif
->link
->name
:"unk",
1123 void zebra_if_set_protodown(struct interface
*ifp
, bool down
)
1126 netlink_protodown(ifp
, down
);
1128 zlog_warn("Protodown is not supported on this platform");
1132 /* Output prefix string to vty. */
1133 static int prefix_vty_out(struct vty
*vty
, struct prefix
*p
)
1135 char str
[INET6_ADDRSTRLEN
];
1137 inet_ntop(p
->family
, &p
->u
.prefix
, str
, sizeof(str
));
1138 vty_out(vty
, "%s", str
);
1142 /* Dump if address information to vty. */
1143 static void connected_dump_vty(struct vty
*vty
, struct connected
*connected
)
1147 /* Print interface address. */
1148 p
= connected
->address
;
1149 vty_out(vty
, " %s ", prefix_family_str(p
));
1150 prefix_vty_out(vty
, p
);
1151 vty_out(vty
, "/%d", p
->prefixlen
);
1153 /* If there is destination address, print it. */
1154 if (CONNECTED_PEER(connected
) && connected
->destination
) {
1155 vty_out(vty
, " peer ");
1156 prefix_vty_out(vty
, connected
->destination
);
1157 vty_out(vty
, "/%d", connected
->destination
->prefixlen
);
1160 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1161 vty_out(vty
, " secondary");
1163 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1164 vty_out(vty
, " unnumbered");
1166 if (connected
->label
)
1167 vty_out(vty
, " %s", connected
->label
);
1172 /* Dump interface neighbor address information to vty. */
1173 static void nbr_connected_dump_vty(struct vty
*vty
,
1174 struct nbr_connected
*connected
)
1178 /* Print interface address. */
1179 p
= connected
->address
;
1180 vty_out(vty
, " %s ", prefix_family_str(p
));
1181 prefix_vty_out(vty
, p
);
1182 vty_out(vty
, "/%d", p
->prefixlen
);
1188 * nhe_connected_dump() - Dump nexthops connected to this interface to vty
1191 * @nhe_connected: List of connected nexthop hash entries
1193 static void nhe_connected_dump_vty(struct vty
*vty
,
1194 struct nhe_connected
*connected
)
1196 /* Just outputing ID for now. */
1197 vty_out(vty
, " (%u)", connected
->nhe
->id
);
1200 static const char *zebra_ziftype_2str(zebra_iftype_t zif_type
)
1203 case ZEBRA_IF_OTHER
:
1207 case ZEBRA_IF_BRIDGE
:
1215 case ZEBRA_IF_VXLAN
:
1230 case ZEBRA_IF_BOND_SLAVE
:
1231 return "bond_slave";
1233 case ZEBRA_IF_MACVLAN
:
1242 /* Interface's brief information print out to vty interface. */
1243 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1245 struct connected
*connected
;
1246 struct listnode
*node
;
1247 struct route_node
*rn
;
1248 struct zebra_if
*zebra_if
;
1250 struct interface
*ifp
;
1251 bool print_header
= true;
1253 FOR_ALL_INTERFACES (vrf
, ifp
) {
1254 char global_pfx
[PREFIX_STRLEN
] = {0};
1255 char buf
[PREFIX_STRLEN
] = {0};
1256 bool first_pfx_printed
= false;
1259 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1260 "Status", "VRF", "Addresses");
1261 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1262 "------", "---", "---------");
1263 print_header
= false; /* We have at least 1 iface */
1265 zebra_if
= ifp
->info
;
1267 vty_out(vty
, "%-16s", ifp
->name
);
1270 vty_out(vty
, "%-8s", "up");
1272 vty_out(vty
, "%-8s", "down");
1274 vty_out(vty
, "%-16s", vrf
->name
);
1276 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1277 rn
= route_next(rn
)) {
1280 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1282 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1284 if (!CHECK_FLAG(connected
->flags
,
1285 ZEBRA_IFA_SECONDARY
)) {
1286 p
= connected
->address
;
1287 prefix2str(p
, buf
, sizeof(buf
));
1288 if (first_pfx_printed
) {
1289 /* padding to prepare row only for ip addr */
1290 vty_out(vty
, "%-40s", "");
1293 vty_out(vty
, "%s\n", buf
);
1297 vty_out(vty
, "%s\n", buf
);
1299 first_pfx_printed
= true;
1305 uint32_t v6_list_size
= 0;
1306 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1307 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1308 && (connected
->address
->family
== AF_INET6
))
1311 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1312 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1313 && !CHECK_FLAG(connected
->flags
,
1314 ZEBRA_IFA_SECONDARY
)
1315 && (connected
->address
->family
== AF_INET6
)) {
1316 p
= connected
->address
;
1317 /* Don't print link local pfx */
1318 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1319 prefix2str(p
, global_pfx
, PREFIX_STRLEN
);
1320 if (first_pfx_printed
) {
1321 /* padding to prepare row only for ip addr */
1322 vty_out(vty
, "%-40s", "");
1323 if (v6_list_size
> 1)
1325 vty_out(vty
, "%s\n", global_pfx
);
1327 if (v6_list_size
> 1)
1329 vty_out(vty
, "%s\n", global_pfx
);
1331 first_pfx_printed
= true;
1336 if (!first_pfx_printed
)
1342 /* Interface's information print out to vty interface. */
1343 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1345 struct connected
*connected
;
1346 struct nbr_connected
*nbr_connected
;
1347 struct nhe_connected
*nhe_connected
;
1348 struct listnode
*node
;
1349 struct route_node
*rn
;
1350 struct zebra_if
*zebra_if
;
1353 zebra_if
= ifp
->info
;
1355 vty_out(vty
, "Interface %s is ", ifp
->name
);
1356 if (if_is_up(ifp
)) {
1357 vty_out(vty
, "up, line protocol ");
1359 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1360 if (if_is_running(ifp
))
1361 vty_out(vty
, "is up\n");
1363 vty_out(vty
, "is down\n");
1365 vty_out(vty
, "detection is disabled\n");
1368 vty_out(vty
, "down\n");
1371 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1372 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1373 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1374 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1376 zebra_ptm_show_status(vty
, ifp
);
1378 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
1379 vty_out(vty
, " vrf: %s\n", vrf
->name
);
1382 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1384 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1386 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1387 vty_out(vty
, " pseudo interface\n");
1389 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1390 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
1394 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
1395 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
1396 if (ifp
->mtu6
!= ifp
->mtu
)
1397 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
1398 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
1400 /* Hardware address. */
1401 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
1402 if (ifp
->hw_addr_len
!= 0) {
1405 vty_out(vty
, " HWaddr: ");
1406 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
1407 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
1412 /* Bandwidth in Mbps */
1413 if (ifp
->bandwidth
!= 0) {
1414 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
1418 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
1422 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1424 connected_dump_vty(vty
, connected
);
1427 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1428 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1429 && (connected
->address
->family
== AF_INET6
))
1430 connected_dump_vty(vty
, connected
);
1433 if (listhead(zebra_if
->nhe_connected
)) {
1434 vty_out(vty
, " Nexthop IDs connected:");
1435 for (ALL_LIST_ELEMENTS_RO(zebra_if
->nhe_connected
, node
,
1437 nhe_connected_dump_vty(vty
, nhe_connected
);
1441 vty_out(vty
, " Interface Type %s\n",
1442 zebra_ziftype_2str(zebra_if
->zif_type
));
1443 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1444 struct zebra_l2info_bridge
*bridge_info
;
1446 bridge_info
= &zebra_if
->l2info
.br
;
1447 vty_out(vty
, " Bridge VLAN-aware: %s\n",
1448 bridge_info
->vlan_aware
? "yes" : "no");
1449 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1450 struct zebra_l2info_vlan
*vlan_info
;
1452 vlan_info
= &zebra_if
->l2info
.vl
;
1453 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
1454 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
1455 struct zebra_l2info_vxlan
*vxlan_info
;
1457 vxlan_info
= &zebra_if
->l2info
.vxl
;
1458 vty_out(vty
, " VxLAN Id %u", vxlan_info
->vni
);
1459 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
1460 vty_out(vty
, " VTEP IP: %s",
1461 inet_ntoa(vxlan_info
->vtep_ip
));
1462 if (vxlan_info
->access_vlan
)
1463 vty_out(vty
, " Access VLAN Id %u\n",
1464 vxlan_info
->access_vlan
);
1465 if (vxlan_info
->mcast_grp
.s_addr
!= INADDR_ANY
)
1466 vty_out(vty
, " Mcast Group %s",
1467 inet_ntoa(vxlan_info
->mcast_grp
));
1471 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
1472 struct zebra_l2info_brslave
*br_slave
;
1474 br_slave
= &zebra_if
->brslave_info
;
1475 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
) {
1476 if (br_slave
->br_if
)
1477 vty_out(vty
, " Master interface: %s\n",
1478 br_slave
->br_if
->name
);
1480 vty_out(vty
, " Master ifindex: %u\n",
1481 br_slave
->bridge_ifindex
);
1485 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
1486 struct zebra_l2info_bondslave
*bond_slave
;
1488 bond_slave
= &zebra_if
->bondslave_info
;
1489 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
) {
1490 if (bond_slave
->bond_if
)
1491 vty_out(vty
, " Master interface: %s\n",
1492 bond_slave
->bond_if
->name
);
1494 vty_out(vty
, " Master ifindex: %u\n",
1495 bond_slave
->bond_ifindex
);
1499 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
1501 vty_out(vty
, " Parent interface: %s\n", zebra_if
->link
->name
);
1503 vty_out(vty
, " Parent ifindex: %d\n", zebra_if
->link_ifindex
);
1506 if (HAS_LINK_PARAMS(ifp
)) {
1508 struct if_link_params
*iflp
= ifp
->link_params
;
1509 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
1510 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
1511 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
1512 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
1513 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
1515 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
1517 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1519 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
1521 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1522 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
1524 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1525 i
, iflp
->unrsv_bw
[i
], i
+ 1,
1526 iflp
->unrsv_bw
[i
+ 1]);
1529 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
1530 vty_out(vty
, " Administrative Group:%u\n",
1532 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
1533 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
1535 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
1536 vty_out(vty
, " Min: %u (micro-sec.)",
1538 vty_out(vty
, " Max: %u (micro-sec.)",
1543 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
1545 " Link Delay Variation %u (micro-sec.)\n",
1547 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
1548 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
1550 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
1551 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
1553 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
1554 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
1556 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
1557 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
1559 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
1560 vty_out(vty
, " Neighbor ASBR IP: %s AS: %u \n",
1561 inet_ntoa(iflp
->rmt_ip
), iflp
->rmt_as
);
1564 hook_call(zebra_if_extra_info
, vty
, ifp
);
1566 if (listhead(ifp
->nbr_connected
))
1567 vty_out(vty
, " Neighbor address(s):\n");
1568 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
1569 nbr_connected_dump_vty(vty
, nbr_connected
);
1571 #ifdef HAVE_PROC_NET_DEV
1572 /* Statistics print out using proc file system. */
1574 " %lu input packets (%lu multicast), %lu bytes, "
1576 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
1577 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
1580 " %lu input errors, %lu length, %lu overrun,"
1581 " %lu CRC, %lu frame\n",
1582 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
1583 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
1584 ifp
->stats
.rx_frame_errors
);
1586 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
1587 ifp
->stats
.rx_missed_errors
);
1589 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
1590 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
1591 ifp
->stats
.tx_dropped
);
1594 " %lu output errors, %lu aborted, %lu carrier,"
1595 " %lu fifo, %lu heartbeat\n",
1596 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
1597 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
1598 ifp
->stats
.tx_heartbeat_errors
);
1600 vty_out(vty
, " %lu window, %lu collisions\n",
1601 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
1602 #endif /* HAVE_PROC_NET_DEV */
1604 #ifdef HAVE_NET_RT_IFLIST
1605 /* Statistics print out using sysctl (). */
1607 " input packets %llu, bytes %llu, dropped %llu,"
1608 " multicast packets %llu\n",
1609 (unsigned long long)ifp
->stats
.ifi_ipackets
,
1610 (unsigned long long)ifp
->stats
.ifi_ibytes
,
1611 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
1612 (unsigned long long)ifp
->stats
.ifi_imcasts
);
1614 vty_out(vty
, " input errors %llu\n",
1615 (unsigned long long)ifp
->stats
.ifi_ierrors
);
1618 " output packets %llu, bytes %llu,"
1619 " multicast packets %llu\n",
1620 (unsigned long long)ifp
->stats
.ifi_opackets
,
1621 (unsigned long long)ifp
->stats
.ifi_obytes
,
1622 (unsigned long long)ifp
->stats
.ifi_omcasts
);
1624 vty_out(vty
, " output errors %llu\n",
1625 (unsigned long long)ifp
->stats
.ifi_oerrors
);
1627 vty_out(vty
, " collisions %llu\n",
1628 (unsigned long long)ifp
->stats
.ifi_collisions
);
1629 #endif /* HAVE_NET_RT_IFLIST */
1632 static void interface_update_stats(void)
1634 #ifdef HAVE_PROC_NET_DEV
1635 /* If system has interface statistics via proc file system, update
1637 ifstat_update_proc();
1638 #endif /* HAVE_PROC_NET_DEV */
1639 #ifdef HAVE_NET_RT_IFLIST
1640 ifstat_update_sysctl();
1641 #endif /* HAVE_NET_RT_IFLIST */
1644 struct cmd_node interface_node
= {INTERFACE_NODE
, "%s(config-if)# ", 1};
1646 #ifndef VTYSH_EXTRACT_PL
1647 #include "zebra/interface_clippy.c"
1649 /* Show all interfaces to vty. */
1650 DEFPY(show_interface
, show_interface_cmd
,
1651 "show interface [vrf NAME$vrf_name] [brief$brief]",
1653 "Interface status and configuration\n"
1655 "Interface status and configuration summary\n")
1658 struct interface
*ifp
;
1659 vrf_id_t vrf_id
= VRF_DEFAULT
;
1661 interface_update_stats();
1664 VRF_GET_ID(vrf_id
, vrf_name
, false);
1666 /* All interface print. */
1667 vrf
= vrf_lookup_by_id(vrf_id
);
1669 ifs_dump_brief_vty(vty
, vrf
);
1671 FOR_ALL_INTERFACES (vrf
, ifp
) {
1672 if_dump_vty(vty
, ifp
);
1680 /* Show all interfaces to vty. */
1681 DEFPY (show_interface_vrf_all
,
1682 show_interface_vrf_all_cmd
,
1683 "show interface vrf all [brief$brief]",
1685 "Interface status and configuration\n"
1686 VRF_ALL_CMD_HELP_STR
1687 "Interface status and configuration summary\n")
1690 struct interface
*ifp
;
1692 interface_update_stats();
1694 /* All interface print. */
1695 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1697 ifs_dump_brief_vty(vty
, vrf
);
1699 FOR_ALL_INTERFACES (vrf
, ifp
)
1700 if_dump_vty(vty
, ifp
);
1707 /* Show specified interface to vty. */
1709 DEFUN (show_interface_name_vrf
,
1710 show_interface_name_vrf_cmd
,
1711 "show interface IFNAME vrf NAME",
1713 "Interface status and configuration\n"
1719 struct interface
*ifp
;
1722 interface_update_stats();
1724 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
1726 /* Specified interface print. */
1727 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1729 vty_out(vty
, "%% Can't find interface %s\n",
1730 argv
[idx_ifname
]->arg
);
1733 if_dump_vty(vty
, ifp
);
1738 /* Show specified interface to vty. */
1739 DEFUN (show_interface_name_vrf_all
,
1740 show_interface_name_vrf_all_cmd
,
1741 "show interface IFNAME [vrf all]",
1743 "Interface status and configuration\n"
1745 VRF_ALL_CMD_HELP_STR
)
1749 struct interface
*ifp
;
1752 interface_update_stats();
1754 /* All interface print. */
1755 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1756 /* Specified interface print. */
1757 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf
->vrf_id
);
1759 if_dump_vty(vty
, ifp
);
1765 vty_out(vty
, "%% Can't find interface %s\n",
1766 argv
[idx_ifname
]->arg
);
1774 static void if_show_description(struct vty
*vty
, vrf_id_t vrf_id
)
1776 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1777 struct interface
*ifp
;
1779 vty_out(vty
, "Interface Status Protocol Description\n");
1780 FOR_ALL_INTERFACES (vrf
, ifp
) {
1782 struct zebra_if
*zif
;
1787 len
= vty_out(vty
, "%s", ifp
->name
);
1788 vty_out(vty
, "%*s", (16 - len
), " ");
1790 if (if_is_up(ifp
)) {
1791 vty_out(vty
, "up ");
1792 if (CHECK_FLAG(ifp
->status
,
1793 ZEBRA_INTERFACE_LINKDETECTION
)) {
1794 if (if_is_running(ifp
))
1795 vty_out(vty
, "up ");
1797 vty_out(vty
, "down ");
1799 vty_out(vty
, "unknown ");
1802 vty_out(vty
, "down down ");
1807 vty_out(vty
, "%s", ifp
->desc
);
1810 if (zif
&& zif
->desc
) {
1811 vty_out(vty
, "%s%s",
1822 DEFUN (show_interface_desc
,
1823 show_interface_desc_cmd
,
1824 "show interface description [vrf NAME]",
1826 "Interface status and configuration\n"
1827 "Interface description\n"
1830 vrf_id_t vrf_id
= VRF_DEFAULT
;
1833 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1835 if_show_description(vty
, vrf_id
);
1841 DEFUN (show_interface_desc_vrf_all
,
1842 show_interface_desc_vrf_all_cmd
,
1843 "show interface description vrf all",
1845 "Interface status and configuration\n"
1846 "Interface description\n"
1847 VRF_ALL_CMD_HELP_STR
)
1851 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1852 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
1853 vty_out(vty
, "\n\tVRF %u\n\n", vrf
->vrf_id
);
1854 if_show_description(vty
, vrf
->vrf_id
);
1863 "Set multicast flag to interface\n")
1865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1867 struct zebra_if
*if_data
;
1869 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1870 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
1872 vty_out(vty
, "Can't set multicast flag\n");
1873 return CMD_WARNING_CONFIG_FAILED
;
1877 if_data
= ifp
->info
;
1878 if_data
->multicast
= IF_ZEBRA_MULTICAST_ON
;
1883 DEFUN (no_multicast
,
1887 "Unset multicast flag to interface\n")
1889 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1891 struct zebra_if
*if_data
;
1893 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1894 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
1896 vty_out(vty
, "Can't unset multicast flag\n");
1897 return CMD_WARNING_CONFIG_FAILED
;
1901 if_data
= ifp
->info
;
1902 if_data
->multicast
= IF_ZEBRA_MULTICAST_OFF
;
1910 "Enable link detection on interface\n")
1912 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1913 int if_was_operative
;
1915 if_was_operative
= if_is_no_ptm_operative(ifp
);
1916 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1918 /* When linkdetection is enabled, if might come down */
1919 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
1922 /* FIXME: Will defer status change forwarding if interface
1923 does not come down! */
1929 DEFUN (no_linkdetect
,
1933 "Disable link detection on interface\n")
1935 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1936 int if_was_operative
;
1938 if_was_operative
= if_is_no_ptm_operative(ifp
);
1939 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1941 /* Interface may come up after disabling link detection */
1942 if (if_is_operative(ifp
) && !if_was_operative
)
1945 /* FIXME: see linkdetect_cmd */
1953 "Shutdown the selected interface\n")
1955 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1957 struct zebra_if
*if_data
;
1959 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1960 ret
= if_unset_flags(ifp
, IFF_UP
);
1962 vty_out(vty
, "Can't shutdown interface\n");
1963 return CMD_WARNING_CONFIG_FAILED
;
1967 if_data
= ifp
->info
;
1968 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_ON
;
1973 DEFUN (no_shutdown_if
,
1977 "Shutdown the selected interface\n")
1979 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1981 struct zebra_if
*if_data
;
1983 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1984 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
1986 vty_out(vty
, "Can't up interface\n");
1987 return CMD_WARNING_CONFIG_FAILED
;
1991 /* Some addresses (in particular, IPv6 addresses on Linux) get
1992 * removed when the interface goes down. They need to be
1995 if_addr_wakeup(ifp
);
1998 if_data
= ifp
->info
;
1999 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
2004 DEFUN (bandwidth_if
,
2006 "bandwidth (1-100000)",
2007 "Set bandwidth informational parameter\n"
2008 "Bandwidth in megabits\n")
2011 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2012 unsigned int bandwidth
;
2014 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
2016 /* bandwidth range is <1-100000> */
2017 if (bandwidth
< 1 || bandwidth
> 100000) {
2018 vty_out(vty
, "Bandwidth is invalid\n");
2019 return CMD_WARNING_CONFIG_FAILED
;
2022 ifp
->bandwidth
= bandwidth
;
2024 /* force protocols to recalculate routes due to cost change */
2025 if (if_is_operative(ifp
))
2026 zebra_interface_up_update(ifp
);
2031 DEFUN (no_bandwidth_if
,
2032 no_bandwidth_if_cmd
,
2033 "no bandwidth [(1-100000)]",
2035 "Set bandwidth informational parameter\n"
2036 "Bandwidth in megabits\n")
2038 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2042 /* force protocols to recalculate routes due to cost change */
2043 if (if_is_operative(ifp
))
2044 zebra_interface_up_update(ifp
);
2050 struct cmd_node link_params_node
= {
2051 LINK_PARAMS_NODE
, "%s(config-link-params)# ", 1,
2054 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
2055 uint32_t type
, uint32_t value
)
2057 /* Update field as needed */
2058 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
2060 SET_PARAM(ifp
->link_params
, type
);
2062 /* force protocols to update LINK STATE due to parameters change
2064 if (if_is_operative(ifp
))
2065 zebra_interface_parameters_update(ifp
);
2068 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
2069 uint32_t type
, float 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
);
2084 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
2086 if (ifp
->link_params
== NULL
)
2090 UNSET_PARAM(ifp
->link_params
, type
);
2092 /* force protocols to update LINK STATE due to parameters change */
2093 if (if_is_operative(ifp
))
2094 zebra_interface_parameters_update(ifp
);
2097 DEFUN_NOSH (link_params
,
2102 /* vty->qobj_index stays the same @ interface pointer */
2103 vty
->node
= LINK_PARAMS_NODE
;
2108 DEFUN_NOSH (exit_link_params
,
2109 exit_link_params_cmd
,
2111 "Exit from Link Params configuration mode\n")
2113 if (vty
->node
== LINK_PARAMS_NODE
)
2114 vty
->node
= INTERFACE_NODE
;
2118 /* Specific Traffic Engineering parameters commands */
2119 DEFUN (link_params_enable
,
2120 link_params_enable_cmd
,
2122 "Activate link parameters on this interface\n")
2124 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2126 /* This command could be issue at startup, when activate MPLS TE */
2127 /* on a new interface or after a ON / OFF / ON toggle */
2128 /* In all case, TE parameters are reset to their default factory */
2129 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2131 "Link-params: enable TE link parameters on interface %s",
2134 if (!if_link_params_get(ifp
)) {
2135 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2137 "Link-params: failed to init TE link parameters %s",
2140 return CMD_WARNING_CONFIG_FAILED
;
2143 /* force protocols to update LINK STATE due to parameters change */
2144 if (if_is_operative(ifp
))
2145 zebra_interface_parameters_update(ifp
);
2150 DEFUN (no_link_params_enable
,
2151 no_link_params_enable_cmd
,
2154 "Disable link parameters on this interface\n")
2156 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2158 if (IS_ZEBRA_DEBUG_EVENT
|| IS_ZEBRA_DEBUG_MPLS
)
2159 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2162 if_link_params_free(ifp
);
2164 /* force protocols to update LINK STATE due to parameters change */
2165 if (if_is_operative(ifp
))
2166 zebra_interface_parameters_update(ifp
);
2171 /* STANDARD TE metrics */
2172 DEFUN (link_params_metric
,
2173 link_params_metric_cmd
,
2174 "metric (0-4294967295)",
2175 "Link metric for MPLS-TE purpose\n"
2176 "Metric value in decimal\n")
2179 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2180 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2183 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2185 /* Update TE metric if needed */
2186 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
2191 DEFUN (no_link_params_metric
,
2192 no_link_params_metric_cmd
,
2195 "Disable Link Metric on this interface\n")
2197 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2199 /* Unset TE Metric */
2200 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
2205 DEFUN (link_params_maxbw
,
2206 link_params_maxbw_cmd
,
2208 "Maximum bandwidth that can be used\n"
2209 "Bytes/second (IEEE floating point format)\n")
2211 int idx_bandwidth
= 1;
2212 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2213 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2217 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2218 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
2219 safe_strerror(errno
));
2220 return CMD_WARNING_CONFIG_FAILED
;
2223 /* Check that Maximum bandwidth is not lower than other bandwidth
2225 if ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0])
2226 || (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2])
2227 || (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4])
2228 || (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6])
2229 || (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
)
2230 || (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
)) {
2232 "Maximum Bandwidth could not be lower than others bandwidth\n");
2233 return CMD_WARNING_CONFIG_FAILED
;
2236 /* Update Maximum Bandwidth if needed */
2237 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
2242 DEFUN (link_params_max_rsv_bw
,
2243 link_params_max_rsv_bw_cmd
,
2244 "max-rsv-bw BANDWIDTH",
2245 "Maximum bandwidth that may be reserved\n"
2246 "Bytes/second (IEEE floating point format)\n")
2248 int idx_bandwidth
= 1;
2249 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2250 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2253 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2254 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
2255 safe_strerror(errno
));
2256 return CMD_WARNING_CONFIG_FAILED
;
2259 /* Check that bandwidth is not greater than maximum bandwidth parameter
2261 if (bw
> iflp
->max_bw
) {
2263 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2265 return CMD_WARNING_CONFIG_FAILED
;
2268 /* Update Maximum Reservable Bandwidth if needed */
2269 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
2274 DEFUN (link_params_unrsv_bw
,
2275 link_params_unrsv_bw_cmd
,
2276 "unrsv-bw (0-7) BANDWIDTH",
2277 "Unreserved bandwidth at each priority level\n"
2279 "Bytes/second (IEEE floating point format)\n")
2282 int idx_bandwidth
= 2;
2283 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2284 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2288 /* We don't have to consider about range check here. */
2289 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
2290 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2291 safe_strerror(errno
));
2292 return CMD_WARNING_CONFIG_FAILED
;
2295 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2296 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2297 safe_strerror(errno
));
2298 return CMD_WARNING_CONFIG_FAILED
;
2301 /* Check that bandwidth is not greater than maximum bandwidth parameter
2303 if (bw
> iflp
->max_bw
) {
2305 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2307 return CMD_WARNING_CONFIG_FAILED
;
2310 /* Update Unreserved Bandwidth if needed */
2311 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
2317 DEFUN (link_params_admin_grp
,
2318 link_params_admin_grp_cmd
,
2319 "admin-grp BITPATTERN",
2320 "Administrative group membership\n"
2321 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2323 int idx_bitpattern
= 1;
2324 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2325 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2326 unsigned long value
;
2328 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
2329 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
2330 safe_strerror(errno
));
2331 return CMD_WARNING_CONFIG_FAILED
;
2334 /* Update Administrative Group if needed */
2335 link_param_cmd_set_uint32(ifp
, &iflp
->admin_grp
, LP_ADM_GRP
, value
);
2340 DEFUN (no_link_params_admin_grp
,
2341 no_link_params_admin_grp_cmd
,
2344 "Disable Administrative group membership on this interface\n")
2346 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2348 /* Unset Admin Group */
2349 link_param_cmd_unset(ifp
, LP_ADM_GRP
);
2354 /* RFC5392 & RFC5316: INTER-AS */
2355 DEFUN (link_params_inter_as
,
2356 link_params_inter_as_cmd
,
2357 "neighbor A.B.C.D as (1-4294967295)",
2358 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2359 "Remote IP address in dot decimal A.B.C.D\n"
2360 "Remote AS number\n"
2361 "AS number in the range <1-4294967295>\n")
2366 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2367 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2368 struct in_addr addr
;
2371 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
2372 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
2373 return CMD_WARNING_CONFIG_FAILED
;
2376 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2378 /* Update Remote IP and Remote AS fields if needed */
2379 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
2380 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
2383 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
2384 SET_PARAM(iflp
, LP_RMT_AS
);
2386 /* force protocols to update LINK STATE due to parameters change
2388 if (if_is_operative(ifp
))
2389 zebra_interface_parameters_update(ifp
);
2394 DEFUN (no_link_params_inter_as
,
2395 no_link_params_inter_as_cmd
,
2398 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2400 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2401 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2403 /* Reset Remote IP and AS neighbor */
2405 iflp
->rmt_ip
.s_addr
= 0;
2406 UNSET_PARAM(iflp
, LP_RMT_AS
);
2408 /* force protocols to update LINK STATE due to parameters change */
2409 if (if_is_operative(ifp
))
2410 zebra_interface_parameters_update(ifp
);
2415 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2416 * draft-ietf-isis-metric-extensions-07.txt */
2417 DEFUN (link_params_delay
,
2418 link_params_delay_cmd
,
2419 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2420 "Unidirectional Average Link Delay\n"
2421 "Average delay in micro-second as decimal (0...16777215)\n"
2423 "Minimum delay in micro-second as decimal (0...16777215)\n"
2425 "Maximum delay in micro-second as decimal (0...16777215)\n")
2427 /* Get and Check new delay values */
2428 uint32_t delay
= 0, low
= 0, high
= 0;
2429 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
2431 low
= strtoul(argv
[3]->arg
, NULL
, 10);
2432 high
= strtoul(argv
[5]->arg
, NULL
, 10);
2435 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2436 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2440 /* Check new delay value against old Min and Max delays if set
2442 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)
2443 && (delay
<= iflp
->min_delay
|| delay
>= iflp
->max_delay
)) {
2445 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2446 iflp
->min_delay
, iflp
->max_delay
);
2447 return CMD_WARNING_CONFIG_FAILED
;
2449 /* Update delay if value is not set or change */
2450 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
2451 iflp
->av_delay
= delay
;
2452 SET_PARAM(iflp
, LP_DELAY
);
2455 /* Unset Min and Max delays if already set */
2456 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2457 iflp
->min_delay
= 0;
2458 iflp
->max_delay
= 0;
2459 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2463 /* Check new delays value coherency */
2464 if (delay
<= low
|| delay
>= high
) {
2466 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2468 return CMD_WARNING_CONFIG_FAILED
;
2470 /* Update Delays if needed */
2471 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
2472 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
2473 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
2474 || iflp
->max_delay
!= high
) {
2475 iflp
->av_delay
= delay
;
2476 SET_PARAM(iflp
, LP_DELAY
);
2477 iflp
->min_delay
= low
;
2478 iflp
->max_delay
= high
;
2479 SET_PARAM(iflp
, LP_MM_DELAY
);
2484 /* force protocols to update LINK STATE due to parameters change */
2485 if (update
== 1 && if_is_operative(ifp
))
2486 zebra_interface_parameters_update(ifp
);
2491 DEFUN (no_link_params_delay
,
2492 no_link_params_delay_cmd
,
2495 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2497 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2498 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2502 UNSET_PARAM(iflp
, LP_DELAY
);
2503 iflp
->min_delay
= 0;
2504 iflp
->max_delay
= 0;
2505 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2507 /* force protocols to update LINK STATE due to parameters change */
2508 if (if_is_operative(ifp
))
2509 zebra_interface_parameters_update(ifp
);
2514 DEFUN (link_params_delay_var
,
2515 link_params_delay_var_cmd
,
2516 "delay-variation (0-16777215)",
2517 "Unidirectional Link Delay Variation\n"
2518 "delay variation in micro-second as decimal (0...16777215)\n")
2521 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2522 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2525 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2527 /* Update Delay Variation if needed */
2528 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
2533 DEFUN (no_link_params_delay_var
,
2534 no_link_params_delay_var_cmd
,
2535 "no delay-variation",
2537 "Disable Unidirectional Delay Variation on this interface\n")
2539 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2541 /* Unset Delay Variation */
2542 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
2547 DEFUN (link_params_pkt_loss
,
2548 link_params_pkt_loss_cmd
,
2549 "packet-loss PERCENTAGE",
2550 "Unidirectional Link Packet Loss\n"
2551 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2553 int idx_percentage
= 1;
2554 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2555 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2558 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
2559 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
2560 safe_strerror(errno
));
2561 return CMD_WARNING_CONFIG_FAILED
;
2564 if (fval
> MAX_PKT_LOSS
)
2565 fval
= MAX_PKT_LOSS
;
2567 /* Update Packet Loss if needed */
2568 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
2573 DEFUN (no_link_params_pkt_loss
,
2574 no_link_params_pkt_loss_cmd
,
2577 "Disable Unidirectional Link Packet Loss on this interface\n")
2579 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2581 /* Unset Packet Loss */
2582 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
2587 DEFUN (link_params_res_bw
,
2588 link_params_res_bw_cmd
,
2590 "Unidirectional Residual Bandwidth\n"
2591 "Bytes/second (IEEE floating point format)\n")
2593 int idx_bandwidth
= 1;
2594 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2595 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2598 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2599 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
2600 safe_strerror(errno
));
2601 return CMD_WARNING_CONFIG_FAILED
;
2604 /* Check that bandwidth is not greater than maximum bandwidth parameter
2606 if (bw
> iflp
->max_bw
) {
2608 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2610 return CMD_WARNING_CONFIG_FAILED
;
2613 /* Update Residual Bandwidth if needed */
2614 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
2619 DEFUN (no_link_params_res_bw
,
2620 no_link_params_res_bw_cmd
,
2623 "Disable Unidirectional Residual Bandwidth on this interface\n")
2625 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2627 /* Unset Residual Bandwidth */
2628 link_param_cmd_unset(ifp
, LP_RES_BW
);
2633 DEFUN (link_params_ava_bw
,
2634 link_params_ava_bw_cmd
,
2636 "Unidirectional Available Bandwidth\n"
2637 "Bytes/second (IEEE floating point format)\n")
2639 int idx_bandwidth
= 1;
2640 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2641 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2644 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2645 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
2646 safe_strerror(errno
));
2647 return CMD_WARNING_CONFIG_FAILED
;
2650 /* Check that bandwidth is not greater than maximum bandwidth parameter
2652 if (bw
> iflp
->max_bw
) {
2654 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2656 return CMD_WARNING_CONFIG_FAILED
;
2659 /* Update Residual Bandwidth if needed */
2660 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
2665 DEFUN (no_link_params_ava_bw
,
2666 no_link_params_ava_bw_cmd
,
2669 "Disable Unidirectional Available Bandwidth on this interface\n")
2671 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2673 /* Unset Available Bandwidth */
2674 link_param_cmd_unset(ifp
, LP_AVA_BW
);
2679 DEFUN (link_params_use_bw
,
2680 link_params_use_bw_cmd
,
2682 "Unidirectional Utilised Bandwidth\n"
2683 "Bytes/second (IEEE floating point format)\n")
2685 int idx_bandwidth
= 1;
2686 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2687 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2690 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2691 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
2692 safe_strerror(errno
));
2693 return CMD_WARNING_CONFIG_FAILED
;
2696 /* Check that bandwidth is not greater than maximum bandwidth parameter
2698 if (bw
> iflp
->max_bw
) {
2700 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2702 return CMD_WARNING_CONFIG_FAILED
;
2705 /* Update Utilized Bandwidth if needed */
2706 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
2711 DEFUN (no_link_params_use_bw
,
2712 no_link_params_use_bw_cmd
,
2715 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2717 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2719 /* Unset Utilised Bandwidth */
2720 link_param_cmd_unset(ifp
, LP_USE_BW
);
2725 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
2726 const char *addr_str
, const char *peer_str
,
2729 struct zebra_if
*if_data
;
2730 struct prefix_ipv4 lp
, pp
;
2731 struct connected
*ifc
;
2732 struct prefix_ipv4
*p
;
2734 enum zebra_dplane_result dplane_res
;
2736 if_data
= ifp
->info
;
2738 ret
= str2prefix_ipv4(addr_str
, &lp
);
2740 vty_out(vty
, "%% Malformed address \n");
2741 return CMD_WARNING_CONFIG_FAILED
;
2744 if (ipv4_martian(&lp
.prefix
)) {
2745 vty_out(vty
, "%% Invalid address\n");
2746 return CMD_WARNING_CONFIG_FAILED
;
2750 if (lp
.prefixlen
!= 32) {
2752 "%% Local prefix length for P-t-P address must be /32\n");
2753 return CMD_WARNING_CONFIG_FAILED
;
2756 ret
= str2prefix_ipv4(peer_str
, &pp
);
2758 vty_out(vty
, "%% Malformed peer address\n");
2759 return CMD_WARNING_CONFIG_FAILED
;
2763 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2765 ifc
= connected_new();
2769 p
= prefix_ipv4_new();
2771 ifc
->address
= (struct prefix
*)p
;
2774 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
2775 p
= prefix_ipv4_new();
2777 ifc
->destination
= (struct prefix
*)p
;
2782 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
2784 /* Add to linked list. */
2785 listnode_add(ifp
->connected
, ifc
);
2788 /* This address is configured from zebra. */
2789 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2790 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2792 /* In case of this route need to install kernel. */
2793 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2794 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
2795 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
2796 /* Some system need to up the interface to set IP address. */
2797 if (!if_is_up(ifp
)) {
2798 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
2802 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
2803 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2804 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
2805 dplane_res2str(dplane_res
));
2806 return CMD_WARNING_CONFIG_FAILED
;
2809 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2810 /* The address will be advertised to zebra clients when the
2812 * from the kernel has been received.
2813 * It will also be added to the subnet chain list, then. */
2819 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
2820 const char *addr_str
, const char *peer_str
,
2823 struct prefix_ipv4 lp
, pp
;
2824 struct connected
*ifc
;
2826 enum zebra_dplane_result dplane_res
;
2828 /* Convert to prefix structure. */
2829 ret
= str2prefix_ipv4(addr_str
, &lp
);
2831 vty_out(vty
, "%% Malformed address \n");
2832 return CMD_WARNING_CONFIG_FAILED
;
2836 if (lp
.prefixlen
!= 32) {
2838 "%% Local prefix length for P-t-P address must be /32\n");
2839 return CMD_WARNING_CONFIG_FAILED
;
2842 ret
= str2prefix_ipv4(peer_str
, &pp
);
2844 vty_out(vty
, "%% Malformed peer address\n");
2845 return CMD_WARNING_CONFIG_FAILED
;
2849 /* Check current interface address. */
2850 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2852 vty_out(vty
, "%% Can't find address\n");
2853 return CMD_WARNING_CONFIG_FAILED
;
2856 /* This is not configured address. */
2857 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2858 return CMD_WARNING_CONFIG_FAILED
;
2860 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2862 /* This is not real address or interface is not active. */
2863 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2864 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2865 listnode_delete(ifp
->connected
, ifc
);
2866 connected_free(ifc
);
2867 return CMD_WARNING_CONFIG_FAILED
;
2870 /* This is real route. */
2871 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
2872 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2873 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
2874 dplane_res2str(dplane_res
));
2875 return CMD_WARNING_CONFIG_FAILED
;
2877 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2878 /* we will receive a kernel notification about this route being removed.
2879 * this will trigger its removal from the connected list. */
2885 "ip address A.B.C.D/M",
2886 "Interface Internet Protocol config commands\n"
2887 "Set the IP address of an interface\n"
2888 "IP address (e.g. 10.0.0.1/8)\n")
2890 int idx_ipv4_prefixlen
= 2;
2891 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2892 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2896 DEFUN (no_ip_address
,
2898 "no ip address A.B.C.D/M",
2900 "Interface Internet Protocol config commands\n"
2901 "Set the IP address of an interface\n"
2902 "IP Address (e.g. 10.0.0.1/8)\n")
2904 int idx_ipv4_prefixlen
= 3;
2905 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2906 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2910 DEFUN(ip_address_peer
,
2911 ip_address_peer_cmd
,
2912 "ip address A.B.C.D peer A.B.C.D/M",
2913 "Interface Internet Protocol config commands\n"
2914 "Set the IP address of an interface\n"
2915 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2916 "Specify P-t-P address\n"
2917 "Peer IP address (e.g. 10.0.0.1/8)\n")
2919 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2920 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
2923 DEFUN(no_ip_address_peer
,
2924 no_ip_address_peer_cmd
,
2925 "no ip address A.B.C.D peer A.B.C.D/M",
2927 "Interface Internet Protocol config commands\n"
2928 "Set the IP address of an interface\n"
2929 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2930 "Specify P-t-P address\n"
2931 "Peer IP address (e.g. 10.0.0.1/8)\n")
2933 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2934 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
2938 DEFUN (ip_address_label
,
2939 ip_address_label_cmd
,
2940 "ip address A.B.C.D/M label LINE",
2941 "Interface Internet Protocol config commands\n"
2942 "Set the IP address of an interface\n"
2943 "IP address (e.g. 10.0.0.1/8)\n"
2944 "Label of this address\n"
2947 int idx_ipv4_prefixlen
= 2;
2949 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2950 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2951 argv
[idx_line
]->arg
);
2954 DEFUN (no_ip_address_label
,
2955 no_ip_address_label_cmd
,
2956 "no ip address A.B.C.D/M label LINE",
2958 "Interface Internet Protocol config commands\n"
2959 "Set the IP address of an interface\n"
2960 "IP address (e.g. 10.0.0.1/8)\n"
2961 "Label of this address\n"
2964 int idx_ipv4_prefixlen
= 3;
2966 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2967 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2968 NULL
, argv
[idx_line
]->arg
);
2970 #endif /* HAVE_NETLINK */
2972 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
2973 const char *addr_str
, const char *peer_str
,
2976 struct zebra_if
*if_data
;
2977 struct prefix_ipv6 cp
;
2978 struct connected
*ifc
;
2979 struct prefix_ipv6
*p
;
2981 enum zebra_dplane_result dplane_res
;
2983 if_data
= ifp
->info
;
2985 ret
= str2prefix_ipv6(addr_str
, &cp
);
2987 vty_out(vty
, "%% Malformed address \n");
2988 return CMD_WARNING_CONFIG_FAILED
;
2991 if (ipv6_martian(&cp
.prefix
)) {
2992 vty_out(vty
, "%% Invalid address\n");
2993 return CMD_WARNING_CONFIG_FAILED
;
2996 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
2998 ifc
= connected_new();
3002 p
= prefix_ipv6_new();
3004 ifc
->address
= (struct prefix
*)p
;
3008 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
3010 /* Add to linked list. */
3011 listnode_add(ifp
->connected
, ifc
);
3014 /* This address is configured from zebra. */
3015 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3016 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3018 /* In case of this route need to install kernel. */
3019 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
3020 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
3021 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
3022 /* Some system need to up the interface to set IP address. */
3023 if (!if_is_up(ifp
)) {
3024 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
3028 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
3029 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3030 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
3031 dplane_res2str(dplane_res
));
3032 return CMD_WARNING_CONFIG_FAILED
;
3035 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3036 /* The address will be advertised to zebra clients when the
3038 * from the kernel has been received. */
3044 /* Return true if an ipv6 address is configured on ifp */
3045 int ipv6_address_configured(struct interface
*ifp
)
3047 struct connected
*connected
;
3048 struct listnode
*node
;
3050 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
3051 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
3052 && (connected
->address
->family
== AF_INET6
))
3058 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
3059 const char *addr_str
, const char *peer_str
,
3062 struct prefix_ipv6 cp
;
3063 struct connected
*ifc
;
3065 enum zebra_dplane_result dplane_res
;
3067 /* Convert to prefix structure. */
3068 ret
= str2prefix_ipv6(addr_str
, &cp
);
3070 vty_out(vty
, "%% Malformed address \n");
3071 return CMD_WARNING_CONFIG_FAILED
;
3074 /* Check current interface address. */
3075 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
3077 vty_out(vty
, "%% Can't find address\n");
3078 return CMD_WARNING_CONFIG_FAILED
;
3081 /* This is not configured address. */
3082 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3083 return CMD_WARNING_CONFIG_FAILED
;
3085 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3087 /* This is not real address or interface is not active. */
3088 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
3089 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3090 listnode_delete(ifp
->connected
, ifc
);
3091 connected_free(ifc
);
3092 return CMD_WARNING_CONFIG_FAILED
;
3095 /* This is real route. */
3096 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
3097 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3098 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
3099 dplane_res2str(dplane_res
));
3100 return CMD_WARNING_CONFIG_FAILED
;
3103 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3104 /* This information will be propagated to the zclients when the
3105 * kernel notification is received. */
3109 DEFUN (ipv6_address
,
3111 "ipv6 address X:X::X:X/M",
3112 "Interface IPv6 config commands\n"
3113 "Set the IP address of an interface\n"
3114 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3116 int idx_ipv6_prefixlen
= 2;
3117 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3118 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3122 DEFUN (no_ipv6_address
,
3123 no_ipv6_address_cmd
,
3124 "no ipv6 address X:X::X:X/M",
3126 "Interface IPv6 config commands\n"
3127 "Set the IP address of an interface\n"
3128 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3130 int idx_ipv6_prefixlen
= 3;
3131 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3132 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3136 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
3140 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
3143 struct if_link_params
*iflp
= ifp
->link_params
;
3145 vty_out(vty
, " link-params\n");
3146 vty_out(vty
, " enable\n");
3147 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
3148 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
3149 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
3150 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
3151 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
3152 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
3153 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
3154 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
3155 for (i
= 0; i
< 8; i
++)
3156 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
3157 vty_out(vty
, " unrsv-bw %d %g\n", i
,
3160 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
3161 vty_out(vty
, " admin-grp 0x%x\n", iflp
->admin_grp
);
3162 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
3163 vty_out(vty
, " delay %u", iflp
->av_delay
);
3164 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3165 vty_out(vty
, " min %u", iflp
->min_delay
);
3166 vty_out(vty
, " max %u", iflp
->max_delay
);
3170 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
3171 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
3172 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
3173 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
3174 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
3175 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
3176 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
3177 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
3178 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
3179 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
3180 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
3181 vty_out(vty
, " neighbor %s as %u\n", inet_ntoa(iflp
->rmt_ip
),
3183 vty_out(vty
, " exit-link-params\n");
3187 static int if_config_write(struct vty
*vty
)
3190 struct interface
*ifp
;
3192 zebra_ptm_write(vty
);
3194 RB_FOREACH (vrf0
, vrf_name_head
, &vrfs_by_name
)
3195 FOR_ALL_INTERFACES (vrf0
, ifp
) {
3196 struct zebra_if
*if_data
;
3197 struct listnode
*addrnode
;
3198 struct connected
*ifc
;
3202 if_data
= ifp
->info
;
3203 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
3205 if (ifp
->vrf_id
== VRF_DEFAULT
)
3206 vty_frame(vty
, "interface %s\n", ifp
->name
);
3208 vty_frame(vty
, "interface %s vrf %s\n",
3209 ifp
->name
, vrf
->name
);
3212 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)
3213 vty_out(vty
, " shutdown\n");
3215 zebra_ptm_if_write(vty
, if_data
);
3219 vty_out(vty
, " description %s\n", ifp
->desc
);
3221 /* Assign bandwidth here to avoid unnecessary interface
3223 while processing config script */
3224 if (ifp
->bandwidth
!= 0)
3225 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
3227 if (!CHECK_FLAG(ifp
->status
,
3228 ZEBRA_INTERFACE_LINKDETECTION
))
3229 vty_out(vty
, " no link-detect\n");
3231 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
3233 if (CHECK_FLAG(ifc
->conf
,
3234 ZEBRA_IFC_CONFIGURED
)) {
3235 char buf
[INET6_ADDRSTRLEN
];
3237 vty_out(vty
, " ip%s address %s",
3238 p
->family
== AF_INET
? ""
3240 inet_ntop(p
->family
,
3243 if (CONNECTED_PEER(ifc
)) {
3244 p
= ifc
->destination
;
3245 vty_out(vty
, " peer %s",
3246 inet_ntop(p
->family
,
3251 vty_out(vty
, "/%d", p
->prefixlen
);
3254 vty_out(vty
, " label %s",
3262 if (if_data
->multicast
3263 != IF_ZEBRA_MULTICAST_UNSPEC
)
3264 vty_out(vty
, " %smulticast\n",
3266 == IF_ZEBRA_MULTICAST_ON
3271 hook_call(zebra_if_config_wr
, vty
, ifp
);
3273 link_params_config_write(vty
, ifp
);
3275 vty_endframe(vty
, "!\n");
3280 /* Allocate and initialize interface vector. */
3281 void zebra_if_init(void)
3283 /* Initialize interface and new hook. */
3284 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
3285 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
3287 /* Install configuration write function. */
3288 install_node(&interface_node
, if_config_write
);
3289 install_node(&link_params_node
, NULL
);
3292 * This is *intentionally* setting this to NULL, signaling
3293 * that interface creation for zebra acts differently
3295 if_zapi_callbacks(NULL
, NULL
, NULL
, NULL
);
3297 install_element(VIEW_NODE
, &show_interface_cmd
);
3298 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
3299 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
3300 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
3302 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
3303 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
3304 install_element(INTERFACE_NODE
, &multicast_cmd
);
3305 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
3306 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
3307 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
3308 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
3309 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
3310 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
3311 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
3312 install_element(INTERFACE_NODE
, &ip_address_cmd
);
3313 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
3314 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
3315 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
3316 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
3317 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
3319 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
3320 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
3321 #endif /* HAVE_NETLINK */
3322 install_element(INTERFACE_NODE
, &link_params_cmd
);
3323 install_default(LINK_PARAMS_NODE
);
3324 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
3325 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
3326 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
3327 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
3328 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
3329 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
3330 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
3331 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
3332 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
3333 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
3334 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
3335 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
3336 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
3337 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
3338 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
3339 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
3340 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
3341 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
3342 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
3343 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
3344 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
3345 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
3346 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
3347 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);