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