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