]> git.proxmox.com Git - mirror_frr.git/blob - zebra/interface.c
Merge pull request #12544 from mjstapp/fix_pathd_sa_pcep_config
[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 "ioctl.h"
32 #include "connected.h"
33 #include "log.h"
34 #include "zclient.h"
35 #include "vrf.h"
36
37 #include "zebra/rtadv.h"
38 #include "zebra_ns.h"
39 #include "zebra_vrf.h"
40 #include "zebra/interface.h"
41 #include "zebra/rib.h"
42 #include "zebra/rt.h"
43 #include "zebra/zebra_router.h"
44 #include "zebra/redistribute.h"
45 #include "zebra/debug.h"
46 #include "zebra/irdp.h"
47 #include "zebra/zebra_ptm.h"
48 #include "zebra/rt_netlink.h"
49 #include "zebra/if_netlink.h"
50 #include "zebra/interface.h"
51 #include "zebra/zebra_vxlan.h"
52 #include "zebra/zebra_errors.h"
53 #include "zebra/zebra_evpn_mh.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 DEFINE_MTYPE(ZEBRA, ZIF_DESC, "Intf desc");
65
66 static void if_down_del_nbr_connected(struct interface *ifp);
67
68 static void if_zebra_speed_update(struct thread *thread)
69 {
70 struct interface *ifp = THREAD_ARG(thread);
71 struct zebra_if *zif = ifp->info;
72 uint32_t new_speed;
73 bool changed = false;
74 int error = 0;
75
76 new_speed = kernel_get_speed(ifp, &error);
77
78 /* error may indicate vrf not available or
79 * interfaces not available.
80 * note that loopback & virtual interfaces can return 0 as speed
81 */
82 if (error < 0)
83 return;
84
85 if (new_speed != ifp->speed) {
86 zlog_info("%s: %s old speed: %u new speed: %u", __func__,
87 ifp->name, ifp->speed, new_speed);
88 ifp->speed = new_speed;
89 if_add_update(ifp);
90 changed = true;
91 }
92
93 if (changed || new_speed == UINT32_MAX) {
94 #define SPEED_UPDATE_SLEEP_TIME 5
95 #define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
96 /*
97 * Some interfaces never actually have an associated speed
98 * with them ( I am looking at you bridges ).
99 * So instead of iterating forever, let's give the
100 * system 4 minutes to try to figure out the speed
101 * if after that it it's probably never going to become
102 * useful.
103 * Since I don't know all the wonderful types of interfaces
104 * that may come into existence in the future I am going
105 * to not update the system to keep track of that. This
106 * is far simpler to just stop trying after 4 minutes
107 */
108 if (new_speed == UINT32_MAX &&
109 zif->speed_update_count == SPEED_UPDATE_COUNT_MAX)
110 return;
111
112 zif->speed_update_count++;
113 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp,
114 SPEED_UPDATE_SLEEP_TIME, &zif->speed_update);
115 thread_ignore_late_timer(zif->speed_update);
116 }
117 }
118
119 static void zebra_if_node_destroy(route_table_delegate_t *delegate,
120 struct route_table *table,
121 struct route_node *node)
122 {
123 if (node->info)
124 list_delete((struct list **)&node->info);
125 route_node_destroy(delegate, table, node);
126 }
127
128 static void zebra_if_nhg_dependents_free(struct zebra_if *zebra_if)
129 {
130 nhg_connected_tree_free(&zebra_if->nhg_dependents);
131 }
132
133 static void zebra_if_nhg_dependents_init(struct zebra_if *zebra_if)
134 {
135 nhg_connected_tree_init(&zebra_if->nhg_dependents);
136 }
137
138
139 route_table_delegate_t zebra_if_table_delegate = {
140 .create_node = route_node_create,
141 .destroy_node = zebra_if_node_destroy};
142
143 /* Called when new interface is added. */
144 static int if_zebra_new_hook(struct interface *ifp)
145 {
146 struct zebra_if *zebra_if;
147
148 zebra_if = XCALLOC(MTYPE_ZINFO, sizeof(struct zebra_if));
149 zebra_if->ifp = ifp;
150
151 zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC;
152 zebra_if->shutdown = IF_ZEBRA_DATA_OFF;
153
154 zebra_if_nhg_dependents_init(zebra_if);
155
156 zebra_ptm_if_init(zebra_if);
157
158 ifp->ptm_enable = zebra_ptm_get_enable_state();
159
160 rtadv_if_init(zebra_if);
161
162 memset(&zebra_if->neigh_mac[0], 0, 6);
163
164 /* Initialize installed address chains tree. */
165 zebra_if->ipv4_subnets =
166 route_table_init_with_delegate(&zebra_if_table_delegate);
167
168 ifp->info = zebra_if;
169
170 /*
171 * Some platforms are telling us that the interface is
172 * up and ready to go. When we check the speed we
173 * sometimes get the wrong value. Wait a couple
174 * of seconds and ask again. Hopefully it's all settled
175 * down upon startup.
176 */
177 zebra_if->speed_update_count = 0;
178 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
179 &zebra_if->speed_update);
180 thread_ignore_late_timer(zebra_if->speed_update);
181
182 return 0;
183 }
184
185 static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
186 {
187 zebra_nhg_check_valid(nhe);
188 }
189
190 static void if_down_nhg_dependents(const struct interface *ifp)
191 {
192 struct nhg_connected *rb_node_dep = NULL;
193 struct zebra_if *zif = (struct zebra_if *)ifp->info;
194
195 frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep)
196 if_nhg_dependents_check_valid(rb_node_dep->nhe);
197 }
198
199 static void if_nhg_dependents_release(const struct interface *ifp)
200 {
201 struct nhg_connected *rb_node_dep = NULL;
202 struct zebra_if *zif = (struct zebra_if *)ifp->info;
203
204 frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
205 rb_node_dep->nhe->ifp = NULL; /* Null it out */
206 if_nhg_dependents_check_valid(rb_node_dep->nhe);
207 }
208 }
209
210 /* Called when interface is deleted. */
211 static int if_zebra_delete_hook(struct interface *ifp)
212 {
213 struct zebra_if *zebra_if;
214
215 if (ifp->info) {
216 zebra_if = ifp->info;
217
218 /* If we set protodown, clear our reason now from the kernel */
219 if (ZEBRA_IF_IS_PROTODOWN(zebra_if) && zebra_if->protodown_rc &&
220 !ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zebra_if))
221 zebra_if_update_protodown_rc(ifp, true,
222 (zebra_if->protodown_rc &
223 ~ZEBRA_PROTODOWN_ALL));
224
225 /* Free installed address chains tree. */
226 if (zebra_if->ipv4_subnets)
227 route_table_finish(zebra_if->ipv4_subnets);
228
229 rtadv_if_fini(zebra_if);
230
231 zebra_evpn_if_cleanup(zebra_if);
232 zebra_evpn_mac_ifp_del(ifp);
233
234 if_nhg_dependents_release(ifp);
235 zebra_if_nhg_dependents_free(zebra_if);
236
237 XFREE(MTYPE_ZIF_DESC, zebra_if->desc);
238
239 THREAD_OFF(zebra_if->speed_update);
240
241 XFREE(MTYPE_ZINFO, zebra_if);
242 }
243
244 return 0;
245 }
246
247 /* Build the table key */
248 static void if_build_key(uint32_t ifindex, struct prefix *p)
249 {
250 p->family = AF_INET;
251 p->prefixlen = IPV4_MAX_BITLEN;
252 p->u.prefix4.s_addr = ifindex;
253 }
254
255 /* Link an interface in a per NS interface tree */
256 struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
257 {
258 struct prefix p;
259 struct route_node *rn;
260
261 if (ifp->ifindex == IFINDEX_INTERNAL)
262 return NULL;
263
264 if_build_key(ifp->ifindex, &p);
265 rn = route_node_get(ns->if_table, &p);
266 if (rn->info) {
267 ifp = (struct interface *)rn->info;
268 route_unlock_node(rn); /* get */
269 return ifp;
270 }
271
272 rn->info = ifp;
273 ifp->node = rn;
274
275 return ifp;
276 }
277
278 /* Delete a VRF. This is called in vrf_terminate(). */
279 void if_unlink_per_ns(struct interface *ifp)
280 {
281 ifp->node->info = NULL;
282 route_unlock_node(ifp->node);
283 ifp->node = NULL;
284 }
285
286 /* Look up an interface by identifier within a NS */
287 struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns,
288 uint32_t ifindex)
289 {
290 struct prefix p;
291 struct route_node *rn;
292 struct interface *ifp = NULL;
293
294 if_build_key(ifindex, &p);
295 rn = route_node_lookup(ns->if_table, &p);
296 if (rn) {
297 ifp = (struct interface *)rn->info;
298 route_unlock_node(rn); /* lookup */
299 }
300 return ifp;
301 }
302
303 /* Look up an interface by name within a NS */
304 struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
305 const char *ifname)
306 {
307 struct route_node *rn;
308 struct interface *ifp;
309
310 for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
311 ifp = (struct interface *)rn->info;
312 if (ifp && strcmp(ifp->name, ifname) == 0) {
313 route_unlock_node(rn);
314 return (ifp);
315 }
316 }
317
318 return NULL;
319 }
320
321 const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
322 {
323 struct interface *ifp;
324
325 return ((ifp = if_lookup_by_index_per_ns(zns, ifindex)) != NULL)
326 ? ifp->name
327 : "unknown";
328 }
329
330 /* Tie an interface address to its derived subnet list of addresses. */
331 int if_subnet_add(struct interface *ifp, struct connected *ifc)
332 {
333 struct route_node *rn;
334 struct zebra_if *zebra_if;
335 struct prefix cp;
336 struct list *addr_list;
337
338 assert(ifp && ifp->info && ifc);
339 zebra_if = ifp->info;
340
341 /* Get address derived subnet node and associated address list, while
342 marking
343 address secondary attribute appropriately. */
344 cp = *CONNECTED_PREFIX(ifc);
345 apply_mask(&cp);
346 rn = route_node_get(zebra_if->ipv4_subnets, &cp);
347
348 if ((addr_list = rn->info))
349 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
350 else {
351 UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
352 rn->info = addr_list = list_new();
353 route_lock_node(rn);
354 }
355
356 /* Tie address at the tail of address list. */
357 listnode_add(addr_list, ifc);
358
359 /* Return list element count. */
360 return (addr_list->count);
361 }
362
363 /* Untie an interface address from its derived subnet list of addresses. */
364 int if_subnet_delete(struct interface *ifp, struct connected *ifc)
365 {
366 struct route_node *rn;
367 struct zebra_if *zebra_if;
368 struct list *addr_list;
369 struct prefix cp;
370
371 assert(ifp && ifp->info && ifc);
372 zebra_if = ifp->info;
373
374 cp = *CONNECTED_PREFIX(ifc);
375 apply_mask(&cp);
376
377 /* Get address derived subnet node. */
378 rn = route_node_lookup(zebra_if->ipv4_subnets, &cp);
379 if (!(rn && rn->info)) {
380 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET,
381 "Trying to remove an address from an unknown subnet. (please report this bug)");
382 return -1;
383 }
384 route_unlock_node(rn);
385
386 /* Untie address from subnet's address list. */
387 addr_list = rn->info;
388
389 /* Deleting an address that is not registered is a bug.
390 * In any case, we shouldn't decrement the lock counter if the address
391 * is unknown. */
392 if (!listnode_lookup(addr_list, ifc)) {
393 flog_warn(
394 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR,
395 "Trying to remove an address from a subnet where it is not currently registered. (please report this bug)");
396 return -1;
397 }
398
399 listnode_delete(addr_list, ifc);
400 route_unlock_node(rn);
401
402 /* Return list element count, if not empty. */
403 if (addr_list->count) {
404 /* If deleted address is primary, mark subsequent one as such
405 * and distribute. */
406 if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
407 ifc = listgetdata(
408 (struct listnode *)listhead(addr_list));
409 zebra_interface_address_delete_update(ifp, ifc);
410 UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
411 /* XXX: Linux kernel removes all the secondary addresses
412 * when the primary
413 * address is removed. We could try to work around that,
414 * though this is
415 * non-trivial. */
416 zebra_interface_address_add_update(ifp, ifc);
417 }
418
419 return addr_list->count;
420 }
421
422 /* Otherwise, free list and route node. */
423 list_delete(&addr_list);
424 rn->info = NULL;
425 route_unlock_node(rn);
426
427 return 0;
428 }
429
430 /* if_flags_mangle: A place for hacks that require mangling
431 * or tweaking the interface flags.
432 *
433 * ******************** Solaris flags hacks **************************
434 *
435 * Solaris IFF_UP flag reflects only the primary interface as the
436 * routing socket only sends IFINFO for the primary interface. Hence
437 * ~IFF_UP does not per se imply all the logical interfaces are also
438 * down - which we only know of as addresses. Instead we must determine
439 * whether the interface really is up or not according to how many
440 * addresses are still attached. (Solaris always sends RTM_DELADDR if
441 * an interface, logical or not, goes ~IFF_UP).
442 *
443 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
444 * are addresses left in struct connected, not just the actual underlying
445 * IFF_UP flag.
446 *
447 * We must hence remember the real state of IFF_UP, which we do in
448 * struct zebra_if.primary_state.
449 *
450 * Setting IFF_UP within zebra to administratively shutdown the
451 * interface will affect only the primary interface/address on Solaris.
452 ************************End Solaris flags hacks ***********************
453 */
454 static void if_flags_mangle(struct interface *ifp, uint64_t *newflags)
455 {
456 return;
457 }
458
459 /* Update the flags field of the ifp with the new flag set provided.
460 * Take whatever actions are required for any changes in flags we care
461 * about.
462 *
463 * newflags should be the raw value, as obtained from the OS.
464 */
465 void if_flags_update(struct interface *ifp, uint64_t newflags)
466 {
467 if_flags_mangle(ifp, &newflags);
468
469 if (if_is_no_ptm_operative(ifp)) {
470 /* operative -> inoperative? */
471 ifp->flags = newflags;
472 if (!if_is_operative(ifp))
473 if_down(ifp);
474 } else {
475 /* inoperative -> operative? */
476 ifp->flags = newflags;
477 if (if_is_operative(ifp))
478 if_up(ifp, true);
479 }
480 }
481
482 /* Wake up configured address if it is not in current kernel
483 address. */
484 void if_addr_wakeup(struct interface *ifp)
485 {
486 struct listnode *node, *nnode;
487 struct connected *ifc;
488 struct prefix *p;
489 enum zebra_dplane_result dplane_res;
490
491 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
492 p = ifc->address;
493
494 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)
495 && !CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)) {
496 /* Address check. */
497 if (p->family == AF_INET) {
498 if (!if_is_up(ifp)) {
499 /* Assume zebra is configured like
500 * following:
501 *
502 * interface gre0
503 * ip addr 192.0.2.1/24
504 * !
505 *
506 * As soon as zebra becomes first aware
507 * that gre0 exists in the
508 * kernel, it will set gre0 up and
509 * configure its addresses.
510 *
511 * (This may happen at startup when the
512 * interface already exists
513 * or during runtime when the interface
514 * is added to the kernel)
515 *
516 * XXX: IRDP code is calling here via
517 * if_add_update - this seems
518 * somewhat weird.
519 * XXX: RUNNING is not a settable flag
520 * on any system
521 * I (paulj) am aware of.
522 */
523 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
524 if_refresh(ifp);
525 }
526
527 dplane_res = dplane_intf_addr_set(ifp, ifc);
528 if (dplane_res ==
529 ZEBRA_DPLANE_REQUEST_FAILURE) {
530 flog_err_sys(
531 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
532 "Can't set interface's address: %s",
533 dplane_res2str(dplane_res));
534 continue;
535 }
536
537 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
538 /* The address will be advertised to zebra
539 * clients when the notification
540 * from the kernel has been received.
541 * It will also be added to the interface's
542 * subnet list then. */
543 }
544 if (p->family == AF_INET6) {
545 if (!if_is_up(ifp)) {
546 /* See long comment above */
547 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
548 if_refresh(ifp);
549 }
550
551
552 dplane_res = dplane_intf_addr_set(ifp, ifc);
553 if (dplane_res ==
554 ZEBRA_DPLANE_REQUEST_FAILURE) {
555 flog_err_sys(
556 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
557 "Can't set interface's address: %s",
558 dplane_res2str(dplane_res));
559 continue;
560 }
561
562 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
563 /* The address will be advertised to zebra
564 * clients when the notification
565 * from the kernel has been received. */
566 }
567 }
568 }
569 }
570
571 /* Handle interface addition */
572 void if_add_update(struct interface *ifp)
573 {
574 struct zebra_if *if_data;
575 struct zebra_ns *zns;
576 struct zebra_vrf *zvrf = ifp->vrf->info;
577
578 /* case interface populate before vrf enabled */
579 if (zvrf->zns)
580 zns = zvrf->zns;
581 else
582 zns = zebra_ns_lookup(NS_DEFAULT);
583 if_link_per_ns(zns, ifp);
584 if_data = ifp->info;
585 assert(if_data);
586
587 if (if_data->multicast == IF_ZEBRA_DATA_ON)
588 if_set_flags(ifp, IFF_MULTICAST);
589 else if (if_data->multicast == IF_ZEBRA_DATA_OFF)
590 if_unset_flags(ifp, IFF_MULTICAST);
591
592 zebra_ptm_if_set_ptm_state(ifp, if_data);
593
594 zebra_interface_add_update(ifp);
595
596 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
597 SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
598
599 if (if_data->shutdown == IF_ZEBRA_DATA_ON) {
600 if (IS_ZEBRA_DEBUG_KERNEL) {
601 zlog_debug(
602 "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.",
603 ifp->name, ifp->vrf->name,
604 ifp->vrf->vrf_id, ifp->ifindex);
605 }
606
607 return;
608 }
609
610 if_addr_wakeup(ifp);
611
612 if (IS_ZEBRA_DEBUG_KERNEL)
613 zlog_debug(
614 "interface %s vrf %s(%u) index %d becomes active.",
615 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
616 ifp->ifindex);
617
618 } else {
619 if (IS_ZEBRA_DEBUG_KERNEL)
620 zlog_debug("interface %s vrf %s(%u) index %d is added.",
621 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
622 ifp->ifindex);
623 }
624 }
625
626 /* Install connected routes corresponding to an interface. */
627 static void if_install_connected(struct interface *ifp)
628 {
629 struct listnode *node;
630 struct listnode *next;
631 struct connected *ifc;
632
633 if (ifp->connected) {
634 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
635 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
636 zebra_interface_address_add_update(ifp, ifc);
637
638 connected_up(ifp, ifc);
639 }
640 }
641 }
642
643 /* Uninstall connected routes corresponding to an interface. */
644 static void if_uninstall_connected(struct interface *ifp)
645 {
646 struct listnode *node;
647 struct listnode *next;
648 struct connected *ifc;
649
650 if (ifp->connected) {
651 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
652 zebra_interface_address_delete_update(ifp, ifc);
653 connected_down(ifp, ifc);
654 }
655 }
656 }
657
658 /* Uninstall and delete connected routes corresponding to an interface. */
659 /* TODO - Check why IPv4 handling here is different from install or if_down */
660 static void if_delete_connected(struct interface *ifp)
661 {
662 struct connected *ifc;
663 struct prefix cp;
664 struct route_node *rn;
665 struct zebra_if *zebra_if;
666 struct listnode *node;
667 struct listnode *last = NULL;
668
669 zebra_if = ifp->info;
670
671 if (!ifp->connected)
672 return;
673
674 while ((node = (last ? last->next : listhead(ifp->connected)))) {
675 ifc = listgetdata(node);
676
677 cp = *CONNECTED_PREFIX(ifc);
678 apply_mask(&cp);
679
680 if (cp.family == AF_INET
681 && (rn = route_node_lookup(zebra_if->ipv4_subnets, &cp))) {
682 struct listnode *anode;
683 struct listnode *next;
684 struct listnode *first;
685 struct list *addr_list;
686
687 route_unlock_node(rn);
688 addr_list = (struct list *)rn->info;
689
690 /* Remove addresses, secondaries first. */
691 first = listhead(addr_list);
692 if (first)
693 for (anode = first->next; anode || first;
694 anode = next) {
695 if (!anode) {
696 anode = first;
697 first = NULL;
698 }
699 next = anode->next;
700
701 ifc = listgetdata(anode);
702 connected_down(ifp, ifc);
703
704 /* XXX: We have to send notifications
705 * here explicitly, because we destroy
706 * the ifc before receiving the
707 * notification about the address being
708 * deleted.
709 */
710 zebra_interface_address_delete_update(
711 ifp, ifc);
712
713 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
714 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
715
716 /* Remove from subnet chain. */
717 list_delete_node(addr_list, anode);
718 route_unlock_node(rn);
719
720 /* Remove from interface address list
721 * (unconditionally). */
722 if (!CHECK_FLAG(ifc->conf,
723 ZEBRA_IFC_CONFIGURED)) {
724 listnode_delete(ifp->connected,
725 ifc);
726 connected_free(&ifc);
727 } else
728 last = node;
729 }
730
731 /* Free chain list and respective route node. */
732 list_delete(&addr_list);
733 rn->info = NULL;
734 route_unlock_node(rn);
735 } else if (cp.family == AF_INET6) {
736 connected_down(ifp, ifc);
737
738 zebra_interface_address_delete_update(ifp, ifc);
739
740 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
741 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
742
743 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
744 last = node;
745 else {
746 listnode_delete(ifp->connected, ifc);
747 connected_free(&ifc);
748 }
749 } else {
750 last = node;
751 }
752 }
753 }
754
755 /* Handle an interface delete event */
756 void if_delete_update(struct interface **pifp)
757 {
758 struct zebra_if *zif;
759 struct interface *ifp = *pifp;
760
761 if (if_is_up(ifp)) {
762 flog_err(
763 EC_LIB_INTERFACE,
764 "interface %s vrf %s(%u) index %d is still up while being deleted.",
765 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
766 ifp->ifindex);
767 return;
768 }
769
770 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
771 return;
772
773 /* Mark interface as inactive */
774 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
775
776 if (IS_ZEBRA_DEBUG_KERNEL)
777 zlog_debug("interface %s vrf %s(%u) index %d is now inactive.",
778 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
779 ifp->ifindex);
780
781 /* Delete connected routes from the kernel. */
782 if_delete_connected(ifp);
783
784 /* Send out notification on interface delete. */
785 zebra_interface_delete_update(ifp);
786
787 if_unlink_per_ns(ifp);
788
789 /* Update ifindex after distributing the delete message. This is in
790 case any client needs to have the old value of ifindex available
791 while processing the deletion. Each client daemon is responsible
792 for setting ifindex to IFINDEX_INTERNAL after processing the
793 interface deletion message. */
794 if_set_index(ifp, IFINDEX_INTERNAL);
795 ifp->node = NULL;
796
797 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
798 * desired. This operation is not done for netns implementation to avoid
799 * collision with interface with the same name in the default vrf (can
800 * occur with this implementation whereas it is not possible with
801 * vrf-lite).
802 */
803 if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
804 if_handle_vrf_change(ifp, VRF_DEFAULT);
805
806 /* Reset some zebra interface params to default values. */
807 zif = ifp->info;
808 if (zif) {
809 zif->zif_type = ZEBRA_IF_OTHER;
810 zif->zif_slave_type = ZEBRA_IF_SLAVE_NONE;
811 memset(&zif->l2info, 0, sizeof(union zebra_l2if_info));
812 memset(&zif->brslave_info, 0,
813 sizeof(struct zebra_l2info_brslave));
814 zebra_evpn_if_cleanup(zif);
815 zebra_evpn_mac_ifp_del(ifp);
816 }
817
818 if (!ifp->configured) {
819 if (IS_ZEBRA_DEBUG_KERNEL)
820 zlog_debug("interface %s is being deleted from the system",
821 ifp->name);
822 if_delete(pifp);
823 }
824 }
825
826 /* VRF change for an interface */
827 void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
828 {
829 vrf_id_t old_vrf_id;
830
831 old_vrf_id = ifp->vrf->vrf_id;
832
833 /* Uninstall connected routes. */
834 if_uninstall_connected(ifp);
835
836 /* Delete any IPv4 neighbors created to implement RFC 5549 */
837 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
838
839 /* Delete all neighbor addresses learnt through IPv6 RA */
840 if_down_del_nbr_connected(ifp);
841
842 /* Send out notification on interface VRF change. */
843 /* This is to issue an UPDATE or a DELETE, as appropriate. */
844 zebra_interface_vrf_update_del(ifp, vrf_id);
845
846 /* update VRF */
847 if_update_to_new_vrf(ifp, vrf_id);
848
849 /* Send out notification on interface VRF change. */
850 /* This is to issue an ADD, if needed. */
851 zebra_interface_vrf_update_add(ifp, old_vrf_id);
852 }
853
854 static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
855 {
856 mac[0] = address->s6_addr[8] ^ 0x02;
857 mac[1] = address->s6_addr[9];
858 mac[2] = address->s6_addr[10];
859 mac[3] = address->s6_addr[13];
860 mac[4] = address->s6_addr[14];
861 mac[5] = address->s6_addr[15];
862 }
863
864 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
865 char mac[6],
866 struct in6_addr *address,
867 int add)
868 {
869 struct zebra_vrf *zvrf = ifp->vrf->info;
870 struct zebra_if *zif = ifp->info;
871 char buf[16] = "169.254.0.1";
872 struct in_addr ipv4_ll;
873 ns_id_t ns_id;
874
875 inet_pton(AF_INET, buf, &ipv4_ll);
876
877 ns_id = zvrf->zns->ns_id;
878
879 /*
880 * Remove and re-add any existing neighbor entry for this address,
881 * since Netlink doesn't currently offer update message types.
882 */
883 kernel_neigh_update(0, ifp->ifindex, (void *)&ipv4_ll.s_addr, mac, 6,
884 ns_id, AF_INET, true);
885
886 /* Add new neighbor entry.
887 *
888 * We force installation even if current neighbor entry is the same.
889 * Since this function is used to refresh our MAC entries after an
890 * interface flap, if we don't force in our custom entries with their
891 * state set to PERMANENT or REACHABLE then the kernel will attempt to
892 * resolve our leftover entries, fail, mark them unreachable and then
893 * they'll be useless to us.
894 */
895 if (add)
896 kernel_neigh_update(add, ifp->ifindex, (void *)&ipv4_ll.s_addr,
897 mac, 6, ns_id, AF_INET, true);
898
899 memcpy(&zif->neigh_mac[0], &mac[0], 6);
900
901 /*
902 * We need to note whether or not we originated a v6
903 * neighbor entry for this interface. So that when
904 * someone unwisely accidentally deletes this entry
905 * we can shove it back in.
906 */
907 zif->v6_2_v4_ll_neigh_entry = !!add;
908 memcpy(&zif->v6_2_v4_ll_addr6, address, sizeof(*address));
909
910 zvrf->neigh_updates++;
911 }
912
913 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
914 struct in6_addr *address, int add)
915 {
916
917 char mac[6];
918
919 ipv6_ll_address_to_mac(address, (uint8_t *)mac);
920 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
921 }
922
923 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
924 {
925 if (listhead(ifp->nbr_connected)) {
926 struct nbr_connected *nbr_connected;
927 struct listnode *node;
928
929 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
930 nbr_connected))
931 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
932 ifp, &nbr_connected->address->u.prefix6, 1);
933 }
934 }
935
936 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)
937 {
938 if (listhead(ifp->nbr_connected)) {
939 struct nbr_connected *nbr_connected;
940 struct listnode *node;
941
942 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
943 nbr_connected))
944 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
945 ifp, &nbr_connected->address->u.prefix6, 0);
946 }
947 }
948
949 static void if_down_del_nbr_connected(struct interface *ifp)
950 {
951 struct nbr_connected *nbr_connected;
952 struct listnode *node, *nnode;
953
954 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode,
955 nbr_connected)) {
956 listnode_delete(ifp->nbr_connected, nbr_connected);
957 nbr_connected_free(nbr_connected);
958 }
959 }
960
961 void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe)
962 {
963 if (ifp->info) {
964 struct zebra_if *zif = (struct zebra_if *)ifp->info;
965
966 nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
967 }
968 }
969
970 void if_nhg_dependents_del(struct interface *ifp, struct nhg_hash_entry *nhe)
971 {
972 if (ifp->info) {
973 struct zebra_if *zif = (struct zebra_if *)ifp->info;
974
975 nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
976 }
977 }
978
979 unsigned int if_nhg_dependents_count(const struct interface *ifp)
980 {
981 if (ifp->info) {
982 struct zebra_if *zif = (struct zebra_if *)ifp->info;
983
984 return nhg_connected_tree_count(&zif->nhg_dependents);
985 }
986
987 return 0;
988 }
989
990
991 bool if_nhg_dependents_is_empty(const struct interface *ifp)
992 {
993 if (ifp->info) {
994 struct zebra_if *zif = (struct zebra_if *)ifp->info;
995
996 return nhg_connected_tree_is_empty(&zif->nhg_dependents);
997 }
998
999 return false;
1000 }
1001
1002 /* Interface is up. */
1003 void if_up(struct interface *ifp, bool install_connected)
1004 {
1005 struct zebra_if *zif;
1006 struct interface *link_if;
1007 struct zebra_vrf *zvrf = ifp->vrf->info;
1008
1009 zif = ifp->info;
1010 zif->up_count++;
1011 frr_timestamp(2, zif->up_last, sizeof(zif->up_last));
1012
1013 /* Notify the protocol daemons. */
1014 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
1015 flog_warn(EC_ZEBRA_PTM_NOT_READY,
1016 "%s: interface %s hasn't passed ptm check",
1017 __func__, ifp->name);
1018 return;
1019 }
1020 zebra_interface_up_update(ifp);
1021
1022 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
1023
1024 rtadv_if_up(zif);
1025
1026 /* Install connected routes to the kernel. */
1027 if (install_connected)
1028 if_install_connected(ifp);
1029
1030 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1031 * are checked to see if (remote) neighbor entries need to be installed
1032 * on them for ARP suppression.
1033 */
1034 if (IS_ZEBRA_IF_VXLAN(ifp))
1035 zebra_vxlan_if_up(ifp);
1036 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1037 link_if = ifp;
1038 zebra_vxlan_svi_up(ifp, link_if);
1039 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1040 link_if = if_lookup_by_index_per_ns(zvrf->zns,
1041 zif->link_ifindex);
1042 if (link_if)
1043 zebra_vxlan_svi_up(ifp, link_if);
1044 } else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
1045 zebra_vxlan_macvlan_up(ifp);
1046 }
1047
1048 if (zif->es_info.es)
1049 zebra_evpn_es_if_oper_state_change(zif, true /*up*/);
1050
1051 if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
1052 zebra_evpn_mh_uplink_oper_update(zif);
1053
1054 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
1055 &zif->speed_update);
1056 thread_ignore_late_timer(zif->speed_update);
1057 }
1058
1059 /* Interface goes down. We have to manage different behavior of based
1060 OS. */
1061 void if_down(struct interface *ifp)
1062 {
1063 struct zebra_if *zif;
1064 struct interface *link_if;
1065 struct zebra_vrf *zvrf = ifp->vrf->info;
1066
1067 zif = ifp->info;
1068 zif->down_count++;
1069 frr_timestamp(2, zif->down_last, sizeof(zif->down_last));
1070
1071 if_down_nhg_dependents(ifp);
1072
1073 /* Handle interface down for specific types for EVPN. Non-VxLAN
1074 * interfaces
1075 * are checked to see if (remote) neighbor entries need to be purged
1076 * for ARP suppression.
1077 */
1078 if (IS_ZEBRA_IF_VXLAN(ifp))
1079 zebra_vxlan_if_down(ifp);
1080 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1081 link_if = ifp;
1082 zebra_vxlan_svi_down(ifp, link_if);
1083 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1084 link_if = if_lookup_by_index_per_ns(zvrf->zns,
1085 zif->link_ifindex);
1086 if (link_if)
1087 zebra_vxlan_svi_down(ifp, link_if);
1088 } else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
1089 zebra_vxlan_macvlan_down(ifp);
1090 }
1091
1092 if (zif->es_info.es)
1093 zebra_evpn_es_if_oper_state_change(zif, false /*up*/);
1094
1095 if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
1096 zebra_evpn_mh_uplink_oper_update(zif);
1097
1098 /* Notify to the protocol daemons. */
1099 zebra_interface_down_update(ifp);
1100
1101 /* Uninstall connected routes from the kernel. */
1102 if_uninstall_connected(ifp);
1103
1104 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
1105
1106 /* Delete all neighbor addresses learnt through IPv6 RA */
1107 if_down_del_nbr_connected(ifp);
1108 }
1109
1110 void if_refresh(struct interface *ifp)
1111 {
1112 #ifndef GNU_LINUX
1113 if_get_flags(ifp);
1114 #endif
1115 }
1116
1117 void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1118 ns_id_t ns_id)
1119 {
1120 struct zebra_if *zif;
1121
1122 if (IS_ZEBRA_IF_VETH(ifp))
1123 return;
1124 zif = (struct zebra_if *)ifp->info;
1125 zif->link_ifindex = link_ifindex;
1126 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
1127 link_ifindex);
1128 }
1129
1130 /*
1131 * during initial link dump kernel does not order lower devices before
1132 * upper devices so we need to fixup link dependencies at the end of dump
1133 */
1134 void zebra_if_update_all_links(struct zebra_ns *zns)
1135 {
1136 struct route_node *rn;
1137 struct interface *ifp;
1138 struct zebra_if *zif;
1139
1140 if (IS_ZEBRA_DEBUG_KERNEL)
1141 zlog_info("fixup link dependencies");
1142
1143 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1144 ifp = (struct interface *)rn->info;
1145 if (!ifp)
1146 continue;
1147 zif = ifp->info;
1148 /* update bond-member to bond linkages */
1149 if ((IS_ZEBRA_IF_BOND_SLAVE(ifp))
1150 && (zif->bondslave_info.bond_ifindex != IFINDEX_INTERNAL)
1151 && !zif->bondslave_info.bond_if) {
1152 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
1153 zlog_debug("bond mbr %s map to bond %d",
1154 zif->ifp->name,
1155 zif->bondslave_info.bond_ifindex);
1156 zebra_l2_map_slave_to_bond(zif, ifp->vrf->vrf_id);
1157 }
1158
1159 /* update SVI linkages */
1160 if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
1161 zif->link = if_lookup_by_index_per_ns(
1162 zns, zif->link_ifindex);
1163 if (IS_ZEBRA_DEBUG_KERNEL)
1164 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1165 ifp->name, ifp->ifindex,
1166 zif->link?zif->link->name:"unk",
1167 zif->link_ifindex);
1168 }
1169
1170 /* Update VLAN<=>SVI map */
1171 if (IS_ZEBRA_IF_VLAN(ifp))
1172 zebra_evpn_acc_bd_svi_set(zif, NULL,
1173 !!if_is_operative(ifp));
1174 }
1175 }
1176
1177 static bool if_ignore_set_protodown(const struct interface *ifp, bool new_down,
1178 uint32_t new_protodown_rc)
1179 {
1180 struct zebra_if *zif;
1181 bool old_down, old_set_down, old_unset_down;
1182
1183 zif = ifp->info;
1184
1185 /* Current state as we know it */
1186 old_down = !!(ZEBRA_IF_IS_PROTODOWN(zif));
1187 old_set_down = !!CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
1188 old_unset_down = !!CHECK_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN);
1189
1190 if (new_protodown_rc == zif->protodown_rc) {
1191 /* Early return if already down & reason bitfield matches */
1192 if (new_down == old_down) {
1193 if (IS_ZEBRA_DEBUG_KERNEL)
1194 zlog_debug(
1195 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already set (reason bitfield: old 0x%x new 0x%x)",
1196 new_down ? "on" : "off", ifp->name,
1197 ifp->ifindex, new_down ? "on" : "off",
1198 zif->protodown_rc, new_protodown_rc);
1199
1200 return true;
1201 }
1202
1203 /* Early return if already set queued & reason bitfield matches
1204 */
1205 if (new_down && old_set_down) {
1206 if (IS_ZEBRA_DEBUG_KERNEL)
1207 zlog_debug(
1208 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already queued to dplane (reason bitfield: old 0x%x new 0x%x)",
1209 new_down ? "on" : "off", ifp->name,
1210 ifp->ifindex, new_down ? "on" : "off",
1211 zif->protodown_rc, new_protodown_rc);
1212
1213 return true;
1214 }
1215
1216 /* Early return if already unset queued & reason bitfield
1217 * matches */
1218 if (!new_down && old_unset_down) {
1219 if (IS_ZEBRA_DEBUG_KERNEL)
1220 zlog_debug(
1221 "Ignoring request to set protodown %s for interface %s (%u): protodown %s is already queued to dplane (reason bitfield: old 0x%x new 0x%x)",
1222 new_down ? "on" : "off", ifp->name,
1223 ifp->ifindex, new_down ? "on" : "off",
1224 zif->protodown_rc, new_protodown_rc);
1225
1226 return true;
1227 }
1228 }
1229
1230 return false;
1231 }
1232
1233 int zebra_if_update_protodown_rc(struct interface *ifp, bool new_down,
1234 uint32_t new_protodown_rc)
1235 {
1236 struct zebra_if *zif;
1237
1238 zif = ifp->info;
1239
1240 /* Check if we already have this state or it's queued */
1241 if (if_ignore_set_protodown(ifp, new_down, new_protodown_rc))
1242 return 1;
1243
1244 zlog_info(
1245 "Setting protodown %s - interface %s (%u): reason bitfield change from 0x%x --> 0x%x",
1246 new_down ? "on" : "off", ifp->name, ifp->ifindex,
1247 zif->protodown_rc, new_protodown_rc);
1248
1249 zif->protodown_rc = new_protodown_rc;
1250
1251 if (new_down)
1252 SET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
1253 else
1254 SET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN);
1255
1256 #ifdef HAVE_NETLINK
1257 dplane_intf_update(ifp);
1258 #else
1259 zlog_warn("Protodown is not supported on this platform");
1260 #endif
1261 return 0;
1262 }
1263
1264 int zebra_if_set_protodown(struct interface *ifp, bool new_down,
1265 enum protodown_reasons new_reason)
1266 {
1267 struct zebra_if *zif;
1268 uint32_t new_protodown_rc;
1269
1270 zif = ifp->info;
1271
1272 if (new_down)
1273 new_protodown_rc = zif->protodown_rc | new_reason;
1274 else
1275 new_protodown_rc = zif->protodown_rc & ~new_reason;
1276
1277 return zebra_if_update_protodown_rc(ifp, new_down, new_protodown_rc);
1278 }
1279
1280 /*
1281 * Handle an interface events based on info in a dplane context object.
1282 * This runs in the main pthread, using the info in the context object to
1283 * modify an interface.
1284 */
1285 static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx,
1286 struct interface *ifp)
1287 {
1288 uint8_t flags = 0;
1289 const char *label = NULL;
1290 uint32_t metric = METRIC_MAX;
1291 const struct prefix *addr, *dest = NULL;
1292 enum dplane_op_e op;
1293
1294 op = dplane_ctx_get_op(ctx);
1295 addr = dplane_ctx_get_intf_addr(ctx);
1296
1297 if (IS_ZEBRA_DEBUG_KERNEL)
1298 zlog_debug("%s: %s: ifindex %s(%u), addr %pFX", __func__,
1299 dplane_op2str(dplane_ctx_get_op(ctx)), ifp->name,
1300 ifp->ifindex, addr);
1301
1302 /* Is there a peer or broadcast address? */
1303 dest = dplane_ctx_get_intf_dest(ctx);
1304 if (dest->prefixlen == 0)
1305 dest = NULL;
1306
1307 if (dplane_ctx_intf_is_connected(ctx))
1308 SET_FLAG(flags, ZEBRA_IFA_PEER);
1309
1310 /* Flags. */
1311 if (dplane_ctx_intf_is_secondary(ctx))
1312 SET_FLAG(flags, ZEBRA_IFA_SECONDARY);
1313
1314 /* Label? */
1315 if (dplane_ctx_intf_has_label(ctx))
1316 label = dplane_ctx_get_intf_label(ctx);
1317
1318 if (label && strcmp(ifp->name, label) == 0)
1319 label = NULL;
1320
1321 metric = dplane_ctx_get_intf_metric(ctx);
1322
1323 /* Register interface address to the interface. */
1324 if (addr->family == AF_INET) {
1325 if (op == DPLANE_OP_INTF_ADDR_ADD)
1326 connected_add_ipv4(
1327 ifp, flags, &addr->u.prefix4, addr->prefixlen,
1328 dest ? &dest->u.prefix4 : NULL, label, metric);
1329 else if (CHECK_FLAG(flags, ZEBRA_IFA_PEER)) {
1330 /* Delete with a peer address */
1331 connected_delete_ipv4(ifp, flags, &addr->u.prefix4,
1332 addr->prefixlen,
1333 &dest->u.prefix4);
1334 } else
1335 connected_delete_ipv4(ifp, flags, &addr->u.prefix4,
1336 addr->prefixlen, NULL);
1337 }
1338
1339 if (addr->family == AF_INET6) {
1340 if (op == DPLANE_OP_INTF_ADDR_ADD) {
1341 connected_add_ipv6(ifp, flags, &addr->u.prefix6,
1342 dest ? &dest->u.prefix6 : NULL,
1343 addr->prefixlen, label, metric);
1344 } else
1345 connected_delete_ipv6(ifp, &addr->u.prefix6, NULL,
1346 addr->prefixlen);
1347 }
1348
1349 /*
1350 * Linux kernel does not send route delete on interface down/addr del
1351 * so we have to re-process routes it owns (i.e. kernel routes)
1352 */
1353 if (op != DPLANE_OP_INTF_ADDR_ADD)
1354 rib_update(RIB_UPDATE_KERNEL);
1355 }
1356
1357 static void zebra_if_update_ctx(struct zebra_dplane_ctx *ctx,
1358 struct interface *ifp)
1359 {
1360 enum zebra_dplane_result dp_res;
1361 struct zebra_if *zif;
1362 bool pd_reason_val;
1363 bool down;
1364
1365 dp_res = dplane_ctx_get_status(ctx);
1366 pd_reason_val = dplane_ctx_get_intf_pd_reason_val(ctx);
1367 down = dplane_ctx_intf_is_protodown(ctx);
1368
1369 if (IS_ZEBRA_DEBUG_KERNEL)
1370 zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason %d",
1371 __func__, dplane_op2str(dplane_ctx_get_op(ctx)),
1372 ifp->name, ifp->ifindex, down ? "on" : "off",
1373 pd_reason_val);
1374
1375 zif = ifp->info;
1376 if (!zif) {
1377 if (IS_ZEBRA_DEBUG_KERNEL)
1378 zlog_debug("%s: if %s(%u) zebra info pointer is NULL",
1379 __func__, ifp->name, ifp->ifindex);
1380 return;
1381 }
1382
1383 if (dp_res != ZEBRA_DPLANE_REQUEST_SUCCESS) {
1384 if (IS_ZEBRA_DEBUG_KERNEL)
1385 zlog_debug("%s: if %s(%u) dplane update failed",
1386 __func__, ifp->name, ifp->ifindex);
1387 goto done;
1388 }
1389
1390 /* Update our info */
1391 COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, down);
1392
1393 done:
1394 /* Clear our dplane flags */
1395 UNSET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
1396 UNSET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN);
1397 }
1398
1399 /*
1400 * Handle netconf change from a dplane context object; runs in the main
1401 * pthread so it can update zebra data structs.
1402 */
1403 static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
1404 struct interface *ifp,
1405 ifindex_t ifindex)
1406 {
1407 struct zebra_if *zif = NULL;
1408 afi_t afi;
1409 enum dplane_netconf_status_e mpls, mcast_on, linkdown;
1410 bool *mcast_set, *linkdown_set;
1411
1412 afi = dplane_ctx_get_afi(ctx);
1413 mpls = dplane_ctx_get_netconf_mpls(ctx);
1414 linkdown = dplane_ctx_get_netconf_linkdown(ctx);
1415 mcast_on = dplane_ctx_get_netconf_mcast(ctx);
1416
1417 if (ifindex == DPLANE_NETCONF_IFINDEX_ALL) {
1418 if (afi == AFI_IP) {
1419 mcast_set = &zrouter.all_mc_forwardingv4;
1420 linkdown_set = &zrouter.all_linkdownv4;
1421 } else {
1422 mcast_set = &zrouter.all_mc_forwardingv6;
1423 linkdown_set = &zrouter.all_linkdownv6;
1424 }
1425 } else if (ifindex == DPLANE_NETCONF_IFINDEX_DEFAULT) {
1426 if (afi == AFI_IP) {
1427 mcast_set = &zrouter.default_mc_forwardingv4;
1428 linkdown_set = &zrouter.default_linkdownv4;
1429 } else {
1430 mcast_set = &zrouter.default_mc_forwardingv6;
1431 linkdown_set = &zrouter.default_linkdownv6;
1432 }
1433 } else {
1434 zif = ifp ? ifp->info : NULL;
1435 if (!zif) {
1436 if (IS_ZEBRA_DEBUG_KERNEL)
1437 zlog_debug(
1438 "%s: if %s(%u) zebra info pointer is NULL",
1439 __func__, ifp->name, ifp->ifindex);
1440 return;
1441 }
1442 if (afi == AFI_IP) {
1443 mcast_set = &zif->v4mcast_on;
1444 linkdown_set = &zif->linkdown;
1445 } else {
1446 mcast_set = &zif->v6mcast_on;
1447 linkdown_set = &zif->linkdownv6;
1448 }
1449
1450 /*
1451 * mpls netconf data is neither v4 or v6 it's AF_MPLS!
1452 */
1453 if (mpls == DPLANE_NETCONF_STATUS_ENABLED) {
1454 zif->mpls = true;
1455 zebra_mpls_turned_on();
1456 } else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
1457 zif->mpls = false;
1458 }
1459
1460 if (linkdown == DPLANE_NETCONF_STATUS_ENABLED)
1461 *linkdown_set = true;
1462 else if (linkdown == DPLANE_NETCONF_STATUS_DISABLED)
1463 *linkdown_set = false;
1464
1465 if (mcast_on == DPLANE_NETCONF_STATUS_ENABLED)
1466 *mcast_set = true;
1467 else if (mcast_on == DPLANE_NETCONF_STATUS_DISABLED)
1468 *mcast_set = false;
1469
1470 if (IS_ZEBRA_DEBUG_KERNEL)
1471 zlog_debug(
1472 "%s: afi: %d if %s, ifindex %d, mpls %s mc_forwarding: %s linkdown %s",
1473 __func__, afi, ifp ? ifp->name : "Global",
1474 ifp ? ifp->ifindex : ifindex,
1475 (zif ? (zif->mpls ? "ON" : "OFF") : "OFF"),
1476 (*mcast_set ? "ON" : "OFF"),
1477 (*linkdown_set ? "ON" : "OFF"));
1478 }
1479
1480 void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
1481 {
1482 struct zebra_ns *zns;
1483 struct interface *ifp;
1484 ns_id_t ns_id;
1485 enum dplane_op_e op;
1486 enum zebra_dplane_result dp_res;
1487 ifindex_t ifindex;
1488
1489 ns_id = dplane_ctx_get_ns_id(ctx);
1490 dp_res = dplane_ctx_get_status(ctx);
1491 op = dplane_ctx_get_op(ctx);
1492 ifindex = dplane_ctx_get_ifindex(ctx);
1493
1494 if (IS_ZEBRA_DEBUG_DPLANE_DETAIL || IS_ZEBRA_DEBUG_KERNEL)
1495 zlog_debug("Intf dplane ctx %p, op %s, ifindex (%u), result %s",
1496 ctx, dplane_op2str(op), ifindex,
1497 dplane_res2str(dp_res));
1498
1499 zns = zebra_ns_lookup(ns_id);
1500 if (zns == NULL) {
1501 /* No ns - deleted maybe? */
1502 if (IS_ZEBRA_DEBUG_KERNEL)
1503 zlog_debug("%s: can't find zns id %u", __func__, ns_id);
1504
1505 return;
1506 }
1507
1508 ifp = if_lookup_by_index_per_ns(zns, ifindex);
1509 if (ifp == NULL) {
1510 if (op != DPLANE_OP_INTF_NETCONFIG ||
1511 (ifindex != -1 && ifindex != -2)) {
1512 if (IS_ZEBRA_DEBUG_KERNEL)
1513 zlog_debug(
1514 "%s: can't find ifp at nsid %u index %d",
1515 __func__, ns_id, ifindex);
1516
1517 return;
1518 }
1519 }
1520
1521 switch (op) {
1522 case DPLANE_OP_INTF_ADDR_ADD:
1523 case DPLANE_OP_INTF_ADDR_DEL:
1524 zebra_if_addr_update_ctx(ctx, ifp);
1525 break;
1526
1527 case DPLANE_OP_INTF_INSTALL:
1528 case DPLANE_OP_INTF_UPDATE:
1529 case DPLANE_OP_INTF_DELETE:
1530 zebra_if_update_ctx(ctx, ifp);
1531 break;
1532
1533 case DPLANE_OP_INTF_NETCONFIG:
1534 zebra_if_netconf_update_ctx(ctx, ifp, ifindex);
1535 break;
1536
1537 case DPLANE_OP_ROUTE_INSTALL:
1538 case DPLANE_OP_ROUTE_UPDATE:
1539 case DPLANE_OP_ROUTE_DELETE:
1540 case DPLANE_OP_NH_DELETE:
1541 case DPLANE_OP_NH_INSTALL:
1542 case DPLANE_OP_NH_UPDATE:
1543 case DPLANE_OP_ROUTE_NOTIFY:
1544 case DPLANE_OP_LSP_INSTALL:
1545 case DPLANE_OP_LSP_UPDATE:
1546 case DPLANE_OP_LSP_DELETE:
1547 case DPLANE_OP_LSP_NOTIFY:
1548 case DPLANE_OP_PW_INSTALL:
1549 case DPLANE_OP_PW_UNINSTALL:
1550 case DPLANE_OP_SYS_ROUTE_ADD:
1551 case DPLANE_OP_SYS_ROUTE_DELETE:
1552 case DPLANE_OP_ADDR_INSTALL:
1553 case DPLANE_OP_ADDR_UNINSTALL:
1554 case DPLANE_OP_MAC_INSTALL:
1555 case DPLANE_OP_MAC_DELETE:
1556 case DPLANE_OP_NEIGH_INSTALL:
1557 case DPLANE_OP_NEIGH_UPDATE:
1558 case DPLANE_OP_NEIGH_DELETE:
1559 case DPLANE_OP_NEIGH_IP_INSTALL:
1560 case DPLANE_OP_NEIGH_IP_DELETE:
1561 case DPLANE_OP_VTEP_ADD:
1562 case DPLANE_OP_VTEP_DELETE:
1563 case DPLANE_OP_RULE_ADD:
1564 case DPLANE_OP_RULE_DELETE:
1565 case DPLANE_OP_RULE_UPDATE:
1566 case DPLANE_OP_NEIGH_DISCOVER:
1567 case DPLANE_OP_BR_PORT_UPDATE:
1568 case DPLANE_OP_NONE:
1569 case DPLANE_OP_IPTABLE_ADD:
1570 case DPLANE_OP_IPTABLE_DELETE:
1571 case DPLANE_OP_IPSET_ADD:
1572 case DPLANE_OP_IPSET_DELETE:
1573 case DPLANE_OP_IPSET_ENTRY_ADD:
1574 case DPLANE_OP_IPSET_ENTRY_DELETE:
1575 case DPLANE_OP_NEIGH_TABLE_UPDATE:
1576 case DPLANE_OP_GRE_SET:
1577 case DPLANE_OP_TC_QDISC_INSTALL:
1578 case DPLANE_OP_TC_QDISC_UNINSTALL:
1579 case DPLANE_OP_TC_CLASS_ADD:
1580 case DPLANE_OP_TC_CLASS_DELETE:
1581 case DPLANE_OP_TC_CLASS_UPDATE:
1582 case DPLANE_OP_TC_FILTER_ADD:
1583 case DPLANE_OP_TC_FILTER_DELETE:
1584 case DPLANE_OP_TC_FILTER_UPDATE:
1585 break; /* should never hit here */
1586 }
1587 }
1588
1589 /* Dump if address information to vty. */
1590 static void connected_dump_vty(struct vty *vty, json_object *json,
1591 struct connected *connected)
1592 {
1593 struct prefix *p;
1594 json_object *json_addr = NULL;
1595
1596 /* Print interface address. */
1597 p = connected->address;
1598
1599 if (json) {
1600 json_addr = json_object_new_object();
1601 json_object_array_add(json, json_addr);
1602 json_object_string_addf(json_addr, "address", "%pFX", p);
1603 } else {
1604 vty_out(vty, " %s %pFX", prefix_family_str(p), p);
1605 }
1606
1607 /* If there is destination address, print it. */
1608 if (CONNECTED_PEER(connected) && connected->destination) {
1609 if (json) {
1610 json_object_string_addf(json_addr, "peer", "%pFX",
1611 connected->destination);
1612 } else {
1613 vty_out(vty, " peer %pFX", connected->destination);
1614 }
1615 }
1616
1617 if (json)
1618 json_object_boolean_add(
1619 json_addr, "secondary",
1620 CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY));
1621 else if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
1622 vty_out(vty, " secondary");
1623
1624 if (json)
1625 json_object_boolean_add(
1626 json_addr, "unnumbered",
1627 CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED));
1628 else if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
1629 vty_out(vty, " unnumbered");
1630
1631 if (connected->label) {
1632 if (json)
1633 json_object_string_add(json_addr, "label",
1634 connected->label);
1635 else
1636 vty_out(vty, " %s", connected->label);
1637 }
1638
1639 if (!json)
1640 vty_out(vty, "\n");
1641 }
1642
1643 /* Dump interface neighbor address information to vty. */
1644 static void nbr_connected_dump_vty(struct vty *vty, json_object *json,
1645 struct nbr_connected *connected)
1646 {
1647 struct prefix *p;
1648 char buf[PREFIX2STR_BUFFER];
1649
1650 /* Print interface address. */
1651 p = connected->address;
1652 if (json)
1653 json_array_string_add(json, prefix2str(p, buf, sizeof(buf)));
1654 else
1655 vty_out(vty, " %s %pFX\n", prefix_family_str(p), p);
1656 }
1657
1658 static const char *
1659 zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type)
1660 {
1661 switch (zif_slave_type) {
1662 case ZEBRA_IF_SLAVE_BRIDGE:
1663 return "Bridge";
1664 case ZEBRA_IF_SLAVE_VRF:
1665 return "Vrf";
1666 case ZEBRA_IF_SLAVE_BOND:
1667 return "Bond";
1668 case ZEBRA_IF_SLAVE_OTHER:
1669 return "Other";
1670 case ZEBRA_IF_SLAVE_NONE:
1671 return "None";
1672 }
1673 return "None";
1674 }
1675
1676 static const char *zebra_ziftype_2str(enum zebra_iftype zif_type)
1677 {
1678 switch (zif_type) {
1679 case ZEBRA_IF_OTHER:
1680 return "Other";
1681
1682 case ZEBRA_IF_BRIDGE:
1683 return "Bridge";
1684
1685 case ZEBRA_IF_VLAN:
1686 return "Vlan";
1687
1688 case ZEBRA_IF_VXLAN:
1689 return "Vxlan";
1690
1691 case ZEBRA_IF_VRF:
1692 return "VRF";
1693
1694 case ZEBRA_IF_VETH:
1695 return "VETH";
1696
1697 case ZEBRA_IF_BOND:
1698 return "bond";
1699
1700 case ZEBRA_IF_BOND_SLAVE:
1701 return "bond_slave";
1702
1703 case ZEBRA_IF_MACVLAN:
1704 return "macvlan";
1705
1706 case ZEBRA_IF_GRE:
1707 return "GRE";
1708
1709 default:
1710 return "Unknown";
1711 }
1712 }
1713
1714 /* Interface's brief information print out to vty interface. */
1715 static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
1716 {
1717 struct connected *connected;
1718 struct listnode *node;
1719 struct route_node *rn;
1720 struct zebra_if *zebra_if;
1721 struct prefix *p;
1722 struct interface *ifp;
1723 bool print_header = true;
1724
1725 FOR_ALL_INTERFACES (vrf, ifp) {
1726 bool first_pfx_printed = false;
1727
1728 if (print_header) {
1729 vty_out(vty, "%-16s%-8s%-16s%s\n", "Interface",
1730 "Status", "VRF", "Addresses");
1731 vty_out(vty, "%-16s%-8s%-16s%s\n", "---------",
1732 "------", "---", "---------");
1733 print_header = false; /* We have at least 1 iface */
1734 }
1735 zebra_if = ifp->info;
1736
1737 vty_out(vty, "%-16s", ifp->name);
1738
1739 if (if_is_up(ifp))
1740 vty_out(vty, "%-8s", "up");
1741 else
1742 vty_out(vty, "%-8s", "down");
1743
1744 vty_out(vty, "%-16s", vrf->name);
1745
1746 for (rn = route_top(zebra_if->ipv4_subnets); rn;
1747 rn = route_next(rn)) {
1748 if (!rn->info)
1749 continue;
1750 uint32_t list_size = listcount((struct list *)rn->info);
1751
1752 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1753 connected)) {
1754 if (!CHECK_FLAG(connected->flags,
1755 ZEBRA_IFA_SECONDARY)) {
1756 p = connected->address;
1757 if (first_pfx_printed) {
1758 /* padding to prepare row only
1759 * for ip addr */
1760 vty_out(vty, "%-40s", "");
1761 if (list_size > 1)
1762 vty_out(vty, "+ ");
1763 vty_out(vty, "%pFX\n", p);
1764 } else {
1765 if (list_size > 1)
1766 vty_out(vty, "+ ");
1767 vty_out(vty, "%pFX\n", p);
1768 }
1769 first_pfx_printed = true;
1770 break;
1771 }
1772 }
1773 }
1774
1775 uint32_t v6_list_size = 0;
1776 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1777 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1778 && (connected->address->family == AF_INET6))
1779 v6_list_size++;
1780 }
1781 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1782 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1783 && !CHECK_FLAG(connected->flags,
1784 ZEBRA_IFA_SECONDARY)
1785 && (connected->address->family == AF_INET6)) {
1786 p = connected->address;
1787 /* Don't print link local pfx */
1788 if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
1789 if (first_pfx_printed) {
1790 /* padding to prepare row only
1791 * for ip addr */
1792 vty_out(vty, "%-40s", "");
1793 if (v6_list_size > 1)
1794 vty_out(vty, "+ ");
1795 vty_out(vty, "%pFX\n", p);
1796 } else {
1797 if (v6_list_size > 1)
1798 vty_out(vty, "+ ");
1799 vty_out(vty, "%pFX\n", p);
1800 }
1801 first_pfx_printed = true;
1802 break;
1803 }
1804 }
1805 }
1806 if (!first_pfx_printed)
1807 vty_out(vty, "\n");
1808 }
1809 vty_out(vty, "\n");
1810 }
1811
1812 static void ifs_dump_brief_vty_json(json_object *json, struct vrf *vrf)
1813 {
1814 struct connected *connected;
1815 struct listnode *node;
1816 struct interface *ifp;
1817
1818 FOR_ALL_INTERFACES (vrf, ifp) {
1819 json_object *json_if;
1820 json_object *json_addrs;
1821
1822 json_if = json_object_new_object();
1823 json_object_object_add(json, ifp->name, json_if);
1824
1825 json_object_string_add(json_if, "status",
1826 if_is_up(ifp) ? "up" : "down");
1827 json_object_string_add(json_if, "vrfName", vrf->name);
1828
1829 json_addrs = json_object_new_array();
1830 json_object_object_add(json_if, "addresses", json_addrs);
1831 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1832 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1833 && !CHECK_FLAG(connected->flags,
1834 ZEBRA_IFA_SECONDARY)
1835 && !(connected->address->family == AF_INET6
1836 && IN6_IS_ADDR_LINKLOCAL(
1837 &connected->address->u.prefix6))) {
1838 char buf[PREFIX2STR_BUFFER];
1839
1840 json_array_string_add(
1841 json_addrs,
1842 prefix2str(connected->address, buf,
1843 sizeof(buf)));
1844 }
1845 }
1846 }
1847 }
1848
1849 const char *zebra_protodown_rc_str(uint32_t protodown_rc, char *pd_buf,
1850 uint32_t pd_buf_len)
1851 {
1852 pd_buf[0] = '\0';
1853 size_t len;
1854
1855 strlcat(pd_buf, "(", pd_buf_len);
1856
1857 if (CHECK_FLAG(protodown_rc, ZEBRA_PROTODOWN_EXTERNAL))
1858 strlcat(pd_buf, "external,", pd_buf_len);
1859
1860 if (CHECK_FLAG(protodown_rc, ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY))
1861 strlcat(pd_buf, "startup-delay,", pd_buf_len);
1862
1863 if (CHECK_FLAG(protodown_rc, ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN))
1864 strlcat(pd_buf, "uplinks-down,", pd_buf_len);
1865
1866 if (CHECK_FLAG(protodown_rc, ZEBRA_PROTODOWN_VRRP))
1867 strlcat(pd_buf, "vrrp,", pd_buf_len);
1868
1869 if (CHECK_FLAG(protodown_rc, ZEBRA_PROTODOWN_SHARP))
1870 strlcat(pd_buf, "sharp,", pd_buf_len);
1871
1872 len = strnlen(pd_buf, pd_buf_len);
1873
1874 /* Remove trailing comma */
1875 if (pd_buf[len - 1] == ',')
1876 pd_buf[len - 1] = '\0';
1877
1878 strlcat(pd_buf, ")", pd_buf_len);
1879
1880 return pd_buf;
1881 }
1882
1883 static inline bool if_is_protodown_applicable(struct interface *ifp)
1884 {
1885 if (IS_ZEBRA_IF_BOND(ifp))
1886 return false;
1887
1888 return true;
1889 }
1890
1891 /* Interface's information print out to vty interface. */
1892 static void if_dump_vty(struct vty *vty, struct interface *ifp)
1893 {
1894 struct connected *connected;
1895 struct nbr_connected *nbr_connected;
1896 struct listnode *node;
1897 struct route_node *rn;
1898 struct zebra_if *zebra_if;
1899 char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
1900
1901 zebra_if = ifp->info;
1902
1903 vty_out(vty, "Interface %s is ", ifp->name);
1904 if (if_is_up(ifp)) {
1905 vty_out(vty, "up, line protocol ");
1906
1907 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1908 if (if_is_running(ifp))
1909 vty_out(vty, "is up\n");
1910 else
1911 vty_out(vty, "is down\n");
1912 } else {
1913 vty_out(vty, "detection is disabled\n");
1914 }
1915 } else {
1916 vty_out(vty, "down\n");
1917 }
1918
1919 vty_out(vty, " Link ups: %5u last: %s\n", zebra_if->up_count,
1920 zebra_if->up_last[0] ? zebra_if->up_last : "(never)");
1921 vty_out(vty, " Link downs: %5u last: %s\n", zebra_if->down_count,
1922 zebra_if->down_last[0] ? zebra_if->down_last : "(never)");
1923
1924 zebra_ptm_show_status(vty, NULL, ifp);
1925
1926 vty_out(vty, " vrf: %s\n", ifp->vrf->name);
1927
1928 if (ifp->desc)
1929 vty_out(vty, " Description: %s\n", ifp->desc);
1930 if (zebra_if->desc)
1931 vty_out(vty, " OS Description: %s\n", zebra_if->desc);
1932
1933 if (ifp->ifindex == IFINDEX_INTERNAL) {
1934 vty_out(vty, " pseudo interface\n");
1935 return;
1936 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1937 vty_out(vty, " index %d inactive interface\n", ifp->ifindex);
1938 return;
1939 }
1940
1941 vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
1942 ifp->metric, ifp->mtu, ifp->speed);
1943 if (ifp->mtu6 != ifp->mtu)
1944 vty_out(vty, "mtu6 %d ", ifp->mtu6);
1945 vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
1946
1947 if (zebra_if->mpls)
1948 vty_out(vty, " MPLS enabled\n");
1949
1950 if (zebra_if->linkdown)
1951 vty_out(vty, " Ignore all v4 routes with linkdown\n");
1952 if (zebra_if->linkdownv6)
1953 vty_out(vty, " Ignore all v6 routes with linkdown\n");
1954
1955 if (zebra_if->v4mcast_on)
1956 vty_out(vty, " v4 Multicast forwarding is on\n");
1957 if (zebra_if->v6mcast_on)
1958 vty_out(vty, " v6 Multicast forwarding is on\n");
1959
1960 /* Hardware address. */
1961 vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
1962 if (ifp->hw_addr_len != 0) {
1963 int i;
1964
1965 vty_out(vty, " HWaddr: ");
1966 for (i = 0; i < ifp->hw_addr_len; i++)
1967 vty_out(vty, "%s%02x", i == 0 ? "" : ":",
1968 ifp->hw_addr[i]);
1969 vty_out(vty, "\n");
1970 }
1971
1972 /* Bandwidth in Mbps */
1973 if (ifp->bandwidth != 0) {
1974 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1975 vty_out(vty, "\n");
1976 }
1977
1978 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
1979 if (!rn->info)
1980 continue;
1981
1982 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1983 connected))
1984 connected_dump_vty(vty, NULL, connected);
1985 }
1986
1987 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1988 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1989 && (connected->address->family == AF_INET6))
1990 connected_dump_vty(vty, NULL, connected);
1991 }
1992
1993 vty_out(vty, " Interface Type %s\n",
1994 zebra_ziftype_2str(zebra_if->zif_type));
1995 vty_out(vty, " Interface Slave Type %s\n",
1996 zebra_zifslavetype_2str(zebra_if->zif_slave_type));
1997
1998 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1999 struct zebra_l2info_bridge *bridge_info;
2000
2001 bridge_info = &zebra_if->l2info.br;
2002 vty_out(vty, " Bridge VLAN-aware: %s\n",
2003 bridge_info->vlan_aware ? "yes" : "no");
2004 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
2005 struct zebra_l2info_vlan *vlan_info;
2006
2007 vlan_info = &zebra_if->l2info.vl;
2008 vty_out(vty, " VLAN Id %u\n", vlan_info->vid);
2009 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
2010 struct zebra_l2info_vxlan *vxlan_info;
2011
2012 vxlan_info = &zebra_if->l2info.vxl;
2013 vty_out(vty, " VxLAN Id %u", vxlan_info->vni);
2014 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
2015 vty_out(vty, " VTEP IP: %pI4",
2016 &vxlan_info->vtep_ip);
2017 if (vxlan_info->access_vlan)
2018 vty_out(vty, " Access VLAN Id %u\n",
2019 vxlan_info->access_vlan);
2020 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
2021 vty_out(vty, " Mcast Group %pI4",
2022 &vxlan_info->mcast_grp);
2023 if (vxlan_info->ifindex_link &&
2024 (vxlan_info->link_nsid != NS_UNKNOWN)) {
2025 struct interface *ifp;
2026
2027 ifp = if_lookup_by_index_per_ns(
2028 zebra_ns_lookup(vxlan_info->link_nsid),
2029 vxlan_info->ifindex_link);
2030 vty_out(vty, " Link Interface %s",
2031 ifp == NULL ? "Unknown" :
2032 ifp->name);
2033 }
2034 vty_out(vty, "\n");
2035 } else if (IS_ZEBRA_IF_GRE(ifp)) {
2036 struct zebra_l2info_gre *gre_info;
2037
2038 gre_info = &zebra_if->l2info.gre;
2039 if (gre_info->vtep_ip.s_addr != INADDR_ANY) {
2040 vty_out(vty, " VTEP IP: %pI4", &gre_info->vtep_ip);
2041 if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY)
2042 vty_out(vty, " , remote %pI4",
2043 &gre_info->vtep_ip_remote);
2044 vty_out(vty, "\n");
2045 }
2046 if (gre_info->ifindex_link &&
2047 (gre_info->link_nsid != NS_UNKNOWN)) {
2048 struct interface *ifp;
2049
2050 ifp = if_lookup_by_index_per_ns(
2051 zebra_ns_lookup(gre_info->link_nsid),
2052 gre_info->ifindex_link);
2053 vty_out(vty, " Link Interface %s\n",
2054 ifp == NULL ? "Unknown" :
2055 ifp->name);
2056 }
2057 }
2058
2059 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
2060 struct zebra_l2info_brslave *br_slave;
2061
2062 br_slave = &zebra_if->brslave_info;
2063 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
2064 if (br_slave->br_if)
2065 vty_out(vty, " Master interface: %s\n",
2066 br_slave->br_if->name);
2067 else
2068 vty_out(vty, " Master ifindex: %u\n",
2069 br_slave->bridge_ifindex);
2070 }
2071 }
2072
2073 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
2074 struct zebra_l2info_bondslave *bond_slave;
2075
2076 bond_slave = &zebra_if->bondslave_info;
2077 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
2078 if (bond_slave->bond_if)
2079 vty_out(vty, " Master interface: %s\n",
2080 bond_slave->bond_if->name);
2081 else
2082 vty_out(vty, " Master ifindex: %u\n",
2083 bond_slave->bond_ifindex);
2084 }
2085 }
2086
2087 if (zebra_if->flags & ZIF_FLAG_LACP_BYPASS)
2088 vty_out(vty, " LACP bypass: on\n");
2089
2090 zebra_evpn_if_es_print(vty, NULL, zebra_if);
2091 vty_out(vty, " protodown: %s %s\n",
2092 (ZEBRA_IF_IS_PROTODOWN(zebra_if)) ? "on" : "off",
2093 if_is_protodown_applicable(ifp) ? "" : "(n/a)");
2094 if (zebra_if->protodown_rc)
2095 vty_out(vty, " protodown reasons: %s\n",
2096 zebra_protodown_rc_str(zebra_if->protodown_rc, pd_buf,
2097 sizeof(pd_buf)));
2098
2099 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
2100 if (zebra_if->link)
2101 vty_out(vty, " Parent interface: %s\n", zebra_if->link->name);
2102 else
2103 vty_out(vty, " Parent ifindex: %d\n", zebra_if->link_ifindex);
2104 }
2105
2106 if (HAS_LINK_PARAMS(ifp)) {
2107 int i;
2108 struct if_link_params *iflp = ifp->link_params;
2109 vty_out(vty, " Traffic Engineering Link Parameters:\n");
2110 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
2111 vty_out(vty, " TE metric %u\n", iflp->te_metric);
2112 if (IS_PARAM_SET(iflp, LP_MAX_BW))
2113 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
2114 iflp->max_bw);
2115 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2116 vty_out(vty,
2117 " Maximum Reservable Bandwidth %g (Byte/s)\n",
2118 iflp->max_rsv_bw);
2119 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2120 vty_out(vty,
2121 " Unreserved Bandwidth per Class Type in Byte/s:\n");
2122 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
2123 vty_out(vty,
2124 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
2125 i, iflp->unrsv_bw[i], i + 1,
2126 iflp->unrsv_bw[i + 1]);
2127 }
2128
2129 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2130 vty_out(vty, " Administrative Group:%u\n",
2131 iflp->admin_grp);
2132 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2133 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
2134 iflp->av_delay);
2135 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2136 vty_out(vty, " Min: %u (micro-sec.)",
2137 iflp->min_delay);
2138 vty_out(vty, " Max: %u (micro-sec.)",
2139 iflp->max_delay);
2140 }
2141 vty_out(vty, "\n");
2142 }
2143 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2144 vty_out(vty,
2145 " Link Delay Variation %u (micro-sec.)\n",
2146 iflp->delay_var);
2147 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2148 vty_out(vty, " Link Packet Loss %g (in %%)\n",
2149 iflp->pkt_loss);
2150 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2151 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
2152 iflp->ava_bw);
2153 if (IS_PARAM_SET(iflp, LP_RES_BW))
2154 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
2155 iflp->res_bw);
2156 if (IS_PARAM_SET(iflp, LP_USE_BW))
2157 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
2158 iflp->use_bw);
2159 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2160 vty_out(vty, " Neighbor ASBR IP: %pI4 AS: %u \n",
2161 &iflp->rmt_ip, iflp->rmt_as);
2162 }
2163
2164 hook_call(zebra_if_extra_info, vty, ifp);
2165
2166 if (listhead(ifp->nbr_connected))
2167 vty_out(vty, " Neighbor address(s):\n");
2168 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
2169 nbr_connected_dump_vty(vty, NULL, nbr_connected);
2170
2171 #ifdef HAVE_PROC_NET_DEV
2172 /* Statistics print out using proc file system. */
2173 vty_out(vty,
2174 " %lu input packets (%lu multicast), %lu bytes, %lu dropped\n",
2175 ifp->stats.rx_packets, ifp->stats.rx_multicast,
2176 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
2177
2178 vty_out(vty,
2179 " %lu input errors, %lu length, %lu overrun, %lu CRC, %lu frame\n",
2180 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
2181 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
2182 ifp->stats.rx_frame_errors);
2183
2184 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
2185 ifp->stats.rx_missed_errors);
2186
2187 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
2188 ifp->stats.tx_packets, ifp->stats.tx_bytes,
2189 ifp->stats.tx_dropped);
2190
2191 vty_out(vty,
2192 " %lu output errors, %lu aborted, %lu carrier, %lu fifo, %lu heartbeat\n",
2193 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
2194 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
2195 ifp->stats.tx_heartbeat_errors);
2196
2197 vty_out(vty, " %lu window, %lu collisions\n",
2198 ifp->stats.tx_window_errors, ifp->stats.collisions);
2199 #endif /* HAVE_PROC_NET_DEV */
2200
2201 #ifdef HAVE_NET_RT_IFLIST
2202 /* Statistics print out using sysctl (). */
2203 vty_out(vty,
2204 " input packets %llu, bytes %llu, dropped %llu, multicast packets %llu\n",
2205 (unsigned long long)ifp->stats.ifi_ipackets,
2206 (unsigned long long)ifp->stats.ifi_ibytes,
2207 (unsigned long long)ifp->stats.ifi_iqdrops,
2208 (unsigned long long)ifp->stats.ifi_imcasts);
2209
2210 vty_out(vty, " input errors %llu\n",
2211 (unsigned long long)ifp->stats.ifi_ierrors);
2212
2213 vty_out(vty,
2214 " output packets %llu, bytes %llu, multicast packets %llu\n",
2215 (unsigned long long)ifp->stats.ifi_opackets,
2216 (unsigned long long)ifp->stats.ifi_obytes,
2217 (unsigned long long)ifp->stats.ifi_omcasts);
2218
2219 vty_out(vty, " output errors %llu\n",
2220 (unsigned long long)ifp->stats.ifi_oerrors);
2221
2222 vty_out(vty, " collisions %llu\n",
2223 (unsigned long long)ifp->stats.ifi_collisions);
2224 #endif /* HAVE_NET_RT_IFLIST */
2225 }
2226
2227 static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
2228 json_object *json)
2229 {
2230 struct connected *connected;
2231 struct nbr_connected *nbr_connected;
2232 struct listnode *node;
2233 struct route_node *rn;
2234 struct zebra_if *zebra_if;
2235 char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
2236 char buf[BUFSIZ];
2237 json_object *json_if;
2238 json_object *json_addrs;
2239
2240 json_if = json_object_new_object();
2241 json_object_object_add(json, ifp->name, json_if);
2242
2243 if (if_is_up(ifp)) {
2244 json_object_string_add(json_if, "administrativeStatus", "up");
2245
2246 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
2247 json_object_string_add(json_if, "operationalStatus",
2248 if_is_running(ifp) ? "up"
2249 : "down");
2250 json_object_boolean_add(json_if, "linkDetection", true);
2251 } else {
2252 json_object_boolean_add(json_if, "linkDetection",
2253 false);
2254 }
2255 } else {
2256 json_object_string_add(json_if, "administrativeStatus", "down");
2257 }
2258
2259 zebra_if = ifp->info;
2260
2261 json_object_int_add(json_if, "linkUps", zebra_if->up_count);
2262 json_object_int_add(json_if, "linkDowns", zebra_if->down_count);
2263 if (zebra_if->up_last[0])
2264 json_object_string_add(json_if, "lastLinkUp",
2265 zebra_if->up_last);
2266 if (zebra_if->down_last[0])
2267 json_object_string_add(json_if, "lastLinkDown",
2268 zebra_if->down_last);
2269
2270 zebra_ptm_show_status(vty, json, ifp);
2271
2272 json_object_string_add(json_if, "vrfName", ifp->vrf->name);
2273
2274 if (ifp->desc)
2275 json_object_string_add(json_if, "description", ifp->desc);
2276 if (zebra_if->desc)
2277 json_object_string_add(json_if, "OsDescription",
2278 zebra_if->desc);
2279
2280 json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls);
2281 json_object_boolean_add(json_if, "linkDown", zebra_if->linkdown);
2282 json_object_boolean_add(json_if, "linkDownV6", zebra_if->linkdownv6);
2283 json_object_boolean_add(json_if, "mcForwardingV4",
2284 zebra_if->v4mcast_on);
2285 json_object_boolean_add(json_if, "mcForwardingV6",
2286 zebra_if->v6mcast_on);
2287
2288 if (ifp->ifindex == IFINDEX_INTERNAL) {
2289 json_object_boolean_add(json_if, "pseudoInterface", true);
2290 return;
2291 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2292 json_object_int_add(json_if, "index", ifp->ifindex);
2293 return;
2294 }
2295
2296 json_object_boolean_add(json_if, "pseudoInterface", false);
2297 json_object_int_add(json_if, "index", ifp->ifindex);
2298 json_object_int_add(json_if, "metric", ifp->metric);
2299 json_object_int_add(json_if, "mtu", ifp->mtu);
2300 if (ifp->mtu6 != ifp->mtu)
2301 json_object_int_add(json_if, "mtu6", ifp->mtu6);
2302 json_object_int_add(json_if, "speed", ifp->speed);
2303 json_object_string_add(json_if, "flags", if_flag_dump(ifp->flags));
2304
2305 /* Hardware address. */
2306 json_object_string_add(json_if, "type", if_link_type_str(ifp->ll_type));
2307 if (ifp->hw_addr_len != 0) {
2308 char hwbuf[BUFSIZ];
2309
2310 hwbuf[0] = '\0';
2311 for (int i = 0; i < ifp->hw_addr_len; i++) {
2312 snprintf(buf, sizeof(buf), "%s%02x", i == 0 ? "" : ":",
2313 ifp->hw_addr[i]);
2314 strlcat(hwbuf, buf, sizeof(hwbuf));
2315 }
2316 json_object_string_add(json_if, "hardwareAddress", hwbuf);
2317 }
2318
2319 /* Bandwidth in Mbps */
2320 if (ifp->bandwidth != 0)
2321 json_object_int_add(json_if, "bandwidth", ifp->bandwidth);
2322
2323
2324 /* IP addresses. */
2325 json_addrs = json_object_new_array();
2326 json_object_object_add(json_if, "ipAddresses", json_addrs);
2327
2328 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
2329 if (!rn->info)
2330 continue;
2331
2332 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
2333 connected))
2334 connected_dump_vty(vty, json_addrs, connected);
2335 }
2336
2337 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
2338 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2339 && (connected->address->family == AF_INET6))
2340 connected_dump_vty(vty, json_addrs, connected);
2341 }
2342
2343 json_object_string_add(json_if, "interfaceType",
2344 zebra_ziftype_2str(zebra_if->zif_type));
2345 json_object_string_add(
2346 json_if, "interfaceSlaveType",
2347 zebra_zifslavetype_2str(zebra_if->zif_slave_type));
2348
2349 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
2350 struct zebra_l2info_bridge *bridge_info;
2351
2352 bridge_info = &zebra_if->l2info.br;
2353 json_object_boolean_add(json_if, "bridgeVlanAware",
2354 bridge_info->vlan_aware);
2355 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
2356 struct zebra_l2info_vlan *vlan_info;
2357
2358 vlan_info = &zebra_if->l2info.vl;
2359 json_object_int_add(json_if, "vlanId", vlan_info->vid);
2360 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
2361 struct zebra_l2info_vxlan *vxlan_info;
2362
2363 vxlan_info = &zebra_if->l2info.vxl;
2364 json_object_int_add(json_if, "vxlanId", vxlan_info->vni);
2365 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
2366 json_object_string_addf(json_if, "vtepIp", "%pI4",
2367 &vxlan_info->vtep_ip);
2368 if (vxlan_info->access_vlan)
2369 json_object_int_add(json_if, "accessVlanId",
2370 vxlan_info->access_vlan);
2371 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
2372 json_object_string_addf(json_if, "mcastGroup", "%pI4",
2373 &vxlan_info->mcast_grp);
2374 if (vxlan_info->ifindex_link
2375 && (vxlan_info->link_nsid != NS_UNKNOWN)) {
2376 struct interface *ifp;
2377
2378 ifp = if_lookup_by_index_per_ns(
2379 zebra_ns_lookup(vxlan_info->link_nsid),
2380 vxlan_info->ifindex_link);
2381 json_object_string_add(json_if, "linkInterface",
2382 ifp == NULL ? "Unknown"
2383 : ifp->name);
2384 }
2385 } else if (IS_ZEBRA_IF_GRE(ifp)) {
2386 struct zebra_l2info_gre *gre_info;
2387
2388 gre_info = &zebra_if->l2info.gre;
2389 if (gre_info->vtep_ip.s_addr != INADDR_ANY) {
2390 json_object_string_addf(json_if, "vtepIp", "%pI4",
2391 &gre_info->vtep_ip);
2392 if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY)
2393 json_object_string_addf(
2394 json_if, "vtepRemoteIp", "%pI4",
2395 &gre_info->vtep_ip_remote);
2396 }
2397 if (gre_info->ifindex_link
2398 && (gre_info->link_nsid != NS_UNKNOWN)) {
2399 struct interface *ifp;
2400
2401 ifp = if_lookup_by_index_per_ns(
2402 zebra_ns_lookup(gre_info->link_nsid),
2403 gre_info->ifindex_link);
2404 json_object_string_add(json_if, "linkInterface",
2405 ifp == NULL ? "Unknown"
2406 : ifp->name);
2407 }
2408 }
2409
2410 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
2411 struct zebra_l2info_brslave *br_slave;
2412
2413 br_slave = &zebra_if->brslave_info;
2414 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
2415 if (br_slave->br_if)
2416 json_object_string_add(json_if,
2417 "masterInterface",
2418 br_slave->br_if->name);
2419 else
2420 json_object_int_add(json_if, "masterIfindex",
2421 br_slave->bridge_ifindex);
2422 }
2423 }
2424
2425 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
2426 struct zebra_l2info_bondslave *bond_slave;
2427
2428 bond_slave = &zebra_if->bondslave_info;
2429 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
2430 if (bond_slave->bond_if)
2431 json_object_string_add(
2432 json_if, "masterInterface",
2433 bond_slave->bond_if->name);
2434 else
2435 json_object_int_add(json_if, "masterIfindex",
2436 bond_slave->bond_ifindex);
2437 }
2438 }
2439
2440 json_object_boolean_add(
2441 json_if, "lacpBypass",
2442 CHECK_FLAG(zebra_if->flags, ZIF_FLAG_LACP_BYPASS));
2443
2444 zebra_evpn_if_es_print(vty, json_if, zebra_if);
2445
2446 if (if_is_protodown_applicable(ifp)) {
2447 json_object_string_add(
2448 json_if, "protodown",
2449 (ZEBRA_IF_IS_PROTODOWN(zebra_if)) ? "on" : "off");
2450 if (zebra_if->protodown_rc)
2451 json_object_string_add(
2452 json_if, "protodownReason",
2453 zebra_protodown_rc_str(zebra_if->protodown_rc,
2454 pd_buf, sizeof(pd_buf)));
2455 }
2456
2457 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
2458 if (zebra_if->link)
2459 json_object_string_add(json_if, "parentInterface",
2460 zebra_if->link->name);
2461 else
2462 json_object_int_add(json_if, "parentIfindex",
2463 zebra_if->link_ifindex);
2464 }
2465
2466 if (HAS_LINK_PARAMS(ifp)) {
2467 struct if_link_params *iflp = ifp->link_params;
2468 json_object *json_te;
2469
2470 json_te = json_object_new_object();
2471 json_object_object_add(
2472 json_if, "trafficEngineeringLinkParameters", json_te);
2473
2474 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
2475 json_object_int_add(json_te, "teMetric",
2476 iflp->te_metric);
2477 if (IS_PARAM_SET(iflp, LP_MAX_BW))
2478 json_object_double_add(json_te, "maximumBandwidth",
2479 iflp->max_bw);
2480 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2481 json_object_double_add(json_te,
2482 "maximumReservableBandwidth",
2483 iflp->max_rsv_bw);
2484 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2485 json_object *json_bws;
2486
2487 json_bws = json_object_new_object();
2488 json_object_object_add(json_te, "unreservedBandwidth",
2489 json_bws);
2490 for (unsigned int i = 0; i < MAX_CLASS_TYPE; ++i) {
2491 char buf_ct[64];
2492
2493 snprintf(buf_ct, sizeof(buf_ct), "classType%u",
2494 i);
2495 json_object_double_add(json_bws, buf_ct,
2496 iflp->unrsv_bw[i]);
2497 }
2498 }
2499
2500 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2501 json_object_int_add(json_te, "administrativeGroup",
2502 iflp->admin_grp);
2503 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2504 json_object_int_add(json_te, "linkDelayAverage",
2505 iflp->av_delay);
2506 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2507 json_object_int_add(json_te, "linkDelayMinimum",
2508 iflp->min_delay);
2509 json_object_int_add(json_te, "linkDelayMaximum",
2510 iflp->max_delay);
2511 }
2512 }
2513 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2514 json_object_int_add(json_te, "linkDelayVariation",
2515 iflp->delay_var);
2516 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2517 json_object_double_add(json_te, "linkPacketLoss",
2518 iflp->pkt_loss);
2519 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2520 json_object_double_add(json_te, "availableBandwidth",
2521 iflp->ava_bw);
2522 if (IS_PARAM_SET(iflp, LP_RES_BW))
2523 json_object_double_add(json_te, "residualBandwidth",
2524 iflp->res_bw);
2525 if (IS_PARAM_SET(iflp, LP_USE_BW))
2526 json_object_double_add(json_te, "utilizedBandwidth",
2527 iflp->use_bw);
2528 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2529 json_object_string_addf(json_te, "neighborAsbrIp",
2530 "%pI4", &iflp->rmt_ip);
2531 json_object_int_add(json_te, "neighborAsbrAs", iflp->rmt_as);
2532 }
2533
2534 if (listhead(ifp->nbr_connected)) {
2535 json_object *json_nbr_addrs;
2536
2537 json_nbr_addrs = json_object_new_array();
2538 json_object_object_add(json_if, "neighborIpAddresses",
2539 json_nbr_addrs);
2540
2541 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
2542 nbr_connected))
2543 nbr_connected_dump_vty(vty, json_nbr_addrs,
2544 nbr_connected);
2545 }
2546
2547 #ifdef HAVE_PROC_NET_DEV
2548 json_object_int_add(json_if, "inputPackets", stats.rx_packets);
2549 json_object_int_add(json_if, "inputBytes", ifp->stats.rx_bytes);
2550 json_object_int_add(json_if, "inputDropped", ifp->stats.rx_dropped);
2551 json_object_int_add(json_if, "inputMulticastPackets",
2552 ifp->stats.rx_multicast);
2553 json_object_int_add(json_if, "inputErrors", ifp->stats.rx_errors);
2554 json_object_int_add(json_if, "inputLengthErrors",
2555 ifp->stats.rx_length_errors);
2556 json_object_int_add(json_if, "inputOverrunErrors",
2557 ifp->stats.rx_over_errors);
2558 json_object_int_add(json_if, "inputCrcErrors",
2559 ifp->stats.rx_crc_errors);
2560 json_object_int_add(json_if, "inputFrameErrors",
2561 ifp->stats.rx_frame_errors);
2562 json_object_int_add(json_if, "inputFifoErrors",
2563 ifp->stats.rx_fifo_errors);
2564 json_object_int_add(json_if, "inputMissedErrors",
2565 ifp->stats.rx_missed_errors);
2566 json_object_int_add(json_if, "outputPackets", ifp->stats.tx_packets);
2567 json_object_int_add(json_if, "outputBytes", ifp->stats.tx_bytes);
2568 json_object_int_add(json_if, "outputDroppedPackets",
2569 ifp->stats.tx_dropped);
2570 json_object_int_add(json_if, "outputErrors", ifp->stats.tx_errors);
2571 json_object_int_add(json_if, "outputAbortedErrors",
2572 ifp->stats.tx_aborted_errors);
2573 json_object_int_add(json_if, "outputCarrierErrors",
2574 ifp->stats.tx_carrier_errors);
2575 json_object_int_add(json_if, "outputFifoErrors",
2576 ifp->stats.tx_fifo_errors);
2577 json_object_int_add(json_if, "outputHeartbeatErrors",
2578 ifp->stats.tx_heartbeat_errors);
2579 json_object_int_add(json_if, "outputWindowErrors",
2580 ifp->stats.tx_window_errors);
2581 json_object_int_add(json_if, "collisions", ifp->stats.collisions);
2582 #endif /* HAVE_PROC_NET_DEV */
2583
2584 #ifdef HAVE_NET_RT_IFLIST
2585 json_object_int_add(json_if, "inputPackets", ifp->stats.ifi_ipackets);
2586 json_object_int_add(json_if, "inputBytes", ifp->stats.ifi_ibytes);
2587 json_object_int_add(json_if, "inputDropd", ifp->stats.ifi_iqdrops);
2588 json_object_int_add(json_if, "inputMulticastPackets",
2589 ifp->stats.ifi_imcasts);
2590 json_object_int_add(json_if, "inputErrors", ifp->stats.ifi_ierrors);
2591 json_object_int_add(json_if, "outputPackets", ifp->stats.ifi_opackets);
2592 json_object_int_add(json_if, "outputBytes", ifp->stats.ifi_obytes);
2593 json_object_int_add(json_if, "outputMulticastPackets",
2594 ifp->stats.ifi_omcasts);
2595 json_object_int_add(json_if, "outputErrors", ifp->stats.ifi_oerrors);
2596 json_object_int_add(json_if, "collisions", ifp->stats.ifi_collisions);
2597 #endif /* HAVE_NET_RT_IFLIST */
2598 }
2599
2600 static void interface_update_stats(void)
2601 {
2602 #ifdef HAVE_PROC_NET_DEV
2603 /* If system has interface statistics via proc file system, update
2604 statistics. */
2605 ifstat_update_proc();
2606 #endif /* HAVE_PROC_NET_DEV */
2607 #ifdef HAVE_NET_RT_IFLIST
2608 ifstat_update_sysctl();
2609 #endif /* HAVE_NET_RT_IFLIST */
2610 }
2611
2612 #include "zebra/interface_clippy.c"
2613 /* Show all interfaces to vty. */
2614 DEFPY(show_interface, show_interface_cmd,
2615 "show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
2616 SHOW_STR
2617 "Interface status and configuration\n"
2618 VRF_CMD_HELP_STR
2619 "Interface status and configuration summary\n"
2620 JSON_STR)
2621 {
2622 struct vrf *vrf;
2623 struct interface *ifp;
2624 json_object *json = NULL;
2625
2626 interface_update_stats();
2627
2628 vrf = vrf_lookup_by_name(vrf_name);
2629 if (!vrf) {
2630 if (uj)
2631 vty_out(vty, "{}\n");
2632 else
2633 vty_out(vty, "%% VRF %s not found\n", vrf_name);
2634 return CMD_WARNING;
2635 }
2636
2637 if (uj)
2638 json = json_object_new_object();
2639
2640 if (brief) {
2641 if (json)
2642 ifs_dump_brief_vty_json(json, vrf);
2643 else
2644 ifs_dump_brief_vty(vty, vrf);
2645 } else {
2646 FOR_ALL_INTERFACES (vrf, ifp) {
2647 if (json)
2648 if_dump_vty_json(vty, ifp, json);
2649 else
2650 if_dump_vty(vty, ifp);
2651 }
2652 }
2653
2654 if (json)
2655 vty_json(vty, json);
2656
2657 return CMD_SUCCESS;
2658 }
2659
2660
2661 /* Show all interfaces to vty. */
2662 DEFPY (show_interface_vrf_all,
2663 show_interface_vrf_all_cmd,
2664 "show interface [vrf all] [brief$brief] [json$uj]",
2665 SHOW_STR
2666 "Interface status and configuration\n"
2667 VRF_ALL_CMD_HELP_STR
2668 "Interface status and configuration summary\n"
2669 JSON_STR)
2670 {
2671 struct vrf *vrf;
2672 struct interface *ifp;
2673 json_object *json = NULL;
2674
2675 interface_update_stats();
2676
2677 if (uj)
2678 json = json_object_new_object();
2679
2680 /* All interface print. */
2681 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2682 if (brief) {
2683 if (json)
2684 ifs_dump_brief_vty_json(json, vrf);
2685 else
2686 ifs_dump_brief_vty(vty, vrf);
2687 } else {
2688 FOR_ALL_INTERFACES (vrf, ifp) {
2689 if (json)
2690 if_dump_vty_json(vty, ifp, json);
2691 else
2692 if_dump_vty(vty, ifp);
2693 }
2694 }
2695 }
2696
2697 if (json)
2698 vty_json(vty, json);
2699
2700 return CMD_SUCCESS;
2701 }
2702
2703 /* Show specified interface to vty. */
2704
2705 DEFPY (show_interface_name_vrf,
2706 show_interface_name_vrf_cmd,
2707 "show interface IFNAME$ifname vrf NAME$vrf_name [json$uj]",
2708 SHOW_STR
2709 "Interface status and configuration\n"
2710 "Interface name\n"
2711 VRF_CMD_HELP_STR
2712 JSON_STR)
2713 {
2714 struct interface *ifp;
2715 struct vrf *vrf;
2716 json_object *json = NULL;
2717
2718 interface_update_stats();
2719
2720 vrf = vrf_lookup_by_name(vrf_name);
2721 if (!vrf) {
2722 if (uj)
2723 vty_out(vty, "{}\n");
2724 else
2725 vty_out(vty, "%% VRF %s not found\n", vrf_name);
2726 return CMD_WARNING;
2727 }
2728
2729 ifp = if_lookup_by_name_vrf(ifname, vrf);
2730 if (ifp == NULL) {
2731 if (uj)
2732 vty_out(vty, "{}\n");
2733 else
2734 vty_out(vty, "%% Can't find interface %s\n", ifname);
2735 return CMD_WARNING;
2736 }
2737
2738 if (uj)
2739 json = json_object_new_object();
2740
2741 if (json)
2742 if_dump_vty_json(vty, ifp, json);
2743 else
2744 if_dump_vty(vty, ifp);
2745
2746 if (json)
2747 vty_json(vty, json);
2748
2749 return CMD_SUCCESS;
2750 }
2751
2752 /* Show specified interface to vty. */
2753 DEFPY (show_interface_name_vrf_all,
2754 show_interface_name_vrf_all_cmd,
2755 "show interface IFNAME$ifname [vrf all] [json$uj]",
2756 SHOW_STR
2757 "Interface status and configuration\n"
2758 "Interface name\n"
2759 VRF_ALL_CMD_HELP_STR
2760 JSON_STR)
2761 {
2762 struct interface *ifp = NULL;
2763 struct interface *ifptmp;
2764 struct vrf *vrf;
2765 json_object *json = NULL;
2766 int count = 0;
2767
2768 interface_update_stats();
2769
2770 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2771 ifptmp = if_lookup_by_name_vrf(ifname, vrf);
2772 if (ifptmp) {
2773 ifp = ifptmp;
2774 count++;
2775 if (!vrf_is_backend_netns())
2776 break;
2777 }
2778 }
2779
2780 if (ifp == NULL) {
2781 if (uj)
2782 vty_out(vty, "{}\n");
2783 else
2784 vty_out(vty, "%% Can't find interface %s\n", ifname);
2785 return CMD_WARNING;
2786 }
2787 if (count > 1) {
2788 if (uj) {
2789 vty_out(vty, "{}\n");
2790 } else {
2791 vty_out(vty,
2792 "%% There are multiple interfaces with name %s\n",
2793 ifname);
2794 vty_out(vty, "%% You must specify the VRF name\n");
2795 }
2796 return CMD_WARNING;
2797 }
2798
2799 if (uj)
2800 json = json_object_new_object();
2801
2802 if (json)
2803 if_dump_vty_json(vty, ifp, json);
2804 else
2805 if_dump_vty(vty, ifp);
2806
2807 if (json)
2808 vty_json(vty, json);
2809
2810 return CMD_SUCCESS;
2811 }
2812
2813 static void if_show_description(struct vty *vty, struct vrf *vrf)
2814 {
2815 struct interface *ifp;
2816
2817 vty_out(vty, "Interface Status Protocol Description\n");
2818 FOR_ALL_INTERFACES (vrf, ifp) {
2819 int len;
2820 struct zebra_if *zif;
2821 bool intf_desc;
2822
2823 intf_desc = false;
2824
2825 len = vty_out(vty, "%s", ifp->name);
2826 vty_out(vty, "%*s", (16 - len), " ");
2827
2828 if (if_is_up(ifp)) {
2829 vty_out(vty, "up ");
2830 if (CHECK_FLAG(ifp->status,
2831 ZEBRA_INTERFACE_LINKDETECTION)) {
2832 if (if_is_running(ifp))
2833 vty_out(vty, "up ");
2834 else
2835 vty_out(vty, "down ");
2836 } else {
2837 vty_out(vty, "unknown ");
2838 }
2839 } else {
2840 vty_out(vty, "down down ");
2841 }
2842
2843 if (ifp->desc) {
2844 intf_desc = true;
2845 vty_out(vty, "%s", ifp->desc);
2846 }
2847 zif = ifp->info;
2848 if (zif && zif->desc) {
2849 vty_out(vty, "%s%s",
2850 intf_desc
2851 ? "\n "
2852 : "",
2853 zif->desc);
2854 }
2855
2856 vty_out(vty, "\n");
2857 }
2858 }
2859
2860 DEFUN (show_interface_desc,
2861 show_interface_desc_cmd,
2862 "show interface description vrf NAME",
2863 SHOW_STR
2864 "Interface status and configuration\n"
2865 "Interface description\n"
2866 VRF_CMD_HELP_STR)
2867 {
2868 struct vrf *vrf;
2869
2870 vrf = vrf_lookup_by_name(argv[4]->arg);
2871 if (!vrf) {
2872 vty_out(vty, "%% VRF %s not found\n", argv[4]->arg);
2873 return CMD_WARNING;
2874 }
2875
2876 if_show_description(vty, vrf);
2877
2878 return CMD_SUCCESS;
2879 }
2880
2881
2882 DEFUN (show_interface_desc_vrf_all,
2883 show_interface_desc_vrf_all_cmd,
2884 "show interface description [vrf all]",
2885 SHOW_STR
2886 "Interface status and configuration\n"
2887 "Interface description\n"
2888 VRF_ALL_CMD_HELP_STR)
2889 {
2890 struct vrf *vrf;
2891
2892 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2893 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
2894 vty_out(vty, "\n\tVRF %s(%u)\n\n", VRF_LOGNAME(vrf),
2895 vrf->vrf_id);
2896 if_show_description(vty, vrf);
2897 }
2898
2899 return CMD_SUCCESS;
2900 }
2901
2902 int if_multicast_set(struct interface *ifp)
2903 {
2904 struct zebra_if *if_data;
2905
2906 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2907 if (if_set_flags(ifp, IFF_MULTICAST) < 0) {
2908 zlog_debug("Can't set multicast flag on interface %s",
2909 ifp->name);
2910 return -1;
2911 }
2912 if_refresh(ifp);
2913 }
2914 if_data = ifp->info;
2915 if_data->multicast = IF_ZEBRA_DATA_ON;
2916
2917 return 0;
2918 }
2919
2920 DEFUN (multicast,
2921 multicast_cmd,
2922 "multicast",
2923 "Set multicast flag to interface\n")
2924 {
2925 VTY_DECLVAR_CONTEXT(interface, ifp);
2926 int ret;
2927 struct zebra_if *if_data;
2928
2929 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2930 ret = if_set_flags(ifp, IFF_MULTICAST);
2931 if (ret < 0) {
2932 vty_out(vty, "Can't set multicast flag\n");
2933 return CMD_WARNING_CONFIG_FAILED;
2934 }
2935 if_refresh(ifp);
2936 }
2937 if_data = ifp->info;
2938 if_data->multicast = IF_ZEBRA_DATA_ON;
2939
2940 return CMD_SUCCESS;
2941 }
2942
2943 DEFPY (mpls,
2944 mpls_cmd,
2945 "[no] mpls enable",
2946 NO_STR
2947 MPLS_STR
2948 "Set mpls to be on for the interface\n")
2949 {
2950 VTY_DECLVAR_CONTEXT(interface, ifp);
2951 struct zebra_if *if_data = ifp->info;
2952
2953 if (no) {
2954 dplane_intf_mpls_modify_state(ifp, false);
2955 if_data->mpls = IF_ZEBRA_DATA_UNSPEC;
2956 } else {
2957 dplane_intf_mpls_modify_state(ifp, true);
2958 if_data->mpls = IF_ZEBRA_DATA_ON;
2959 }
2960
2961 return CMD_SUCCESS;
2962 }
2963
2964 int if_multicast_unset(struct interface *ifp)
2965 {
2966 struct zebra_if *if_data;
2967
2968 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2969 if (if_unset_flags(ifp, IFF_MULTICAST) < 0) {
2970 zlog_debug("Can't unset multicast flag on interface %s",
2971 ifp->name);
2972 return -1;
2973 }
2974 if_refresh(ifp);
2975 }
2976 if_data = ifp->info;
2977 if_data->multicast = IF_ZEBRA_DATA_OFF;
2978
2979 return 0;
2980 }
2981
2982 DEFUN (no_multicast,
2983 no_multicast_cmd,
2984 "no multicast",
2985 NO_STR
2986 "Unset multicast flag to interface\n")
2987 {
2988 VTY_DECLVAR_CONTEXT(interface, ifp);
2989 int ret;
2990 struct zebra_if *if_data;
2991
2992 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2993 ret = if_unset_flags(ifp, IFF_MULTICAST);
2994 if (ret < 0) {
2995 vty_out(vty, "Can't unset multicast flag\n");
2996 return CMD_WARNING_CONFIG_FAILED;
2997 }
2998 if_refresh(ifp);
2999 }
3000 if_data = ifp->info;
3001 if_data->multicast = IF_ZEBRA_DATA_OFF;
3002
3003 return CMD_SUCCESS;
3004 }
3005
3006 int if_linkdetect(struct interface *ifp, bool detect)
3007 {
3008 int if_was_operative;
3009
3010 if_was_operative = if_is_no_ptm_operative(ifp);
3011 if (detect) {
3012 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
3013
3014 /* When linkdetection is enabled, if might come down */
3015 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
3016 if_down(ifp);
3017 } else {
3018 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
3019
3020 /* Interface may come up after disabling link detection */
3021 if (if_is_operative(ifp) && !if_was_operative)
3022 if_up(ifp, true);
3023 }
3024 /* FIXME: Will defer status change forwarding if interface
3025 does not come down! */
3026 return 0;
3027 }
3028
3029 DEFUN(linkdetect, linkdetect_cmd, "link-detect",
3030 "Enable link detection on interface\n")
3031 {
3032 VTY_DECLVAR_CONTEXT(interface, ifp);
3033
3034 if_linkdetect(ifp, true);
3035
3036 return CMD_SUCCESS;
3037 }
3038
3039
3040 DEFUN (no_linkdetect,
3041 no_linkdetect_cmd,
3042 "no link-detect",
3043 NO_STR
3044 "Disable link detection on interface\n")
3045 {
3046 VTY_DECLVAR_CONTEXT(interface, ifp);
3047
3048 if_linkdetect(ifp, false);
3049
3050 return CMD_SUCCESS;
3051 }
3052
3053 int if_shutdown(struct interface *ifp)
3054 {
3055 struct zebra_if *if_data;
3056
3057 if (ifp->ifindex != IFINDEX_INTERNAL) {
3058 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3059 rtadv_stop_ra(ifp);
3060 if (if_unset_flags(ifp, IFF_UP) < 0) {
3061 zlog_debug("Can't shutdown interface %s", ifp->name);
3062 return -1;
3063 }
3064 if_refresh(ifp);
3065 }
3066 if_data = ifp->info;
3067 if_data->shutdown = IF_ZEBRA_DATA_ON;
3068
3069 return 0;
3070 }
3071
3072 DEFUN (shutdown_if,
3073 shutdown_if_cmd,
3074 "shutdown",
3075 "Shutdown the selected interface\n")
3076 {
3077 VTY_DECLVAR_CONTEXT(interface, ifp);
3078 int ret;
3079 struct zebra_if *if_data;
3080
3081 if (ifp->ifindex != IFINDEX_INTERNAL) {
3082 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
3083 rtadv_stop_ra(ifp);
3084 ret = if_unset_flags(ifp, IFF_UP);
3085 if (ret < 0) {
3086 vty_out(vty, "Can't shutdown interface\n");
3087 return CMD_WARNING_CONFIG_FAILED;
3088 }
3089 if_refresh(ifp);
3090 }
3091 if_data = ifp->info;
3092 if_data->shutdown = IF_ZEBRA_DATA_ON;
3093
3094 return CMD_SUCCESS;
3095 }
3096
3097 int if_no_shutdown(struct interface *ifp)
3098 {
3099 struct zebra_if *if_data;
3100
3101 if (ifp->ifindex != IFINDEX_INTERNAL) {
3102 if (if_set_flags(ifp, IFF_UP | IFF_RUNNING) < 0) {
3103 zlog_debug("Can't up interface %s", ifp->name);
3104 return -1;
3105 }
3106 if_refresh(ifp);
3107
3108 /* Some addresses (in particular, IPv6 addresses on Linux) get
3109 * removed when the interface goes down. They need to be
3110 * readded.
3111 */
3112 if_addr_wakeup(ifp);
3113 }
3114
3115 if_data = ifp->info;
3116 if_data->shutdown = IF_ZEBRA_DATA_OFF;
3117
3118 return 0;
3119 }
3120
3121 DEFUN (no_shutdown_if,
3122 no_shutdown_if_cmd,
3123 "no shutdown",
3124 NO_STR
3125 "Shutdown the selected interface\n")
3126 {
3127 VTY_DECLVAR_CONTEXT(interface, ifp);
3128 int ret;
3129 struct zebra_if *if_data;
3130
3131 if (ifp->ifindex != IFINDEX_INTERNAL) {
3132 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
3133 if (ret < 0) {
3134 vty_out(vty, "Can't up interface\n");
3135 return CMD_WARNING_CONFIG_FAILED;
3136 }
3137 if_refresh(ifp);
3138
3139 /* Some addresses (in particular, IPv6 addresses on Linux) get
3140 * removed when the interface goes down. They need to be
3141 * readded.
3142 */
3143 if_addr_wakeup(ifp);
3144 }
3145
3146 if_data = ifp->info;
3147 if_data->shutdown = IF_ZEBRA_DATA_OFF;
3148
3149 return CMD_SUCCESS;
3150 }
3151
3152 DEFUN (bandwidth_if,
3153 bandwidth_if_cmd,
3154 "bandwidth (1-100000)",
3155 "Set bandwidth informational parameter\n"
3156 "Bandwidth in megabits\n")
3157 {
3158 int idx_number = 1;
3159 VTY_DECLVAR_CONTEXT(interface, ifp);
3160 unsigned int bandwidth;
3161
3162 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
3163
3164 /* bandwidth range is <1-100000> */
3165 if (bandwidth < 1 || bandwidth > 100000) {
3166 vty_out(vty, "Bandwidth is invalid\n");
3167 return CMD_WARNING_CONFIG_FAILED;
3168 }
3169
3170 ifp->bandwidth = bandwidth;
3171
3172 /* force protocols to recalculate routes due to cost change */
3173 if (if_is_operative(ifp))
3174 zebra_interface_up_update(ifp);
3175
3176 return CMD_SUCCESS;
3177 }
3178
3179 DEFUN (no_bandwidth_if,
3180 no_bandwidth_if_cmd,
3181 "no bandwidth [(1-100000)]",
3182 NO_STR
3183 "Set bandwidth informational parameter\n"
3184 "Bandwidth in megabits\n")
3185 {
3186 VTY_DECLVAR_CONTEXT(interface, ifp);
3187
3188 ifp->bandwidth = 0;
3189
3190 /* force protocols to recalculate routes due to cost change */
3191 if (if_is_operative(ifp))
3192 zebra_interface_up_update(ifp);
3193
3194 return CMD_SUCCESS;
3195 }
3196
3197
3198 struct cmd_node link_params_node = {
3199 .name = "link-params",
3200 .node = LINK_PARAMS_NODE,
3201 .parent_node = INTERFACE_NODE,
3202 .prompt = "%s(config-link-params)# ",
3203 .no_xpath = true,
3204 };
3205
3206 static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
3207 uint32_t type, uint32_t value)
3208 {
3209 /* Update field as needed */
3210 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
3211 *field = value;
3212 SET_PARAM(ifp->link_params, type);
3213
3214 /* force protocols to update LINK STATE due to parameters change
3215 */
3216 if (if_is_operative(ifp))
3217 zebra_interface_parameters_update(ifp);
3218 }
3219 }
3220 static void link_param_cmd_set_float(struct interface *ifp, float *field,
3221 uint32_t type, float value)
3222 {
3223
3224 /* Update field as needed */
3225 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
3226 *field = value;
3227 SET_PARAM(ifp->link_params, type);
3228
3229 /* force protocols to update LINK STATE due to parameters change
3230 */
3231 if (if_is_operative(ifp))
3232 zebra_interface_parameters_update(ifp);
3233 }
3234 }
3235
3236 static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
3237 {
3238 if (ifp->link_params == NULL)
3239 return;
3240
3241 /* Unset field */
3242 UNSET_PARAM(ifp->link_params, type);
3243
3244 /* force protocols to update LINK STATE due to parameters change */
3245 if (if_is_operative(ifp))
3246 zebra_interface_parameters_update(ifp);
3247 }
3248
3249 DEFUN_NOSH (link_params,
3250 link_params_cmd,
3251 "link-params",
3252 LINK_PARAMS_STR)
3253 {
3254 /* vty->qobj_index stays the same @ interface pointer */
3255 vty->node = LINK_PARAMS_NODE;
3256
3257 return CMD_SUCCESS;
3258 }
3259
3260 DEFUN_NOSH (exit_link_params,
3261 exit_link_params_cmd,
3262 "exit-link-params",
3263 "Exit from Link Params configuration mode\n")
3264 {
3265 if (vty->node == LINK_PARAMS_NODE)
3266 vty->node = INTERFACE_NODE;
3267 return CMD_SUCCESS;
3268 }
3269
3270 /* Specific Traffic Engineering parameters commands */
3271 DEFUN (link_params_enable,
3272 link_params_enable_cmd,
3273 "enable",
3274 "Activate link parameters on this interface\n")
3275 {
3276 VTY_DECLVAR_CONTEXT(interface, ifp);
3277
3278 /* This command could be issue at startup, when activate MPLS TE */
3279 /* on a new interface or after a ON / OFF / ON toggle */
3280 /* In all case, TE parameters are reset to their default factory */
3281 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
3282 zlog_debug(
3283 "Link-params: enable TE link parameters on interface %s",
3284 ifp->name);
3285
3286 if (!if_link_params_get(ifp))
3287 if_link_params_enable(ifp);
3288
3289 /* force protocols to update LINK STATE due to parameters change */
3290 if (if_is_operative(ifp))
3291 zebra_interface_parameters_update(ifp);
3292
3293 return CMD_SUCCESS;
3294 }
3295
3296 DEFUN (no_link_params_enable,
3297 no_link_params_enable_cmd,
3298 "no enable",
3299 NO_STR
3300 "Disable link parameters on this interface\n")
3301 {
3302 VTY_DECLVAR_CONTEXT(interface, ifp);
3303
3304 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
3305 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
3306 ifp->name);
3307
3308 if_link_params_free(ifp);
3309
3310 /* force protocols to update LINK STATE due to parameters change */
3311 if (if_is_operative(ifp))
3312 zebra_interface_parameters_update(ifp);
3313
3314 return CMD_SUCCESS;
3315 }
3316
3317 /* STANDARD TE metrics */
3318 DEFUN (link_params_metric,
3319 link_params_metric_cmd,
3320 "metric (0-4294967295)",
3321 "Link metric for MPLS-TE purpose\n"
3322 "Metric value in decimal\n")
3323 {
3324 int idx_number = 1;
3325 VTY_DECLVAR_CONTEXT(interface, ifp);
3326 struct if_link_params *iflp = if_link_params_get(ifp);
3327 uint32_t metric;
3328
3329 metric = strtoul(argv[idx_number]->arg, NULL, 10);
3330
3331 if (!iflp)
3332 iflp = if_link_params_enable(ifp);
3333
3334 /* Update TE metric if needed */
3335 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
3336
3337 return CMD_SUCCESS;
3338 }
3339
3340 DEFUN (no_link_params_metric,
3341 no_link_params_metric_cmd,
3342 "no metric",
3343 NO_STR
3344 "Disable Link Metric on this interface\n")
3345 {
3346 VTY_DECLVAR_CONTEXT(interface, ifp);
3347
3348 /* Unset TE Metric */
3349 link_param_cmd_unset(ifp, LP_TE_METRIC);
3350
3351 return CMD_SUCCESS;
3352 }
3353
3354 DEFUN (link_params_maxbw,
3355 link_params_maxbw_cmd,
3356 "max-bw BANDWIDTH",
3357 "Maximum bandwidth that can be used\n"
3358 "Bytes/second (IEEE floating point format)\n")
3359 {
3360 int idx_bandwidth = 1;
3361 VTY_DECLVAR_CONTEXT(interface, ifp);
3362 struct if_link_params *iflp = if_link_params_get(ifp);
3363
3364 float bw;
3365
3366 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3367 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
3368 safe_strerror(errno));
3369 return CMD_WARNING_CONFIG_FAILED;
3370 }
3371
3372 /* Check that Maximum bandwidth is not lower than other bandwidth
3373 * parameters */
3374 if (iflp && ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) ||
3375 (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) ||
3376 (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) ||
3377 (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) ||
3378 (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) ||
3379 (bw <= iflp->res_bw) || (bw <= iflp->use_bw))) {
3380 vty_out(vty,
3381 "Maximum Bandwidth could not be lower than others bandwidth\n");
3382 return CMD_WARNING_CONFIG_FAILED;
3383 }
3384
3385 if (!iflp)
3386 iflp = if_link_params_enable(ifp);
3387
3388 /* Update Maximum Bandwidth if needed */
3389 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
3390
3391 return CMD_SUCCESS;
3392 }
3393
3394 DEFUN (link_params_max_rsv_bw,
3395 link_params_max_rsv_bw_cmd,
3396 "max-rsv-bw BANDWIDTH",
3397 "Maximum bandwidth that may be reserved\n"
3398 "Bytes/second (IEEE floating point format)\n")
3399 {
3400 int idx_bandwidth = 1;
3401 VTY_DECLVAR_CONTEXT(interface, ifp);
3402 struct if_link_params *iflp = if_link_params_get(ifp);
3403 float bw;
3404
3405 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3406 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
3407 safe_strerror(errno));
3408 return CMD_WARNING_CONFIG_FAILED;
3409 }
3410
3411 /* Check that bandwidth is not greater than maximum bandwidth parameter
3412 */
3413 if (iflp && bw > iflp->max_bw) {
3414 vty_out(vty,
3415 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3416 iflp->max_bw);
3417 return CMD_WARNING_CONFIG_FAILED;
3418 }
3419
3420 if (!iflp)
3421 iflp = if_link_params_enable(ifp);
3422
3423 /* Update Maximum Reservable Bandwidth if needed */
3424 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
3425
3426 return CMD_SUCCESS;
3427 }
3428
3429 DEFUN (link_params_unrsv_bw,
3430 link_params_unrsv_bw_cmd,
3431 "unrsv-bw (0-7) BANDWIDTH",
3432 "Unreserved bandwidth at each priority level\n"
3433 "Priority\n"
3434 "Bytes/second (IEEE floating point format)\n")
3435 {
3436 int idx_number = 1;
3437 int idx_bandwidth = 2;
3438 VTY_DECLVAR_CONTEXT(interface, ifp);
3439 struct if_link_params *iflp = if_link_params_get(ifp);
3440 int priority;
3441 float bw;
3442
3443 /* We don't have to consider about range check here. */
3444 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
3445 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
3446 safe_strerror(errno));
3447 return CMD_WARNING_CONFIG_FAILED;
3448 }
3449
3450 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3451 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
3452 safe_strerror(errno));
3453 return CMD_WARNING_CONFIG_FAILED;
3454 }
3455
3456 /* Check that bandwidth is not greater than maximum bandwidth parameter
3457 */
3458 if (iflp && bw > iflp->max_bw) {
3459 vty_out(vty,
3460 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3461 iflp->max_bw);
3462 return CMD_WARNING_CONFIG_FAILED;
3463 }
3464
3465 if (!iflp)
3466 iflp = if_link_params_enable(ifp);
3467
3468 /* Update Unreserved Bandwidth if needed */
3469 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
3470 bw);
3471
3472 return CMD_SUCCESS;
3473 }
3474
3475 DEFUN (link_params_admin_grp,
3476 link_params_admin_grp_cmd,
3477 "admin-grp BITPATTERN",
3478 "Administrative group membership\n"
3479 "32-bit Hexadecimal value (e.g. 0xa1)\n")
3480 {
3481 int idx_bitpattern = 1;
3482 VTY_DECLVAR_CONTEXT(interface, ifp);
3483 struct if_link_params *iflp = if_link_params_get(ifp);
3484 unsigned long value;
3485
3486 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
3487 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
3488 safe_strerror(errno));
3489 return CMD_WARNING_CONFIG_FAILED;
3490 }
3491
3492 if (!iflp)
3493 iflp = if_link_params_enable(ifp);
3494
3495 /* Update Administrative Group if needed */
3496 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
3497
3498 return CMD_SUCCESS;
3499 }
3500
3501 DEFUN (no_link_params_admin_grp,
3502 no_link_params_admin_grp_cmd,
3503 "no admin-grp",
3504 NO_STR
3505 "Disable Administrative group membership on this interface\n")
3506 {
3507 VTY_DECLVAR_CONTEXT(interface, ifp);
3508
3509 /* Unset Admin Group */
3510 link_param_cmd_unset(ifp, LP_ADM_GRP);
3511
3512 return CMD_SUCCESS;
3513 }
3514
3515 /* RFC5392 & RFC5316: INTER-AS */
3516 DEFUN (link_params_inter_as,
3517 link_params_inter_as_cmd,
3518 "neighbor A.B.C.D as (1-4294967295)",
3519 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
3520 "Remote IP address in dot decimal A.B.C.D\n"
3521 "Remote AS number\n"
3522 "AS number in the range <1-4294967295>\n")
3523 {
3524 int idx_ipv4 = 1;
3525 int idx_number = 3;
3526
3527 VTY_DECLVAR_CONTEXT(interface, ifp);
3528 struct if_link_params *iflp = if_link_params_get(ifp);
3529 struct in_addr addr;
3530 uint32_t as;
3531
3532 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
3533 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
3534 return CMD_WARNING_CONFIG_FAILED;
3535 }
3536
3537 if (!iflp)
3538 iflp = if_link_params_enable(ifp);
3539
3540 as = strtoul(argv[idx_number]->arg, NULL, 10);
3541
3542 /* Update Remote IP and Remote AS fields if needed */
3543 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
3544 || iflp->rmt_ip.s_addr != addr.s_addr) {
3545
3546 iflp->rmt_as = as;
3547 iflp->rmt_ip.s_addr = addr.s_addr;
3548 SET_PARAM(iflp, LP_RMT_AS);
3549
3550 /* force protocols to update LINK STATE due to parameters change
3551 */
3552 if (if_is_operative(ifp))
3553 zebra_interface_parameters_update(ifp);
3554 }
3555 return CMD_SUCCESS;
3556 }
3557
3558 DEFUN (no_link_params_inter_as,
3559 no_link_params_inter_as_cmd,
3560 "no neighbor",
3561 NO_STR
3562 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
3563 {
3564 VTY_DECLVAR_CONTEXT(interface, ifp);
3565 struct if_link_params *iflp = if_link_params_get(ifp);
3566
3567 if (!iflp)
3568 return CMD_SUCCESS;
3569
3570 /* Reset Remote IP and AS neighbor */
3571 iflp->rmt_as = 0;
3572 iflp->rmt_ip.s_addr = 0;
3573 UNSET_PARAM(iflp, LP_RMT_AS);
3574
3575 /* force protocols to update LINK STATE due to parameters change */
3576 if (if_is_operative(ifp))
3577 zebra_interface_parameters_update(ifp);
3578
3579 return CMD_SUCCESS;
3580 }
3581
3582 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
3583 * draft-ietf-isis-metric-extensions-07.txt */
3584 DEFUN (link_params_delay,
3585 link_params_delay_cmd,
3586 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
3587 "Unidirectional Average Link Delay\n"
3588 "Average delay in micro-second as decimal (0...16777215)\n"
3589 "Minimum delay\n"
3590 "Minimum delay in micro-second as decimal (0...16777215)\n"
3591 "Maximum delay\n"
3592 "Maximum delay in micro-second as decimal (0...16777215)\n")
3593 {
3594 /* Get and Check new delay values */
3595 uint32_t delay = 0, low = 0, high = 0;
3596 delay = strtoul(argv[1]->arg, NULL, 10);
3597 if (argc == 6) {
3598 low = strtoul(argv[3]->arg, NULL, 10);
3599 high = strtoul(argv[5]->arg, NULL, 10);
3600 }
3601
3602 VTY_DECLVAR_CONTEXT(interface, ifp);
3603 struct if_link_params *iflp = if_link_params_get(ifp);
3604 uint8_t update = 0;
3605
3606 if (argc == 2) {
3607 /*
3608 * Check new delay value against old Min and Max delays if set
3609 *
3610 * RFC 7471 Section 4.2.7:
3611 * It is possible for min delay and max delay to be
3612 * the same value.
3613 *
3614 * Therefore, it is also allowed that the average
3615 * delay be equal to the min delay or max delay.
3616 */
3617 if (iflp && IS_PARAM_SET(iflp, LP_MM_DELAY) &&
3618 (delay < iflp->min_delay || delay > iflp->max_delay)) {
3619 vty_out(vty,
3620 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3621 iflp->min_delay, iflp->max_delay);
3622 return CMD_WARNING_CONFIG_FAILED;
3623 }
3624
3625 if (!iflp)
3626 iflp = if_link_params_enable(ifp);
3627
3628 /* Update delay if value is not set or change */
3629 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
3630 iflp->av_delay = delay;
3631 SET_PARAM(iflp, LP_DELAY);
3632 update = 1;
3633 }
3634 /* Unset Min and Max delays if already set */
3635 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
3636 iflp->min_delay = 0;
3637 iflp->max_delay = 0;
3638 UNSET_PARAM(iflp, LP_MM_DELAY);
3639 update = 1;
3640 }
3641 } else {
3642 /*
3643 * Check new delays value coherency. See above note
3644 * regarding average delay equal to min/max allowed
3645 */
3646 if (delay < low || delay > high) {
3647 vty_out(vty,
3648 "Average delay should be in range Min (%d) - Max (%d) delay\n",
3649 low, high);
3650 return CMD_WARNING_CONFIG_FAILED;
3651 }
3652
3653 if (!iflp)
3654 iflp = if_link_params_enable(ifp);
3655
3656 /* Update Delays if needed */
3657 if (IS_PARAM_UNSET(iflp, LP_DELAY)
3658 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
3659 || iflp->av_delay != delay || iflp->min_delay != low
3660 || iflp->max_delay != high) {
3661 iflp->av_delay = delay;
3662 SET_PARAM(iflp, LP_DELAY);
3663 iflp->min_delay = low;
3664 iflp->max_delay = high;
3665 SET_PARAM(iflp, LP_MM_DELAY);
3666 update = 1;
3667 }
3668 }
3669
3670 /* force protocols to update LINK STATE due to parameters change */
3671 if (update == 1 && if_is_operative(ifp))
3672 zebra_interface_parameters_update(ifp);
3673
3674 return CMD_SUCCESS;
3675 }
3676
3677 DEFUN (no_link_params_delay,
3678 no_link_params_delay_cmd,
3679 "no delay",
3680 NO_STR
3681 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
3682 {
3683 VTY_DECLVAR_CONTEXT(interface, ifp);
3684 struct if_link_params *iflp = if_link_params_get(ifp);
3685
3686 if (!iflp)
3687 return CMD_SUCCESS;
3688
3689 /* Unset Delays */
3690 iflp->av_delay = 0;
3691 UNSET_PARAM(iflp, LP_DELAY);
3692 iflp->min_delay = 0;
3693 iflp->max_delay = 0;
3694 UNSET_PARAM(iflp, LP_MM_DELAY);
3695
3696 /* force protocols to update LINK STATE due to parameters change */
3697 if (if_is_operative(ifp))
3698 zebra_interface_parameters_update(ifp);
3699
3700 return CMD_SUCCESS;
3701 }
3702
3703 DEFUN (link_params_delay_var,
3704 link_params_delay_var_cmd,
3705 "delay-variation (0-16777215)",
3706 "Unidirectional Link Delay Variation\n"
3707 "delay variation in micro-second as decimal (0...16777215)\n")
3708 {
3709 int idx_number = 1;
3710 VTY_DECLVAR_CONTEXT(interface, ifp);
3711 struct if_link_params *iflp = if_link_params_get(ifp);
3712 uint32_t value;
3713
3714 value = strtoul(argv[idx_number]->arg, NULL, 10);
3715
3716 if (!iflp)
3717 iflp = if_link_params_enable(ifp);
3718
3719 /* Update Delay Variation if needed */
3720 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
3721
3722 return CMD_SUCCESS;
3723 }
3724
3725 DEFUN (no_link_params_delay_var,
3726 no_link_params_delay_var_cmd,
3727 "no delay-variation",
3728 NO_STR
3729 "Disable Unidirectional Delay Variation on this interface\n")
3730 {
3731 VTY_DECLVAR_CONTEXT(interface, ifp);
3732
3733 /* Unset Delay Variation */
3734 link_param_cmd_unset(ifp, LP_DELAY_VAR);
3735
3736 return CMD_SUCCESS;
3737 }
3738
3739 DEFUN (link_params_pkt_loss,
3740 link_params_pkt_loss_cmd,
3741 "packet-loss PERCENTAGE",
3742 "Unidirectional Link Packet Loss\n"
3743 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
3744 {
3745 int idx_percentage = 1;
3746 VTY_DECLVAR_CONTEXT(interface, ifp);
3747 struct if_link_params *iflp = if_link_params_get(ifp);
3748 float fval;
3749
3750 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
3751 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
3752 safe_strerror(errno));
3753 return CMD_WARNING_CONFIG_FAILED;
3754 }
3755
3756 if (fval > MAX_PKT_LOSS)
3757 fval = MAX_PKT_LOSS;
3758
3759 if (!iflp)
3760 iflp = if_link_params_enable(ifp);
3761
3762 /* Update Packet Loss if needed */
3763 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
3764
3765 return CMD_SUCCESS;
3766 }
3767
3768 DEFUN (no_link_params_pkt_loss,
3769 no_link_params_pkt_loss_cmd,
3770 "no packet-loss",
3771 NO_STR
3772 "Disable Unidirectional Link Packet Loss on this interface\n")
3773 {
3774 VTY_DECLVAR_CONTEXT(interface, ifp);
3775
3776 /* Unset Packet Loss */
3777 link_param_cmd_unset(ifp, LP_PKT_LOSS);
3778
3779 return CMD_SUCCESS;
3780 }
3781
3782 DEFUN (link_params_res_bw,
3783 link_params_res_bw_cmd,
3784 "res-bw BANDWIDTH",
3785 "Unidirectional Residual Bandwidth\n"
3786 "Bytes/second (IEEE floating point format)\n")
3787 {
3788 int idx_bandwidth = 1;
3789 VTY_DECLVAR_CONTEXT(interface, ifp);
3790 struct if_link_params *iflp = if_link_params_get(ifp);
3791 float bw;
3792
3793 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3794 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
3795 safe_strerror(errno));
3796 return CMD_WARNING_CONFIG_FAILED;
3797 }
3798
3799 /* Check that bandwidth is not greater than maximum bandwidth parameter
3800 */
3801 if (iflp && bw > iflp->max_bw) {
3802 vty_out(vty,
3803 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3804 iflp->max_bw);
3805 return CMD_WARNING_CONFIG_FAILED;
3806 }
3807
3808 if (!iflp)
3809 iflp = if_link_params_enable(ifp);
3810
3811 /* Update Residual Bandwidth if needed */
3812 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
3813
3814 return CMD_SUCCESS;
3815 }
3816
3817 DEFUN (no_link_params_res_bw,
3818 no_link_params_res_bw_cmd,
3819 "no res-bw",
3820 NO_STR
3821 "Disable Unidirectional Residual Bandwidth on this interface\n")
3822 {
3823 VTY_DECLVAR_CONTEXT(interface, ifp);
3824
3825 /* Unset Residual Bandwidth */
3826 link_param_cmd_unset(ifp, LP_RES_BW);
3827
3828 return CMD_SUCCESS;
3829 }
3830
3831 DEFUN (link_params_ava_bw,
3832 link_params_ava_bw_cmd,
3833 "ava-bw BANDWIDTH",
3834 "Unidirectional Available Bandwidth\n"
3835 "Bytes/second (IEEE floating point format)\n")
3836 {
3837 int idx_bandwidth = 1;
3838 VTY_DECLVAR_CONTEXT(interface, ifp);
3839 struct if_link_params *iflp = if_link_params_get(ifp);
3840 float bw;
3841
3842 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3843 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
3844 safe_strerror(errno));
3845 return CMD_WARNING_CONFIG_FAILED;
3846 }
3847
3848 /* Check that bandwidth is not greater than maximum bandwidth parameter
3849 */
3850 if (iflp && bw > iflp->max_bw) {
3851 vty_out(vty,
3852 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3853 iflp->max_bw);
3854 return CMD_WARNING_CONFIG_FAILED;
3855 }
3856
3857 if (!iflp)
3858 iflp = if_link_params_enable(ifp);
3859
3860 /* Update Residual Bandwidth if needed */
3861 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
3862
3863 return CMD_SUCCESS;
3864 }
3865
3866 DEFUN (no_link_params_ava_bw,
3867 no_link_params_ava_bw_cmd,
3868 "no ava-bw",
3869 NO_STR
3870 "Disable Unidirectional Available Bandwidth on this interface\n")
3871 {
3872 VTY_DECLVAR_CONTEXT(interface, ifp);
3873
3874 /* Unset Available Bandwidth */
3875 link_param_cmd_unset(ifp, LP_AVA_BW);
3876
3877 return CMD_SUCCESS;
3878 }
3879
3880 DEFUN (link_params_use_bw,
3881 link_params_use_bw_cmd,
3882 "use-bw BANDWIDTH",
3883 "Unidirectional Utilised Bandwidth\n"
3884 "Bytes/second (IEEE floating point format)\n")
3885 {
3886 int idx_bandwidth = 1;
3887 VTY_DECLVAR_CONTEXT(interface, ifp);
3888 struct if_link_params *iflp = if_link_params_get(ifp);
3889 float bw;
3890
3891 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3892 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
3893 safe_strerror(errno));
3894 return CMD_WARNING_CONFIG_FAILED;
3895 }
3896
3897 /* Check that bandwidth is not greater than maximum bandwidth parameter
3898 */
3899 if (iflp && bw > iflp->max_bw) {
3900 vty_out(vty,
3901 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3902 iflp->max_bw);
3903 return CMD_WARNING_CONFIG_FAILED;
3904 }
3905
3906 if (!iflp)
3907 iflp = if_link_params_enable(ifp);
3908
3909 /* Update Utilized Bandwidth if needed */
3910 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
3911
3912 return CMD_SUCCESS;
3913 }
3914
3915 DEFUN (no_link_params_use_bw,
3916 no_link_params_use_bw_cmd,
3917 "no use-bw",
3918 NO_STR
3919 "Disable Unidirectional Utilised Bandwidth on this interface\n")
3920 {
3921 VTY_DECLVAR_CONTEXT(interface, ifp);
3922
3923 /* Unset Utilised Bandwidth */
3924 link_param_cmd_unset(ifp, LP_USE_BW);
3925
3926 return CMD_SUCCESS;
3927 }
3928
3929 int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
3930 const char *label, struct prefix *pp)
3931 {
3932 struct zebra_if *if_data;
3933 struct prefix_ipv4 lp;
3934 struct prefix_ipv4 *p;
3935 struct connected *ifc;
3936 enum zebra_dplane_result dplane_res;
3937
3938 if_data = ifp->info;
3939
3940 lp.family = prefix->family;
3941 lp.prefix = prefix->u.prefix4;
3942 lp.prefixlen = prefix->prefixlen;
3943 apply_mask_ipv4(&lp);
3944
3945 ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL);
3946 if (!ifc) {
3947 ifc = connected_new();
3948 ifc->ifp = ifp;
3949
3950 /* Address. */
3951 p = prefix_ipv4_new();
3952 *p = lp;
3953 ifc->address = (struct prefix *)p;
3954
3955 if (pp) {
3956 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
3957 p = prefix_ipv4_new();
3958 *p = *(struct prefix_ipv4 *)pp;
3959 ifc->destination = (struct prefix *)p;
3960 }
3961
3962 /* Label. */
3963 if (label)
3964 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
3965
3966 /* Add to linked list. */
3967 listnode_add(ifp->connected, ifc);
3968 }
3969
3970 /* This address is configured from zebra. */
3971 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
3972 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3973
3974 /* In case of this route need to install kernel. */
3975 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
3976 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
3977 !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
3978 /* Some system need to up the interface to set IP address. */
3979 if (!if_is_up(ifp)) {
3980 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
3981 if_refresh(ifp);
3982 }
3983
3984 dplane_res = dplane_intf_addr_set(ifp, ifc);
3985 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
3986 zlog_debug(
3987 "dplane can't set interface IP address: %s.",
3988 dplane_res2str(dplane_res));
3989 return NB_ERR;
3990 }
3991
3992 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3993 /* The address will be advertised to zebra clients when the
3994 * notification
3995 * from the kernel has been received.
3996 * It will also be added to the subnet chain list, then. */
3997 }
3998
3999 return 0;
4000 }
4001
4002 static int ip_address_install(struct vty *vty, struct interface *ifp,
4003 const char *addr_str, const char *peer_str,
4004 const char *label)
4005 {
4006 struct zebra_if *if_data;
4007 struct prefix_ipv4 lp, pp;
4008 struct connected *ifc;
4009 struct prefix_ipv4 *p;
4010 int ret;
4011 enum zebra_dplane_result dplane_res;
4012
4013 if_data = ifp->info;
4014
4015 ret = str2prefix_ipv4(addr_str, &lp);
4016 if (ret <= 0) {
4017 vty_out(vty, "%% Malformed address \n");
4018 return CMD_WARNING_CONFIG_FAILED;
4019 }
4020
4021 if (ipv4_martian(&lp.prefix)) {
4022 vty_out(vty, "%% Invalid address\n");
4023 return CMD_WARNING_CONFIG_FAILED;
4024 }
4025
4026 if (peer_str) {
4027 if (lp.prefixlen != IPV4_MAX_BITLEN) {
4028 vty_out(vty,
4029 "%% Local prefix length for P-t-P address must be /32\n");
4030 return CMD_WARNING_CONFIG_FAILED;
4031 }
4032
4033 ret = str2prefix_ipv4(peer_str, &pp);
4034 if (ret <= 0) {
4035 vty_out(vty, "%% Malformed peer address\n");
4036 return CMD_WARNING_CONFIG_FAILED;
4037 }
4038 }
4039
4040 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
4041 if (!ifc) {
4042 ifc = connected_new();
4043 ifc->ifp = ifp;
4044
4045 /* Address. */
4046 p = prefix_ipv4_new();
4047 *p = lp;
4048 ifc->address = (struct prefix *)p;
4049
4050 if (peer_str) {
4051 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
4052 p = prefix_ipv4_new();
4053 *p = pp;
4054 ifc->destination = (struct prefix *)p;
4055 }
4056
4057 /* Label. */
4058 if (label)
4059 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
4060
4061 /* Add to linked list. */
4062 listnode_add(ifp->connected, ifc);
4063 }
4064
4065 /* This address is configured from zebra. */
4066 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4067 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4068
4069 /* In case of this route need to install kernel. */
4070 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
4071 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
4072 !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
4073 /* Some system need to up the interface to set IP address. */
4074 if (!if_is_up(ifp)) {
4075 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
4076 if_refresh(ifp);
4077 }
4078
4079 dplane_res = dplane_intf_addr_set(ifp, ifc);
4080 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4081 vty_out(vty, "%% Can't set interface IP address: %s.\n",
4082 dplane_res2str(dplane_res));
4083 return CMD_WARNING_CONFIG_FAILED;
4084 }
4085
4086 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4087 /* The address will be advertised to zebra clients when the
4088 * notification
4089 * from the kernel has been received.
4090 * It will also be added to the subnet chain list, then. */
4091 }
4092
4093 return CMD_SUCCESS;
4094 }
4095
4096 int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix)
4097 {
4098 struct connected *ifc = NULL;
4099 enum zebra_dplane_result dplane_res;
4100
4101 if (prefix->family == AF_INET) {
4102 /* Check current interface address. */
4103 ifc = connected_check_ptp(ifp, prefix, NULL);
4104 if (!ifc) {
4105 zlog_debug("interface %s Can't find address",
4106 ifp->name);
4107 return -1;
4108 }
4109
4110 } else if (prefix->family == AF_INET6) {
4111 /* Check current interface address. */
4112 ifc = connected_check(ifp, prefix);
4113 }
4114
4115 if (!ifc) {
4116 zlog_debug("interface %s Can't find address", ifp->name);
4117 return -1;
4118 }
4119 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4120
4121 /* This is not real address or interface is not active. */
4122 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4123 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
4124 listnode_delete(ifp->connected, ifc);
4125 connected_free(&ifc);
4126 return CMD_WARNING_CONFIG_FAILED;
4127 }
4128
4129 /* This is real route. */
4130 dplane_res = dplane_intf_addr_unset(ifp, ifc);
4131 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4132 zlog_debug("Can't unset interface IP address: %s.",
4133 dplane_res2str(dplane_res));
4134 return -1;
4135 }
4136 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4137
4138 return 0;
4139 }
4140
4141 static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
4142 const char *addr_str, const char *peer_str,
4143 const char *label)
4144 {
4145 struct prefix_ipv4 lp, pp;
4146 struct connected *ifc;
4147 int ret;
4148 enum zebra_dplane_result dplane_res;
4149
4150 /* Convert to prefix structure. */
4151 ret = str2prefix_ipv4(addr_str, &lp);
4152 if (ret <= 0) {
4153 vty_out(vty, "%% Malformed address \n");
4154 return CMD_WARNING_CONFIG_FAILED;
4155 }
4156
4157 if (peer_str) {
4158 if (lp.prefixlen != IPV4_MAX_BITLEN) {
4159 vty_out(vty,
4160 "%% Local prefix length for P-t-P address must be /32\n");
4161 return CMD_WARNING_CONFIG_FAILED;
4162 }
4163
4164 ret = str2prefix_ipv4(peer_str, &pp);
4165 if (ret <= 0) {
4166 vty_out(vty, "%% Malformed peer address\n");
4167 return CMD_WARNING_CONFIG_FAILED;
4168 }
4169 }
4170
4171 /* Check current interface address. */
4172 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
4173 if (!ifc) {
4174 vty_out(vty, "%% Can't find address\n");
4175 return CMD_WARNING_CONFIG_FAILED;
4176 }
4177
4178 /* This is not configured address. */
4179 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4180 return CMD_WARNING_CONFIG_FAILED;
4181
4182 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4183
4184 /* This is not real address or interface is not active. */
4185 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4186 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
4187 listnode_delete(ifp->connected, ifc);
4188 connected_free(&ifc);
4189 return CMD_WARNING_CONFIG_FAILED;
4190 }
4191
4192 /* This is real route. */
4193 dplane_res = dplane_intf_addr_unset(ifp, ifc);
4194 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4195 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
4196 dplane_res2str(dplane_res));
4197 return CMD_WARNING_CONFIG_FAILED;
4198 }
4199 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4200 /* we will receive a kernel notification about this route being removed.
4201 * this will trigger its removal from the connected list. */
4202 return CMD_SUCCESS;
4203 }
4204
4205 DEFUN (ip_address,
4206 ip_address_cmd,
4207 "ip address A.B.C.D/M",
4208 "Interface Internet Protocol config commands\n"
4209 "Set the IP address of an interface\n"
4210 "IP address (e.g. 10.0.0.1/8)\n")
4211 {
4212 int idx_ipv4_prefixlen = 2;
4213 VTY_DECLVAR_CONTEXT(interface, ifp);
4214 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
4215 NULL);
4216 }
4217
4218 DEFUN (no_ip_address,
4219 no_ip_address_cmd,
4220 "no ip address A.B.C.D/M",
4221 NO_STR
4222 "Interface Internet Protocol config commands\n"
4223 "Set the IP address of an interface\n"
4224 "IP Address (e.g. 10.0.0.1/8)\n")
4225 {
4226 int idx_ipv4_prefixlen = 3;
4227 VTY_DECLVAR_CONTEXT(interface, ifp);
4228 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
4229 NULL, NULL);
4230 }
4231
4232 DEFUN(ip_address_peer,
4233 ip_address_peer_cmd,
4234 "ip address A.B.C.D peer A.B.C.D/M",
4235 "Interface Internet Protocol config commands\n"
4236 "Set the IP address of an interface\n"
4237 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4238 "Specify P-t-P address\n"
4239 "Peer IP address (e.g. 10.0.0.1/8)\n")
4240 {
4241 VTY_DECLVAR_CONTEXT(interface, ifp);
4242 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
4243 }
4244
4245 DEFUN(no_ip_address_peer,
4246 no_ip_address_peer_cmd,
4247 "no ip address A.B.C.D peer A.B.C.D/M",
4248 NO_STR
4249 "Interface Internet Protocol config commands\n"
4250 "Set the IP address of an interface\n"
4251 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
4252 "Specify P-t-P address\n"
4253 "Peer IP address (e.g. 10.0.0.1/8)\n")
4254 {
4255 VTY_DECLVAR_CONTEXT(interface, ifp);
4256 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
4257 }
4258
4259 #ifdef HAVE_NETLINK
4260 DEFUN (ip_address_label,
4261 ip_address_label_cmd,
4262 "ip address A.B.C.D/M label LINE",
4263 "Interface Internet Protocol config commands\n"
4264 "Set the IP address of an interface\n"
4265 "IP address (e.g. 10.0.0.1/8)\n"
4266 "Label of this address\n"
4267 "Label\n")
4268 {
4269 int idx_ipv4_prefixlen = 2;
4270 int idx_line = 4;
4271 VTY_DECLVAR_CONTEXT(interface, ifp);
4272 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
4273 argv[idx_line]->arg);
4274 }
4275
4276 DEFUN (no_ip_address_label,
4277 no_ip_address_label_cmd,
4278 "no ip address A.B.C.D/M label LINE",
4279 NO_STR
4280 "Interface Internet Protocol config commands\n"
4281 "Set the IP address of an interface\n"
4282 "IP address (e.g. 10.0.0.1/8)\n"
4283 "Label of this address\n"
4284 "Label\n")
4285 {
4286 int idx_ipv4_prefixlen = 3;
4287 int idx_line = 5;
4288 VTY_DECLVAR_CONTEXT(interface, ifp);
4289 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
4290 NULL, argv[idx_line]->arg);
4291 }
4292 #endif /* HAVE_NETLINK */
4293
4294 int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix,
4295 const char *label)
4296 {
4297 struct zebra_if *if_data;
4298 struct prefix_ipv6 cp;
4299 struct connected *ifc;
4300 struct prefix_ipv6 *p;
4301 enum zebra_dplane_result dplane_res;
4302
4303 if_data = ifp->info;
4304
4305 cp.family = prefix->family;
4306 cp.prefixlen = prefix->prefixlen;
4307 cp.prefix = prefix->u.prefix6;
4308 apply_mask_ipv6(&cp);
4309
4310 ifc = connected_check(ifp, (struct prefix *)&cp);
4311 if (!ifc) {
4312 ifc = connected_new();
4313 ifc->ifp = ifp;
4314
4315 /* Address. */
4316 p = prefix_ipv6_new();
4317 *p = cp;
4318 ifc->address = (struct prefix *)p;
4319
4320 /* Label. */
4321 if (label)
4322 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
4323
4324 /* Add to linked list. */
4325 listnode_add(ifp->connected, ifc);
4326 }
4327
4328 /* This address is configured from zebra. */
4329 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4330 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4331
4332 /* In case of this route need to install kernel. */
4333 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
4334 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
4335 !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
4336 /* Some system need to up the interface to set IP address. */
4337 if (!if_is_up(ifp)) {
4338 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
4339 if_refresh(ifp);
4340 }
4341
4342 dplane_res = dplane_intf_addr_set(ifp, ifc);
4343 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4344 zlog_debug(
4345 "dplane can't set interface IP address: %s.",
4346 dplane_res2str(dplane_res));
4347 return NB_ERR;
4348 }
4349
4350 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4351 /* The address will be advertised to zebra clients when the
4352 * notification
4353 * from the kernel has been received. */
4354 }
4355
4356 return 0;
4357 }
4358
4359 static int ipv6_address_install(struct vty *vty, struct interface *ifp,
4360 const char *addr_str, const char *peer_str,
4361 const char *label)
4362 {
4363 struct zebra_if *if_data;
4364 struct prefix_ipv6 cp;
4365 struct connected *ifc;
4366 struct prefix_ipv6 *p;
4367 int ret;
4368 enum zebra_dplane_result dplane_res;
4369
4370 if_data = ifp->info;
4371
4372 ret = str2prefix_ipv6(addr_str, &cp);
4373 if (ret <= 0) {
4374 vty_out(vty, "%% Malformed address \n");
4375 return CMD_WARNING_CONFIG_FAILED;
4376 }
4377
4378 if (ipv6_martian(&cp.prefix)) {
4379 vty_out(vty, "%% Invalid address\n");
4380 return CMD_WARNING_CONFIG_FAILED;
4381 }
4382
4383 ifc = connected_check(ifp, (struct prefix *)&cp);
4384 if (!ifc) {
4385 ifc = connected_new();
4386 ifc->ifp = ifp;
4387
4388 /* Address. */
4389 p = prefix_ipv6_new();
4390 *p = cp;
4391 ifc->address = (struct prefix *)p;
4392
4393 /* Label. */
4394 if (label)
4395 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
4396
4397 /* Add to linked list. */
4398 listnode_add(ifp->connected, ifc);
4399 }
4400
4401 /* This address is configured from zebra. */
4402 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4403 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4404
4405 /* In case of this route need to install kernel. */
4406 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
4407 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
4408 !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
4409 /* Some system need to up the interface to set IP address. */
4410 if (!if_is_up(ifp)) {
4411 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
4412 if_refresh(ifp);
4413 }
4414
4415 dplane_res = dplane_intf_addr_set(ifp, ifc);
4416 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4417 vty_out(vty, "%% Can't set interface IP address: %s.\n",
4418 dplane_res2str(dplane_res));
4419 return CMD_WARNING_CONFIG_FAILED;
4420 }
4421
4422 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4423 /* The address will be advertised to zebra clients when the
4424 * notification
4425 * from the kernel has been received. */
4426 }
4427
4428 return CMD_SUCCESS;
4429 }
4430
4431 /* Return true if an ipv6 address is configured on ifp */
4432 int ipv6_address_configured(struct interface *ifp)
4433 {
4434 struct connected *connected;
4435 struct listnode *node;
4436
4437 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
4438 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
4439 && (connected->address->family == AF_INET6))
4440 return 1;
4441
4442 return 0;
4443 }
4444
4445 static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
4446 const char *addr_str, const char *peer_str,
4447 const char *label)
4448 {
4449 struct prefix_ipv6 cp;
4450 struct connected *ifc;
4451 int ret;
4452 enum zebra_dplane_result dplane_res;
4453
4454 /* Convert to prefix structure. */
4455 ret = str2prefix_ipv6(addr_str, &cp);
4456 if (ret <= 0) {
4457 vty_out(vty, "%% Malformed address \n");
4458 return CMD_WARNING_CONFIG_FAILED;
4459 }
4460
4461 /* Check current interface address. */
4462 ifc = connected_check(ifp, (struct prefix *)&cp);
4463 if (!ifc) {
4464 vty_out(vty, "%% Can't find address\n");
4465 return CMD_WARNING_CONFIG_FAILED;
4466 }
4467
4468 /* This is not configured address. */
4469 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4470 return CMD_WARNING_CONFIG_FAILED;
4471
4472 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4473
4474 /* This is not real address or interface is not active. */
4475 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4476 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
4477 listnode_delete(ifp->connected, ifc);
4478 connected_free(&ifc);
4479 return CMD_WARNING_CONFIG_FAILED;
4480 }
4481
4482 /* This is real route. */
4483 dplane_res = dplane_intf_addr_unset(ifp, ifc);
4484 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4485 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
4486 dplane_res2str(dplane_res));
4487 return CMD_WARNING_CONFIG_FAILED;
4488 }
4489
4490 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4491 /* This information will be propagated to the zclients when the
4492 * kernel notification is received. */
4493 return CMD_SUCCESS;
4494 }
4495
4496 DEFUN (ipv6_address,
4497 ipv6_address_cmd,
4498 "ipv6 address X:X::X:X/M",
4499 "Interface IPv6 config commands\n"
4500 "Set the IP address of an interface\n"
4501 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4502 {
4503 int idx_ipv6_prefixlen = 2;
4504 VTY_DECLVAR_CONTEXT(interface, ifp);
4505 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
4506 NULL, NULL);
4507 }
4508
4509 DEFUN (no_ipv6_address,
4510 no_ipv6_address_cmd,
4511 "no ipv6 address X:X::X:X/M",
4512 NO_STR
4513 "Interface IPv6 config commands\n"
4514 "Set the IP address of an interface\n"
4515 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4516 {
4517 int idx_ipv6_prefixlen = 3;
4518 VTY_DECLVAR_CONTEXT(interface, ifp);
4519 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
4520 NULL, NULL);
4521 }
4522
4523 static int link_params_config_write(struct vty *vty, struct interface *ifp)
4524 {
4525 int i;
4526
4527 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
4528 return -1;
4529
4530 struct if_link_params *iflp = ifp->link_params;
4531
4532 vty_out(vty, " link-params\n");
4533 vty_out(vty, " enable\n");
4534 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
4535 vty_out(vty, " metric %u\n", iflp->te_metric);
4536 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
4537 vty_out(vty, " max-bw %g\n", iflp->max_bw);
4538 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
4539 && iflp->max_rsv_bw != iflp->default_bw)
4540 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
4541 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
4542 for (i = 0; i < 8; i++)
4543 if (iflp->unrsv_bw[i] != iflp->default_bw)
4544 vty_out(vty, " unrsv-bw %d %g\n", i,
4545 iflp->unrsv_bw[i]);
4546 }
4547 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
4548 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
4549 if (IS_PARAM_SET(iflp, LP_DELAY)) {
4550 vty_out(vty, " delay %u", iflp->av_delay);
4551 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
4552 vty_out(vty, " min %u", iflp->min_delay);
4553 vty_out(vty, " max %u", iflp->max_delay);
4554 }
4555 vty_out(vty, "\n");
4556 }
4557 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
4558 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
4559 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
4560 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
4561 if (IS_PARAM_SET(iflp, LP_AVA_BW))
4562 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
4563 if (IS_PARAM_SET(iflp, LP_RES_BW))
4564 vty_out(vty, " res-bw %g\n", iflp->res_bw);
4565 if (IS_PARAM_SET(iflp, LP_USE_BW))
4566 vty_out(vty, " use-bw %g\n", iflp->use_bw);
4567 if (IS_PARAM_SET(iflp, LP_RMT_AS))
4568 vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip,
4569 iflp->rmt_as);
4570 vty_out(vty, " exit-link-params\n");
4571 return 0;
4572 }
4573
4574 static int if_config_write(struct vty *vty)
4575 {
4576 struct vrf *vrf;
4577 struct interface *ifp;
4578
4579 zebra_ptm_write(vty);
4580
4581 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
4582 FOR_ALL_INTERFACES (vrf, ifp) {
4583 struct zebra_if *if_data;
4584 struct listnode *addrnode;
4585 struct connected *ifc;
4586 struct prefix *p;
4587
4588 if_data = ifp->info;
4589
4590 if_vty_config_start(vty, ifp);
4591
4592 if (if_data) {
4593 if (if_data->shutdown == IF_ZEBRA_DATA_ON)
4594 vty_out(vty, " shutdown\n");
4595
4596 zebra_ptm_if_write(vty, if_data);
4597 }
4598
4599 if (ifp->desc)
4600 vty_out(vty, " description %s\n", ifp->desc);
4601
4602 /* Assign bandwidth here to avoid unnecessary interface
4603 flap
4604 while processing config script */
4605 if (ifp->bandwidth != 0)
4606 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
4607
4608 if (!CHECK_FLAG(ifp->status,
4609 ZEBRA_INTERFACE_LINKDETECTION))
4610 vty_out(vty, " no link-detect\n");
4611
4612 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
4613 ifc)) {
4614 if (CHECK_FLAG(ifc->conf,
4615 ZEBRA_IFC_CONFIGURED)) {
4616 char buf[INET6_ADDRSTRLEN];
4617 p = ifc->address;
4618 vty_out(vty, " ip%s address %s",
4619 p->family == AF_INET ? ""
4620 : "v6",
4621 inet_ntop(p->family,
4622 &p->u.prefix, buf,
4623 sizeof(buf)));
4624 if (CONNECTED_PEER(ifc)) {
4625 p = ifc->destination;
4626 vty_out(vty, " peer %s",
4627 inet_ntop(p->family,
4628 &p->u.prefix,
4629 buf,
4630 sizeof(buf)));
4631 }
4632 vty_out(vty, "/%d", p->prefixlen);
4633
4634 if (ifc->label)
4635 vty_out(vty, " label %s",
4636 ifc->label);
4637
4638 vty_out(vty, "\n");
4639 }
4640 }
4641
4642 if (if_data) {
4643 if (if_data->multicast != IF_ZEBRA_DATA_UNSPEC)
4644 vty_out(vty, " %smulticast\n",
4645 if_data->multicast ==
4646 IF_ZEBRA_DATA_ON
4647 ? ""
4648 : "no ");
4649 if (if_data->mpls == IF_ZEBRA_DATA_ON)
4650 vty_out(vty, " mpls enable\n");
4651 }
4652
4653 hook_call(zebra_if_config_wr, vty, ifp);
4654 zebra_evpn_mh_if_write(vty, ifp);
4655 link_params_config_write(vty, ifp);
4656
4657 if_vty_config_end(vty);
4658 }
4659 return 0;
4660 }
4661
4662 /* Allocate and initialize interface vector. */
4663 void zebra_if_init(void)
4664 {
4665 /* Initialize interface and new hook. */
4666 hook_register_prio(if_add, 0, if_zebra_new_hook);
4667 hook_register_prio(if_del, 0, if_zebra_delete_hook);
4668
4669 /* Install configuration write function. */
4670 if_cmd_init(if_config_write);
4671 install_node(&link_params_node);
4672 /*
4673 * This is *intentionally* setting this to NULL, signaling
4674 * that interface creation for zebra acts differently
4675 */
4676 if_zapi_callbacks(NULL, NULL, NULL, NULL);
4677
4678 install_element(VIEW_NODE, &show_interface_cmd);
4679 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
4680 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
4681 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
4682
4683 install_element(ENABLE_NODE, &show_interface_desc_cmd);
4684 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
4685 install_element(INTERFACE_NODE, &multicast_cmd);
4686 install_element(INTERFACE_NODE, &no_multicast_cmd);
4687 install_element(INTERFACE_NODE, &mpls_cmd);
4688 install_element(INTERFACE_NODE, &linkdetect_cmd);
4689 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
4690 install_element(INTERFACE_NODE, &shutdown_if_cmd);
4691 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
4692 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
4693 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
4694 install_element(INTERFACE_NODE, &ip_address_cmd);
4695 install_element(INTERFACE_NODE, &no_ip_address_cmd);
4696 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
4697 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
4698 install_element(INTERFACE_NODE, &ipv6_address_cmd);
4699 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
4700 #ifdef HAVE_NETLINK
4701 install_element(INTERFACE_NODE, &ip_address_label_cmd);
4702 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
4703 #endif /* HAVE_NETLINK */
4704 install_element(INTERFACE_NODE, &link_params_cmd);
4705 install_default(LINK_PARAMS_NODE);
4706 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
4707 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
4708 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
4709 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
4710 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
4711 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
4712 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
4713 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
4714 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
4715 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
4716 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
4717 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
4718 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
4719 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
4720 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
4721 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
4722 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
4723 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
4724 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
4725 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
4726 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
4727 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
4728 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
4729 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
4730
4731 /* setup EVPN MH elements */
4732 zebra_evpn_interface_init();
4733 }