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