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