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