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