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