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