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