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