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