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