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