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