]> git.proxmox.com Git - mirror_frr.git/blob - zebra/interface.c
*: change interface structure, from vrf_id to vrf
[mirror_frr.git] / zebra / interface.c
1 /*
2 * Interface function.
3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
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
20 */
21
22 #include <zebra.h>
23
24 #include "if.h"
25 #include "lib_errors.h"
26 #include "vty.h"
27 #include "sockunion.h"
28 #include "prefix.h"
29 #include "command.h"
30 #include "memory.h"
31 #include "zebra_memory.h"
32 #include "ioctl.h"
33 #include "connected.h"
34 #include "log.h"
35 #include "zclient.h"
36 #include "vrf.h"
37
38 #include "zebra/rtadv.h"
39 #include "zebra_ns.h"
40 #include "zebra_vrf.h"
41 #include "zebra/interface.h"
42 #include "zebra/rib.h"
43 #include "zebra/rt.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"
54
55 DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information")
56
57 #define ZEBRA_PTM_SUPPORT
58
59 DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp),
60 (vty, ifp))
61 DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
62 (vty, ifp))
63
64
65 static void if_down_del_nbr_connected(struct interface *ifp);
66
67 static int if_zebra_speed_update(struct thread *thread)
68 {
69 struct interface *ifp = THREAD_ARG(thread);
70 struct zebra_if *zif = ifp->info;
71 uint32_t new_speed;
72
73 zif->speed_update = NULL;
74
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,
79 new_speed);
80 ifp->speed = new_speed;
81 if_add_update(ifp);
82 }
83
84 return 1;
85 }
86
87 static void zebra_if_node_destroy(route_table_delegate_t *delegate,
88 struct route_table *table,
89 struct route_node *node)
90 {
91 if (node->info)
92 list_delete((struct list **)&node->info);
93 route_node_destroy(delegate, table, node);
94 }
95
96 route_table_delegate_t zebra_if_table_delegate = {
97 .create_node = route_node_create,
98 .destroy_node = zebra_if_node_destroy};
99
100 /* Called when new interface is added. */
101 static int if_zebra_new_hook(struct interface *ifp)
102 {
103 struct zebra_if *zebra_if;
104
105 zebra_if = XCALLOC(MTYPE_ZINFO, sizeof(struct zebra_if));
106
107 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
108 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
109 zebra_ptm_if_init(zebra_if);
110
111 ifp->ptm_enable = zebra_ptm_get_enable_state();
112 #if defined(HAVE_RTADV)
113 {
114 /* Set default router advertise values. */
115 struct rtadvconf *rtadv;
116
117 rtadv = &zebra_if->rtadv;
118
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;
137
138 rtadv->AdvPrefixList = list_new();
139 rtadv->AdvRDNSSList = list_new();
140 rtadv->AdvDNSSLList = list_new();
141 }
142 #endif /* HAVE_RTADV */
143
144 memset(&zebra_if->neigh_mac[0], 0, 6);
145
146 /* Initialize installed address chains tree. */
147 zebra_if->ipv4_subnets =
148 route_table_init_with_delegate(&zebra_if_table_delegate);
149
150 ifp->info = zebra_if;
151
152 /*
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
157 * down upon startup.
158 */
159 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
160 &zebra_if->speed_update);
161 return 0;
162 }
163
164 /* Called when interface is deleted. */
165 static int if_zebra_delete_hook(struct interface *ifp)
166 {
167 struct zebra_if *zebra_if;
168
169 if (ifp->info) {
170 zebra_if = ifp->info;
171
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)
176
177 struct rtadvconf *rtadv;
178
179 rtadv = &zebra_if->rtadv;
180 list_delete(&rtadv->AdvPrefixList);
181 list_delete(&rtadv->AdvRDNSSList);
182 list_delete(&rtadv->AdvDNSSLList);
183 #endif /* HAVE_RTADV */
184
185 XFREE(MTYPE_TMP, zebra_if->desc);
186 THREAD_OFF(zebra_if->speed_update);
187
188 XFREE(MTYPE_ZINFO, zebra_if);
189 }
190
191 return 0;
192 }
193
194 /* Build the table key */
195 static void if_build_key(uint32_t ifindex, struct prefix *p)
196 {
197 p->family = AF_INET;
198 p->prefixlen = IPV4_MAX_BITLEN;
199 p->u.prefix4.s_addr = ifindex;
200 }
201
202 /* Link an interface in a per NS interface tree */
203 struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
204 {
205 struct prefix p;
206 struct route_node *rn;
207
208 if (ifp->ifindex == IFINDEX_INTERNAL)
209 return NULL;
210
211 if_build_key(ifp->ifindex, &p);
212 rn = route_node_get(ns->if_table, &p);
213 if (rn->info) {
214 ifp = (struct interface *)rn->info;
215 route_unlock_node(rn); /* get */
216 return ifp;
217 }
218
219 rn->info = ifp;
220 ifp->node = rn;
221
222 return ifp;
223 }
224
225 /* Delete a VRF. This is called in vrf_terminate(). */
226 void if_unlink_per_ns(struct interface *ifp)
227 {
228 ifp->node->info = NULL;
229 route_unlock_node(ifp->node);
230 ifp->node = NULL;
231 }
232
233 /* Look up an interface by identifier within a NS */
234 struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns,
235 uint32_t ifindex)
236 {
237 struct prefix p;
238 struct route_node *rn;
239 struct interface *ifp = NULL;
240
241 if_build_key(ifindex, &p);
242 rn = route_node_lookup(ns->if_table, &p);
243 if (rn) {
244 ifp = (struct interface *)rn->info;
245 route_unlock_node(rn); /* lookup */
246 }
247 return ifp;
248 }
249
250 /* Look up an interface by name within a NS */
251 struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
252 const char *ifname)
253 {
254 struct route_node *rn;
255 struct interface *ifp;
256
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)
260 return (ifp);
261 }
262
263 return NULL;
264 }
265
266 const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
267 {
268 struct interface *ifp;
269
270 return ((ifp = if_lookup_by_index_per_ns(zns, ifindex)) != NULL)
271 ? ifp->name
272 : "unknown";
273 }
274
275 /* Tie an interface address to its derived subnet list of addresses. */
276 int if_subnet_add(struct interface *ifp, struct connected *ifc)
277 {
278 struct route_node *rn;
279 struct zebra_if *zebra_if;
280 struct prefix cp;
281 struct list *addr_list;
282
283 assert(ifp && ifp->info && ifc);
284 zebra_if = ifp->info;
285
286 /* Get address derived subnet node and associated address list, while
287 marking
288 address secondary attribute appropriately. */
289 cp = *CONNECTED_PREFIX(ifc);
290 apply_mask(&cp);
291 rn = route_node_get(zebra_if->ipv4_subnets, &cp);
292
293 if ((addr_list = rn->info))
294 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
295 else {
296 UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
297 rn->info = addr_list = list_new();
298 route_lock_node(rn);
299 }
300
301 /* Tie address at the tail of address list. */
302 listnode_add(addr_list, ifc);
303
304 /* Return list element count. */
305 return (addr_list->count);
306 }
307
308 /* Untie an interface address from its derived subnet list of addresses. */
309 int if_subnet_delete(struct interface *ifp, struct connected *ifc)
310 {
311 struct route_node *rn;
312 struct zebra_if *zebra_if;
313 struct list *addr_list;
314 struct prefix cp;
315
316 assert(ifp && ifp->info && ifc);
317 zebra_if = ifp->info;
318
319 cp = *CONNECTED_PREFIX(ifc);
320 apply_mask(&cp);
321
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)");
328 return -1;
329 }
330 route_unlock_node(rn);
331
332 /* Untie address from subnet's address list. */
333 addr_list = rn->info;
334
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
337 * is unknown. */
338 if (!listnode_lookup(addr_list, ifc)) {
339 flog_warn(
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)");
343 return -1;
344 }
345
346 listnode_delete(addr_list, ifc);
347 route_unlock_node(rn);
348
349 /* Return list element count, if not empty. */
350 if (addr_list->count) {
351 /* If deleted address is primary, mark subsequent one as such
352 * and distribute. */
353 if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
354 ifc = listgetdata(
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
359 * when the primary
360 * address is removed. We could try to work around that,
361 * though this is
362 * non-trivial. */
363 zebra_interface_address_add_update(ifp, ifc);
364 }
365
366 return addr_list->count;
367 }
368
369 /* Otherwise, free list and route node. */
370 list_delete(&addr_list);
371 rn->info = NULL;
372 route_unlock_node(rn);
373
374 return 0;
375 }
376
377 /* if_flags_mangle: A place for hacks that require mangling
378 * or tweaking the interface flags.
379 *
380 * ******************** Solaris flags hacks **************************
381 *
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).
389 *
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
392 * IFF_UP flag.
393 *
394 * We must hence remember the real state of IFF_UP, which we do in
395 * struct zebra_if.primary_state.
396 *
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 ***********************
400 */
401 static void if_flags_mangle(struct interface *ifp, uint64_t *newflags)
402 {
403 #ifdef SUNOS_5
404 struct zebra_if *zif = ifp->info;
405
406 zif->primary_state = *newflags & (IFF_UP & 0xff);
407
408 if (CHECK_FLAG(zif->primary_state, IFF_UP)
409 || listcount(ifp->connected) > 0)
410 SET_FLAG(*newflags, IFF_UP);
411 else
412 UNSET_FLAG(*newflags, IFF_UP);
413 #endif /* SUNOS_5 */
414 }
415
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
418 * about.
419 *
420 * newflags should be the raw value, as obtained from the OS.
421 */
422 void if_flags_update(struct interface *ifp, uint64_t newflags)
423 {
424 if_flags_mangle(ifp, &newflags);
425
426 if (if_is_no_ptm_operative(ifp)) {
427 /* operative -> inoperative? */
428 ifp->flags = newflags;
429 if (!if_is_operative(ifp))
430 if_down(ifp);
431 } else {
432 /* inoperative -> operative? */
433 ifp->flags = newflags;
434 if (if_is_operative(ifp))
435 if_up(ifp);
436 }
437 }
438
439 /* Wake up configured address if it is not in current kernel
440 address. */
441 static void if_addr_wakeup(struct interface *ifp)
442 {
443 struct listnode *node, *nnode;
444 struct connected *ifc;
445 struct prefix *p;
446 enum zebra_dplane_result dplane_res;
447
448 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
449 p = ifc->address;
450
451 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)
452 && !CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)) {
453 /* Address check. */
454 if (p->family == AF_INET) {
455 if (!if_is_up(ifp)) {
456 /* Assume zebra is configured like
457 * following:
458 *
459 * interface gre0
460 * ip addr 192.0.2.1/24
461 * !
462 *
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.
467 *
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)
472 *
473 * XXX: IRDP code is calling here via
474 * if_add_update - this seems
475 * somewhat weird.
476 * XXX: RUNNING is not a settable flag
477 * on any system
478 * I (paulj) am aware of.
479 */
480 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
481 if_refresh(ifp);
482 }
483
484 dplane_res = dplane_intf_addr_set(ifp, ifc);
485 if (dplane_res ==
486 ZEBRA_DPLANE_REQUEST_FAILURE) {
487 flog_err_sys(
488 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
489 "Can't set interface's address: %s",
490 dplane_res2str(dplane_res));
491 continue;
492 }
493
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. */
500 }
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);
505 if_refresh(ifp);
506 }
507
508
509 dplane_res = dplane_intf_addr_set(ifp, ifc);
510 if (dplane_res ==
511 ZEBRA_DPLANE_REQUEST_FAILURE) {
512 flog_err_sys(
513 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
514 "Can't set interface's address: %s",
515 dplane_res2str(dplane_res));
516 continue;
517 }
518
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. */
523 }
524 }
525 }
526 }
527
528 /* Handle interface addition */
529 void if_add_update(struct interface *ifp)
530 {
531 struct zebra_if *if_data;
532 struct zebra_ns *zns;
533 struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
534
535 /* case interface populate before vrf enabled */
536 if (zvrf->zns)
537 zns = zvrf->zns;
538 else
539 zns = zebra_ns_lookup(NS_DEFAULT);
540 if_link_per_ns(zns, ifp);
541 if_data = ifp->info;
542 assert(if_data);
543
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);
548
549 zebra_ptm_if_set_ptm_state(ifp, if_data);
550
551 zebra_interface_add_update(ifp);
552
553 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
554 SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
555
556 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) {
557 if (IS_ZEBRA_DEBUG_KERNEL)
558 zlog_debug(
559 "interface %s vrf %u index %d is shutdown. "
560 "Won't wake it up.",
561 ifp->name, vrf_to_id(ifp->vrf),
562 ifp->ifindex);
563 return;
564 }
565
566 if_addr_wakeup(ifp);
567
568 if (IS_ZEBRA_DEBUG_KERNEL)
569 zlog_debug(
570 "interface %s vrf %u index %d becomes active.",
571 ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
572
573 } else {
574 if (IS_ZEBRA_DEBUG_KERNEL)
575 zlog_debug("interface %s vrf %u index %d is added.",
576 ifp->name, vrf_to_id(ifp->vrf),
577 ifp->ifindex);
578 }
579 }
580
581 /* Install connected routes corresponding to an interface. */
582 static void if_install_connected(struct interface *ifp)
583 {
584 struct listnode *node;
585 struct listnode *next;
586 struct connected *ifc;
587
588 if (ifp->connected) {
589 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
590 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
591 zebra_interface_address_add_update(ifp, ifc);
592
593 connected_up(ifp, ifc);
594 }
595 }
596 }
597
598 /* Uninstall connected routes corresponding to an interface. */
599 static void if_uninstall_connected(struct interface *ifp)
600 {
601 struct listnode *node;
602 struct listnode *next;
603 struct connected *ifc;
604
605 if (ifp->connected) {
606 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
607 zebra_interface_address_delete_update(ifp, ifc);
608 connected_down(ifp, ifc);
609 }
610 }
611 }
612
613 /* Uninstall and delete connected routes corresponding to an interface. */
614 /* TODO - Check why IPv4 handling here is different from install or if_down */
615 static void if_delete_connected(struct interface *ifp)
616 {
617 struct connected *ifc;
618 struct prefix cp;
619 struct route_node *rn;
620 struct zebra_if *zebra_if;
621 struct listnode *node;
622 struct listnode *last = NULL;
623
624 zebra_if = ifp->info;
625
626 if (!ifp->connected)
627 return;
628
629 while ((node = (last ? last->next : listhead(ifp->connected)))) {
630 ifc = listgetdata(node);
631
632 cp = *CONNECTED_PREFIX(ifc);
633 apply_mask(&cp);
634
635 if (cp.family == AF_INET
636 && (rn = route_node_lookup(zebra_if->ipv4_subnets, &cp))) {
637 struct listnode *anode;
638 struct listnode *next;
639 struct listnode *first;
640 struct list *addr_list;
641
642 route_unlock_node(rn);
643 addr_list = (struct list *)rn->info;
644
645 /* Remove addresses, secondaries first. */
646 first = listhead(addr_list);
647 if (first)
648 for (anode = first->next; anode || first;
649 anode = next) {
650 if (!anode) {
651 anode = first;
652 first = NULL;
653 }
654 next = anode->next;
655
656 ifc = listgetdata(anode);
657 connected_down(ifp, ifc);
658
659 /* XXX: We have to send notifications
660 * here explicitly, because we destroy
661 * the ifc before receiving the
662 * notification about the address being
663 * deleted.
664 */
665 zebra_interface_address_delete_update(
666 ifp, ifc);
667
668 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
669 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
670
671 /* Remove from subnet chain. */
672 list_delete_node(addr_list, anode);
673 route_unlock_node(rn);
674
675 /* Remove from interface address list
676 * (unconditionally). */
677 if (!CHECK_FLAG(ifc->conf,
678 ZEBRA_IFC_CONFIGURED)) {
679 listnode_delete(ifp->connected,
680 ifc);
681 connected_free(ifc);
682 } else
683 last = node;
684 }
685
686 /* Free chain list and respective route node. */
687 list_delete(&addr_list);
688 rn->info = NULL;
689 route_unlock_node(rn);
690 } else if (cp.family == AF_INET6) {
691 connected_down(ifp, ifc);
692
693 zebra_interface_address_delete_update(ifp, ifc);
694
695 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
696 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
697
698 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
699 last = node;
700 else {
701 listnode_delete(ifp->connected, ifc);
702 connected_free(ifc);
703 }
704 } else {
705 last = node;
706 }
707 }
708 }
709
710 /* Handle an interface delete event */
711 void if_delete_update(struct interface *ifp)
712 {
713 struct zebra_if *zif;
714
715 if (if_is_up(ifp)) {
716 flog_err(
717 EC_LIB_INTERFACE,
718 "interface %s vrf %u index %d is still up while being deleted.",
719 ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
720 return;
721 }
722
723 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
724 return;
725
726 /* Mark interface as inactive */
727 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
728
729 if (IS_ZEBRA_DEBUG_KERNEL)
730 zlog_debug("interface %s vrf %u index %d is now inactive.",
731 ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
732
733 /* Delete connected routes from the kernel. */
734 if_delete_connected(ifp);
735
736 /* Send out notification on interface delete. */
737 zebra_interface_delete_update(ifp);
738
739 if_unlink_per_ns(ifp);
740
741 /* Update ifindex after distributing the delete message. This is in
742 case any client needs to have the old value of ifindex available
743 while processing the deletion. Each client daemon is responsible
744 for setting ifindex to IFINDEX_INTERNAL after processing the
745 interface deletion message. */
746 if_set_index(ifp, IFINDEX_INTERNAL);
747 ifp->node = NULL;
748
749 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
750 * desired. This operation is not done for netns implementation to avoid
751 * collision with interface with the same name in the default vrf (can
752 * occur with this implementation whereas it is not possible with
753 * vrf-lite).
754 */
755 if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
756 if_handle_vrf_change(ifp, VRF_DEFAULT);
757
758 /* Reset some zebra interface params to default values. */
759 zif = ifp->info;
760 if (zif) {
761 zif->zif_type = ZEBRA_IF_OTHER;
762 zif->zif_slave_type = ZEBRA_IF_SLAVE_NONE;
763 memset(&zif->l2info, 0, sizeof(union zebra_l2if_info));
764 memset(&zif->brslave_info, 0,
765 sizeof(struct zebra_l2info_brslave));
766 }
767 }
768
769 /* VRF change for an interface */
770 void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
771 {
772 vrf_id_t old_vrf_id;
773 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
774
775 old_vrf_id = vrf_to_id(ifp->vrf);
776
777 /* Uninstall connected routes. */
778 if_uninstall_connected(ifp);
779
780 /* Delete any IPv4 neighbors created to implement RFC 5549 */
781 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
782
783 /* Delete all neighbor addresses learnt through IPv6 RA */
784 if_down_del_nbr_connected(ifp);
785
786 /* Send out notification on interface VRF change. */
787 /* This is to issue an UPDATE or a DELETE, as appropriate. */
788 zebra_interface_vrf_update_del(ifp, vrf_id);
789
790 /* update VRF */
791 if_update_to_new_vrf(ifp, vrf);
792
793 /* Send out notification on interface VRF change. */
794 /* This is to issue an ADD, if needed. */
795 zebra_interface_vrf_update_add(ifp, old_vrf_id);
796
797 /* Install connected routes (in new VRF). */
798 if (if_is_operative(ifp))
799 if_install_connected(ifp);
800
801 /* Due to connected route change, schedule RIB processing for both old
802 * and new VRF.
803 */
804 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
805 zlog_debug("%u: IF %s VRF change, scheduling RIB processing",
806 vrf_to_id(ifp->vrf), ifp->name);
807 rib_update(old_vrf_id, RIB_UPDATE_IF_CHANGE);
808 rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
809 }
810
811 static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
812 {
813 mac[0] = address->s6_addr[8] ^ 0x02;
814 mac[1] = address->s6_addr[9];
815 mac[2] = address->s6_addr[10];
816 mac[3] = address->s6_addr[13];
817 mac[4] = address->s6_addr[14];
818 mac[5] = address->s6_addr[15];
819 }
820
821 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
822 char mac[6],
823 struct in6_addr *address,
824 int add)
825 {
826 struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
827 struct zebra_if *zif = ifp->info;
828 char buf[16] = "169.254.0.1";
829 struct in_addr ipv4_ll;
830 ns_id_t ns_id;
831
832 inet_pton(AF_INET, buf, &ipv4_ll);
833
834 ns_id = zvrf->zns->ns_id;
835
836 /*
837 * Remove and re-add any existing neighbor entry for this address,
838 * since Netlink doesn't currently offer update message types.
839 */
840 kernel_neigh_update(0, ifp->ifindex, ipv4_ll.s_addr, mac, 6, ns_id);
841
842 /* Add new neighbor entry.
843 *
844 * We force installation even if current neighbor entry is the same.
845 * Since this function is used to refresh our MAC entries after an
846 * interface flap, if we don't force in our custom entries with their
847 * state set to PERMANENT or REACHABLE then the kernel will attempt to
848 * resolve our leftover entries, fail, mark them unreachable and then
849 * they'll be useless to us.
850 */
851 if (add)
852 kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr, mac, 6,
853 ns_id);
854
855 memcpy(&zif->neigh_mac[0], &mac[0], 6);
856
857 /*
858 * We need to note whether or not we originated a v6
859 * neighbor entry for this interface. So that when
860 * someone unwisely accidently deletes this entry
861 * we can shove it back in.
862 */
863 zif->v6_2_v4_ll_neigh_entry = !!add;
864 memcpy(&zif->v6_2_v4_ll_addr6, address, sizeof(*address));
865
866 zvrf->neigh_updates++;
867 }
868
869 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
870 struct in6_addr *address, int add)
871 {
872
873 char mac[6];
874
875 ipv6_ll_address_to_mac(address, (uint8_t *)mac);
876 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
877 }
878
879 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
880 {
881 if (listhead(ifp->nbr_connected)) {
882 struct nbr_connected *nbr_connected;
883 struct listnode *node;
884
885 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
886 nbr_connected))
887 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
888 ifp, &nbr_connected->address->u.prefix6, 1);
889 }
890 }
891
892 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)
893 {
894 if (listhead(ifp->nbr_connected)) {
895 struct nbr_connected *nbr_connected;
896 struct listnode *node;
897
898 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
899 nbr_connected))
900 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
901 ifp, &nbr_connected->address->u.prefix6, 0);
902 }
903 }
904
905 static void if_down_del_nbr_connected(struct interface *ifp)
906 {
907 struct nbr_connected *nbr_connected;
908 struct listnode *node, *nnode;
909
910 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode,
911 nbr_connected)) {
912 listnode_delete(ifp->nbr_connected, nbr_connected);
913 nbr_connected_free(nbr_connected);
914 }
915 }
916
917 /* Interface is up. */
918 void if_up(struct interface *ifp)
919 {
920 struct zebra_if *zif;
921 struct interface *link_if;
922 struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
923
924 zif = ifp->info;
925 zif->up_count++;
926 quagga_timestamp(2, zif->up_last, sizeof(zif->up_last));
927
928 /* Notify the protocol daemons. */
929 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
930 flog_warn(EC_ZEBRA_PTM_NOT_READY,
931 "%s: interface %s hasn't passed ptm check\n",
932 __func__, ifp->name);
933 return;
934 }
935 zebra_interface_up_update(ifp);
936
937 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
938
939 #if defined(HAVE_RTADV)
940 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
941 if (zif->rtadv.AdvSendAdvertisements
942 && (zif->rtadv.MaxRtrAdvInterval >= 1000)) {
943 zif->rtadv.inFastRexmit = 1;
944 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
945 }
946 #endif
947
948 /* Install connected routes to the kernel. */
949 if_install_connected(ifp);
950
951 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
952 zlog_debug("%u: IF %s up, scheduling RIB processing",
953 vrf_to_id(ifp->vrf), ifp->name);
954 rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
955
956 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
957 * are checked to see if (remote) neighbor entries need to be installed
958 * on them for ARP suppression.
959 */
960 if (IS_ZEBRA_IF_VXLAN(ifp))
961 zebra_vxlan_if_up(ifp);
962 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
963 link_if = ifp;
964 zebra_vxlan_svi_up(ifp, link_if);
965 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
966 link_if = if_lookup_by_index_per_ns(zvrf->zns,
967 zif->link_ifindex);
968 if (link_if)
969 zebra_vxlan_svi_up(ifp, link_if);
970 }
971 }
972
973 /* Interface goes down. We have to manage different behavior of based
974 OS. */
975 void if_down(struct interface *ifp)
976 {
977 struct zebra_if *zif;
978 struct interface *link_if;
979 struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
980
981 zif = ifp->info;
982 zif->down_count++;
983 quagga_timestamp(2, zif->down_last, sizeof(zif->down_last));
984
985 /* Handle interface down for specific types for EVPN. Non-VxLAN
986 * interfaces
987 * are checked to see if (remote) neighbor entries need to be purged
988 * for ARP suppression.
989 */
990 if (IS_ZEBRA_IF_VXLAN(ifp))
991 zebra_vxlan_if_down(ifp);
992 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
993 link_if = ifp;
994 zebra_vxlan_svi_down(ifp, link_if);
995 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
996 link_if = if_lookup_by_index_per_ns(zvrf->zns,
997 zif->link_ifindex);
998 if (link_if)
999 zebra_vxlan_svi_down(ifp, link_if);
1000 }
1001
1002
1003 /* Notify to the protocol daemons. */
1004 zebra_interface_down_update(ifp);
1005
1006 /* Uninstall connected routes from the kernel. */
1007 if_uninstall_connected(ifp);
1008
1009 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1010 zlog_debug("%u: IF %s down, scheduling RIB processing",
1011 vrf_to_id(ifp->vrf), ifp->name);
1012 rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
1013
1014 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
1015
1016 /* Delete all neighbor addresses learnt through IPv6 RA */
1017 if_down_del_nbr_connected(ifp);
1018 }
1019
1020 void if_refresh(struct interface *ifp)
1021 {
1022 if_get_flags(ifp);
1023 }
1024
1025 void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1026 ns_id_t ns_id)
1027 {
1028 struct zebra_if *zif;
1029
1030 if (IS_ZEBRA_IF_VETH(ifp))
1031 return;
1032 zif = (struct zebra_if *)ifp->info;
1033 zif->link_ifindex = link_ifindex;
1034 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
1035 link_ifindex);
1036 }
1037
1038 /*
1039 * during initial link dump kernel does not order lower devices before
1040 * upper devices so we need to fixup link dependencies at the end of dump
1041 */
1042 void zebra_if_update_all_links(void)
1043 {
1044 struct route_node *rn;
1045 struct interface *ifp;
1046 struct zebra_if *zif;
1047 struct zebra_ns *ns;
1048
1049 if (IS_ZEBRA_DEBUG_KERNEL)
1050 zlog_info("fixup link dependencies");
1051
1052 ns = zebra_ns_lookup(NS_DEFAULT);
1053 for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
1054 ifp = (struct interface *)rn->info;
1055 if (!ifp)
1056 continue;
1057 zif = ifp->info;
1058 if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
1059 zif->link = if_lookup_by_index_per_ns(ns,
1060 zif->link_ifindex);
1061 if (IS_ZEBRA_DEBUG_KERNEL)
1062 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1063 ifp->name, ifp->ifindex,
1064 zif->link?zif->link->name:"unk",
1065 zif->link_ifindex);
1066 }
1067 }
1068 }
1069
1070 void zebra_if_set_protodown(struct interface *ifp, bool down)
1071 {
1072 #ifdef HAVE_NETLINK
1073 netlink_protodown(ifp, down);
1074 #else
1075 zlog_warn("Protodown is not supported on this platform");
1076 #endif
1077 }
1078
1079 /* Output prefix string to vty. */
1080 static int prefix_vty_out(struct vty *vty, struct prefix *p)
1081 {
1082 char str[INET6_ADDRSTRLEN];
1083
1084 inet_ntop(p->family, &p->u.prefix, str, sizeof(str));
1085 vty_out(vty, "%s", str);
1086 return strlen(str);
1087 }
1088
1089 /* Dump if address information to vty. */
1090 static void connected_dump_vty(struct vty *vty, struct connected *connected)
1091 {
1092 struct prefix *p;
1093
1094 /* Print interface address. */
1095 p = connected->address;
1096 vty_out(vty, " %s ", prefix_family_str(p));
1097 prefix_vty_out(vty, p);
1098 vty_out(vty, "/%d", p->prefixlen);
1099
1100 /* If there is destination address, print it. */
1101 if (connected->destination) {
1102 vty_out(vty,
1103 (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
1104 prefix_vty_out(vty, connected->destination);
1105 if (CONNECTED_PEER(connected))
1106 vty_out(vty, "/%d", connected->destination->prefixlen);
1107 }
1108
1109 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
1110 vty_out(vty, " secondary");
1111
1112 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
1113 vty_out(vty, " unnumbered");
1114
1115 if (connected->label)
1116 vty_out(vty, " %s", connected->label);
1117
1118 vty_out(vty, "\n");
1119 }
1120
1121 /* Dump interface neighbor address information to vty. */
1122 static void nbr_connected_dump_vty(struct vty *vty,
1123 struct nbr_connected *connected)
1124 {
1125 struct prefix *p;
1126
1127 /* Print interface address. */
1128 p = connected->address;
1129 vty_out(vty, " %s ", prefix_family_str(p));
1130 prefix_vty_out(vty, p);
1131 vty_out(vty, "/%d", p->prefixlen);
1132
1133 vty_out(vty, "\n");
1134 }
1135
1136 static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
1137 {
1138 switch (zif_type) {
1139 case ZEBRA_IF_OTHER:
1140 return "Other";
1141 break;
1142
1143 case ZEBRA_IF_BRIDGE:
1144 return "Bridge";
1145 break;
1146
1147 case ZEBRA_IF_VLAN:
1148 return "Vlan";
1149 break;
1150
1151 case ZEBRA_IF_VXLAN:
1152 return "Vxlan";
1153 break;
1154
1155 case ZEBRA_IF_VRF:
1156 return "VRF";
1157 break;
1158
1159 case ZEBRA_IF_VETH:
1160 return "VETH";
1161 break;
1162
1163 case ZEBRA_IF_BOND:
1164 return "bond";
1165
1166 case ZEBRA_IF_BOND_SLAVE:
1167 return "bond_slave";
1168
1169 case ZEBRA_IF_MACVLAN:
1170 return "macvlan";
1171
1172 default:
1173 return "Unknown";
1174 break;
1175 }
1176 }
1177
1178 /* Interface's brief information print out to vty interface. */
1179 static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
1180 {
1181 struct connected *connected;
1182 struct listnode *node;
1183 struct route_node *rn;
1184 struct zebra_if *zebra_if;
1185 struct prefix *p;
1186 struct interface *ifp;
1187 bool print_header = true;
1188
1189 FOR_ALL_INTERFACES (vrf, ifp) {
1190 char global_pfx[PREFIX_STRLEN] = {0};
1191 char buf[PREFIX_STRLEN] = {0};
1192 bool first_pfx_printed = false;
1193
1194 if (print_header) {
1195 vty_out(vty, "%-16s%-8s%-16s%s\n", "Interface",
1196 "Status", "VRF", "Addresses");
1197 vty_out(vty, "%-16s%-8s%-16s%s\n", "---------",
1198 "------", "---", "---------");
1199 print_header = false; /* We have at least 1 iface */
1200 }
1201 zebra_if = ifp->info;
1202
1203 vty_out(vty, "%-16s", ifp->name);
1204
1205 if (if_is_up(ifp))
1206 vty_out(vty, "%-8s", "up");
1207 else
1208 vty_out(vty, "%-8s", "down");
1209
1210 vty_out(vty, "%-16s", vrf->name);
1211
1212 for (rn = route_top(zebra_if->ipv4_subnets); rn;
1213 rn = route_next(rn)) {
1214 if (!rn->info)
1215 continue;
1216 uint32_t list_size = listcount((struct list *)rn->info);
1217
1218 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1219 connected)) {
1220 if (!CHECK_FLAG(connected->flags,
1221 ZEBRA_IFA_SECONDARY)) {
1222 p = connected->address;
1223 prefix2str(p, buf, sizeof(buf));
1224 if (first_pfx_printed) {
1225 /* padding to prepare row only for ip addr */
1226 vty_out(vty, "%-40s", "");
1227 if (list_size > 1)
1228 vty_out(vty, "+ ");
1229 vty_out(vty, "%s\n", buf);
1230 } else {
1231 if (list_size > 1)
1232 vty_out(vty, "+ ");
1233 vty_out(vty, "%s\n", buf);
1234 }
1235 first_pfx_printed = true;
1236 break;
1237 }
1238 }
1239 }
1240
1241 uint32_t v6_list_size = 0;
1242 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1243 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1244 && (connected->address->family == AF_INET6))
1245 v6_list_size++;
1246 }
1247 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1248 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1249 && !CHECK_FLAG(connected->flags,
1250 ZEBRA_IFA_SECONDARY)
1251 && (connected->address->family == AF_INET6)) {
1252 p = connected->address;
1253 /* Don't print link local pfx */
1254 if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
1255 prefix2str(p, global_pfx, PREFIX_STRLEN);
1256 if (first_pfx_printed) {
1257 /* padding to prepare row only for ip addr */
1258 vty_out(vty, "%-40s", "");
1259 if (v6_list_size > 1)
1260 vty_out(vty, "+ ");
1261 vty_out(vty, "%s\n", global_pfx);
1262 } else {
1263 if (v6_list_size > 1)
1264 vty_out(vty, "+ ");
1265 vty_out(vty, "%s\n", global_pfx);
1266 }
1267 first_pfx_printed = true;
1268 break;
1269 }
1270 }
1271 }
1272 if (!first_pfx_printed)
1273 vty_out(vty, "\n");
1274 }
1275 vty_out(vty, "\n");
1276 }
1277
1278 /* Interface's information print out to vty interface. */
1279 static void if_dump_vty(struct vty *vty, struct interface *ifp)
1280 {
1281 struct connected *connected;
1282 struct nbr_connected *nbr_connected;
1283 struct listnode *node;
1284 struct route_node *rn;
1285 struct zebra_if *zebra_if;
1286 struct vrf *vrf;
1287
1288 zebra_if = ifp->info;
1289
1290 vty_out(vty, "Interface %s is ", ifp->name);
1291 if (if_is_up(ifp)) {
1292 vty_out(vty, "up, line protocol ");
1293
1294 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1295 if (if_is_running(ifp))
1296 vty_out(vty, "is up\n");
1297 else
1298 vty_out(vty, "is down\n");
1299 } else {
1300 vty_out(vty, "detection is disabled\n");
1301 }
1302 } else {
1303 vty_out(vty, "down\n");
1304 }
1305
1306 vty_out(vty, " Link ups: %5u last: %s\n", zebra_if->up_count,
1307 zebra_if->up_last[0] ? zebra_if->up_last : "(never)");
1308 vty_out(vty, " Link downs: %5u last: %s\n", zebra_if->down_count,
1309 zebra_if->down_last[0] ? zebra_if->down_last : "(never)");
1310
1311 zebra_ptm_show_status(vty, ifp);
1312
1313 vrf = ifp->vrf;
1314 vty_out(vty, " vrf: %s\n", vrf->name);
1315
1316 if (ifp->desc)
1317 vty_out(vty, " Description: %s\n", ifp->desc);
1318 if (zebra_if->desc)
1319 vty_out(vty, " OS Description: %s\n", zebra_if->desc);
1320
1321 if (ifp->ifindex == IFINDEX_INTERNAL) {
1322 vty_out(vty, " pseudo interface\n");
1323 return;
1324 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1325 vty_out(vty, " index %d inactive interface\n", ifp->ifindex);
1326 return;
1327 }
1328
1329 vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
1330 ifp->metric, ifp->mtu, ifp->speed);
1331 if (ifp->mtu6 != ifp->mtu)
1332 vty_out(vty, "mtu6 %d ", ifp->mtu6);
1333 vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
1334
1335 /* Hardware address. */
1336 vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
1337 if (ifp->hw_addr_len != 0) {
1338 int i;
1339
1340 vty_out(vty, " HWaddr: ");
1341 for (i = 0; i < ifp->hw_addr_len; i++)
1342 vty_out(vty, "%s%02x", i == 0 ? "" : ":",
1343 ifp->hw_addr[i]);
1344 vty_out(vty, "\n");
1345 }
1346
1347 /* Bandwidth in Mbps */
1348 if (ifp->bandwidth != 0) {
1349 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1350 vty_out(vty, "\n");
1351 }
1352
1353 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
1354 if (!rn->info)
1355 continue;
1356
1357 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1358 connected))
1359 connected_dump_vty(vty, connected);
1360 }
1361
1362 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1363 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1364 && (connected->address->family == AF_INET6))
1365 connected_dump_vty(vty, connected);
1366 }
1367
1368 vty_out(vty, " Interface Type %s\n",
1369 zebra_ziftype_2str(zebra_if->zif_type));
1370 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1371 struct zebra_l2info_bridge *bridge_info;
1372
1373 bridge_info = &zebra_if->l2info.br;
1374 vty_out(vty, " Bridge VLAN-aware: %s\n",
1375 bridge_info->vlan_aware ? "yes" : "no");
1376 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1377 struct zebra_l2info_vlan *vlan_info;
1378
1379 vlan_info = &zebra_if->l2info.vl;
1380 vty_out(vty, " VLAN Id %u\n", vlan_info->vid);
1381 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
1382 struct zebra_l2info_vxlan *vxlan_info;
1383
1384 vxlan_info = &zebra_if->l2info.vxl;
1385 vty_out(vty, " VxLAN Id %u", vxlan_info->vni);
1386 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
1387 vty_out(vty, " VTEP IP: %s",
1388 inet_ntoa(vxlan_info->vtep_ip));
1389 if (vxlan_info->access_vlan)
1390 vty_out(vty, " Access VLAN Id %u\n",
1391 vxlan_info->access_vlan);
1392 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
1393 vty_out(vty, " Mcast Group %s",
1394 inet_ntoa(vxlan_info->mcast_grp));
1395 vty_out(vty, "\n");
1396 }
1397
1398 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
1399 struct zebra_l2info_brslave *br_slave;
1400
1401 br_slave = &zebra_if->brslave_info;
1402 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL)
1403 vty_out(vty, " Master (bridge) ifindex %u\n",
1404 br_slave->bridge_ifindex);
1405 }
1406
1407 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
1408 struct zebra_l2info_bondslave *bond_slave;
1409
1410 bond_slave = &zebra_if->bondslave_info;
1411 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL)
1412 vty_out(vty, " Master (bond) ifindex %u\n",
1413 bond_slave->bond_ifindex);
1414 }
1415
1416 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
1417 vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
1418 if (zebra_if->link)
1419 vty_out(vty, "(%s)\n", zebra_if->link->name);
1420 else
1421 vty_out(vty, "(Unknown)\n");
1422 }
1423
1424 if (HAS_LINK_PARAMS(ifp)) {
1425 int i;
1426 struct if_link_params *iflp = ifp->link_params;
1427 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1428 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1429 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1430 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1431 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1432 iflp->max_bw);
1433 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1434 vty_out(vty,
1435 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1436 iflp->max_rsv_bw);
1437 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1438 vty_out(vty,
1439 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1440 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1441 vty_out(vty,
1442 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1443 i, iflp->unrsv_bw[i], i + 1,
1444 iflp->unrsv_bw[i + 1]);
1445 }
1446
1447 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1448 vty_out(vty, " Administrative Group:%u\n",
1449 iflp->admin_grp);
1450 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1451 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1452 iflp->av_delay);
1453 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1454 vty_out(vty, " Min: %u (micro-sec.)",
1455 iflp->min_delay);
1456 vty_out(vty, " Max: %u (micro-sec.)",
1457 iflp->max_delay);
1458 }
1459 vty_out(vty, "\n");
1460 }
1461 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1462 vty_out(vty,
1463 " Link Delay Variation %u (micro-sec.)\n",
1464 iflp->delay_var);
1465 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1466 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1467 iflp->pkt_loss);
1468 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1469 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1470 iflp->ava_bw);
1471 if (IS_PARAM_SET(iflp, LP_RES_BW))
1472 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1473 iflp->res_bw);
1474 if (IS_PARAM_SET(iflp, LP_USE_BW))
1475 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1476 iflp->use_bw);
1477 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1478 vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n",
1479 inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
1480 }
1481
1482 hook_call(zebra_if_extra_info, vty, ifp);
1483
1484 if (listhead(ifp->nbr_connected))
1485 vty_out(vty, " Neighbor address(s):\n");
1486 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
1487 nbr_connected_dump_vty(vty, nbr_connected);
1488
1489 #ifdef HAVE_PROC_NET_DEV
1490 /* Statistics print out using proc file system. */
1491 vty_out(vty,
1492 " %lu input packets (%lu multicast), %lu bytes, "
1493 "%lu dropped\n",
1494 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1495 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1496
1497 vty_out(vty,
1498 " %lu input errors, %lu length, %lu overrun,"
1499 " %lu CRC, %lu frame\n",
1500 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1501 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1502 ifp->stats.rx_frame_errors);
1503
1504 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1505 ifp->stats.rx_missed_errors);
1506
1507 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1508 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1509 ifp->stats.tx_dropped);
1510
1511 vty_out(vty,
1512 " %lu output errors, %lu aborted, %lu carrier,"
1513 " %lu fifo, %lu heartbeat\n",
1514 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1515 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1516 ifp->stats.tx_heartbeat_errors);
1517
1518 vty_out(vty, " %lu window, %lu collisions\n",
1519 ifp->stats.tx_window_errors, ifp->stats.collisions);
1520 #endif /* HAVE_PROC_NET_DEV */
1521
1522 #ifdef HAVE_NET_RT_IFLIST
1523 #if defined(__bsdi__) || defined(__NetBSD__)
1524 /* Statistics print out using sysctl (). */
1525 vty_out(vty,
1526 " input packets %llu, bytes %llu, dropped %llu,"
1527 " multicast packets %llu\n",
1528 (unsigned long long)ifp->stats.ifi_ipackets,
1529 (unsigned long long)ifp->stats.ifi_ibytes,
1530 (unsigned long long)ifp->stats.ifi_iqdrops,
1531 (unsigned long long)ifp->stats.ifi_imcasts);
1532
1533 vty_out(vty, " input errors %llu\n",
1534 (unsigned long long)ifp->stats.ifi_ierrors);
1535
1536 vty_out(vty,
1537 " output packets %llu, bytes %llu,"
1538 " multicast packets %llu\n",
1539 (unsigned long long)ifp->stats.ifi_opackets,
1540 (unsigned long long)ifp->stats.ifi_obytes,
1541 (unsigned long long)ifp->stats.ifi_omcasts);
1542
1543 vty_out(vty, " output errors %llu\n",
1544 (unsigned long long)ifp->stats.ifi_oerrors);
1545
1546 vty_out(vty, " collisions %llu\n",
1547 (unsigned long long)ifp->stats.ifi_collisions);
1548 #else
1549 /* Statistics print out using sysctl (). */
1550 vty_out(vty,
1551 " input packets %lu, bytes %lu, dropped %lu,"
1552 " multicast packets %lu\n",
1553 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1554 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts);
1555
1556 vty_out(vty, " input errors %lu\n", ifp->stats.ifi_ierrors);
1557
1558 vty_out(vty,
1559 " output packets %lu, bytes %lu, multicast packets %lu\n",
1560 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1561 ifp->stats.ifi_omcasts);
1562
1563 vty_out(vty, " output errors %lu\n", ifp->stats.ifi_oerrors);
1564
1565 vty_out(vty, " collisions %lu\n", ifp->stats.ifi_collisions);
1566 #endif /* __bsdi__ || __NetBSD__ */
1567 #endif /* HAVE_NET_RT_IFLIST */
1568 }
1569
1570 static void interface_update_stats(void)
1571 {
1572 #ifdef HAVE_PROC_NET_DEV
1573 /* If system has interface statistics via proc file system, update
1574 statistics. */
1575 ifstat_update_proc();
1576 #endif /* HAVE_PROC_NET_DEV */
1577 #ifdef HAVE_NET_RT_IFLIST
1578 ifstat_update_sysctl();
1579 #endif /* HAVE_NET_RT_IFLIST */
1580 }
1581
1582 struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
1583
1584 #ifndef VTYSH_EXTRACT_PL
1585 #include "zebra/interface_clippy.c"
1586 #endif
1587 /* Show all interfaces to vty. */
1588 DEFPY(show_interface, show_interface_cmd,
1589 "show interface [vrf NAME$name] [brief$brief]",
1590 SHOW_STR
1591 "Interface status and configuration\n"
1592 VRF_CMD_HELP_STR
1593 "Interface status and configuration summary\n")
1594 {
1595 struct vrf *vrf = NULL;
1596 struct interface *ifp;
1597
1598 interface_update_stats();
1599
1600 if (name)
1601 VRF_GET_INSTANCE(vrf, name, false, false);
1602
1603 /* All interface print. */
1604 if (brief) {
1605 ifs_dump_brief_vty(vty, vrf);
1606 } else {
1607 FOR_ALL_INTERFACES (vrf, ifp) {
1608 if_dump_vty(vty, ifp);
1609 }
1610 }
1611
1612 return CMD_SUCCESS;
1613 }
1614
1615
1616 /* Show all interfaces to vty. */
1617 DEFUN (show_interface_vrf_all,
1618 show_interface_vrf_all_cmd,
1619 "show interface vrf all",
1620 SHOW_STR
1621 "Interface status and configuration\n"
1622 VRF_ALL_CMD_HELP_STR)
1623 {
1624 struct vrf *vrf;
1625 struct interface *ifp;
1626
1627 interface_update_stats();
1628
1629 /* All interface print. */
1630 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1631 FOR_ALL_INTERFACES (vrf, ifp)
1632 if_dump_vty(vty, ifp);
1633
1634 return CMD_SUCCESS;
1635 }
1636
1637 /* Show specified interface to vty. */
1638
1639 DEFUN (show_interface_name_vrf,
1640 show_interface_name_vrf_cmd,
1641 "show interface IFNAME vrf NAME",
1642 SHOW_STR
1643 "Interface status and configuration\n"
1644 "Interface name\n"
1645 VRF_CMD_HELP_STR)
1646 {
1647 int idx_ifname = 2;
1648 int idx_name = 4;
1649 struct interface *ifp;
1650 struct vrf *vrf;
1651
1652 interface_update_stats();
1653
1654 VRF_GET_INSTANCE(vrf, argv[idx_name]->arg, false, false);
1655
1656 /* Specified interface print. */
1657 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf);
1658 if (ifp == NULL) {
1659 vty_out(vty, "%% Can't find interface %s\n",
1660 argv[idx_ifname]->arg);
1661 return CMD_WARNING;
1662 }
1663 if_dump_vty(vty, ifp);
1664
1665 return CMD_SUCCESS;
1666 }
1667
1668 /* Show specified interface to vty. */
1669 DEFUN (show_interface_name_vrf_all,
1670 show_interface_name_vrf_all_cmd,
1671 "show interface IFNAME [vrf all]",
1672 SHOW_STR
1673 "Interface status and configuration\n"
1674 "Interface name\n"
1675 VRF_ALL_CMD_HELP_STR)
1676 {
1677 int idx_ifname = 2;
1678 struct vrf *vrf;
1679 struct interface *ifp;
1680 int found = 0;
1681
1682 interface_update_stats();
1683
1684 /* All interface print. */
1685 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1686 /* Specified interface print. */
1687 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf);
1688 if (ifp) {
1689 if_dump_vty(vty, ifp);
1690 found++;
1691 }
1692 }
1693
1694 if (!found) {
1695 vty_out(vty, "%% Can't find interface %s\n",
1696 argv[idx_ifname]->arg);
1697 return CMD_WARNING;
1698 }
1699
1700 return CMD_SUCCESS;
1701 }
1702
1703
1704 static void if_show_description(struct vty *vty, struct vrf *vrf)
1705 {
1706 struct interface *ifp;
1707
1708 vty_out(vty, "Interface Status Protocol Description\n");
1709 FOR_ALL_INTERFACES (vrf, ifp) {
1710 int len;
1711 struct zebra_if *zif;
1712 bool intf_desc;
1713
1714 intf_desc = false;
1715
1716 len = vty_out(vty, "%s", ifp->name);
1717 vty_out(vty, "%*s", (16 - len), " ");
1718
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 ");
1725 else
1726 vty_out(vty, "down ");
1727 } else {
1728 vty_out(vty, "unknown ");
1729 }
1730 } else {
1731 vty_out(vty, "down down ");
1732 }
1733
1734 if (ifp->desc) {
1735 intf_desc = true;
1736 vty_out(vty, "%s", ifp->desc);
1737 }
1738 zif = ifp->info;
1739 if (zif && zif->desc) {
1740 vty_out(vty, "%s%s",
1741 intf_desc
1742 ? "\n "
1743 : "",
1744 zif->desc);
1745 }
1746
1747 vty_out(vty, "\n");
1748 }
1749 }
1750
1751 DEFUN (show_interface_desc,
1752 show_interface_desc_cmd,
1753 "show interface description [vrf NAME]",
1754 SHOW_STR
1755 "Interface status and configuration\n"
1756 "Interface description\n"
1757 VRF_CMD_HELP_STR)
1758 {
1759 struct vrf *vrf;
1760
1761 if (argc > 3)
1762 VRF_GET_INSTANCE(vrf, argv[4]->arg, false, false);
1763 else
1764 vrf = vrf_lookup_by_id(VRF_DEFAULT);
1765
1766 if_show_description(vty, vrf);
1767
1768 return CMD_SUCCESS;
1769 }
1770
1771
1772 DEFUN (show_interface_desc_vrf_all,
1773 show_interface_desc_vrf_all_cmd,
1774 "show interface description vrf all",
1775 SHOW_STR
1776 "Interface status and configuration\n"
1777 "Interface description\n"
1778 VRF_ALL_CMD_HELP_STR)
1779 {
1780 struct vrf *vrf;
1781
1782 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1783 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
1784 vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
1785 if_show_description(vty, vrf);
1786 }
1787
1788 return CMD_SUCCESS;
1789 }
1790
1791 DEFUN (multicast,
1792 multicast_cmd,
1793 "multicast",
1794 "Set multicast flag to interface\n")
1795 {
1796 VTY_DECLVAR_CONTEXT(interface, ifp);
1797 int ret;
1798 struct zebra_if *if_data;
1799
1800 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1801 ret = if_set_flags(ifp, IFF_MULTICAST);
1802 if (ret < 0) {
1803 vty_out(vty, "Can't set multicast flag\n");
1804 return CMD_WARNING_CONFIG_FAILED;
1805 }
1806 if_refresh(ifp);
1807 }
1808 if_data = ifp->info;
1809 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
1810
1811 return CMD_SUCCESS;
1812 }
1813
1814 DEFUN (no_multicast,
1815 no_multicast_cmd,
1816 "no multicast",
1817 NO_STR
1818 "Unset multicast flag to interface\n")
1819 {
1820 VTY_DECLVAR_CONTEXT(interface, ifp);
1821 int ret;
1822 struct zebra_if *if_data;
1823
1824 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1825 ret = if_unset_flags(ifp, IFF_MULTICAST);
1826 if (ret < 0) {
1827 vty_out(vty, "Can't unset multicast flag\n");
1828 return CMD_WARNING_CONFIG_FAILED;
1829 }
1830 if_refresh(ifp);
1831 }
1832 if_data = ifp->info;
1833 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1834
1835 return CMD_SUCCESS;
1836 }
1837
1838 DEFUN (linkdetect,
1839 linkdetect_cmd,
1840 "link-detect",
1841 "Enable link detection on interface\n")
1842 {
1843 VTY_DECLVAR_CONTEXT(interface, ifp);
1844 int if_was_operative;
1845
1846 if_was_operative = if_is_no_ptm_operative(ifp);
1847 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1848
1849 /* When linkdetection is enabled, if might come down */
1850 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
1851 if_down(ifp);
1852
1853 /* FIXME: Will defer status change forwarding if interface
1854 does not come down! */
1855
1856 return CMD_SUCCESS;
1857 }
1858
1859
1860 DEFUN (no_linkdetect,
1861 no_linkdetect_cmd,
1862 "no link-detect",
1863 NO_STR
1864 "Disable link detection on interface\n")
1865 {
1866 VTY_DECLVAR_CONTEXT(interface, ifp);
1867 int if_was_operative;
1868
1869 if_was_operative = if_is_no_ptm_operative(ifp);
1870 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1871
1872 /* Interface may come up after disabling link detection */
1873 if (if_is_operative(ifp) && !if_was_operative)
1874 if_up(ifp);
1875
1876 /* FIXME: see linkdetect_cmd */
1877
1878 return CMD_SUCCESS;
1879 }
1880
1881 DEFUN (shutdown_if,
1882 shutdown_if_cmd,
1883 "shutdown",
1884 "Shutdown the selected interface\n")
1885 {
1886 VTY_DECLVAR_CONTEXT(interface, ifp);
1887 int ret;
1888 struct zebra_if *if_data;
1889
1890 if (ifp->ifindex != IFINDEX_INTERNAL) {
1891 ret = if_unset_flags(ifp, IFF_UP);
1892 if (ret < 0) {
1893 vty_out(vty, "Can't shutdown interface\n");
1894 return CMD_WARNING_CONFIG_FAILED;
1895 }
1896 if_refresh(ifp);
1897 }
1898 if_data = ifp->info;
1899 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1900
1901 return CMD_SUCCESS;
1902 }
1903
1904 DEFUN (no_shutdown_if,
1905 no_shutdown_if_cmd,
1906 "no shutdown",
1907 NO_STR
1908 "Shutdown the selected interface\n")
1909 {
1910 VTY_DECLVAR_CONTEXT(interface, ifp);
1911 int ret;
1912 struct zebra_if *if_data;
1913
1914 if (ifp->ifindex != IFINDEX_INTERNAL) {
1915 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
1916 if (ret < 0) {
1917 vty_out(vty, "Can't up interface\n");
1918 return CMD_WARNING_CONFIG_FAILED;
1919 }
1920 if_refresh(ifp);
1921
1922 /* Some addresses (in particular, IPv6 addresses on Linux) get
1923 * removed when the interface goes down. They need to be
1924 * readded.
1925 */
1926 if_addr_wakeup(ifp);
1927 }
1928
1929 if_data = ifp->info;
1930 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1931
1932 return CMD_SUCCESS;
1933 }
1934
1935 DEFUN (bandwidth_if,
1936 bandwidth_if_cmd,
1937 "bandwidth (1-100000)",
1938 "Set bandwidth informational parameter\n"
1939 "Bandwidth in megabits\n")
1940 {
1941 int idx_number = 1;
1942 VTY_DECLVAR_CONTEXT(interface, ifp);
1943 unsigned int bandwidth;
1944
1945 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1946
1947 /* bandwidth range is <1-100000> */
1948 if (bandwidth < 1 || bandwidth > 100000) {
1949 vty_out(vty, "Bandwidth is invalid\n");
1950 return CMD_WARNING_CONFIG_FAILED;
1951 }
1952
1953 ifp->bandwidth = bandwidth;
1954
1955 /* force protocols to recalculate routes due to cost change */
1956 if (if_is_operative(ifp))
1957 zebra_interface_up_update(ifp);
1958
1959 return CMD_SUCCESS;
1960 }
1961
1962 DEFUN (no_bandwidth_if,
1963 no_bandwidth_if_cmd,
1964 "no bandwidth [(1-100000)]",
1965 NO_STR
1966 "Set bandwidth informational parameter\n"
1967 "Bandwidth in megabits\n")
1968 {
1969 VTY_DECLVAR_CONTEXT(interface, ifp);
1970
1971 ifp->bandwidth = 0;
1972
1973 /* force protocols to recalculate routes due to cost change */
1974 if (if_is_operative(ifp))
1975 zebra_interface_up_update(ifp);
1976
1977 return CMD_SUCCESS;
1978 }
1979
1980
1981 struct cmd_node link_params_node = {
1982 LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,
1983 };
1984
1985 static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1986 uint32_t type, uint32_t value)
1987 {
1988 /* Update field as needed */
1989 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1990 *field = value;
1991 SET_PARAM(ifp->link_params, type);
1992
1993 /* force protocols to update LINK STATE due to parameters change
1994 */
1995 if (if_is_operative(ifp))
1996 zebra_interface_parameters_update(ifp);
1997 }
1998 }
1999 static void link_param_cmd_set_float(struct interface *ifp, float *field,
2000 uint32_t type, float value)
2001 {
2002
2003 /* Update field as needed */
2004 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
2005 *field = value;
2006 SET_PARAM(ifp->link_params, type);
2007
2008 /* force protocols to update LINK STATE due to parameters change
2009 */
2010 if (if_is_operative(ifp))
2011 zebra_interface_parameters_update(ifp);
2012 }
2013 }
2014
2015 static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
2016 {
2017 if (ifp->link_params == NULL)
2018 return;
2019
2020 /* Unset field */
2021 UNSET_PARAM(ifp->link_params, type);
2022
2023 /* force protocols to update LINK STATE due to parameters change */
2024 if (if_is_operative(ifp))
2025 zebra_interface_parameters_update(ifp);
2026 }
2027
2028 DEFUN_NOSH (link_params,
2029 link_params_cmd,
2030 "link-params",
2031 LINK_PARAMS_STR)
2032 {
2033 /* vty->qobj_index stays the same @ interface pointer */
2034 vty->node = LINK_PARAMS_NODE;
2035
2036 return CMD_SUCCESS;
2037 }
2038
2039 DEFUN_NOSH (exit_link_params,
2040 exit_link_params_cmd,
2041 "exit-link-params",
2042 "Exit from Link Params configuration mode\n")
2043 {
2044 if (vty->node == LINK_PARAMS_NODE)
2045 vty->node = INTERFACE_NODE;
2046 return CMD_SUCCESS;
2047 }
2048
2049 /* Specific Traffic Engineering parameters commands */
2050 DEFUN (link_params_enable,
2051 link_params_enable_cmd,
2052 "enable",
2053 "Activate link parameters on this interface\n")
2054 {
2055 VTY_DECLVAR_CONTEXT(interface, ifp);
2056
2057 /* This command could be issue at startup, when activate MPLS TE */
2058 /* on a new interface or after a ON / OFF / ON toggle */
2059 /* In all case, TE parameters are reset to their default factory */
2060 if (IS_ZEBRA_DEBUG_EVENT)
2061 zlog_debug(
2062 "Link-params: enable TE link parameters on interface %s",
2063 ifp->name);
2064
2065 if (!if_link_params_get(ifp)) {
2066 if (IS_ZEBRA_DEBUG_EVENT)
2067 zlog_debug(
2068 "Link-params: failed to init TE link parameters %s",
2069 ifp->name);
2070
2071 return CMD_WARNING_CONFIG_FAILED;
2072 }
2073
2074 /* force protocols to update LINK STATE due to parameters change */
2075 if (if_is_operative(ifp))
2076 zebra_interface_parameters_update(ifp);
2077
2078 return CMD_SUCCESS;
2079 }
2080
2081 DEFUN (no_link_params_enable,
2082 no_link_params_enable_cmd,
2083 "no enable",
2084 NO_STR
2085 "Disable link parameters on this interface\n")
2086 {
2087 VTY_DECLVAR_CONTEXT(interface, ifp);
2088
2089 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2090 ifp->name);
2091
2092 if_link_params_free(ifp);
2093
2094 /* force protocols to update LINK STATE due to parameters change */
2095 if (if_is_operative(ifp))
2096 zebra_interface_parameters_update(ifp);
2097
2098 return CMD_SUCCESS;
2099 }
2100
2101 /* STANDARD TE metrics */
2102 DEFUN (link_params_metric,
2103 link_params_metric_cmd,
2104 "metric (0-4294967295)",
2105 "Link metric for MPLS-TE purpose\n"
2106 "Metric value in decimal\n")
2107 {
2108 int idx_number = 1;
2109 VTY_DECLVAR_CONTEXT(interface, ifp);
2110 struct if_link_params *iflp = if_link_params_get(ifp);
2111 uint32_t metric;
2112
2113 metric = strtoul(argv[idx_number]->arg, NULL, 10);
2114
2115 /* Update TE metric if needed */
2116 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
2117
2118 return CMD_SUCCESS;
2119 }
2120
2121 DEFUN (no_link_params_metric,
2122 no_link_params_metric_cmd,
2123 "no metric",
2124 NO_STR
2125 "Disable Link Metric on this interface\n")
2126 {
2127 VTY_DECLVAR_CONTEXT(interface, ifp);
2128
2129 /* Unset TE Metric */
2130 link_param_cmd_unset(ifp, LP_TE_METRIC);
2131
2132 return CMD_SUCCESS;
2133 }
2134
2135 DEFUN (link_params_maxbw,
2136 link_params_maxbw_cmd,
2137 "max-bw BANDWIDTH",
2138 "Maximum bandwidth that can be used\n"
2139 "Bytes/second (IEEE floating point format)\n")
2140 {
2141 int idx_bandwidth = 1;
2142 VTY_DECLVAR_CONTEXT(interface, ifp);
2143 struct if_link_params *iflp = if_link_params_get(ifp);
2144
2145 float bw;
2146
2147 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2148 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
2149 safe_strerror(errno));
2150 return CMD_WARNING_CONFIG_FAILED;
2151 }
2152
2153 /* Check that Maximum bandwidth is not lower than other bandwidth
2154 * parameters */
2155 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
2156 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
2157 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
2158 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
2159 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
2160 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
2161 vty_out(vty,
2162 "Maximum Bandwidth could not be lower than others bandwidth\n");
2163 return CMD_WARNING_CONFIG_FAILED;
2164 }
2165
2166 /* Update Maximum Bandwidth if needed */
2167 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
2168
2169 return CMD_SUCCESS;
2170 }
2171
2172 DEFUN (link_params_max_rsv_bw,
2173 link_params_max_rsv_bw_cmd,
2174 "max-rsv-bw BANDWIDTH",
2175 "Maximum bandwidth that may be reserved\n"
2176 "Bytes/second (IEEE floating point format)\n")
2177 {
2178 int idx_bandwidth = 1;
2179 VTY_DECLVAR_CONTEXT(interface, ifp);
2180 struct if_link_params *iflp = if_link_params_get(ifp);
2181 float bw;
2182
2183 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2184 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
2185 safe_strerror(errno));
2186 return CMD_WARNING_CONFIG_FAILED;
2187 }
2188
2189 /* Check that bandwidth is not greater than maximum bandwidth parameter
2190 */
2191 if (bw > iflp->max_bw) {
2192 vty_out(vty,
2193 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2194 iflp->max_bw);
2195 return CMD_WARNING_CONFIG_FAILED;
2196 }
2197
2198 /* Update Maximum Reservable Bandwidth if needed */
2199 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
2200
2201 return CMD_SUCCESS;
2202 }
2203
2204 DEFUN (link_params_unrsv_bw,
2205 link_params_unrsv_bw_cmd,
2206 "unrsv-bw (0-7) BANDWIDTH",
2207 "Unreserved bandwidth at each priority level\n"
2208 "Priority\n"
2209 "Bytes/second (IEEE floating point format)\n")
2210 {
2211 int idx_number = 1;
2212 int idx_bandwidth = 2;
2213 VTY_DECLVAR_CONTEXT(interface, ifp);
2214 struct if_link_params *iflp = if_link_params_get(ifp);
2215 int priority;
2216 float bw;
2217
2218 /* We don't have to consider about range check here. */
2219 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2220 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2221 safe_strerror(errno));
2222 return CMD_WARNING_CONFIG_FAILED;
2223 }
2224
2225 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2226 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2227 safe_strerror(errno));
2228 return CMD_WARNING_CONFIG_FAILED;
2229 }
2230
2231 /* Check that bandwidth is not greater than maximum bandwidth parameter
2232 */
2233 if (bw > iflp->max_bw) {
2234 vty_out(vty,
2235 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2236 iflp->max_bw);
2237 return CMD_WARNING_CONFIG_FAILED;
2238 }
2239
2240 /* Update Unreserved Bandwidth if needed */
2241 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2242 bw);
2243
2244 return CMD_SUCCESS;
2245 }
2246
2247 DEFUN (link_params_admin_grp,
2248 link_params_admin_grp_cmd,
2249 "admin-grp BITPATTERN",
2250 "Administrative group membership\n"
2251 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2252 {
2253 int idx_bitpattern = 1;
2254 VTY_DECLVAR_CONTEXT(interface, ifp);
2255 struct if_link_params *iflp = if_link_params_get(ifp);
2256 unsigned long value;
2257
2258 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2259 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2260 safe_strerror(errno));
2261 return CMD_WARNING_CONFIG_FAILED;
2262 }
2263
2264 /* Update Administrative Group if needed */
2265 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
2266
2267 return CMD_SUCCESS;
2268 }
2269
2270 DEFUN (no_link_params_admin_grp,
2271 no_link_params_admin_grp_cmd,
2272 "no admin-grp",
2273 NO_STR
2274 "Disable Administrative group membership on this interface\n")
2275 {
2276 VTY_DECLVAR_CONTEXT(interface, ifp);
2277
2278 /* Unset Admin Group */
2279 link_param_cmd_unset(ifp, LP_ADM_GRP);
2280
2281 return CMD_SUCCESS;
2282 }
2283
2284 /* RFC5392 & RFC5316: INTER-AS */
2285 DEFUN (link_params_inter_as,
2286 link_params_inter_as_cmd,
2287 "neighbor A.B.C.D as (1-4294967295)",
2288 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2289 "Remote IP address in dot decimal A.B.C.D\n"
2290 "Remote AS number\n"
2291 "AS number in the range <1-4294967295>\n")
2292 {
2293 int idx_ipv4 = 1;
2294 int idx_number = 3;
2295
2296 VTY_DECLVAR_CONTEXT(interface, ifp);
2297 struct if_link_params *iflp = if_link_params_get(ifp);
2298 struct in_addr addr;
2299 uint32_t as;
2300
2301 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2302 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2303 return CMD_WARNING_CONFIG_FAILED;
2304 }
2305
2306 as = strtoul(argv[idx_number]->arg, NULL, 10);
2307
2308 /* Update Remote IP and Remote AS fields if needed */
2309 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2310 || iflp->rmt_ip.s_addr != addr.s_addr) {
2311
2312 iflp->rmt_as = as;
2313 iflp->rmt_ip.s_addr = addr.s_addr;
2314 SET_PARAM(iflp, LP_RMT_AS);
2315
2316 /* force protocols to update LINK STATE due to parameters change
2317 */
2318 if (if_is_operative(ifp))
2319 zebra_interface_parameters_update(ifp);
2320 }
2321 return CMD_SUCCESS;
2322 }
2323
2324 DEFUN (no_link_params_inter_as,
2325 no_link_params_inter_as_cmd,
2326 "no neighbor",
2327 NO_STR
2328 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2329 {
2330 VTY_DECLVAR_CONTEXT(interface, ifp);
2331 struct if_link_params *iflp = if_link_params_get(ifp);
2332
2333 /* Reset Remote IP and AS neighbor */
2334 iflp->rmt_as = 0;
2335 iflp->rmt_ip.s_addr = 0;
2336 UNSET_PARAM(iflp, LP_RMT_AS);
2337
2338 /* force protocols to update LINK STATE due to parameters change */
2339 if (if_is_operative(ifp))
2340 zebra_interface_parameters_update(ifp);
2341
2342 return CMD_SUCCESS;
2343 }
2344
2345 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2346 * draft-ietf-isis-metric-extensions-07.txt */
2347 DEFUN (link_params_delay,
2348 link_params_delay_cmd,
2349 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2350 "Unidirectional Average Link Delay\n"
2351 "Average delay in micro-second as decimal (0...16777215)\n"
2352 "Minimum delay\n"
2353 "Minimum delay in micro-second as decimal (0...16777215)\n"
2354 "Maximum delay\n"
2355 "Maximum delay in micro-second as decimal (0...16777215)\n")
2356 {
2357 /* Get and Check new delay values */
2358 uint32_t delay = 0, low = 0, high = 0;
2359 delay = strtoul(argv[1]->arg, NULL, 10);
2360 if (argc == 6) {
2361 low = strtoul(argv[3]->arg, NULL, 10);
2362 high = strtoul(argv[5]->arg, NULL, 10);
2363 }
2364
2365 VTY_DECLVAR_CONTEXT(interface, ifp);
2366 struct if_link_params *iflp = if_link_params_get(ifp);
2367 uint8_t update = 0;
2368
2369 if (argc == 2) {
2370 /* Check new delay value against old Min and Max delays if set
2371 */
2372 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2373 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2374 vty_out(vty,
2375 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2376 iflp->min_delay, iflp->max_delay);
2377 return CMD_WARNING_CONFIG_FAILED;
2378 }
2379 /* Update delay if value is not set or change */
2380 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2381 iflp->av_delay = delay;
2382 SET_PARAM(iflp, LP_DELAY);
2383 update = 1;
2384 }
2385 /* Unset Min and Max delays if already set */
2386 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2387 iflp->min_delay = 0;
2388 iflp->max_delay = 0;
2389 UNSET_PARAM(iflp, LP_MM_DELAY);
2390 update = 1;
2391 }
2392 } else {
2393 /* Check new delays value coherency */
2394 if (delay <= low || delay >= high) {
2395 vty_out(vty,
2396 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2397 low, high);
2398 return CMD_WARNING_CONFIG_FAILED;
2399 }
2400 /* Update Delays if needed */
2401 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2402 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2403 || iflp->av_delay != delay || iflp->min_delay != low
2404 || iflp->max_delay != high) {
2405 iflp->av_delay = delay;
2406 SET_PARAM(iflp, LP_DELAY);
2407 iflp->min_delay = low;
2408 iflp->max_delay = high;
2409 SET_PARAM(iflp, LP_MM_DELAY);
2410 update = 1;
2411 }
2412 }
2413
2414 /* force protocols to update LINK STATE due to parameters change */
2415 if (update == 1 && if_is_operative(ifp))
2416 zebra_interface_parameters_update(ifp);
2417
2418 return CMD_SUCCESS;
2419 }
2420
2421 DEFUN (no_link_params_delay,
2422 no_link_params_delay_cmd,
2423 "no delay",
2424 NO_STR
2425 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2426 {
2427 VTY_DECLVAR_CONTEXT(interface, ifp);
2428 struct if_link_params *iflp = if_link_params_get(ifp);
2429
2430 /* Unset Delays */
2431 iflp->av_delay = 0;
2432 UNSET_PARAM(iflp, LP_DELAY);
2433 iflp->min_delay = 0;
2434 iflp->max_delay = 0;
2435 UNSET_PARAM(iflp, LP_MM_DELAY);
2436
2437 /* force protocols to update LINK STATE due to parameters change */
2438 if (if_is_operative(ifp))
2439 zebra_interface_parameters_update(ifp);
2440
2441 return CMD_SUCCESS;
2442 }
2443
2444 DEFUN (link_params_delay_var,
2445 link_params_delay_var_cmd,
2446 "delay-variation (0-16777215)",
2447 "Unidirectional Link Delay Variation\n"
2448 "delay variation in micro-second as decimal (0...16777215)\n")
2449 {
2450 int idx_number = 1;
2451 VTY_DECLVAR_CONTEXT(interface, ifp);
2452 struct if_link_params *iflp = if_link_params_get(ifp);
2453 uint32_t value;
2454
2455 value = strtoul(argv[idx_number]->arg, NULL, 10);
2456
2457 /* Update Delay Variation if needed */
2458 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2459
2460 return CMD_SUCCESS;
2461 }
2462
2463 DEFUN (no_link_params_delay_var,
2464 no_link_params_delay_var_cmd,
2465 "no delay-variation",
2466 NO_STR
2467 "Disable Unidirectional Delay Variation on this interface\n")
2468 {
2469 VTY_DECLVAR_CONTEXT(interface, ifp);
2470
2471 /* Unset Delay Variation */
2472 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2473
2474 return CMD_SUCCESS;
2475 }
2476
2477 DEFUN (link_params_pkt_loss,
2478 link_params_pkt_loss_cmd,
2479 "packet-loss PERCENTAGE",
2480 "Unidirectional Link Packet Loss\n"
2481 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2482 {
2483 int idx_percentage = 1;
2484 VTY_DECLVAR_CONTEXT(interface, ifp);
2485 struct if_link_params *iflp = if_link_params_get(ifp);
2486 float fval;
2487
2488 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2489 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2490 safe_strerror(errno));
2491 return CMD_WARNING_CONFIG_FAILED;
2492 }
2493
2494 if (fval > MAX_PKT_LOSS)
2495 fval = MAX_PKT_LOSS;
2496
2497 /* Update Packet Loss if needed */
2498 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2499
2500 return CMD_SUCCESS;
2501 }
2502
2503 DEFUN (no_link_params_pkt_loss,
2504 no_link_params_pkt_loss_cmd,
2505 "no packet-loss",
2506 NO_STR
2507 "Disable Unidirectional Link Packet Loss on this interface\n")
2508 {
2509 VTY_DECLVAR_CONTEXT(interface, ifp);
2510
2511 /* Unset Packet Loss */
2512 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2513
2514 return CMD_SUCCESS;
2515 }
2516
2517 DEFUN (link_params_res_bw,
2518 link_params_res_bw_cmd,
2519 "res-bw BANDWIDTH",
2520 "Unidirectional Residual Bandwidth\n"
2521 "Bytes/second (IEEE floating point format)\n")
2522 {
2523 int idx_bandwidth = 1;
2524 VTY_DECLVAR_CONTEXT(interface, ifp);
2525 struct if_link_params *iflp = if_link_params_get(ifp);
2526 float bw;
2527
2528 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2529 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2530 safe_strerror(errno));
2531 return CMD_WARNING_CONFIG_FAILED;
2532 }
2533
2534 /* Check that bandwidth is not greater than maximum bandwidth parameter
2535 */
2536 if (bw > iflp->max_bw) {
2537 vty_out(vty,
2538 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2539 iflp->max_bw);
2540 return CMD_WARNING_CONFIG_FAILED;
2541 }
2542
2543 /* Update Residual Bandwidth if needed */
2544 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
2545
2546 return CMD_SUCCESS;
2547 }
2548
2549 DEFUN (no_link_params_res_bw,
2550 no_link_params_res_bw_cmd,
2551 "no res-bw",
2552 NO_STR
2553 "Disable Unidirectional Residual Bandwidth on this interface\n")
2554 {
2555 VTY_DECLVAR_CONTEXT(interface, ifp);
2556
2557 /* Unset Residual Bandwidth */
2558 link_param_cmd_unset(ifp, LP_RES_BW);
2559
2560 return CMD_SUCCESS;
2561 }
2562
2563 DEFUN (link_params_ava_bw,
2564 link_params_ava_bw_cmd,
2565 "ava-bw BANDWIDTH",
2566 "Unidirectional Available Bandwidth\n"
2567 "Bytes/second (IEEE floating point format)\n")
2568 {
2569 int idx_bandwidth = 1;
2570 VTY_DECLVAR_CONTEXT(interface, ifp);
2571 struct if_link_params *iflp = if_link_params_get(ifp);
2572 float bw;
2573
2574 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2575 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2576 safe_strerror(errno));
2577 return CMD_WARNING_CONFIG_FAILED;
2578 }
2579
2580 /* Check that bandwidth is not greater than maximum bandwidth parameter
2581 */
2582 if (bw > iflp->max_bw) {
2583 vty_out(vty,
2584 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2585 iflp->max_bw);
2586 return CMD_WARNING_CONFIG_FAILED;
2587 }
2588
2589 /* Update Residual Bandwidth if needed */
2590 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2591
2592 return CMD_SUCCESS;
2593 }
2594
2595 DEFUN (no_link_params_ava_bw,
2596 no_link_params_ava_bw_cmd,
2597 "no ava-bw",
2598 NO_STR
2599 "Disable Unidirectional Available Bandwidth on this interface\n")
2600 {
2601 VTY_DECLVAR_CONTEXT(interface, ifp);
2602
2603 /* Unset Available Bandwidth */
2604 link_param_cmd_unset(ifp, LP_AVA_BW);
2605
2606 return CMD_SUCCESS;
2607 }
2608
2609 DEFUN (link_params_use_bw,
2610 link_params_use_bw_cmd,
2611 "use-bw BANDWIDTH",
2612 "Unidirectional Utilised Bandwidth\n"
2613 "Bytes/second (IEEE floating point format)\n")
2614 {
2615 int idx_bandwidth = 1;
2616 VTY_DECLVAR_CONTEXT(interface, ifp);
2617 struct if_link_params *iflp = if_link_params_get(ifp);
2618 float bw;
2619
2620 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2621 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2622 safe_strerror(errno));
2623 return CMD_WARNING_CONFIG_FAILED;
2624 }
2625
2626 /* Check that bandwidth is not greater than maximum bandwidth parameter
2627 */
2628 if (bw > iflp->max_bw) {
2629 vty_out(vty,
2630 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2631 iflp->max_bw);
2632 return CMD_WARNING_CONFIG_FAILED;
2633 }
2634
2635 /* Update Utilized Bandwidth if needed */
2636 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
2637
2638 return CMD_SUCCESS;
2639 }
2640
2641 DEFUN (no_link_params_use_bw,
2642 no_link_params_use_bw_cmd,
2643 "no use-bw",
2644 NO_STR
2645 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2646 {
2647 VTY_DECLVAR_CONTEXT(interface, ifp);
2648
2649 /* Unset Utilised Bandwidth */
2650 link_param_cmd_unset(ifp, LP_USE_BW);
2651
2652 return CMD_SUCCESS;
2653 }
2654
2655 static int ip_address_install(struct vty *vty, struct interface *ifp,
2656 const char *addr_str, const char *peer_str,
2657 const char *label)
2658 {
2659 struct zebra_if *if_data;
2660 struct prefix_ipv4 lp, pp;
2661 struct connected *ifc;
2662 struct prefix_ipv4 *p;
2663 int ret;
2664 enum zebra_dplane_result dplane_res;
2665
2666 if_data = ifp->info;
2667
2668 ret = str2prefix_ipv4(addr_str, &lp);
2669 if (ret <= 0) {
2670 vty_out(vty, "%% Malformed address \n");
2671 return CMD_WARNING_CONFIG_FAILED;
2672 }
2673
2674 if (ipv4_martian(&lp.prefix)) {
2675 vty_out(vty, "%% Invalid address\n");
2676 return CMD_WARNING_CONFIG_FAILED;
2677 }
2678
2679 if (peer_str) {
2680 if (lp.prefixlen != 32) {
2681 vty_out(vty,
2682 "%% Local prefix length for P-t-P address must be /32\n");
2683 return CMD_WARNING_CONFIG_FAILED;
2684 }
2685
2686 ret = str2prefix_ipv4(peer_str, &pp);
2687 if (ret <= 0) {
2688 vty_out(vty, "%% Malformed peer address\n");
2689 return CMD_WARNING_CONFIG_FAILED;
2690 }
2691 }
2692
2693 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
2694 if (!ifc) {
2695 ifc = connected_new();
2696 ifc->ifp = ifp;
2697
2698 /* Address. */
2699 p = prefix_ipv4_new();
2700 *p = lp;
2701 ifc->address = (struct prefix *)p;
2702
2703 if (peer_str) {
2704 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2705 p = prefix_ipv4_new();
2706 *p = pp;
2707 ifc->destination = (struct prefix *)p;
2708 } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
2709 p = prefix_ipv4_new();
2710 *p = lp;
2711 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
2712 p->prefixlen);
2713 ifc->destination = (struct prefix *)p;
2714 }
2715
2716 /* Label. */
2717 if (label)
2718 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2719
2720 /* Add to linked list. */
2721 listnode_add(ifp->connected, ifc);
2722 }
2723
2724 /* This address is configured from zebra. */
2725 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2726 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2727
2728 /* In case of this route need to install kernel. */
2729 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2730 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2731 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2732 /* Some system need to up the interface to set IP address. */
2733 if (!if_is_up(ifp)) {
2734 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2735 if_refresh(ifp);
2736 }
2737
2738 dplane_res = dplane_intf_addr_set(ifp, ifc);
2739 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2740 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2741 dplane_res2str(dplane_res));
2742 return CMD_WARNING_CONFIG_FAILED;
2743 }
2744
2745 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2746 /* The address will be advertised to zebra clients when the
2747 * notification
2748 * from the kernel has been received.
2749 * It will also be added to the subnet chain list, then. */
2750 }
2751
2752 return CMD_SUCCESS;
2753 }
2754
2755 static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2756 const char *addr_str, const char *peer_str,
2757 const char *label)
2758 {
2759 struct prefix_ipv4 lp, pp;
2760 struct connected *ifc;
2761 int ret;
2762 enum zebra_dplane_result dplane_res;
2763
2764 /* Convert to prefix structure. */
2765 ret = str2prefix_ipv4(addr_str, &lp);
2766 if (ret <= 0) {
2767 vty_out(vty, "%% Malformed address \n");
2768 return CMD_WARNING_CONFIG_FAILED;
2769 }
2770
2771 if (peer_str) {
2772 if (lp.prefixlen != 32) {
2773 vty_out(vty,
2774 "%% Local prefix length for P-t-P address must be /32\n");
2775 return CMD_WARNING_CONFIG_FAILED;
2776 }
2777
2778 ret = str2prefix_ipv4(peer_str, &pp);
2779 if (ret <= 0) {
2780 vty_out(vty, "%% Malformed peer address\n");
2781 return CMD_WARNING_CONFIG_FAILED;
2782 }
2783 }
2784
2785 /* Check current interface address. */
2786 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
2787 if (!ifc) {
2788 vty_out(vty, "%% Can't find address\n");
2789 return CMD_WARNING_CONFIG_FAILED;
2790 }
2791
2792 /* This is not configured address. */
2793 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2794 return CMD_WARNING_CONFIG_FAILED;
2795
2796 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2797
2798 /* This is not real address or interface is not active. */
2799 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2800 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2801 listnode_delete(ifp->connected, ifc);
2802 connected_free(ifc);
2803 return CMD_WARNING_CONFIG_FAILED;
2804 }
2805
2806 /* This is real route. */
2807 dplane_res = dplane_intf_addr_unset(ifp, ifc);
2808 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2809 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2810 dplane_res2str(dplane_res));
2811 return CMD_WARNING_CONFIG_FAILED;
2812 }
2813 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2814 /* we will receive a kernel notification about this route being removed.
2815 * this will trigger its removal from the connected list. */
2816 return CMD_SUCCESS;
2817 }
2818
2819 DEFUN (ip_address,
2820 ip_address_cmd,
2821 "ip address A.B.C.D/M",
2822 "Interface Internet Protocol config commands\n"
2823 "Set the IP address of an interface\n"
2824 "IP address (e.g. 10.0.0.1/8)\n")
2825 {
2826 int idx_ipv4_prefixlen = 2;
2827 VTY_DECLVAR_CONTEXT(interface, ifp);
2828 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2829 NULL);
2830 }
2831
2832 DEFUN (no_ip_address,
2833 no_ip_address_cmd,
2834 "no ip address A.B.C.D/M",
2835 NO_STR
2836 "Interface Internet Protocol config commands\n"
2837 "Set the IP address of an interface\n"
2838 "IP Address (e.g. 10.0.0.1/8)\n")
2839 {
2840 int idx_ipv4_prefixlen = 3;
2841 VTY_DECLVAR_CONTEXT(interface, ifp);
2842 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2843 NULL, NULL);
2844 }
2845
2846 DEFUN(ip_address_peer,
2847 ip_address_peer_cmd,
2848 "ip address A.B.C.D peer A.B.C.D/M",
2849 "Interface Internet Protocol config commands\n"
2850 "Set the IP address of an interface\n"
2851 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2852 "Specify P-t-P address\n"
2853 "Peer IP address (e.g. 10.0.0.1/8)\n")
2854 {
2855 VTY_DECLVAR_CONTEXT(interface, ifp);
2856 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
2857 }
2858
2859 DEFUN(no_ip_address_peer,
2860 no_ip_address_peer_cmd,
2861 "no ip address A.B.C.D peer A.B.C.D/M",
2862 NO_STR
2863 "Interface Internet Protocol config commands\n"
2864 "Set the IP address of an interface\n"
2865 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2866 "Specify P-t-P address\n"
2867 "Peer IP address (e.g. 10.0.0.1/8)\n")
2868 {
2869 VTY_DECLVAR_CONTEXT(interface, ifp);
2870 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
2871 }
2872
2873 #ifdef HAVE_NETLINK
2874 DEFUN (ip_address_label,
2875 ip_address_label_cmd,
2876 "ip address A.B.C.D/M label LINE",
2877 "Interface Internet Protocol config commands\n"
2878 "Set the IP address of an interface\n"
2879 "IP address (e.g. 10.0.0.1/8)\n"
2880 "Label of this address\n"
2881 "Label\n")
2882 {
2883 int idx_ipv4_prefixlen = 2;
2884 int idx_line = 4;
2885 VTY_DECLVAR_CONTEXT(interface, ifp);
2886 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2887 argv[idx_line]->arg);
2888 }
2889
2890 DEFUN (no_ip_address_label,
2891 no_ip_address_label_cmd,
2892 "no ip address A.B.C.D/M label LINE",
2893 NO_STR
2894 "Interface Internet Protocol config commands\n"
2895 "Set the IP address of an interface\n"
2896 "IP address (e.g. 10.0.0.1/8)\n"
2897 "Label of this address\n"
2898 "Label\n")
2899 {
2900 int idx_ipv4_prefixlen = 3;
2901 int idx_line = 5;
2902 VTY_DECLVAR_CONTEXT(interface, ifp);
2903 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2904 NULL, argv[idx_line]->arg);
2905 }
2906 #endif /* HAVE_NETLINK */
2907
2908 static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2909 const char *addr_str, const char *peer_str,
2910 const char *label)
2911 {
2912 struct zebra_if *if_data;
2913 struct prefix_ipv6 cp;
2914 struct connected *ifc;
2915 struct prefix_ipv6 *p;
2916 int ret;
2917 enum zebra_dplane_result dplane_res;
2918
2919 if_data = ifp->info;
2920
2921 ret = str2prefix_ipv6(addr_str, &cp);
2922 if (ret <= 0) {
2923 vty_out(vty, "%% Malformed address \n");
2924 return CMD_WARNING_CONFIG_FAILED;
2925 }
2926
2927 if (ipv6_martian(&cp.prefix)) {
2928 vty_out(vty, "%% Invalid address\n");
2929 return CMD_WARNING_CONFIG_FAILED;
2930 }
2931
2932 ifc = connected_check(ifp, (struct prefix *)&cp);
2933 if (!ifc) {
2934 ifc = connected_new();
2935 ifc->ifp = ifp;
2936
2937 /* Address. */
2938 p = prefix_ipv6_new();
2939 *p = cp;
2940 ifc->address = (struct prefix *)p;
2941
2942 /* Label. */
2943 if (label)
2944 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2945
2946 /* Add to linked list. */
2947 listnode_add(ifp->connected, ifc);
2948 }
2949
2950 /* This address is configured from zebra. */
2951 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2952 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2953
2954 /* In case of this route need to install kernel. */
2955 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2956 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2957 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2958 /* Some system need to up the interface to set IP address. */
2959 if (!if_is_up(ifp)) {
2960 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2961 if_refresh(ifp);
2962 }
2963
2964 dplane_res = dplane_intf_addr_set(ifp, ifc);
2965 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2966 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2967 dplane_res2str(dplane_res));
2968 return CMD_WARNING_CONFIG_FAILED;
2969 }
2970
2971 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2972 /* The address will be advertised to zebra clients when the
2973 * notification
2974 * from the kernel has been received. */
2975 }
2976
2977 return CMD_SUCCESS;
2978 }
2979
2980 /* Return true if an ipv6 address is configured on ifp */
2981 int ipv6_address_configured(struct interface *ifp)
2982 {
2983 struct connected *connected;
2984 struct listnode *node;
2985
2986 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2987 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2988 && (connected->address->family == AF_INET6))
2989 return 1;
2990
2991 return 0;
2992 }
2993
2994 static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2995 const char *addr_str, const char *peer_str,
2996 const char *label)
2997 {
2998 struct prefix_ipv6 cp;
2999 struct connected *ifc;
3000 int ret;
3001 enum zebra_dplane_result dplane_res;
3002
3003 /* Convert to prefix structure. */
3004 ret = str2prefix_ipv6(addr_str, &cp);
3005 if (ret <= 0) {
3006 vty_out(vty, "%% Malformed address \n");
3007 return CMD_WARNING_CONFIG_FAILED;
3008 }
3009
3010 /* Check current interface address. */
3011 ifc = connected_check(ifp, (struct prefix *)&cp);
3012 if (!ifc) {
3013 vty_out(vty, "%% Can't find address\n");
3014 return CMD_WARNING_CONFIG_FAILED;
3015 }
3016
3017 /* This is not configured address. */
3018 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
3019 return CMD_WARNING_CONFIG_FAILED;
3020
3021 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3022
3023 /* This is not real address or interface is not active. */
3024 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
3025 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
3026 listnode_delete(ifp->connected, ifc);
3027 connected_free(ifc);
3028 return CMD_WARNING_CONFIG_FAILED;
3029 }
3030
3031 /* This is real route. */
3032 dplane_res = dplane_intf_addr_unset(ifp, ifc);
3033 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
3034 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
3035 dplane_res2str(dplane_res));
3036 return CMD_WARNING_CONFIG_FAILED;
3037 }
3038
3039 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3040 /* This information will be propagated to the zclients when the
3041 * kernel notification is received. */
3042 return CMD_SUCCESS;
3043 }
3044
3045 DEFUN (ipv6_address,
3046 ipv6_address_cmd,
3047 "ipv6 address X:X::X:X/M",
3048 "Interface IPv6 config commands\n"
3049 "Set the IP address of an interface\n"
3050 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3051 {
3052 int idx_ipv6_prefixlen = 2;
3053 VTY_DECLVAR_CONTEXT(interface, ifp);
3054 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
3055 NULL, NULL);
3056 }
3057
3058 DEFUN (no_ipv6_address,
3059 no_ipv6_address_cmd,
3060 "no ipv6 address X:X::X:X/M",
3061 NO_STR
3062 "Interface IPv6 config commands\n"
3063 "Set the IP address of an interface\n"
3064 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3065 {
3066 int idx_ipv6_prefixlen = 3;
3067 VTY_DECLVAR_CONTEXT(interface, ifp);
3068 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
3069 NULL, NULL);
3070 }
3071
3072 static int link_params_config_write(struct vty *vty, struct interface *ifp)
3073 {
3074 int i;
3075
3076 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
3077 return -1;
3078
3079 struct if_link_params *iflp = ifp->link_params;
3080
3081 vty_out(vty, " link-params\n");
3082 vty_out(vty, " enable\n");
3083 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
3084 vty_out(vty, " metric %u\n", iflp->te_metric);
3085 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
3086 vty_out(vty, " max-bw %g\n", iflp->max_bw);
3087 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
3088 && iflp->max_rsv_bw != iflp->default_bw)
3089 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
3090 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
3091 for (i = 0; i < 8; i++)
3092 if (iflp->unrsv_bw[i] != iflp->default_bw)
3093 vty_out(vty, " unrsv-bw %d %g\n", i,
3094 iflp->unrsv_bw[i]);
3095 }
3096 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
3097 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
3098 if (IS_PARAM_SET(iflp, LP_DELAY)) {
3099 vty_out(vty, " delay %u", iflp->av_delay);
3100 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
3101 vty_out(vty, " min %u", iflp->min_delay);
3102 vty_out(vty, " max %u", iflp->max_delay);
3103 }
3104 vty_out(vty, "\n");
3105 }
3106 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
3107 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
3108 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
3109 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
3110 if (IS_PARAM_SET(iflp, LP_AVA_BW))
3111 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
3112 if (IS_PARAM_SET(iflp, LP_RES_BW))
3113 vty_out(vty, " res-bw %g\n", iflp->res_bw);
3114 if (IS_PARAM_SET(iflp, LP_USE_BW))
3115 vty_out(vty, " use-bw %g\n", iflp->use_bw);
3116 if (IS_PARAM_SET(iflp, LP_RMT_AS))
3117 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
3118 iflp->rmt_as);
3119 vty_out(vty, " exit-link-params\n");
3120 return 0;
3121 }
3122
3123 static int if_config_write(struct vty *vty)
3124 {
3125 struct vrf *vrf0;
3126 struct interface *ifp;
3127
3128 zebra_ptm_write(vty);
3129
3130 RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
3131 FOR_ALL_INTERFACES (vrf0, ifp) {
3132 struct zebra_if *if_data;
3133 struct listnode *addrnode;
3134 struct connected *ifc;
3135 struct prefix *p;
3136 struct vrf *vrf;
3137
3138 if_data = ifp->info;
3139 vrf = ifp->vrf;
3140
3141 if (vrf->vrf_id == VRF_DEFAULT)
3142 vty_frame(vty, "interface %s\n", ifp->name);
3143 else
3144 vty_frame(vty, "interface %s vrf %s\n",
3145 ifp->name, vrf->name);
3146
3147 if (if_data) {
3148 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
3149 vty_out(vty, " shutdown\n");
3150
3151 zebra_ptm_if_write(vty, if_data);
3152 }
3153
3154 if (ifp->desc)
3155 vty_out(vty, " description %s\n", ifp->desc);
3156
3157 /* Assign bandwidth here to avoid unnecessary interface
3158 flap
3159 while processing config script */
3160 if (ifp->bandwidth != 0)
3161 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
3162
3163 if (!CHECK_FLAG(ifp->status,
3164 ZEBRA_INTERFACE_LINKDETECTION))
3165 vty_out(vty, " no link-detect\n");
3166
3167 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
3168 ifc)) {
3169 if (CHECK_FLAG(ifc->conf,
3170 ZEBRA_IFC_CONFIGURED)) {
3171 char buf[INET6_ADDRSTRLEN];
3172 p = ifc->address;
3173 vty_out(vty, " ip%s address %s",
3174 p->family == AF_INET ? ""
3175 : "v6",
3176 inet_ntop(p->family,
3177 &p->u.prefix, buf,
3178 sizeof(buf)));
3179 if (CONNECTED_PEER(ifc)) {
3180 p = ifc->destination;
3181 vty_out(vty, " peer %s",
3182 inet_ntop(p->family,
3183 &p->u.prefix,
3184 buf,
3185 sizeof(buf)));
3186 }
3187 vty_out(vty, "/%d", p->prefixlen);
3188
3189 if (ifc->label)
3190 vty_out(vty, " label %s",
3191 ifc->label);
3192
3193 vty_out(vty, "\n");
3194 }
3195 }
3196
3197 if (if_data) {
3198 if (if_data->multicast
3199 != IF_ZEBRA_MULTICAST_UNSPEC)
3200 vty_out(vty, " %smulticast\n",
3201 if_data->multicast
3202 == IF_ZEBRA_MULTICAST_ON
3203 ? ""
3204 : "no ");
3205 }
3206
3207 hook_call(zebra_if_config_wr, vty, ifp);
3208
3209 link_params_config_write(vty, ifp);
3210
3211 vty_endframe(vty, "!\n");
3212 }
3213 return 0;
3214 }
3215
3216 /* Allocate and initialize interface vector. */
3217 void zebra_if_init(void)
3218 {
3219 /* Initialize interface and new hook. */
3220 hook_register_prio(if_add, 0, if_zebra_new_hook);
3221 hook_register_prio(if_del, 0, if_zebra_delete_hook);
3222
3223 /* Install configuration write function. */
3224 install_node(&interface_node, if_config_write);
3225 install_node(&link_params_node, NULL);
3226 if_cmd_init();
3227
3228 install_element(VIEW_NODE, &show_interface_cmd);
3229 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
3230 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
3231 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
3232
3233 install_element(ENABLE_NODE, &show_interface_desc_cmd);
3234 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
3235 install_element(INTERFACE_NODE, &multicast_cmd);
3236 install_element(INTERFACE_NODE, &no_multicast_cmd);
3237 install_element(INTERFACE_NODE, &linkdetect_cmd);
3238 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
3239 install_element(INTERFACE_NODE, &shutdown_if_cmd);
3240 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
3241 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
3242 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
3243 install_element(INTERFACE_NODE, &ip_address_cmd);
3244 install_element(INTERFACE_NODE, &no_ip_address_cmd);
3245 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
3246 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
3247 install_element(INTERFACE_NODE, &ipv6_address_cmd);
3248 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
3249 #ifdef HAVE_NETLINK
3250 install_element(INTERFACE_NODE, &ip_address_label_cmd);
3251 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
3252 #endif /* HAVE_NETLINK */
3253 install_element(INTERFACE_NODE, &link_params_cmd);
3254 install_default(LINK_PARAMS_NODE);
3255 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
3256 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
3257 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
3258 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
3259 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
3260 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
3261 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
3262 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
3263 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
3264 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
3265 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
3266 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
3267 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
3268 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
3269 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
3270 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
3271 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
3272 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
3273 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
3274 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
3275 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
3276 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
3277 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
3278 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
3279 }