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
;
73 zif
->speed_update
= NULL
;
75 new_speed
= kernel_get_speed(ifp
);
76 if (new_speed
!= ifp
->speed
) {
77 zlog_info("%s: %s old speed: %u new speed: %u",
78 __PRETTY_FUNCTION__
, ifp
->name
, ifp
->speed
,
80 ifp
->speed
= new_speed
;
87 static void zebra_if_node_destroy(route_table_delegate_t
*delegate
,
88 struct route_table
*table
,
89 struct route_node
*node
)
92 list_delete((struct list
**)&node
->info
);
93 route_node_destroy(delegate
, table
, node
);
96 route_table_delegate_t zebra_if_table_delegate
= {
97 .create_node
= route_node_create
,
98 .destroy_node
= zebra_if_node_destroy
};
100 /* Called when new interface is added. */
101 static int if_zebra_new_hook(struct interface
*ifp
)
103 struct zebra_if
*zebra_if
;
105 zebra_if
= XCALLOC(MTYPE_ZINFO
, sizeof(struct zebra_if
));
107 zebra_if
->multicast
= IF_ZEBRA_MULTICAST_UNSPEC
;
108 zebra_if
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
109 zebra_ptm_if_init(zebra_if
);
111 ifp
->ptm_enable
= zebra_ptm_get_enable_state();
112 #if defined(HAVE_RTADV)
114 /* Set default router advertise values. */
115 struct rtadvconf
*rtadv
;
117 rtadv
= &zebra_if
->rtadv
;
119 rtadv
->AdvSendAdvertisements
= 0;
120 rtadv
->MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
121 rtadv
->MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
122 rtadv
->AdvIntervalTimer
= 0;
123 rtadv
->AdvManagedFlag
= 0;
124 rtadv
->AdvOtherConfigFlag
= 0;
125 rtadv
->AdvHomeAgentFlag
= 0;
126 rtadv
->AdvLinkMTU
= 0;
127 rtadv
->AdvReachableTime
= 0;
128 rtadv
->AdvRetransTimer
= 0;
129 rtadv
->AdvCurHopLimit
= 0;
130 rtadv
->AdvDefaultLifetime
=
131 -1; /* derive from MaxRtrAdvInterval */
132 rtadv
->HomeAgentPreference
= 0;
133 rtadv
->HomeAgentLifetime
=
134 -1; /* derive from AdvDefaultLifetime */
135 rtadv
->AdvIntervalOption
= 0;
136 rtadv
->DefaultPreference
= RTADV_PREF_MEDIUM
;
138 rtadv
->AdvPrefixList
= list_new();
139 rtadv
->AdvRDNSSList
= list_new();
140 rtadv
->AdvDNSSLList
= list_new();
142 #endif /* HAVE_RTADV */
144 memset(&zebra_if
->neigh_mac
[0], 0, 6);
146 /* Initialize installed address chains tree. */
147 zebra_if
->ipv4_subnets
=
148 route_table_init_with_delegate(&zebra_if_table_delegate
);
150 ifp
->info
= zebra_if
;
153 * Some platforms are telling us that the interface is
154 * up and ready to go. When we check the speed we
155 * sometimes get the wrong value. Wait a couple
156 * of seconds and ask again. Hopefully it's all settled
159 thread_add_timer(zrouter
.master
, if_zebra_speed_update
, ifp
, 15,
160 &zebra_if
->speed_update
);
164 /* Called when interface is deleted. */
165 static int if_zebra_delete_hook(struct interface
*ifp
)
167 struct zebra_if
*zebra_if
;
170 zebra_if
= ifp
->info
;
172 /* Free installed address chains tree. */
173 if (zebra_if
->ipv4_subnets
)
174 route_table_finish(zebra_if
->ipv4_subnets
);
175 #if defined(HAVE_RTADV)
177 struct rtadvconf
*rtadv
;
179 rtadv
= &zebra_if
->rtadv
;
180 list_delete(&rtadv
->AdvPrefixList
);
181 list_delete(&rtadv
->AdvRDNSSList
);
182 list_delete(&rtadv
->AdvDNSSLList
);
183 #endif /* HAVE_RTADV */
185 XFREE(MTYPE_TMP
, zebra_if
->desc
);
186 THREAD_OFF(zebra_if
->speed_update
);
188 XFREE(MTYPE_ZINFO
, zebra_if
);
194 /* Build the table key */
195 static void if_build_key(uint32_t ifindex
, struct prefix
*p
)
198 p
->prefixlen
= IPV4_MAX_BITLEN
;
199 p
->u
.prefix4
.s_addr
= ifindex
;
202 /* Link an interface in a per NS interface tree */
203 struct interface
*if_link_per_ns(struct zebra_ns
*ns
, struct interface
*ifp
)
206 struct route_node
*rn
;
208 if (ifp
->ifindex
== IFINDEX_INTERNAL
)
211 if_build_key(ifp
->ifindex
, &p
);
212 rn
= route_node_get(ns
->if_table
, &p
);
214 ifp
= (struct interface
*)rn
->info
;
215 route_unlock_node(rn
); /* get */
225 /* Delete a VRF. This is called in vrf_terminate(). */
226 void if_unlink_per_ns(struct interface
*ifp
)
228 ifp
->node
->info
= NULL
;
229 route_unlock_node(ifp
->node
);
233 /* Look up an interface by identifier within a NS */
234 struct interface
*if_lookup_by_index_per_ns(struct zebra_ns
*ns
,
238 struct route_node
*rn
;
239 struct interface
*ifp
= NULL
;
241 if_build_key(ifindex
, &p
);
242 rn
= route_node_lookup(ns
->if_table
, &p
);
244 ifp
= (struct interface
*)rn
->info
;
245 route_unlock_node(rn
); /* lookup */
250 /* Look up an interface by name within a NS */
251 struct interface
*if_lookup_by_name_per_ns(struct zebra_ns
*ns
,
254 struct route_node
*rn
;
255 struct interface
*ifp
;
257 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
258 ifp
= (struct interface
*)rn
->info
;
259 if (ifp
&& strcmp(ifp
->name
, ifname
) == 0)
266 const char *ifindex2ifname_per_ns(struct zebra_ns
*zns
, unsigned int ifindex
)
268 struct interface
*ifp
;
270 return ((ifp
= if_lookup_by_index_per_ns(zns
, ifindex
)) != NULL
)
275 /* Tie an interface address to its derived subnet list of addresses. */
276 int if_subnet_add(struct interface
*ifp
, struct connected
*ifc
)
278 struct route_node
*rn
;
279 struct zebra_if
*zebra_if
;
281 struct list
*addr_list
;
283 assert(ifp
&& ifp
->info
&& ifc
);
284 zebra_if
= ifp
->info
;
286 /* Get address derived subnet node and associated address list, while
288 address secondary attribute appropriately. */
289 cp
= *CONNECTED_PREFIX(ifc
);
291 rn
= route_node_get(zebra_if
->ipv4_subnets
, &cp
);
293 if ((addr_list
= rn
->info
))
294 SET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
296 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
297 rn
->info
= addr_list
= list_new();
301 /* Tie address at the tail of address list. */
302 listnode_add(addr_list
, ifc
);
304 /* Return list element count. */
305 return (addr_list
->count
);
308 /* Untie an interface address from its derived subnet list of addresses. */
309 int if_subnet_delete(struct interface
*ifp
, struct connected
*ifc
)
311 struct route_node
*rn
;
312 struct zebra_if
*zebra_if
;
313 struct list
*addr_list
;
316 assert(ifp
&& ifp
->info
&& ifc
);
317 zebra_if
= ifp
->info
;
319 cp
= *CONNECTED_PREFIX(ifc
);
322 /* Get address derived subnet node. */
323 rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
);
324 if (!(rn
&& rn
->info
)) {
325 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET
,
326 "Trying to remove an address from an unknown subnet."
327 " (please report this bug)");
330 route_unlock_node(rn
);
332 /* Untie address from subnet's address list. */
333 addr_list
= rn
->info
;
335 /* Deleting an address that is not registered is a bug.
336 * In any case, we shouldn't decrement the lock counter if the address
338 if (!listnode_lookup(addr_list
, ifc
)) {
340 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR
,
341 "Trying to remove an address from a subnet where it is not"
342 " currently registered. (please report this bug)");
346 listnode_delete(addr_list
, ifc
);
347 route_unlock_node(rn
);
349 /* Return list element count, if not empty. */
350 if (addr_list
->count
) {
351 /* If deleted address is primary, mark subsequent one as such
353 if (!CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)) {
355 (struct listnode
*)listhead(addr_list
));
356 zebra_interface_address_delete_update(ifp
, ifc
);
357 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
);
358 /* XXX: Linux kernel removes all the secondary addresses
360 * address is removed. We could try to work around that,
363 zebra_interface_address_add_update(ifp
, ifc
);
366 return addr_list
->count
;
369 /* Otherwise, free list and route node. */
370 list_delete(&addr_list
);
372 route_unlock_node(rn
);
377 /* if_flags_mangle: A place for hacks that require mangling
378 * or tweaking the interface flags.
380 * ******************** Solaris flags hacks **************************
382 * Solaris IFF_UP flag reflects only the primary interface as the
383 * routing socket only sends IFINFO for the primary interface. Hence
384 * ~IFF_UP does not per se imply all the logical interfaces are also
385 * down - which we only know of as addresses. Instead we must determine
386 * whether the interface really is up or not according to how many
387 * addresses are still attached. (Solaris always sends RTM_DELADDR if
388 * an interface, logical or not, goes ~IFF_UP).
390 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
391 * are addresses left in struct connected, not just the actual underlying
394 * We must hence remember the real state of IFF_UP, which we do in
395 * struct zebra_if.primary_state.
397 * Setting IFF_UP within zebra to administratively shutdown the
398 * interface will affect only the primary interface/address on Solaris.
399 ************************End Solaris flags hacks ***********************
401 static void if_flags_mangle(struct interface
*ifp
, uint64_t *newflags
)
404 struct zebra_if
*zif
= ifp
->info
;
406 zif
->primary_state
= *newflags
& (IFF_UP
& 0xff);
408 if (CHECK_FLAG(zif
->primary_state
, IFF_UP
)
409 || listcount(ifp
->connected
) > 0)
410 SET_FLAG(*newflags
, IFF_UP
);
412 UNSET_FLAG(*newflags
, IFF_UP
);
416 /* Update the flags field of the ifp with the new flag set provided.
417 * Take whatever actions are required for any changes in flags we care
420 * newflags should be the raw value, as obtained from the OS.
422 void if_flags_update(struct interface
*ifp
, uint64_t newflags
)
424 if_flags_mangle(ifp
, &newflags
);
426 if (if_is_no_ptm_operative(ifp
)) {
427 /* operative -> inoperative? */
428 ifp
->flags
= newflags
;
429 if (!if_is_operative(ifp
))
432 /* inoperative -> operative? */
433 ifp
->flags
= newflags
;
434 if (if_is_operative(ifp
))
439 /* Wake up configured address if it is not in current kernel
441 static void if_addr_wakeup(struct interface
*ifp
)
443 struct listnode
*node
, *nnode
;
444 struct connected
*ifc
;
446 enum zebra_dplane_result dplane_res
;
448 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nnode
, ifc
)) {
451 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)
452 && !CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)) {
454 if (p
->family
== AF_INET
) {
455 if (!if_is_up(ifp
)) {
456 /* Assume zebra is configured like
460 * ip addr 192.0.2.1/24
463 * As soon as zebra becomes first aware
464 * that gre0 exists in the
465 * kernel, it will set gre0 up and
466 * configure its addresses.
468 * (This may happen at startup when the
469 * interface already exists
470 * or during runtime when the interface
471 * is added to the kernel)
473 * XXX: IRDP code is calling here via
474 * if_add_update - this seems
476 * XXX: RUNNING is not a settable flag
478 * I (paulj) am aware of.
480 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
484 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
486 ZEBRA_DPLANE_REQUEST_FAILURE
) {
488 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
489 "Can't set interface's address: %s",
490 dplane_res2str(dplane_res
));
494 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
495 /* The address will be advertised to zebra
496 * clients when the notification
497 * from the kernel has been received.
498 * It will also be added to the interface's
499 * subnet list then. */
501 if (p
->family
== AF_INET6
) {
502 if (!if_is_up(ifp
)) {
503 /* See long comment above */
504 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
509 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
511 ZEBRA_DPLANE_REQUEST_FAILURE
) {
513 EC_ZEBRA_IFACE_ADDR_ADD_FAILED
,
514 "Can't set interface's address: %s",
515 dplane_res2str(dplane_res
));
519 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
520 /* The address will be advertised to zebra
521 * clients when the notification
522 * from the kernel has been received. */
528 /* Handle interface addition */
529 void if_add_update(struct interface
*ifp
)
531 struct zebra_if
*if_data
;
532 struct zebra_ns
*zns
;
533 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
535 /* case interface populate before vrf enabled */
539 zns
= zebra_ns_lookup(NS_DEFAULT
);
540 if_link_per_ns(zns
, ifp
);
544 if (if_data
->multicast
== IF_ZEBRA_MULTICAST_ON
)
545 if_set_flags(ifp
, IFF_MULTICAST
);
546 else if (if_data
->multicast
== IF_ZEBRA_MULTICAST_OFF
)
547 if_unset_flags(ifp
, IFF_MULTICAST
);
549 zebra_ptm_if_set_ptm_state(ifp
, if_data
);
551 zebra_interface_add_update(ifp
);
553 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
554 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
556 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
) {
557 if (IS_ZEBRA_DEBUG_KERNEL
)
559 "interface %s vrf %u index %d is shutdown. "
561 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
567 if (IS_ZEBRA_DEBUG_KERNEL
)
569 "interface %s vrf %u index %d becomes active.",
570 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
573 if (IS_ZEBRA_DEBUG_KERNEL
)
574 zlog_debug("interface %s vrf %u index %d is added.",
575 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
579 /* Install connected routes corresponding to an interface. */
580 static void if_install_connected(struct interface
*ifp
)
582 struct listnode
*node
;
583 struct listnode
*next
;
584 struct connected
*ifc
;
586 if (ifp
->connected
) {
587 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
588 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
589 zebra_interface_address_add_update(ifp
, ifc
);
591 connected_up(ifp
, ifc
);
596 /* Uninstall connected routes corresponding to an interface. */
597 static void if_uninstall_connected(struct interface
*ifp
)
599 struct listnode
*node
;
600 struct listnode
*next
;
601 struct connected
*ifc
;
603 if (ifp
->connected
) {
604 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, next
, ifc
)) {
605 zebra_interface_address_delete_update(ifp
, ifc
);
606 connected_down(ifp
, ifc
);
611 /* Uninstall and delete connected routes corresponding to an interface. */
612 /* TODO - Check why IPv4 handling here is different from install or if_down */
613 static void if_delete_connected(struct interface
*ifp
)
615 struct connected
*ifc
;
617 struct route_node
*rn
;
618 struct zebra_if
*zebra_if
;
619 struct listnode
*node
;
620 struct listnode
*last
= NULL
;
622 zebra_if
= ifp
->info
;
627 while ((node
= (last
? last
->next
: listhead(ifp
->connected
)))) {
628 ifc
= listgetdata(node
);
630 cp
= *CONNECTED_PREFIX(ifc
);
633 if (cp
.family
== AF_INET
634 && (rn
= route_node_lookup(zebra_if
->ipv4_subnets
, &cp
))) {
635 struct listnode
*anode
;
636 struct listnode
*next
;
637 struct listnode
*first
;
638 struct list
*addr_list
;
640 route_unlock_node(rn
);
641 addr_list
= (struct list
*)rn
->info
;
643 /* Remove addresses, secondaries first. */
644 first
= listhead(addr_list
);
646 for (anode
= first
->next
; anode
|| first
;
654 ifc
= listgetdata(anode
);
655 connected_down(ifp
, ifc
);
657 /* XXX: We have to send notifications
658 * here explicitly, because we destroy
659 * the ifc before receiving the
660 * notification about the address being
663 zebra_interface_address_delete_update(
666 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
667 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
669 /* Remove from subnet chain. */
670 list_delete_node(addr_list
, anode
);
671 route_unlock_node(rn
);
673 /* Remove from interface address list
674 * (unconditionally). */
675 if (!CHECK_FLAG(ifc
->conf
,
676 ZEBRA_IFC_CONFIGURED
)) {
677 listnode_delete(ifp
->connected
,
684 /* Free chain list and respective route node. */
685 list_delete(&addr_list
);
687 route_unlock_node(rn
);
688 } else if (cp
.family
== AF_INET6
) {
689 connected_down(ifp
, ifc
);
691 zebra_interface_address_delete_update(ifp
, ifc
);
693 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
694 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
696 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
699 listnode_delete(ifp
->connected
, ifc
);
708 /* Handle an interface delete event */
709 void if_delete_update(struct interface
*ifp
)
711 struct zebra_if
*zif
;
716 "interface %s vrf %u index %d is still up while being deleted.",
717 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
721 if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
724 /* Mark interface as inactive */
725 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
);
727 if (IS_ZEBRA_DEBUG_KERNEL
)
728 zlog_debug("interface %s vrf %u index %d is now inactive.",
729 ifp
->name
, ifp
->vrf_id
, ifp
->ifindex
);
731 /* Delete connected routes from the kernel. */
732 if_delete_connected(ifp
);
734 /* Send out notification on interface delete. */
735 zebra_interface_delete_update(ifp
);
737 if_unlink_per_ns(ifp
);
739 /* Update ifindex after distributing the delete message. This is in
740 case any client needs to have the old value of ifindex available
741 while processing the deletion. Each client daemon is responsible
742 for setting ifindex to IFINDEX_INTERNAL after processing the
743 interface deletion message. */
744 if_set_index(ifp
, IFINDEX_INTERNAL
);
747 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
748 * desired. This operation is not done for netns implementation to avoid
749 * collision with interface with the same name in the default vrf (can
750 * occur with this implementation whereas it is not possible with
753 if (ifp
->vrf_id
&& !vrf_is_backend_netns())
754 if_handle_vrf_change(ifp
, VRF_DEFAULT
);
756 /* Reset some zebra interface params to default values. */
759 zif
->zif_type
= ZEBRA_IF_OTHER
;
760 zif
->zif_slave_type
= ZEBRA_IF_SLAVE_NONE
;
761 memset(&zif
->l2info
, 0, sizeof(union zebra_l2if_info
));
762 memset(&zif
->brslave_info
, 0,
763 sizeof(struct zebra_l2info_brslave
));
767 /* VRF change for an interface */
768 void if_handle_vrf_change(struct interface
*ifp
, vrf_id_t vrf_id
)
772 old_vrf_id
= ifp
->vrf_id
;
774 /* Uninstall connected routes. */
775 if_uninstall_connected(ifp
);
777 /* Delete any IPv4 neighbors created to implement RFC 5549 */
778 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
780 /* Delete all neighbor addresses learnt through IPv6 RA */
781 if_down_del_nbr_connected(ifp
);
783 /* Send out notification on interface VRF change. */
784 /* This is to issue an UPDATE or a DELETE, as appropriate. */
785 zebra_interface_vrf_update_del(ifp
, vrf_id
);
788 if_update_to_new_vrf(ifp
, vrf_id
);
790 /* Send out notification on interface VRF change. */
791 /* This is to issue an ADD, if needed. */
792 zebra_interface_vrf_update_add(ifp
, old_vrf_id
);
794 /* Install connected routes (in new VRF). */
795 if (if_is_operative(ifp
))
796 if_install_connected(ifp
);
798 /* Due to connected route change, schedule RIB processing for both old
801 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
802 zlog_debug("%u: IF %s VRF change, scheduling RIB processing",
803 ifp
->vrf_id
, ifp
->name
);
804 rib_update(old_vrf_id
, RIB_UPDATE_IF_CHANGE
);
805 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
808 static void ipv6_ll_address_to_mac(struct in6_addr
*address
, uint8_t *mac
)
810 mac
[0] = address
->s6_addr
[8] ^ 0x02;
811 mac
[1] = address
->s6_addr
[9];
812 mac
[2] = address
->s6_addr
[10];
813 mac
[3] = address
->s6_addr
[13];
814 mac
[4] = address
->s6_addr
[14];
815 mac
[5] = address
->s6_addr
[15];
818 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface
*ifp
,
820 struct in6_addr
*address
,
823 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
824 struct zebra_if
*zif
= ifp
->info
;
825 char buf
[16] = "169.254.0.1";
826 struct in_addr ipv4_ll
;
829 inet_pton(AF_INET
, buf
, &ipv4_ll
);
831 ns_id
= zvrf
->zns
->ns_id
;
834 * Remove and re-add any existing neighbor entry for this address,
835 * since Netlink doesn't currently offer update message types.
837 kernel_neigh_update(0, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6, ns_id
);
839 /* Add new neighbor entry.
841 * We force installation even if current neighbor entry is the same.
842 * Since this function is used to refresh our MAC entries after an
843 * interface flap, if we don't force in our custom entries with their
844 * state set to PERMANENT or REACHABLE then the kernel will attempt to
845 * resolve our leftover entries, fail, mark them unreachable and then
846 * they'll be useless to us.
849 kernel_neigh_update(add
, ifp
->ifindex
, ipv4_ll
.s_addr
, mac
, 6,
852 memcpy(&zif
->neigh_mac
[0], &mac
[0], 6);
855 * We need to note whether or not we originated a v6
856 * neighbor entry for this interface. So that when
857 * someone unwisely accidently deletes this entry
858 * we can shove it back in.
860 zif
->v6_2_v4_ll_neigh_entry
= !!add
;
861 memcpy(&zif
->v6_2_v4_ll_addr6
, address
, sizeof(*address
));
863 zvrf
->neigh_updates
++;
866 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface
*ifp
,
867 struct in6_addr
*address
, int add
)
872 ipv6_ll_address_to_mac(address
, (uint8_t *)mac
);
873 if_nbr_mac_to_ipv4ll_neigh_update(ifp
, mac
, address
, add
);
876 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface
*ifp
)
878 if (listhead(ifp
->nbr_connected
)) {
879 struct nbr_connected
*nbr_connected
;
880 struct listnode
*node
;
882 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
884 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
885 ifp
, &nbr_connected
->address
->u
.prefix6
, 1);
889 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface
*ifp
)
891 if (listhead(ifp
->nbr_connected
)) {
892 struct nbr_connected
*nbr_connected
;
893 struct listnode
*node
;
895 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
,
897 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
898 ifp
, &nbr_connected
->address
->u
.prefix6
, 0);
902 static void if_down_del_nbr_connected(struct interface
*ifp
)
904 struct nbr_connected
*nbr_connected
;
905 struct listnode
*node
, *nnode
;
907 for (ALL_LIST_ELEMENTS(ifp
->nbr_connected
, node
, nnode
,
909 listnode_delete(ifp
->nbr_connected
, nbr_connected
);
910 nbr_connected_free(nbr_connected
);
914 /* Interface is up. */
915 void if_up(struct interface
*ifp
)
917 struct zebra_if
*zif
;
918 struct interface
*link_if
;
919 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
923 quagga_timestamp(2, zif
->up_last
, sizeof(zif
->up_last
));
925 /* Notify the protocol daemons. */
926 if (ifp
->ptm_enable
&& (ifp
->ptm_status
== ZEBRA_PTM_STATUS_DOWN
)) {
927 flog_warn(EC_ZEBRA_PTM_NOT_READY
,
928 "%s: interface %s hasn't passed ptm check\n",
929 __func__
, ifp
->name
);
932 zebra_interface_up_update(ifp
);
934 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp
);
936 #if defined(HAVE_RTADV)
937 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
938 if (zif
->rtadv
.AdvSendAdvertisements
939 && (zif
->rtadv
.MaxRtrAdvInterval
>= 1000)) {
940 zif
->rtadv
.inFastRexmit
= 1;
941 zif
->rtadv
.NumFastReXmitsRemain
= RTADV_NUM_FAST_REXMITS
;
945 /* Install connected routes to the kernel. */
946 if_install_connected(ifp
);
948 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
949 zlog_debug("%u: IF %s up, scheduling RIB processing",
950 ifp
->vrf_id
, ifp
->name
);
951 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
953 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
954 * are checked to see if (remote) neighbor entries need to be installed
955 * on them for ARP suppression.
957 if (IS_ZEBRA_IF_VXLAN(ifp
))
958 zebra_vxlan_if_up(ifp
);
959 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
961 zebra_vxlan_svi_up(ifp
, link_if
);
962 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
963 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
966 zebra_vxlan_svi_up(ifp
, link_if
);
970 /* Interface goes down. We have to manage different behavior of based
972 void if_down(struct interface
*ifp
)
974 struct zebra_if
*zif
;
975 struct interface
*link_if
;
976 struct zebra_vrf
*zvrf
= vrf_info_lookup(ifp
->vrf_id
);
980 quagga_timestamp(2, zif
->down_last
, sizeof(zif
->down_last
));
982 /* Handle interface down for specific types for EVPN. Non-VxLAN
984 * are checked to see if (remote) neighbor entries need to be purged
985 * for ARP suppression.
987 if (IS_ZEBRA_IF_VXLAN(ifp
))
988 zebra_vxlan_if_down(ifp
);
989 else if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
991 zebra_vxlan_svi_down(ifp
, link_if
);
992 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
993 link_if
= if_lookup_by_index_per_ns(zvrf
->zns
,
996 zebra_vxlan_svi_down(ifp
, link_if
);
1000 /* Notify to the protocol daemons. */
1001 zebra_interface_down_update(ifp
);
1003 /* Uninstall connected routes from the kernel. */
1004 if_uninstall_connected(ifp
);
1006 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1007 zlog_debug("%u: IF %s down, scheduling RIB processing",
1008 ifp
->vrf_id
, ifp
->name
);
1009 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
1011 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp
);
1013 /* Delete all neighbor addresses learnt through IPv6 RA */
1014 if_down_del_nbr_connected(ifp
);
1017 void if_refresh(struct interface
*ifp
)
1022 void zebra_if_update_link(struct interface
*ifp
, ifindex_t link_ifindex
,
1025 struct zebra_if
*zif
;
1027 if (IS_ZEBRA_IF_VETH(ifp
))
1029 zif
= (struct zebra_if
*)ifp
->info
;
1030 zif
->link_ifindex
= link_ifindex
;
1031 zif
->link
= if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id
),
1036 * during initial link dump kernel does not order lower devices before
1037 * upper devices so we need to fixup link dependencies at the end of dump
1039 void zebra_if_update_all_links(void)
1041 struct route_node
*rn
;
1042 struct interface
*ifp
;
1043 struct zebra_if
*zif
;
1044 struct zebra_ns
*ns
;
1046 if (IS_ZEBRA_DEBUG_KERNEL
)
1047 zlog_info("fixup link dependencies");
1049 ns
= zebra_ns_lookup(NS_DEFAULT
);
1050 for (rn
= route_top(ns
->if_table
); rn
; rn
= route_next(rn
)) {
1051 ifp
= (struct interface
*)rn
->info
;
1055 if ((zif
->link_ifindex
!= IFINDEX_INTERNAL
) && !zif
->link
) {
1056 zif
->link
= if_lookup_by_index_per_ns(ns
,
1058 if (IS_ZEBRA_DEBUG_KERNEL
)
1059 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1060 ifp
->name
, ifp
->ifindex
,
1061 zif
->link
?zif
->link
->name
:"unk",
1067 void zebra_if_set_protodown(struct interface
*ifp
, bool down
)
1070 netlink_protodown(ifp
, down
);
1072 zlog_warn("Protodown is not supported on this platform");
1076 /* Output prefix string to vty. */
1077 static int prefix_vty_out(struct vty
*vty
, struct prefix
*p
)
1079 char str
[INET6_ADDRSTRLEN
];
1081 inet_ntop(p
->family
, &p
->u
.prefix
, str
, sizeof(str
));
1082 vty_out(vty
, "%s", str
);
1086 /* Dump if address information to vty. */
1087 static void connected_dump_vty(struct vty
*vty
, struct connected
*connected
)
1091 /* Print interface address. */
1092 p
= connected
->address
;
1093 vty_out(vty
, " %s ", prefix_family_str(p
));
1094 prefix_vty_out(vty
, p
);
1095 vty_out(vty
, "/%d", p
->prefixlen
);
1097 /* If there is destination address, print it. */
1098 if (connected
->destination
) {
1100 (CONNECTED_PEER(connected
) ? " peer " : " broadcast "));
1101 prefix_vty_out(vty
, connected
->destination
);
1102 if (CONNECTED_PEER(connected
))
1103 vty_out(vty
, "/%d", connected
->destination
->prefixlen
);
1106 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_SECONDARY
))
1107 vty_out(vty
, " secondary");
1109 if (CHECK_FLAG(connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
1110 vty_out(vty
, " unnumbered");
1112 if (connected
->label
)
1113 vty_out(vty
, " %s", connected
->label
);
1118 /* Dump interface neighbor address information to vty. */
1119 static void nbr_connected_dump_vty(struct vty
*vty
,
1120 struct nbr_connected
*connected
)
1124 /* Print interface address. */
1125 p
= connected
->address
;
1126 vty_out(vty
, " %s ", prefix_family_str(p
));
1127 prefix_vty_out(vty
, p
);
1128 vty_out(vty
, "/%d", p
->prefixlen
);
1133 static const char *zebra_ziftype_2str(zebra_iftype_t zif_type
)
1136 case ZEBRA_IF_OTHER
:
1140 case ZEBRA_IF_BRIDGE
:
1148 case ZEBRA_IF_VXLAN
:
1163 case ZEBRA_IF_BOND_SLAVE
:
1164 return "bond_slave";
1166 case ZEBRA_IF_MACVLAN
:
1175 /* Interface's brief information print out to vty interface. */
1176 static void ifs_dump_brief_vty(struct vty
*vty
, struct vrf
*vrf
)
1178 struct connected
*connected
;
1179 struct listnode
*node
;
1180 struct route_node
*rn
;
1181 struct zebra_if
*zebra_if
;
1183 struct interface
*ifp
;
1184 bool print_header
= true;
1186 FOR_ALL_INTERFACES (vrf
, ifp
) {
1187 char global_pfx
[PREFIX_STRLEN
] = {0};
1188 char buf
[PREFIX_STRLEN
] = {0};
1189 bool first_pfx_printed
= false;
1192 vty_out(vty
, "%-16s%-8s%-16s%s\n", "Interface",
1193 "Status", "VRF", "Addresses");
1194 vty_out(vty
, "%-16s%-8s%-16s%s\n", "---------",
1195 "------", "---", "---------");
1196 print_header
= false; /* We have at least 1 iface */
1198 zebra_if
= ifp
->info
;
1200 vty_out(vty
, "%-16s", ifp
->name
);
1203 vty_out(vty
, "%-8s", "up");
1205 vty_out(vty
, "%-8s", "down");
1207 vty_out(vty
, "%-16s", vrf
->name
);
1209 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
;
1210 rn
= route_next(rn
)) {
1213 uint32_t list_size
= listcount((struct list
*)rn
->info
);
1215 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1217 if (!CHECK_FLAG(connected
->flags
,
1218 ZEBRA_IFA_SECONDARY
)) {
1219 p
= connected
->address
;
1220 prefix2str(p
, buf
, sizeof(buf
));
1221 if (first_pfx_printed
) {
1222 /* padding to prepare row only for ip addr */
1223 vty_out(vty
, "%-40s", "");
1226 vty_out(vty
, "%s\n", buf
);
1230 vty_out(vty
, "%s\n", buf
);
1232 first_pfx_printed
= true;
1238 uint32_t v6_list_size
= 0;
1239 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1240 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1241 && (connected
->address
->family
== AF_INET6
))
1244 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1245 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1246 && !CHECK_FLAG(connected
->flags
,
1247 ZEBRA_IFA_SECONDARY
)
1248 && (connected
->address
->family
== AF_INET6
)) {
1249 p
= connected
->address
;
1250 /* Don't print link local pfx */
1251 if (!IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
)) {
1252 prefix2str(p
, global_pfx
, PREFIX_STRLEN
);
1253 if (first_pfx_printed
) {
1254 /* padding to prepare row only for ip addr */
1255 vty_out(vty
, "%-40s", "");
1256 if (v6_list_size
> 1)
1258 vty_out(vty
, "%s\n", global_pfx
);
1260 if (v6_list_size
> 1)
1262 vty_out(vty
, "%s\n", global_pfx
);
1264 first_pfx_printed
= true;
1269 if (!first_pfx_printed
)
1275 /* Interface's information print out to vty interface. */
1276 static void if_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1278 struct connected
*connected
;
1279 struct nbr_connected
*nbr_connected
;
1280 struct listnode
*node
;
1281 struct route_node
*rn
;
1282 struct zebra_if
*zebra_if
;
1285 zebra_if
= ifp
->info
;
1287 vty_out(vty
, "Interface %s is ", ifp
->name
);
1288 if (if_is_up(ifp
)) {
1289 vty_out(vty
, "up, line protocol ");
1291 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
)) {
1292 if (if_is_running(ifp
))
1293 vty_out(vty
, "is up\n");
1295 vty_out(vty
, "is down\n");
1297 vty_out(vty
, "detection is disabled\n");
1300 vty_out(vty
, "down\n");
1303 vty_out(vty
, " Link ups: %5u last: %s\n", zebra_if
->up_count
,
1304 zebra_if
->up_last
[0] ? zebra_if
->up_last
: "(never)");
1305 vty_out(vty
, " Link downs: %5u last: %s\n", zebra_if
->down_count
,
1306 zebra_if
->down_last
[0] ? zebra_if
->down_last
: "(never)");
1308 zebra_ptm_show_status(vty
, ifp
);
1310 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
1311 vty_out(vty
, " vrf: %s\n", vrf
->name
);
1314 vty_out(vty
, " Description: %s\n", ifp
->desc
);
1316 vty_out(vty
, " OS Description: %s\n", zebra_if
->desc
);
1318 if (ifp
->ifindex
== IFINDEX_INTERNAL
) {
1319 vty_out(vty
, " pseudo interface\n");
1321 } else if (!CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1322 vty_out(vty
, " index %d inactive interface\n", ifp
->ifindex
);
1326 vty_out(vty
, " index %d metric %d mtu %d speed %u ", ifp
->ifindex
,
1327 ifp
->metric
, ifp
->mtu
, ifp
->speed
);
1328 if (ifp
->mtu6
!= ifp
->mtu
)
1329 vty_out(vty
, "mtu6 %d ", ifp
->mtu6
);
1330 vty_out(vty
, "\n flags: %s\n", if_flag_dump(ifp
->flags
));
1332 /* Hardware address. */
1333 vty_out(vty
, " Type: %s\n", if_link_type_str(ifp
->ll_type
));
1334 if (ifp
->hw_addr_len
!= 0) {
1337 vty_out(vty
, " HWaddr: ");
1338 for (i
= 0; i
< ifp
->hw_addr_len
; i
++)
1339 vty_out(vty
, "%s%02x", i
== 0 ? "" : ":",
1344 /* Bandwidth in Mbps */
1345 if (ifp
->bandwidth
!= 0) {
1346 vty_out(vty
, " bandwidth %u Mbps", ifp
->bandwidth
);
1350 for (rn
= route_top(zebra_if
->ipv4_subnets
); rn
; rn
= route_next(rn
)) {
1354 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
,
1356 connected_dump_vty(vty
, connected
);
1359 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
1360 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
1361 && (connected
->address
->family
== AF_INET6
))
1362 connected_dump_vty(vty
, connected
);
1365 vty_out(vty
, " Interface Type %s\n",
1366 zebra_ziftype_2str(zebra_if
->zif_type
));
1367 if (IS_ZEBRA_IF_BRIDGE(ifp
)) {
1368 struct zebra_l2info_bridge
*bridge_info
;
1370 bridge_info
= &zebra_if
->l2info
.br
;
1371 vty_out(vty
, " Bridge VLAN-aware: %s\n",
1372 bridge_info
->vlan_aware
? "yes" : "no");
1373 } else if (IS_ZEBRA_IF_VLAN(ifp
)) {
1374 struct zebra_l2info_vlan
*vlan_info
;
1376 vlan_info
= &zebra_if
->l2info
.vl
;
1377 vty_out(vty
, " VLAN Id %u\n", vlan_info
->vid
);
1378 } else if (IS_ZEBRA_IF_VXLAN(ifp
)) {
1379 struct zebra_l2info_vxlan
*vxlan_info
;
1381 vxlan_info
= &zebra_if
->l2info
.vxl
;
1382 vty_out(vty
, " VxLAN Id %u", vxlan_info
->vni
);
1383 if (vxlan_info
->vtep_ip
.s_addr
!= INADDR_ANY
)
1384 vty_out(vty
, " VTEP IP: %s",
1385 inet_ntoa(vxlan_info
->vtep_ip
));
1386 if (vxlan_info
->access_vlan
)
1387 vty_out(vty
, " Access VLAN Id %u\n",
1388 vxlan_info
->access_vlan
);
1389 if (vxlan_info
->mcast_grp
.s_addr
!= INADDR_ANY
)
1390 vty_out(vty
, " Mcast Group %s",
1391 inet_ntoa(vxlan_info
->mcast_grp
));
1395 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
)) {
1396 struct zebra_l2info_brslave
*br_slave
;
1398 br_slave
= &zebra_if
->brslave_info
;
1399 if (br_slave
->bridge_ifindex
!= IFINDEX_INTERNAL
)
1400 vty_out(vty
, " Master (bridge) ifindex %u\n",
1401 br_slave
->bridge_ifindex
);
1404 if (IS_ZEBRA_IF_BOND_SLAVE(ifp
)) {
1405 struct zebra_l2info_bondslave
*bond_slave
;
1407 bond_slave
= &zebra_if
->bondslave_info
;
1408 if (bond_slave
->bond_ifindex
!= IFINDEX_INTERNAL
)
1409 vty_out(vty
, " Master (bond) ifindex %u\n",
1410 bond_slave
->bond_ifindex
);
1413 if (zebra_if
->link_ifindex
!= IFINDEX_INTERNAL
) {
1414 vty_out(vty
, " Link ifindex %u", zebra_if
->link_ifindex
);
1416 vty_out(vty
, "(%s)\n", zebra_if
->link
->name
);
1418 vty_out(vty
, "(Unknown)\n");
1421 if (HAS_LINK_PARAMS(ifp
)) {
1423 struct if_link_params
*iflp
= ifp
->link_params
;
1424 vty_out(vty
, " Traffic Engineering Link Parameters:\n");
1425 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
))
1426 vty_out(vty
, " TE metric %u\n", iflp
->te_metric
);
1427 if (IS_PARAM_SET(iflp
, LP_MAX_BW
))
1428 vty_out(vty
, " Maximum Bandwidth %g (Byte/s)\n",
1430 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
))
1432 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1434 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
1436 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1437 for (i
= 0; i
< MAX_CLASS_TYPE
; i
+= 2)
1439 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1440 i
, iflp
->unrsv_bw
[i
], i
+ 1,
1441 iflp
->unrsv_bw
[i
+ 1]);
1444 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
1445 vty_out(vty
, " Administrative Group:%u\n",
1447 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
1448 vty_out(vty
, " Link Delay Average: %u (micro-sec.)",
1450 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
1451 vty_out(vty
, " Min: %u (micro-sec.)",
1453 vty_out(vty
, " Max: %u (micro-sec.)",
1458 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
1460 " Link Delay Variation %u (micro-sec.)\n",
1462 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
1463 vty_out(vty
, " Link Packet Loss %g (in %%)\n",
1465 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
1466 vty_out(vty
, " Available Bandwidth %g (Byte/s)\n",
1468 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
1469 vty_out(vty
, " Residual Bandwidth %g (Byte/s)\n",
1471 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
1472 vty_out(vty
, " Utilized Bandwidth %g (Byte/s)\n",
1474 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
1475 vty_out(vty
, " Neighbor ASBR IP: %s AS: %u \n",
1476 inet_ntoa(iflp
->rmt_ip
), iflp
->rmt_as
);
1479 hook_call(zebra_if_extra_info
, vty
, ifp
);
1481 if (listhead(ifp
->nbr_connected
))
1482 vty_out(vty
, " Neighbor address(s):\n");
1483 for (ALL_LIST_ELEMENTS_RO(ifp
->nbr_connected
, node
, nbr_connected
))
1484 nbr_connected_dump_vty(vty
, nbr_connected
);
1486 #ifdef HAVE_PROC_NET_DEV
1487 /* Statistics print out using proc file system. */
1489 " %lu input packets (%lu multicast), %lu bytes, "
1491 ifp
->stats
.rx_packets
, ifp
->stats
.rx_multicast
,
1492 ifp
->stats
.rx_bytes
, ifp
->stats
.rx_dropped
);
1495 " %lu input errors, %lu length, %lu overrun,"
1496 " %lu CRC, %lu frame\n",
1497 ifp
->stats
.rx_errors
, ifp
->stats
.rx_length_errors
,
1498 ifp
->stats
.rx_over_errors
, ifp
->stats
.rx_crc_errors
,
1499 ifp
->stats
.rx_frame_errors
);
1501 vty_out(vty
, " %lu fifo, %lu missed\n", ifp
->stats
.rx_fifo_errors
,
1502 ifp
->stats
.rx_missed_errors
);
1504 vty_out(vty
, " %lu output packets, %lu bytes, %lu dropped\n",
1505 ifp
->stats
.tx_packets
, ifp
->stats
.tx_bytes
,
1506 ifp
->stats
.tx_dropped
);
1509 " %lu output errors, %lu aborted, %lu carrier,"
1510 " %lu fifo, %lu heartbeat\n",
1511 ifp
->stats
.tx_errors
, ifp
->stats
.tx_aborted_errors
,
1512 ifp
->stats
.tx_carrier_errors
, ifp
->stats
.tx_fifo_errors
,
1513 ifp
->stats
.tx_heartbeat_errors
);
1515 vty_out(vty
, " %lu window, %lu collisions\n",
1516 ifp
->stats
.tx_window_errors
, ifp
->stats
.collisions
);
1517 #endif /* HAVE_PROC_NET_DEV */
1519 #ifdef HAVE_NET_RT_IFLIST
1520 #if defined(__bsdi__) || defined(__NetBSD__)
1521 /* Statistics print out using sysctl (). */
1523 " input packets %llu, bytes %llu, dropped %llu,"
1524 " multicast packets %llu\n",
1525 (unsigned long long)ifp
->stats
.ifi_ipackets
,
1526 (unsigned long long)ifp
->stats
.ifi_ibytes
,
1527 (unsigned long long)ifp
->stats
.ifi_iqdrops
,
1528 (unsigned long long)ifp
->stats
.ifi_imcasts
);
1530 vty_out(vty
, " input errors %llu\n",
1531 (unsigned long long)ifp
->stats
.ifi_ierrors
);
1534 " output packets %llu, bytes %llu,"
1535 " multicast packets %llu\n",
1536 (unsigned long long)ifp
->stats
.ifi_opackets
,
1537 (unsigned long long)ifp
->stats
.ifi_obytes
,
1538 (unsigned long long)ifp
->stats
.ifi_omcasts
);
1540 vty_out(vty
, " output errors %llu\n",
1541 (unsigned long long)ifp
->stats
.ifi_oerrors
);
1543 vty_out(vty
, " collisions %llu\n",
1544 (unsigned long long)ifp
->stats
.ifi_collisions
);
1546 /* Statistics print out using sysctl (). */
1548 " input packets %lu, bytes %lu, dropped %lu,"
1549 " multicast packets %lu\n",
1550 ifp
->stats
.ifi_ipackets
, ifp
->stats
.ifi_ibytes
,
1551 ifp
->stats
.ifi_iqdrops
, ifp
->stats
.ifi_imcasts
);
1553 vty_out(vty
, " input errors %lu\n", ifp
->stats
.ifi_ierrors
);
1556 " output packets %lu, bytes %lu, multicast packets %lu\n",
1557 ifp
->stats
.ifi_opackets
, ifp
->stats
.ifi_obytes
,
1558 ifp
->stats
.ifi_omcasts
);
1560 vty_out(vty
, " output errors %lu\n", ifp
->stats
.ifi_oerrors
);
1562 vty_out(vty
, " collisions %lu\n", ifp
->stats
.ifi_collisions
);
1563 #endif /* __bsdi__ || __NetBSD__ */
1564 #endif /* HAVE_NET_RT_IFLIST */
1567 static void interface_update_stats(void)
1569 #ifdef HAVE_PROC_NET_DEV
1570 /* If system has interface statistics via proc file system, update
1572 ifstat_update_proc();
1573 #endif /* HAVE_PROC_NET_DEV */
1574 #ifdef HAVE_NET_RT_IFLIST
1575 ifstat_update_sysctl();
1576 #endif /* HAVE_NET_RT_IFLIST */
1579 struct cmd_node interface_node
= {INTERFACE_NODE
, "%s(config-if)# ", 1};
1581 #ifndef VTYSH_EXTRACT_PL
1582 #include "zebra/interface_clippy.c"
1584 /* Show all interfaces to vty. */
1585 DEFPY(show_interface
, show_interface_cmd
,
1586 "show interface [vrf NAME$name] [brief$brief]",
1588 "Interface status and configuration\n"
1590 "Interface status and configuration summary\n")
1593 struct interface
*ifp
;
1594 vrf_id_t vrf_id
= VRF_DEFAULT
;
1596 interface_update_stats();
1599 VRF_GET_ID(vrf_id
, name
, false);
1601 /* All interface print. */
1602 vrf
= vrf_lookup_by_id(vrf_id
);
1604 ifs_dump_brief_vty(vty
, vrf
);
1606 FOR_ALL_INTERFACES (vrf
, ifp
) {
1607 if_dump_vty(vty
, ifp
);
1615 /* Show all interfaces to vty. */
1616 DEFUN (show_interface_vrf_all
,
1617 show_interface_vrf_all_cmd
,
1618 "show interface vrf all",
1620 "Interface status and configuration\n"
1621 VRF_ALL_CMD_HELP_STR
)
1624 struct interface
*ifp
;
1626 interface_update_stats();
1628 /* All interface print. */
1629 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1630 FOR_ALL_INTERFACES (vrf
, ifp
)
1631 if_dump_vty(vty
, ifp
);
1636 /* Show specified interface to vty. */
1638 DEFUN (show_interface_name_vrf
,
1639 show_interface_name_vrf_cmd
,
1640 "show interface IFNAME vrf NAME",
1642 "Interface status and configuration\n"
1648 struct interface
*ifp
;
1651 interface_update_stats();
1653 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
1655 /* Specified interface print. */
1656 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1658 vty_out(vty
, "%% Can't find interface %s\n",
1659 argv
[idx_ifname
]->arg
);
1662 if_dump_vty(vty
, ifp
);
1667 /* Show specified interface to vty. */
1668 DEFUN (show_interface_name_vrf_all
,
1669 show_interface_name_vrf_all_cmd
,
1670 "show interface IFNAME [vrf all]",
1672 "Interface status and configuration\n"
1674 VRF_ALL_CMD_HELP_STR
)
1678 struct interface
*ifp
;
1681 interface_update_stats();
1683 /* All interface print. */
1684 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1685 /* Specified interface print. */
1686 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, vrf
->vrf_id
);
1688 if_dump_vty(vty
, ifp
);
1694 vty_out(vty
, "%% Can't find interface %s\n",
1695 argv
[idx_ifname
]->arg
);
1703 static void if_show_description(struct vty
*vty
, vrf_id_t vrf_id
)
1705 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
1706 struct interface
*ifp
;
1708 vty_out(vty
, "Interface Status Protocol Description\n");
1709 FOR_ALL_INTERFACES (vrf
, ifp
) {
1711 struct zebra_if
*zif
;
1716 len
= vty_out(vty
, "%s", ifp
->name
);
1717 vty_out(vty
, "%*s", (16 - len
), " ");
1719 if (if_is_up(ifp
)) {
1720 vty_out(vty
, "up ");
1721 if (CHECK_FLAG(ifp
->status
,
1722 ZEBRA_INTERFACE_LINKDETECTION
)) {
1723 if (if_is_running(ifp
))
1724 vty_out(vty
, "up ");
1726 vty_out(vty
, "down ");
1728 vty_out(vty
, "unknown ");
1731 vty_out(vty
, "down down ");
1736 vty_out(vty
, "%s", ifp
->desc
);
1739 if (zif
&& zif
->desc
) {
1740 vty_out(vty
, "%s%s",
1751 DEFUN (show_interface_desc
,
1752 show_interface_desc_cmd
,
1753 "show interface description [vrf NAME]",
1755 "Interface status and configuration\n"
1756 "Interface description\n"
1759 vrf_id_t vrf_id
= VRF_DEFAULT
;
1762 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1764 if_show_description(vty
, vrf_id
);
1770 DEFUN (show_interface_desc_vrf_all
,
1771 show_interface_desc_vrf_all_cmd
,
1772 "show interface description vrf all",
1774 "Interface status and configuration\n"
1775 "Interface description\n"
1776 VRF_ALL_CMD_HELP_STR
)
1780 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1781 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
)) {
1782 vty_out(vty
, "\n\tVRF %u\n\n", vrf
->vrf_id
);
1783 if_show_description(vty
, vrf
->vrf_id
);
1792 "Set multicast flag to interface\n")
1794 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1796 struct zebra_if
*if_data
;
1798 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1799 ret
= if_set_flags(ifp
, IFF_MULTICAST
);
1801 vty_out(vty
, "Can't set multicast flag\n");
1802 return CMD_WARNING_CONFIG_FAILED
;
1806 if_data
= ifp
->info
;
1807 if_data
->multicast
= IF_ZEBRA_MULTICAST_ON
;
1812 DEFUN (no_multicast
,
1816 "Unset multicast flag to interface\n")
1818 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1820 struct zebra_if
*if_data
;
1822 if (CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
1823 ret
= if_unset_flags(ifp
, IFF_MULTICAST
);
1825 vty_out(vty
, "Can't unset multicast flag\n");
1826 return CMD_WARNING_CONFIG_FAILED
;
1830 if_data
= ifp
->info
;
1831 if_data
->multicast
= IF_ZEBRA_MULTICAST_OFF
;
1839 "Enable link detection on interface\n")
1841 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1842 int if_was_operative
;
1844 if_was_operative
= if_is_no_ptm_operative(ifp
);
1845 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1847 /* When linkdetection is enabled, if might come down */
1848 if (!if_is_no_ptm_operative(ifp
) && if_was_operative
)
1851 /* FIXME: Will defer status change forwarding if interface
1852 does not come down! */
1858 DEFUN (no_linkdetect
,
1862 "Disable link detection on interface\n")
1864 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1865 int if_was_operative
;
1867 if_was_operative
= if_is_no_ptm_operative(ifp
);
1868 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_LINKDETECTION
);
1870 /* Interface may come up after disabling link detection */
1871 if (if_is_operative(ifp
) && !if_was_operative
)
1874 /* FIXME: see linkdetect_cmd */
1882 "Shutdown the selected interface\n")
1884 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1886 struct zebra_if
*if_data
;
1888 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1889 ret
= if_unset_flags(ifp
, IFF_UP
);
1891 vty_out(vty
, "Can't shutdown interface\n");
1892 return CMD_WARNING_CONFIG_FAILED
;
1896 if_data
= ifp
->info
;
1897 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_ON
;
1902 DEFUN (no_shutdown_if
,
1906 "Shutdown the selected interface\n")
1908 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1910 struct zebra_if
*if_data
;
1912 if (ifp
->ifindex
!= IFINDEX_INTERNAL
) {
1913 ret
= if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
1915 vty_out(vty
, "Can't up interface\n");
1916 return CMD_WARNING_CONFIG_FAILED
;
1920 /* Some addresses (in particular, IPv6 addresses on Linux) get
1921 * removed when the interface goes down. They need to be
1924 if_addr_wakeup(ifp
);
1927 if_data
= ifp
->info
;
1928 if_data
->shutdown
= IF_ZEBRA_SHUTDOWN_OFF
;
1933 DEFUN (bandwidth_if
,
1935 "bandwidth (1-100000)",
1936 "Set bandwidth informational parameter\n"
1937 "Bandwidth in megabits\n")
1940 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1941 unsigned int bandwidth
;
1943 bandwidth
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1945 /* bandwidth range is <1-100000> */
1946 if (bandwidth
< 1 || bandwidth
> 100000) {
1947 vty_out(vty
, "Bandwidth is invalid\n");
1948 return CMD_WARNING_CONFIG_FAILED
;
1951 ifp
->bandwidth
= bandwidth
;
1953 /* force protocols to recalculate routes due to cost change */
1954 if (if_is_operative(ifp
))
1955 zebra_interface_up_update(ifp
);
1960 DEFUN (no_bandwidth_if
,
1961 no_bandwidth_if_cmd
,
1962 "no bandwidth [(1-100000)]",
1964 "Set bandwidth informational parameter\n"
1965 "Bandwidth in megabits\n")
1967 VTY_DECLVAR_CONTEXT(interface
, ifp
);
1971 /* force protocols to recalculate routes due to cost change */
1972 if (if_is_operative(ifp
))
1973 zebra_interface_up_update(ifp
);
1979 struct cmd_node link_params_node
= {
1980 LINK_PARAMS_NODE
, "%s(config-link-params)# ", 1,
1983 static void link_param_cmd_set_uint32(struct interface
*ifp
, uint32_t *field
,
1984 uint32_t type
, uint32_t value
)
1986 /* Update field as needed */
1987 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
1989 SET_PARAM(ifp
->link_params
, type
);
1991 /* force protocols to update LINK STATE due to parameters change
1993 if (if_is_operative(ifp
))
1994 zebra_interface_parameters_update(ifp
);
1997 static void link_param_cmd_set_float(struct interface
*ifp
, float *field
,
1998 uint32_t type
, float value
)
2001 /* Update field as needed */
2002 if (IS_PARAM_UNSET(ifp
->link_params
, type
) || *field
!= value
) {
2004 SET_PARAM(ifp
->link_params
, type
);
2006 /* force protocols to update LINK STATE due to parameters change
2008 if (if_is_operative(ifp
))
2009 zebra_interface_parameters_update(ifp
);
2013 static void link_param_cmd_unset(struct interface
*ifp
, uint32_t type
)
2015 if (ifp
->link_params
== NULL
)
2019 UNSET_PARAM(ifp
->link_params
, type
);
2021 /* force protocols to update LINK STATE due to parameters change */
2022 if (if_is_operative(ifp
))
2023 zebra_interface_parameters_update(ifp
);
2026 DEFUN_NOSH (link_params
,
2031 /* vty->qobj_index stays the same @ interface pointer */
2032 vty
->node
= LINK_PARAMS_NODE
;
2037 DEFUN_NOSH (exit_link_params
,
2038 exit_link_params_cmd
,
2040 "Exit from Link Params configuration mode\n")
2042 if (vty
->node
== LINK_PARAMS_NODE
)
2043 vty
->node
= INTERFACE_NODE
;
2047 /* Specific Traffic Engineering parameters commands */
2048 DEFUN (link_params_enable
,
2049 link_params_enable_cmd
,
2051 "Activate link parameters on this interface\n")
2053 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2055 /* This command could be issue at startup, when activate MPLS TE */
2056 /* on a new interface or after a ON / OFF / ON toggle */
2057 /* In all case, TE parameters are reset to their default factory */
2058 if (IS_ZEBRA_DEBUG_EVENT
)
2060 "Link-params: enable TE link parameters on interface %s",
2063 if (!if_link_params_get(ifp
)) {
2064 if (IS_ZEBRA_DEBUG_EVENT
)
2066 "Link-params: failed to init TE link parameters %s",
2069 return CMD_WARNING_CONFIG_FAILED
;
2072 /* force protocols to update LINK STATE due to parameters change */
2073 if (if_is_operative(ifp
))
2074 zebra_interface_parameters_update(ifp
);
2079 DEFUN (no_link_params_enable
,
2080 no_link_params_enable_cmd
,
2083 "Disable link parameters on this interface\n")
2085 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2087 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2090 if_link_params_free(ifp
);
2092 /* force protocols to update LINK STATE due to parameters change */
2093 if (if_is_operative(ifp
))
2094 zebra_interface_parameters_update(ifp
);
2099 /* STANDARD TE metrics */
2100 DEFUN (link_params_metric
,
2101 link_params_metric_cmd
,
2102 "metric (0-4294967295)",
2103 "Link metric for MPLS-TE purpose\n"
2104 "Metric value in decimal\n")
2107 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2108 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2111 metric
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2113 /* Update TE metric if needed */
2114 link_param_cmd_set_uint32(ifp
, &iflp
->te_metric
, LP_TE_METRIC
, metric
);
2119 DEFUN (no_link_params_metric
,
2120 no_link_params_metric_cmd
,
2123 "Disable Link Metric on this interface\n")
2125 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2127 /* Unset TE Metric */
2128 link_param_cmd_unset(ifp
, LP_TE_METRIC
);
2133 DEFUN (link_params_maxbw
,
2134 link_params_maxbw_cmd
,
2136 "Maximum bandwidth that can be used\n"
2137 "Bytes/second (IEEE floating point format)\n")
2139 int idx_bandwidth
= 1;
2140 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2141 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2145 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2146 vty_out(vty
, "link_params_maxbw: fscanf: %s\n",
2147 safe_strerror(errno
));
2148 return CMD_WARNING_CONFIG_FAILED
;
2151 /* Check that Maximum bandwidth is not lower than other bandwidth
2153 if ((bw
<= iflp
->max_rsv_bw
) || (bw
<= iflp
->unrsv_bw
[0])
2154 || (bw
<= iflp
->unrsv_bw
[1]) || (bw
<= iflp
->unrsv_bw
[2])
2155 || (bw
<= iflp
->unrsv_bw
[3]) || (bw
<= iflp
->unrsv_bw
[4])
2156 || (bw
<= iflp
->unrsv_bw
[5]) || (bw
<= iflp
->unrsv_bw
[6])
2157 || (bw
<= iflp
->unrsv_bw
[7]) || (bw
<= iflp
->ava_bw
)
2158 || (bw
<= iflp
->res_bw
) || (bw
<= iflp
->use_bw
)) {
2160 "Maximum Bandwidth could not be lower than others bandwidth\n");
2161 return CMD_WARNING_CONFIG_FAILED
;
2164 /* Update Maximum Bandwidth if needed */
2165 link_param_cmd_set_float(ifp
, &iflp
->max_bw
, LP_MAX_BW
, bw
);
2170 DEFUN (link_params_max_rsv_bw
,
2171 link_params_max_rsv_bw_cmd
,
2172 "max-rsv-bw BANDWIDTH",
2173 "Maximum bandwidth that may be reserved\n"
2174 "Bytes/second (IEEE floating point format)\n")
2176 int idx_bandwidth
= 1;
2177 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2178 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2181 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2182 vty_out(vty
, "link_params_max_rsv_bw: fscanf: %s\n",
2183 safe_strerror(errno
));
2184 return CMD_WARNING_CONFIG_FAILED
;
2187 /* Check that bandwidth is not greater than maximum bandwidth parameter
2189 if (bw
> iflp
->max_bw
) {
2191 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2193 return CMD_WARNING_CONFIG_FAILED
;
2196 /* Update Maximum Reservable Bandwidth if needed */
2197 link_param_cmd_set_float(ifp
, &iflp
->max_rsv_bw
, LP_MAX_RSV_BW
, bw
);
2202 DEFUN (link_params_unrsv_bw
,
2203 link_params_unrsv_bw_cmd
,
2204 "unrsv-bw (0-7) BANDWIDTH",
2205 "Unreserved bandwidth at each priority level\n"
2207 "Bytes/second (IEEE floating point format)\n")
2210 int idx_bandwidth
= 2;
2211 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2212 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2216 /* We don't have to consider about range check here. */
2217 if (sscanf(argv
[idx_number
]->arg
, "%d", &priority
) != 1) {
2218 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2219 safe_strerror(errno
));
2220 return CMD_WARNING_CONFIG_FAILED
;
2223 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2224 vty_out(vty
, "link_params_unrsv_bw: fscanf: %s\n",
2225 safe_strerror(errno
));
2226 return CMD_WARNING_CONFIG_FAILED
;
2229 /* Check that bandwidth is not greater than maximum bandwidth parameter
2231 if (bw
> iflp
->max_bw
) {
2233 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2235 return CMD_WARNING_CONFIG_FAILED
;
2238 /* Update Unreserved Bandwidth if needed */
2239 link_param_cmd_set_float(ifp
, &iflp
->unrsv_bw
[priority
], LP_UNRSV_BW
,
2245 DEFUN (link_params_admin_grp
,
2246 link_params_admin_grp_cmd
,
2247 "admin-grp BITPATTERN",
2248 "Administrative group membership\n"
2249 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2251 int idx_bitpattern
= 1;
2252 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2253 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2254 unsigned long value
;
2256 if (sscanf(argv
[idx_bitpattern
]->arg
, "0x%lx", &value
) != 1) {
2257 vty_out(vty
, "link_params_admin_grp: fscanf: %s\n",
2258 safe_strerror(errno
));
2259 return CMD_WARNING_CONFIG_FAILED
;
2262 /* Update Administrative Group if needed */
2263 link_param_cmd_set_uint32(ifp
, &iflp
->admin_grp
, LP_ADM_GRP
, value
);
2268 DEFUN (no_link_params_admin_grp
,
2269 no_link_params_admin_grp_cmd
,
2272 "Disable Administrative group membership on this interface\n")
2274 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2276 /* Unset Admin Group */
2277 link_param_cmd_unset(ifp
, LP_ADM_GRP
);
2282 /* RFC5392 & RFC5316: INTER-AS */
2283 DEFUN (link_params_inter_as
,
2284 link_params_inter_as_cmd
,
2285 "neighbor A.B.C.D as (1-4294967295)",
2286 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2287 "Remote IP address in dot decimal A.B.C.D\n"
2288 "Remote AS number\n"
2289 "AS number in the range <1-4294967295>\n")
2294 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2295 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2296 struct in_addr addr
;
2299 if (!inet_aton(argv
[idx_ipv4
]->arg
, &addr
)) {
2300 vty_out(vty
, "Please specify Router-Addr by A.B.C.D\n");
2301 return CMD_WARNING_CONFIG_FAILED
;
2304 as
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2306 /* Update Remote IP and Remote AS fields if needed */
2307 if (IS_PARAM_UNSET(iflp
, LP_RMT_AS
) || iflp
->rmt_as
!= as
2308 || iflp
->rmt_ip
.s_addr
!= addr
.s_addr
) {
2311 iflp
->rmt_ip
.s_addr
= addr
.s_addr
;
2312 SET_PARAM(iflp
, LP_RMT_AS
);
2314 /* force protocols to update LINK STATE due to parameters change
2316 if (if_is_operative(ifp
))
2317 zebra_interface_parameters_update(ifp
);
2322 DEFUN (no_link_params_inter_as
,
2323 no_link_params_inter_as_cmd
,
2326 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2328 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2329 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2331 /* Reset Remote IP and AS neighbor */
2333 iflp
->rmt_ip
.s_addr
= 0;
2334 UNSET_PARAM(iflp
, LP_RMT_AS
);
2336 /* force protocols to update LINK STATE due to parameters change */
2337 if (if_is_operative(ifp
))
2338 zebra_interface_parameters_update(ifp
);
2343 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2344 * draft-ietf-isis-metric-extensions-07.txt */
2345 DEFUN (link_params_delay
,
2346 link_params_delay_cmd
,
2347 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2348 "Unidirectional Average Link Delay\n"
2349 "Average delay in micro-second as decimal (0...16777215)\n"
2351 "Minimum delay in micro-second as decimal (0...16777215)\n"
2353 "Maximum delay in micro-second as decimal (0...16777215)\n")
2355 /* Get and Check new delay values */
2356 uint32_t delay
= 0, low
= 0, high
= 0;
2357 delay
= strtoul(argv
[1]->arg
, NULL
, 10);
2359 low
= strtoul(argv
[3]->arg
, NULL
, 10);
2360 high
= strtoul(argv
[5]->arg
, NULL
, 10);
2363 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2364 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2368 /* Check new delay value against old Min and Max delays if set
2370 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)
2371 && (delay
<= iflp
->min_delay
|| delay
>= iflp
->max_delay
)) {
2373 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2374 iflp
->min_delay
, iflp
->max_delay
);
2375 return CMD_WARNING_CONFIG_FAILED
;
2377 /* Update delay if value is not set or change */
2378 if (IS_PARAM_UNSET(iflp
, LP_DELAY
) || iflp
->av_delay
!= delay
) {
2379 iflp
->av_delay
= delay
;
2380 SET_PARAM(iflp
, LP_DELAY
);
2383 /* Unset Min and Max delays if already set */
2384 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
2385 iflp
->min_delay
= 0;
2386 iflp
->max_delay
= 0;
2387 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2391 /* Check new delays value coherency */
2392 if (delay
<= low
|| delay
>= high
) {
2394 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2396 return CMD_WARNING_CONFIG_FAILED
;
2398 /* Update Delays if needed */
2399 if (IS_PARAM_UNSET(iflp
, LP_DELAY
)
2400 || IS_PARAM_UNSET(iflp
, LP_MM_DELAY
)
2401 || iflp
->av_delay
!= delay
|| iflp
->min_delay
!= low
2402 || iflp
->max_delay
!= high
) {
2403 iflp
->av_delay
= delay
;
2404 SET_PARAM(iflp
, LP_DELAY
);
2405 iflp
->min_delay
= low
;
2406 iflp
->max_delay
= high
;
2407 SET_PARAM(iflp
, LP_MM_DELAY
);
2412 /* force protocols to update LINK STATE due to parameters change */
2413 if (update
== 1 && if_is_operative(ifp
))
2414 zebra_interface_parameters_update(ifp
);
2419 DEFUN (no_link_params_delay
,
2420 no_link_params_delay_cmd
,
2423 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2425 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2426 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2430 UNSET_PARAM(iflp
, LP_DELAY
);
2431 iflp
->min_delay
= 0;
2432 iflp
->max_delay
= 0;
2433 UNSET_PARAM(iflp
, LP_MM_DELAY
);
2435 /* force protocols to update LINK STATE due to parameters change */
2436 if (if_is_operative(ifp
))
2437 zebra_interface_parameters_update(ifp
);
2442 DEFUN (link_params_delay_var
,
2443 link_params_delay_var_cmd
,
2444 "delay-variation (0-16777215)",
2445 "Unidirectional Link Delay Variation\n"
2446 "delay variation in micro-second as decimal (0...16777215)\n")
2449 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2450 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2453 value
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
2455 /* Update Delay Variation if needed */
2456 link_param_cmd_set_uint32(ifp
, &iflp
->delay_var
, LP_DELAY_VAR
, value
);
2461 DEFUN (no_link_params_delay_var
,
2462 no_link_params_delay_var_cmd
,
2463 "no delay-variation",
2465 "Disable Unidirectional Delay Variation on this interface\n")
2467 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2469 /* Unset Delay Variation */
2470 link_param_cmd_unset(ifp
, LP_DELAY_VAR
);
2475 DEFUN (link_params_pkt_loss
,
2476 link_params_pkt_loss_cmd
,
2477 "packet-loss PERCENTAGE",
2478 "Unidirectional Link Packet Loss\n"
2479 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2481 int idx_percentage
= 1;
2482 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2483 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2486 if (sscanf(argv
[idx_percentage
]->arg
, "%g", &fval
) != 1) {
2487 vty_out(vty
, "link_params_pkt_loss: fscanf: %s\n",
2488 safe_strerror(errno
));
2489 return CMD_WARNING_CONFIG_FAILED
;
2492 if (fval
> MAX_PKT_LOSS
)
2493 fval
= MAX_PKT_LOSS
;
2495 /* Update Packet Loss if needed */
2496 link_param_cmd_set_float(ifp
, &iflp
->pkt_loss
, LP_PKT_LOSS
, fval
);
2501 DEFUN (no_link_params_pkt_loss
,
2502 no_link_params_pkt_loss_cmd
,
2505 "Disable Unidirectional Link Packet Loss on this interface\n")
2507 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2509 /* Unset Packet Loss */
2510 link_param_cmd_unset(ifp
, LP_PKT_LOSS
);
2515 DEFUN (link_params_res_bw
,
2516 link_params_res_bw_cmd
,
2518 "Unidirectional Residual Bandwidth\n"
2519 "Bytes/second (IEEE floating point format)\n")
2521 int idx_bandwidth
= 1;
2522 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2523 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2526 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2527 vty_out(vty
, "link_params_res_bw: fscanf: %s\n",
2528 safe_strerror(errno
));
2529 return CMD_WARNING_CONFIG_FAILED
;
2532 /* Check that bandwidth is not greater than maximum bandwidth parameter
2534 if (bw
> iflp
->max_bw
) {
2536 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2538 return CMD_WARNING_CONFIG_FAILED
;
2541 /* Update Residual Bandwidth if needed */
2542 link_param_cmd_set_float(ifp
, &iflp
->res_bw
, LP_RES_BW
, bw
);
2547 DEFUN (no_link_params_res_bw
,
2548 no_link_params_res_bw_cmd
,
2551 "Disable Unidirectional Residual Bandwidth on this interface\n")
2553 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2555 /* Unset Residual Bandwidth */
2556 link_param_cmd_unset(ifp
, LP_RES_BW
);
2561 DEFUN (link_params_ava_bw
,
2562 link_params_ava_bw_cmd
,
2564 "Unidirectional Available Bandwidth\n"
2565 "Bytes/second (IEEE floating point format)\n")
2567 int idx_bandwidth
= 1;
2568 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2569 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2572 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2573 vty_out(vty
, "link_params_ava_bw: fscanf: %s\n",
2574 safe_strerror(errno
));
2575 return CMD_WARNING_CONFIG_FAILED
;
2578 /* Check that bandwidth is not greater than maximum bandwidth parameter
2580 if (bw
> iflp
->max_bw
) {
2582 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2584 return CMD_WARNING_CONFIG_FAILED
;
2587 /* Update Residual Bandwidth if needed */
2588 link_param_cmd_set_float(ifp
, &iflp
->ava_bw
, LP_AVA_BW
, bw
);
2593 DEFUN (no_link_params_ava_bw
,
2594 no_link_params_ava_bw_cmd
,
2597 "Disable Unidirectional Available Bandwidth on this interface\n")
2599 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2601 /* Unset Available Bandwidth */
2602 link_param_cmd_unset(ifp
, LP_AVA_BW
);
2607 DEFUN (link_params_use_bw
,
2608 link_params_use_bw_cmd
,
2610 "Unidirectional Utilised Bandwidth\n"
2611 "Bytes/second (IEEE floating point format)\n")
2613 int idx_bandwidth
= 1;
2614 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2615 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2618 if (sscanf(argv
[idx_bandwidth
]->arg
, "%g", &bw
) != 1) {
2619 vty_out(vty
, "link_params_use_bw: fscanf: %s\n",
2620 safe_strerror(errno
));
2621 return CMD_WARNING_CONFIG_FAILED
;
2624 /* Check that bandwidth is not greater than maximum bandwidth parameter
2626 if (bw
> iflp
->max_bw
) {
2628 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2630 return CMD_WARNING_CONFIG_FAILED
;
2633 /* Update Utilized Bandwidth if needed */
2634 link_param_cmd_set_float(ifp
, &iflp
->use_bw
, LP_USE_BW
, bw
);
2639 DEFUN (no_link_params_use_bw
,
2640 no_link_params_use_bw_cmd
,
2643 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2645 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2647 /* Unset Utilised Bandwidth */
2648 link_param_cmd_unset(ifp
, LP_USE_BW
);
2653 static int ip_address_install(struct vty
*vty
, struct interface
*ifp
,
2654 const char *addr_str
, const char *peer_str
,
2657 struct zebra_if
*if_data
;
2658 struct prefix_ipv4 lp
, pp
;
2659 struct connected
*ifc
;
2660 struct prefix_ipv4
*p
;
2662 enum zebra_dplane_result dplane_res
;
2664 if_data
= ifp
->info
;
2666 ret
= str2prefix_ipv4(addr_str
, &lp
);
2668 vty_out(vty
, "%% Malformed address \n");
2669 return CMD_WARNING_CONFIG_FAILED
;
2672 if (ipv4_martian(&lp
.prefix
)) {
2673 vty_out(vty
, "%% Invalid address\n");
2674 return CMD_WARNING_CONFIG_FAILED
;
2678 if (lp
.prefixlen
!= 32) {
2680 "%% Local prefix length for P-t-P address must be /32\n");
2681 return CMD_WARNING_CONFIG_FAILED
;
2684 ret
= str2prefix_ipv4(peer_str
, &pp
);
2686 vty_out(vty
, "%% Malformed peer address\n");
2687 return CMD_WARNING_CONFIG_FAILED
;
2691 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2693 ifc
= connected_new();
2697 p
= prefix_ipv4_new();
2699 ifc
->address
= (struct prefix
*)p
;
2702 SET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
2703 p
= prefix_ipv4_new();
2705 ifc
->destination
= (struct prefix
*)p
;
2706 } else if (p
->prefixlen
<= IPV4_MAX_PREFIXLEN
- 2) {
2707 p
= prefix_ipv4_new();
2709 p
->prefix
.s_addr
= ipv4_broadcast_addr(p
->prefix
.s_addr
,
2711 ifc
->destination
= (struct prefix
*)p
;
2716 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
2718 /* Add to linked list. */
2719 listnode_add(ifp
->connected
, ifc
);
2722 /* This address is configured from zebra. */
2723 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2724 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2726 /* In case of this route need to install kernel. */
2727 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2728 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
2729 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
2730 /* Some system need to up the interface to set IP address. */
2731 if (!if_is_up(ifp
)) {
2732 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
2736 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
2737 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2738 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
2739 dplane_res2str(dplane_res
));
2740 return CMD_WARNING_CONFIG_FAILED
;
2743 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2744 /* The address will be advertised to zebra clients when the
2746 * from the kernel has been received.
2747 * It will also be added to the subnet chain list, then. */
2753 static int ip_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
2754 const char *addr_str
, const char *peer_str
,
2757 struct prefix_ipv4 lp
, pp
;
2758 struct connected
*ifc
;
2760 enum zebra_dplane_result dplane_res
;
2762 /* Convert to prefix structure. */
2763 ret
= str2prefix_ipv4(addr_str
, &lp
);
2765 vty_out(vty
, "%% Malformed address \n");
2766 return CMD_WARNING_CONFIG_FAILED
;
2770 if (lp
.prefixlen
!= 32) {
2772 "%% Local prefix length for P-t-P address must be /32\n");
2773 return CMD_WARNING_CONFIG_FAILED
;
2776 ret
= str2prefix_ipv4(peer_str
, &pp
);
2778 vty_out(vty
, "%% Malformed peer address\n");
2779 return CMD_WARNING_CONFIG_FAILED
;
2783 /* Check current interface address. */
2784 ifc
= connected_check_ptp(ifp
, &lp
, peer_str
? &pp
: NULL
);
2786 vty_out(vty
, "%% Can't find address\n");
2787 return CMD_WARNING_CONFIG_FAILED
;
2790 /* This is not configured address. */
2791 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2792 return CMD_WARNING_CONFIG_FAILED
;
2794 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2796 /* This is not real address or interface is not active. */
2797 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2798 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
2799 listnode_delete(ifp
->connected
, ifc
);
2800 connected_free(ifc
);
2801 return CMD_WARNING_CONFIG_FAILED
;
2804 /* This is real route. */
2805 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
2806 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2807 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
2808 dplane_res2str(dplane_res
));
2809 return CMD_WARNING_CONFIG_FAILED
;
2811 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2812 /* we will receive a kernel notification about this route being removed.
2813 * this will trigger its removal from the connected list. */
2819 "ip address A.B.C.D/M",
2820 "Interface Internet Protocol config commands\n"
2821 "Set the IP address of an interface\n"
2822 "IP address (e.g. 10.0.0.1/8)\n")
2824 int idx_ipv4_prefixlen
= 2;
2825 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2826 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2830 DEFUN (no_ip_address
,
2832 "no ip address A.B.C.D/M",
2834 "Interface Internet Protocol config commands\n"
2835 "Set the IP address of an interface\n"
2836 "IP Address (e.g. 10.0.0.1/8)\n")
2838 int idx_ipv4_prefixlen
= 3;
2839 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2840 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2844 DEFUN(ip_address_peer
,
2845 ip_address_peer_cmd
,
2846 "ip address A.B.C.D peer A.B.C.D/M",
2847 "Interface Internet Protocol config commands\n"
2848 "Set the IP address of an interface\n"
2849 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2850 "Specify P-t-P address\n"
2851 "Peer IP address (e.g. 10.0.0.1/8)\n")
2853 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2854 return ip_address_install(vty
, ifp
, argv
[2]->arg
, argv
[4]->arg
, NULL
);
2857 DEFUN(no_ip_address_peer
,
2858 no_ip_address_peer_cmd
,
2859 "no ip address A.B.C.D peer A.B.C.D/M",
2861 "Interface Internet Protocol config commands\n"
2862 "Set the IP address of an interface\n"
2863 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2864 "Specify P-t-P address\n"
2865 "Peer IP address (e.g. 10.0.0.1/8)\n")
2867 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2868 return ip_address_uninstall(vty
, ifp
, argv
[3]->arg
, argv
[5]->arg
, NULL
);
2872 DEFUN (ip_address_label
,
2873 ip_address_label_cmd
,
2874 "ip address A.B.C.D/M label LINE",
2875 "Interface Internet Protocol config commands\n"
2876 "Set the IP address of an interface\n"
2877 "IP address (e.g. 10.0.0.1/8)\n"
2878 "Label of this address\n"
2881 int idx_ipv4_prefixlen
= 2;
2883 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2884 return ip_address_install(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
2885 argv
[idx_line
]->arg
);
2888 DEFUN (no_ip_address_label
,
2889 no_ip_address_label_cmd
,
2890 "no ip address A.B.C.D/M label LINE",
2892 "Interface Internet Protocol config commands\n"
2893 "Set the IP address of an interface\n"
2894 "IP address (e.g. 10.0.0.1/8)\n"
2895 "Label of this address\n"
2898 int idx_ipv4_prefixlen
= 3;
2900 VTY_DECLVAR_CONTEXT(interface
, ifp
);
2901 return ip_address_uninstall(vty
, ifp
, argv
[idx_ipv4_prefixlen
]->arg
,
2902 NULL
, argv
[idx_line
]->arg
);
2904 #endif /* HAVE_NETLINK */
2906 static int ipv6_address_install(struct vty
*vty
, struct interface
*ifp
,
2907 const char *addr_str
, const char *peer_str
,
2910 struct zebra_if
*if_data
;
2911 struct prefix_ipv6 cp
;
2912 struct connected
*ifc
;
2913 struct prefix_ipv6
*p
;
2915 enum zebra_dplane_result dplane_res
;
2917 if_data
= ifp
->info
;
2919 ret
= str2prefix_ipv6(addr_str
, &cp
);
2921 vty_out(vty
, "%% Malformed address \n");
2922 return CMD_WARNING_CONFIG_FAILED
;
2925 if (ipv6_martian(&cp
.prefix
)) {
2926 vty_out(vty
, "%% Invalid address\n");
2927 return CMD_WARNING_CONFIG_FAILED
;
2930 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
2932 ifc
= connected_new();
2936 p
= prefix_ipv6_new();
2938 ifc
->address
= (struct prefix
*)p
;
2942 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
2944 /* Add to linked list. */
2945 listnode_add(ifp
->connected
, ifc
);
2948 /* This address is configured from zebra. */
2949 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
2950 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
2952 /* In case of this route need to install kernel. */
2953 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
2954 && CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)
2955 && !(if_data
&& if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)) {
2956 /* Some system need to up the interface to set IP address. */
2957 if (!if_is_up(ifp
)) {
2958 if_set_flags(ifp
, IFF_UP
| IFF_RUNNING
);
2962 dplane_res
= dplane_intf_addr_set(ifp
, ifc
);
2963 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
2964 vty_out(vty
, "%% Can't set interface IP address: %s.\n",
2965 dplane_res2str(dplane_res
));
2966 return CMD_WARNING_CONFIG_FAILED
;
2969 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
2970 /* The address will be advertised to zebra clients when the
2972 * from the kernel has been received. */
2978 /* Return true if an ipv6 address is configured on ifp */
2979 int ipv6_address_configured(struct interface
*ifp
)
2981 struct connected
*connected
;
2982 struct listnode
*node
;
2984 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
))
2985 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
2986 && (connected
->address
->family
== AF_INET6
))
2992 static int ipv6_address_uninstall(struct vty
*vty
, struct interface
*ifp
,
2993 const char *addr_str
, const char *peer_str
,
2996 struct prefix_ipv6 cp
;
2997 struct connected
*ifc
;
2999 enum zebra_dplane_result dplane_res
;
3001 /* Convert to prefix structure. */
3002 ret
= str2prefix_ipv6(addr_str
, &cp
);
3004 vty_out(vty
, "%% Malformed address \n");
3005 return CMD_WARNING_CONFIG_FAILED
;
3008 /* Check current interface address. */
3009 ifc
= connected_check(ifp
, (struct prefix
*)&cp
);
3011 vty_out(vty
, "%% Can't find address\n");
3012 return CMD_WARNING_CONFIG_FAILED
;
3015 /* This is not configured address. */
3016 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
))
3017 return CMD_WARNING_CONFIG_FAILED
;
3019 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
3021 /* This is not real address or interface is not active. */
3022 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
)
3023 || !CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_ACTIVE
)) {
3024 listnode_delete(ifp
->connected
, ifc
);
3025 connected_free(ifc
);
3026 return CMD_WARNING_CONFIG_FAILED
;
3029 /* This is real route. */
3030 dplane_res
= dplane_intf_addr_unset(ifp
, ifc
);
3031 if (dplane_res
== ZEBRA_DPLANE_REQUEST_FAILURE
) {
3032 vty_out(vty
, "%% Can't unset interface IP address: %s.\n",
3033 dplane_res2str(dplane_res
));
3034 return CMD_WARNING_CONFIG_FAILED
;
3037 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
3038 /* This information will be propagated to the zclients when the
3039 * kernel notification is received. */
3043 DEFUN (ipv6_address
,
3045 "ipv6 address X:X::X:X/M",
3046 "Interface IPv6 config commands\n"
3047 "Set the IP address of an interface\n"
3048 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3050 int idx_ipv6_prefixlen
= 2;
3051 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3052 return ipv6_address_install(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3056 DEFUN (no_ipv6_address
,
3057 no_ipv6_address_cmd
,
3058 "no ipv6 address X:X::X:X/M",
3060 "Interface IPv6 config commands\n"
3061 "Set the IP address of an interface\n"
3062 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3064 int idx_ipv6_prefixlen
= 3;
3065 VTY_DECLVAR_CONTEXT(interface
, ifp
);
3066 return ipv6_address_uninstall(vty
, ifp
, argv
[idx_ipv6_prefixlen
]->arg
,
3070 static int link_params_config_write(struct vty
*vty
, struct interface
*ifp
)
3074 if ((ifp
== NULL
) || !HAS_LINK_PARAMS(ifp
))
3077 struct if_link_params
*iflp
= ifp
->link_params
;
3079 vty_out(vty
, " link-params\n");
3080 vty_out(vty
, " enable\n");
3081 if (IS_PARAM_SET(iflp
, LP_TE_METRIC
) && iflp
->te_metric
!= ifp
->metric
)
3082 vty_out(vty
, " metric %u\n", iflp
->te_metric
);
3083 if (IS_PARAM_SET(iflp
, LP_MAX_BW
) && iflp
->max_bw
!= iflp
->default_bw
)
3084 vty_out(vty
, " max-bw %g\n", iflp
->max_bw
);
3085 if (IS_PARAM_SET(iflp
, LP_MAX_RSV_BW
)
3086 && iflp
->max_rsv_bw
!= iflp
->default_bw
)
3087 vty_out(vty
, " max-rsv-bw %g\n", iflp
->max_rsv_bw
);
3088 if (IS_PARAM_SET(iflp
, LP_UNRSV_BW
)) {
3089 for (i
= 0; i
< 8; i
++)
3090 if (iflp
->unrsv_bw
[i
] != iflp
->default_bw
)
3091 vty_out(vty
, " unrsv-bw %d %g\n", i
,
3094 if (IS_PARAM_SET(iflp
, LP_ADM_GRP
))
3095 vty_out(vty
, " admin-grp 0x%x\n", iflp
->admin_grp
);
3096 if (IS_PARAM_SET(iflp
, LP_DELAY
)) {
3097 vty_out(vty
, " delay %u", iflp
->av_delay
);
3098 if (IS_PARAM_SET(iflp
, LP_MM_DELAY
)) {
3099 vty_out(vty
, " min %u", iflp
->min_delay
);
3100 vty_out(vty
, " max %u", iflp
->max_delay
);
3104 if (IS_PARAM_SET(iflp
, LP_DELAY_VAR
))
3105 vty_out(vty
, " delay-variation %u\n", iflp
->delay_var
);
3106 if (IS_PARAM_SET(iflp
, LP_PKT_LOSS
))
3107 vty_out(vty
, " packet-loss %g\n", iflp
->pkt_loss
);
3108 if (IS_PARAM_SET(iflp
, LP_AVA_BW
))
3109 vty_out(vty
, " ava-bw %g\n", iflp
->ava_bw
);
3110 if (IS_PARAM_SET(iflp
, LP_RES_BW
))
3111 vty_out(vty
, " res-bw %g\n", iflp
->res_bw
);
3112 if (IS_PARAM_SET(iflp
, LP_USE_BW
))
3113 vty_out(vty
, " use-bw %g\n", iflp
->use_bw
);
3114 if (IS_PARAM_SET(iflp
, LP_RMT_AS
))
3115 vty_out(vty
, " neighbor %s as %u\n", inet_ntoa(iflp
->rmt_ip
),
3117 vty_out(vty
, " exit-link-params\n");
3121 static int if_config_write(struct vty
*vty
)
3124 struct interface
*ifp
;
3126 zebra_ptm_write(vty
);
3128 RB_FOREACH (vrf0
, vrf_name_head
, &vrfs_by_name
)
3129 FOR_ALL_INTERFACES (vrf0
, ifp
) {
3130 struct zebra_if
*if_data
;
3131 struct listnode
*addrnode
;
3132 struct connected
*ifc
;
3136 if_data
= ifp
->info
;
3137 vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
3139 if (ifp
->vrf_id
== VRF_DEFAULT
)
3140 vty_frame(vty
, "interface %s\n", ifp
->name
);
3142 vty_frame(vty
, "interface %s vrf %s\n",
3143 ifp
->name
, vrf
->name
);
3146 if (if_data
->shutdown
== IF_ZEBRA_SHUTDOWN_ON
)
3147 vty_out(vty
, " shutdown\n");
3149 zebra_ptm_if_write(vty
, if_data
);
3153 vty_out(vty
, " description %s\n", ifp
->desc
);
3155 /* Assign bandwidth here to avoid unnecessary interface
3157 while processing config script */
3158 if (ifp
->bandwidth
!= 0)
3159 vty_out(vty
, " bandwidth %u\n", ifp
->bandwidth
);
3161 if (!CHECK_FLAG(ifp
->status
,
3162 ZEBRA_INTERFACE_LINKDETECTION
))
3163 vty_out(vty
, " no link-detect\n");
3165 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, addrnode
,
3167 if (CHECK_FLAG(ifc
->conf
,
3168 ZEBRA_IFC_CONFIGURED
)) {
3169 char buf
[INET6_ADDRSTRLEN
];
3171 vty_out(vty
, " ip%s address %s",
3172 p
->family
== AF_INET
? ""
3174 inet_ntop(p
->family
,
3177 if (CONNECTED_PEER(ifc
)) {
3178 p
= ifc
->destination
;
3179 vty_out(vty
, " peer %s",
3180 inet_ntop(p
->family
,
3185 vty_out(vty
, "/%d", p
->prefixlen
);
3188 vty_out(vty
, " label %s",
3196 if (if_data
->multicast
3197 != IF_ZEBRA_MULTICAST_UNSPEC
)
3198 vty_out(vty
, " %smulticast\n",
3200 == IF_ZEBRA_MULTICAST_ON
3205 hook_call(zebra_if_config_wr
, vty
, ifp
);
3207 link_params_config_write(vty
, ifp
);
3209 vty_endframe(vty
, "!\n");
3214 /* Allocate and initialize interface vector. */
3215 void zebra_if_init(void)
3217 /* Initialize interface and new hook. */
3218 hook_register_prio(if_add
, 0, if_zebra_new_hook
);
3219 hook_register_prio(if_del
, 0, if_zebra_delete_hook
);
3221 /* Install configuration write function. */
3222 install_node(&interface_node
, if_config_write
);
3223 install_node(&link_params_node
, NULL
);
3226 install_element(VIEW_NODE
, &show_interface_cmd
);
3227 install_element(VIEW_NODE
, &show_interface_vrf_all_cmd
);
3228 install_element(VIEW_NODE
, &show_interface_name_vrf_cmd
);
3229 install_element(VIEW_NODE
, &show_interface_name_vrf_all_cmd
);
3231 install_element(ENABLE_NODE
, &show_interface_desc_cmd
);
3232 install_element(ENABLE_NODE
, &show_interface_desc_vrf_all_cmd
);
3233 install_element(INTERFACE_NODE
, &multicast_cmd
);
3234 install_element(INTERFACE_NODE
, &no_multicast_cmd
);
3235 install_element(INTERFACE_NODE
, &linkdetect_cmd
);
3236 install_element(INTERFACE_NODE
, &no_linkdetect_cmd
);
3237 install_element(INTERFACE_NODE
, &shutdown_if_cmd
);
3238 install_element(INTERFACE_NODE
, &no_shutdown_if_cmd
);
3239 install_element(INTERFACE_NODE
, &bandwidth_if_cmd
);
3240 install_element(INTERFACE_NODE
, &no_bandwidth_if_cmd
);
3241 install_element(INTERFACE_NODE
, &ip_address_cmd
);
3242 install_element(INTERFACE_NODE
, &no_ip_address_cmd
);
3243 install_element(INTERFACE_NODE
, &ip_address_peer_cmd
);
3244 install_element(INTERFACE_NODE
, &no_ip_address_peer_cmd
);
3245 install_element(INTERFACE_NODE
, &ipv6_address_cmd
);
3246 install_element(INTERFACE_NODE
, &no_ipv6_address_cmd
);
3248 install_element(INTERFACE_NODE
, &ip_address_label_cmd
);
3249 install_element(INTERFACE_NODE
, &no_ip_address_label_cmd
);
3250 #endif /* HAVE_NETLINK */
3251 install_element(INTERFACE_NODE
, &link_params_cmd
);
3252 install_default(LINK_PARAMS_NODE
);
3253 install_element(LINK_PARAMS_NODE
, &link_params_enable_cmd
);
3254 install_element(LINK_PARAMS_NODE
, &no_link_params_enable_cmd
);
3255 install_element(LINK_PARAMS_NODE
, &link_params_metric_cmd
);
3256 install_element(LINK_PARAMS_NODE
, &no_link_params_metric_cmd
);
3257 install_element(LINK_PARAMS_NODE
, &link_params_maxbw_cmd
);
3258 install_element(LINK_PARAMS_NODE
, &link_params_max_rsv_bw_cmd
);
3259 install_element(LINK_PARAMS_NODE
, &link_params_unrsv_bw_cmd
);
3260 install_element(LINK_PARAMS_NODE
, &link_params_admin_grp_cmd
);
3261 install_element(LINK_PARAMS_NODE
, &no_link_params_admin_grp_cmd
);
3262 install_element(LINK_PARAMS_NODE
, &link_params_inter_as_cmd
);
3263 install_element(LINK_PARAMS_NODE
, &no_link_params_inter_as_cmd
);
3264 install_element(LINK_PARAMS_NODE
, &link_params_delay_cmd
);
3265 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_cmd
);
3266 install_element(LINK_PARAMS_NODE
, &link_params_delay_var_cmd
);
3267 install_element(LINK_PARAMS_NODE
, &no_link_params_delay_var_cmd
);
3268 install_element(LINK_PARAMS_NODE
, &link_params_pkt_loss_cmd
);
3269 install_element(LINK_PARAMS_NODE
, &no_link_params_pkt_loss_cmd
);
3270 install_element(LINK_PARAMS_NODE
, &link_params_ava_bw_cmd
);
3271 install_element(LINK_PARAMS_NODE
, &no_link_params_ava_bw_cmd
);
3272 install_element(LINK_PARAMS_NODE
, &link_params_res_bw_cmd
);
3273 install_element(LINK_PARAMS_NODE
, &no_link_params_res_bw_cmd
);
3274 install_element(LINK_PARAMS_NODE
, &link_params_use_bw_cmd
);
3275 install_element(LINK_PARAMS_NODE
, &no_link_params_use_bw_cmd
);
3276 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);