]> git.proxmox.com Git - mirror_frr.git/blob - zebra/interface.c
Merge pull request #4995 from opensourcerouting/ospf6d-iftype
[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
772 /* VRF change for an interface */
773 void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
774 {
775 vrf_id_t old_vrf_id;
776
777 old_vrf_id = ifp->vrf_id;
778
779 /* Uninstall connected routes. */
780 if_uninstall_connected(ifp);
781
782 /* Delete any IPv4 neighbors created to implement RFC 5549 */
783 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
784
785 /* Delete all neighbor addresses learnt through IPv6 RA */
786 if_down_del_nbr_connected(ifp);
787
788 /* Send out notification on interface VRF change. */
789 /* This is to issue an UPDATE or a DELETE, as appropriate. */
790 zebra_interface_vrf_update_del(ifp, vrf_id);
791
792 /* update VRF */
793 if_update_to_new_vrf(ifp, vrf_id);
794
795 /* Send out notification on interface VRF change. */
796 /* This is to issue an ADD, if needed. */
797 zebra_interface_vrf_update_add(ifp, old_vrf_id);
798
799 /* Install connected routes (in new VRF). */
800 if (if_is_operative(ifp))
801 if_install_connected(ifp);
802 }
803
804 static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
805 {
806 mac[0] = address->s6_addr[8] ^ 0x02;
807 mac[1] = address->s6_addr[9];
808 mac[2] = address->s6_addr[10];
809 mac[3] = address->s6_addr[13];
810 mac[4] = address->s6_addr[14];
811 mac[5] = address->s6_addr[15];
812 }
813
814 void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
815 char mac[6],
816 struct in6_addr *address,
817 int add)
818 {
819 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
820 struct zebra_if *zif = ifp->info;
821 char buf[16] = "169.254.0.1";
822 struct in_addr ipv4_ll;
823 ns_id_t ns_id;
824
825 inet_pton(AF_INET, buf, &ipv4_ll);
826
827 ns_id = zvrf->zns->ns_id;
828
829 /*
830 * Remove and re-add any existing neighbor entry for this address,
831 * since Netlink doesn't currently offer update message types.
832 */
833 kernel_neigh_update(0, ifp->ifindex, ipv4_ll.s_addr, mac, 6, ns_id);
834
835 /* Add new neighbor entry.
836 *
837 * We force installation even if current neighbor entry is the same.
838 * Since this function is used to refresh our MAC entries after an
839 * interface flap, if we don't force in our custom entries with their
840 * state set to PERMANENT or REACHABLE then the kernel will attempt to
841 * resolve our leftover entries, fail, mark them unreachable and then
842 * they'll be useless to us.
843 */
844 if (add)
845 kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr, mac, 6,
846 ns_id);
847
848 memcpy(&zif->neigh_mac[0], &mac[0], 6);
849
850 /*
851 * We need to note whether or not we originated a v6
852 * neighbor entry for this interface. So that when
853 * someone unwisely accidently deletes this entry
854 * we can shove it back in.
855 */
856 zif->v6_2_v4_ll_neigh_entry = !!add;
857 memcpy(&zif->v6_2_v4_ll_addr6, address, sizeof(*address));
858
859 zvrf->neigh_updates++;
860 }
861
862 void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
863 struct in6_addr *address, int add)
864 {
865
866 char mac[6];
867
868 ipv6_ll_address_to_mac(address, (uint8_t *)mac);
869 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
870 }
871
872 static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
873 {
874 if (listhead(ifp->nbr_connected)) {
875 struct nbr_connected *nbr_connected;
876 struct listnode *node;
877
878 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
879 nbr_connected))
880 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
881 ifp, &nbr_connected->address->u.prefix6, 1);
882 }
883 }
884
885 void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)
886 {
887 if (listhead(ifp->nbr_connected)) {
888 struct nbr_connected *nbr_connected;
889 struct listnode *node;
890
891 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
892 nbr_connected))
893 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
894 ifp, &nbr_connected->address->u.prefix6, 0);
895 }
896 }
897
898 static void if_down_del_nbr_connected(struct interface *ifp)
899 {
900 struct nbr_connected *nbr_connected;
901 struct listnode *node, *nnode;
902
903 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode,
904 nbr_connected)) {
905 listnode_delete(ifp->nbr_connected, nbr_connected);
906 nbr_connected_free(nbr_connected);
907 }
908 }
909
910 /* Interface is up. */
911 void if_up(struct interface *ifp)
912 {
913 struct zebra_if *zif;
914 struct interface *link_if;
915 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
916
917 zif = ifp->info;
918 zif->up_count++;
919 quagga_timestamp(2, zif->up_last, sizeof(zif->up_last));
920
921 /* Notify the protocol daemons. */
922 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
923 flog_warn(EC_ZEBRA_PTM_NOT_READY,
924 "%s: interface %s hasn't passed ptm check\n",
925 __func__, ifp->name);
926 return;
927 }
928 zebra_interface_up_update(ifp);
929
930 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
931
932 #if defined(HAVE_RTADV)
933 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
934 if (zif->rtadv.AdvSendAdvertisements
935 && (zif->rtadv.MaxRtrAdvInterval >= 1000)) {
936 zif->rtadv.inFastRexmit = 1;
937 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
938 }
939 #endif
940
941 /* Install connected routes to the kernel. */
942 if_install_connected(ifp);
943
944 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
945 * are checked to see if (remote) neighbor entries need to be installed
946 * on them for ARP suppression.
947 */
948 if (IS_ZEBRA_IF_VXLAN(ifp))
949 zebra_vxlan_if_up(ifp);
950 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
951 link_if = ifp;
952 zebra_vxlan_svi_up(ifp, link_if);
953 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
954 link_if = if_lookup_by_index_per_ns(zvrf->zns,
955 zif->link_ifindex);
956 if (link_if)
957 zebra_vxlan_svi_up(ifp, link_if);
958 }
959 }
960
961 /* Interface goes down. We have to manage different behavior of based
962 OS. */
963 void if_down(struct interface *ifp)
964 {
965 struct zebra_if *zif;
966 struct interface *link_if;
967 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
968
969 zif = ifp->info;
970 zif->down_count++;
971 quagga_timestamp(2, zif->down_last, sizeof(zif->down_last));
972
973 /* Handle interface down for specific types for EVPN. Non-VxLAN
974 * interfaces
975 * are checked to see if (remote) neighbor entries need to be purged
976 * for ARP suppression.
977 */
978 if (IS_ZEBRA_IF_VXLAN(ifp))
979 zebra_vxlan_if_down(ifp);
980 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
981 link_if = ifp;
982 zebra_vxlan_svi_down(ifp, link_if);
983 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
984 link_if = if_lookup_by_index_per_ns(zvrf->zns,
985 zif->link_ifindex);
986 if (link_if)
987 zebra_vxlan_svi_down(ifp, link_if);
988 }
989
990
991 /* Notify to the protocol daemons. */
992 zebra_interface_down_update(ifp);
993
994 /* Uninstall connected routes from the kernel. */
995 if_uninstall_connected(ifp);
996
997 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
998
999 /* Delete all neighbor addresses learnt through IPv6 RA */
1000 if_down_del_nbr_connected(ifp);
1001 }
1002
1003 void if_refresh(struct interface *ifp)
1004 {
1005 if_get_flags(ifp);
1006 }
1007
1008 void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1009 ns_id_t ns_id)
1010 {
1011 struct zebra_if *zif;
1012
1013 if (IS_ZEBRA_IF_VETH(ifp))
1014 return;
1015 zif = (struct zebra_if *)ifp->info;
1016 zif->link_ifindex = link_ifindex;
1017 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
1018 link_ifindex);
1019 }
1020
1021 /*
1022 * during initial link dump kernel does not order lower devices before
1023 * upper devices so we need to fixup link dependencies at the end of dump
1024 */
1025 void zebra_if_update_all_links(void)
1026 {
1027 struct route_node *rn;
1028 struct interface *ifp;
1029 struct zebra_if *zif;
1030 struct zebra_ns *ns;
1031
1032 if (IS_ZEBRA_DEBUG_KERNEL)
1033 zlog_info("fixup link dependencies");
1034
1035 ns = zebra_ns_lookup(NS_DEFAULT);
1036 for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
1037 ifp = (struct interface *)rn->info;
1038 if (!ifp)
1039 continue;
1040 zif = ifp->info;
1041 if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
1042 zif->link = if_lookup_by_index_per_ns(ns,
1043 zif->link_ifindex);
1044 if (IS_ZEBRA_DEBUG_KERNEL)
1045 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1046 ifp->name, ifp->ifindex,
1047 zif->link?zif->link->name:"unk",
1048 zif->link_ifindex);
1049 }
1050 }
1051 }
1052
1053 void zebra_if_set_protodown(struct interface *ifp, bool down)
1054 {
1055 #ifdef HAVE_NETLINK
1056 netlink_protodown(ifp, down);
1057 #else
1058 zlog_warn("Protodown is not supported on this platform");
1059 #endif
1060 }
1061
1062 /* Output prefix string to vty. */
1063 static int prefix_vty_out(struct vty *vty, struct prefix *p)
1064 {
1065 char str[INET6_ADDRSTRLEN];
1066
1067 inet_ntop(p->family, &p->u.prefix, str, sizeof(str));
1068 vty_out(vty, "%s", str);
1069 return strlen(str);
1070 }
1071
1072 /* Dump if address information to vty. */
1073 static void connected_dump_vty(struct vty *vty, struct connected *connected)
1074 {
1075 struct prefix *p;
1076
1077 /* Print interface address. */
1078 p = connected->address;
1079 vty_out(vty, " %s ", prefix_family_str(p));
1080 prefix_vty_out(vty, p);
1081 vty_out(vty, "/%d", p->prefixlen);
1082
1083 /* If there is destination address, print it. */
1084 if (CONNECTED_PEER(connected) && connected->destination) {
1085 vty_out(vty, " peer ");
1086 prefix_vty_out(vty, connected->destination);
1087 vty_out(vty, "/%d", connected->destination->prefixlen);
1088 }
1089
1090 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
1091 vty_out(vty, " secondary");
1092
1093 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
1094 vty_out(vty, " unnumbered");
1095
1096 if (connected->label)
1097 vty_out(vty, " %s", connected->label);
1098
1099 vty_out(vty, "\n");
1100 }
1101
1102 /* Dump interface neighbor address information to vty. */
1103 static void nbr_connected_dump_vty(struct vty *vty,
1104 struct nbr_connected *connected)
1105 {
1106 struct prefix *p;
1107
1108 /* Print interface address. */
1109 p = connected->address;
1110 vty_out(vty, " %s ", prefix_family_str(p));
1111 prefix_vty_out(vty, p);
1112 vty_out(vty, "/%d", p->prefixlen);
1113
1114 vty_out(vty, "\n");
1115 }
1116
1117 static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
1118 {
1119 switch (zif_type) {
1120 case ZEBRA_IF_OTHER:
1121 return "Other";
1122 break;
1123
1124 case ZEBRA_IF_BRIDGE:
1125 return "Bridge";
1126 break;
1127
1128 case ZEBRA_IF_VLAN:
1129 return "Vlan";
1130 break;
1131
1132 case ZEBRA_IF_VXLAN:
1133 return "Vxlan";
1134 break;
1135
1136 case ZEBRA_IF_VRF:
1137 return "VRF";
1138 break;
1139
1140 case ZEBRA_IF_VETH:
1141 return "VETH";
1142 break;
1143
1144 case ZEBRA_IF_BOND:
1145 return "bond";
1146
1147 case ZEBRA_IF_BOND_SLAVE:
1148 return "bond_slave";
1149
1150 case ZEBRA_IF_MACVLAN:
1151 return "macvlan";
1152
1153 default:
1154 return "Unknown";
1155 break;
1156 }
1157 }
1158
1159 /* Interface's brief information print out to vty interface. */
1160 static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
1161 {
1162 struct connected *connected;
1163 struct listnode *node;
1164 struct route_node *rn;
1165 struct zebra_if *zebra_if;
1166 struct prefix *p;
1167 struct interface *ifp;
1168 bool print_header = true;
1169
1170 FOR_ALL_INTERFACES (vrf, ifp) {
1171 char global_pfx[PREFIX_STRLEN] = {0};
1172 char buf[PREFIX_STRLEN] = {0};
1173 bool first_pfx_printed = false;
1174
1175 if (print_header) {
1176 vty_out(vty, "%-16s%-8s%-16s%s\n", "Interface",
1177 "Status", "VRF", "Addresses");
1178 vty_out(vty, "%-16s%-8s%-16s%s\n", "---------",
1179 "------", "---", "---------");
1180 print_header = false; /* We have at least 1 iface */
1181 }
1182 zebra_if = ifp->info;
1183
1184 vty_out(vty, "%-16s", ifp->name);
1185
1186 if (if_is_up(ifp))
1187 vty_out(vty, "%-8s", "up");
1188 else
1189 vty_out(vty, "%-8s", "down");
1190
1191 vty_out(vty, "%-16s", vrf->name);
1192
1193 for (rn = route_top(zebra_if->ipv4_subnets); rn;
1194 rn = route_next(rn)) {
1195 if (!rn->info)
1196 continue;
1197 uint32_t list_size = listcount((struct list *)rn->info);
1198
1199 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1200 connected)) {
1201 if (!CHECK_FLAG(connected->flags,
1202 ZEBRA_IFA_SECONDARY)) {
1203 p = connected->address;
1204 prefix2str(p, buf, sizeof(buf));
1205 if (first_pfx_printed) {
1206 /* padding to prepare row only for ip addr */
1207 vty_out(vty, "%-40s", "");
1208 if (list_size > 1)
1209 vty_out(vty, "+ ");
1210 vty_out(vty, "%s\n", buf);
1211 } else {
1212 if (list_size > 1)
1213 vty_out(vty, "+ ");
1214 vty_out(vty, "%s\n", buf);
1215 }
1216 first_pfx_printed = true;
1217 break;
1218 }
1219 }
1220 }
1221
1222 uint32_t v6_list_size = 0;
1223 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1224 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1225 && (connected->address->family == AF_INET6))
1226 v6_list_size++;
1227 }
1228 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1229 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1230 && !CHECK_FLAG(connected->flags,
1231 ZEBRA_IFA_SECONDARY)
1232 && (connected->address->family == AF_INET6)) {
1233 p = connected->address;
1234 /* Don't print link local pfx */
1235 if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
1236 prefix2str(p, global_pfx, PREFIX_STRLEN);
1237 if (first_pfx_printed) {
1238 /* padding to prepare row only for ip addr */
1239 vty_out(vty, "%-40s", "");
1240 if (v6_list_size > 1)
1241 vty_out(vty, "+ ");
1242 vty_out(vty, "%s\n", global_pfx);
1243 } else {
1244 if (v6_list_size > 1)
1245 vty_out(vty, "+ ");
1246 vty_out(vty, "%s\n", global_pfx);
1247 }
1248 first_pfx_printed = true;
1249 break;
1250 }
1251 }
1252 }
1253 if (!first_pfx_printed)
1254 vty_out(vty, "\n");
1255 }
1256 vty_out(vty, "\n");
1257 }
1258
1259 /* Interface's information print out to vty interface. */
1260 static void if_dump_vty(struct vty *vty, struct interface *ifp)
1261 {
1262 struct connected *connected;
1263 struct nbr_connected *nbr_connected;
1264 struct listnode *node;
1265 struct route_node *rn;
1266 struct zebra_if *zebra_if;
1267 struct vrf *vrf;
1268
1269 zebra_if = ifp->info;
1270
1271 vty_out(vty, "Interface %s is ", ifp->name);
1272 if (if_is_up(ifp)) {
1273 vty_out(vty, "up, line protocol ");
1274
1275 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1276 if (if_is_running(ifp))
1277 vty_out(vty, "is up\n");
1278 else
1279 vty_out(vty, "is down\n");
1280 } else {
1281 vty_out(vty, "detection is disabled\n");
1282 }
1283 } else {
1284 vty_out(vty, "down\n");
1285 }
1286
1287 vty_out(vty, " Link ups: %5u last: %s\n", zebra_if->up_count,
1288 zebra_if->up_last[0] ? zebra_if->up_last : "(never)");
1289 vty_out(vty, " Link downs: %5u last: %s\n", zebra_if->down_count,
1290 zebra_if->down_last[0] ? zebra_if->down_last : "(never)");
1291
1292 zebra_ptm_show_status(vty, ifp);
1293
1294 vrf = vrf_lookup_by_id(ifp->vrf_id);
1295 vty_out(vty, " vrf: %s\n", vrf->name);
1296
1297 if (ifp->desc)
1298 vty_out(vty, " Description: %s\n", ifp->desc);
1299 if (zebra_if->desc)
1300 vty_out(vty, " OS Description: %s\n", zebra_if->desc);
1301
1302 if (ifp->ifindex == IFINDEX_INTERNAL) {
1303 vty_out(vty, " pseudo interface\n");
1304 return;
1305 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1306 vty_out(vty, " index %d inactive interface\n", ifp->ifindex);
1307 return;
1308 }
1309
1310 vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
1311 ifp->metric, ifp->mtu, ifp->speed);
1312 if (ifp->mtu6 != ifp->mtu)
1313 vty_out(vty, "mtu6 %d ", ifp->mtu6);
1314 vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
1315
1316 /* Hardware address. */
1317 vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
1318 if (ifp->hw_addr_len != 0) {
1319 int i;
1320
1321 vty_out(vty, " HWaddr: ");
1322 for (i = 0; i < ifp->hw_addr_len; i++)
1323 vty_out(vty, "%s%02x", i == 0 ? "" : ":",
1324 ifp->hw_addr[i]);
1325 vty_out(vty, "\n");
1326 }
1327
1328 /* Bandwidth in Mbps */
1329 if (ifp->bandwidth != 0) {
1330 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1331 vty_out(vty, "\n");
1332 }
1333
1334 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
1335 if (!rn->info)
1336 continue;
1337
1338 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1339 connected))
1340 connected_dump_vty(vty, connected);
1341 }
1342
1343 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1344 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1345 && (connected->address->family == AF_INET6))
1346 connected_dump_vty(vty, connected);
1347 }
1348
1349 vty_out(vty, " Interface Type %s\n",
1350 zebra_ziftype_2str(zebra_if->zif_type));
1351 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1352 struct zebra_l2info_bridge *bridge_info;
1353
1354 bridge_info = &zebra_if->l2info.br;
1355 vty_out(vty, " Bridge VLAN-aware: %s\n",
1356 bridge_info->vlan_aware ? "yes" : "no");
1357 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1358 struct zebra_l2info_vlan *vlan_info;
1359
1360 vlan_info = &zebra_if->l2info.vl;
1361 vty_out(vty, " VLAN Id %u\n", vlan_info->vid);
1362 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
1363 struct zebra_l2info_vxlan *vxlan_info;
1364
1365 vxlan_info = &zebra_if->l2info.vxl;
1366 vty_out(vty, " VxLAN Id %u", vxlan_info->vni);
1367 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
1368 vty_out(vty, " VTEP IP: %s",
1369 inet_ntoa(vxlan_info->vtep_ip));
1370 if (vxlan_info->access_vlan)
1371 vty_out(vty, " Access VLAN Id %u\n",
1372 vxlan_info->access_vlan);
1373 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
1374 vty_out(vty, " Mcast Group %s",
1375 inet_ntoa(vxlan_info->mcast_grp));
1376 vty_out(vty, "\n");
1377 }
1378
1379 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
1380 struct zebra_l2info_brslave *br_slave;
1381
1382 br_slave = &zebra_if->brslave_info;
1383 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
1384 if (br_slave->br_if)
1385 vty_out(vty, " Master interface: %s\n",
1386 br_slave->br_if->name);
1387 else
1388 vty_out(vty, " Master ifindex: %u\n",
1389 br_slave->bridge_ifindex);
1390 }
1391 }
1392
1393 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
1394 struct zebra_l2info_bondslave *bond_slave;
1395
1396 bond_slave = &zebra_if->bondslave_info;
1397 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
1398 if (bond_slave->bond_if)
1399 vty_out(vty, " Master interface: %s\n",
1400 bond_slave->bond_if->name);
1401 else
1402 vty_out(vty, " Master ifindex: %u\n",
1403 bond_slave->bond_ifindex);
1404 }
1405 }
1406
1407 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
1408 if (zebra_if->link)
1409 vty_out(vty, " Parent interface: %s\n", zebra_if->link->name);
1410 else
1411 vty_out(vty, " Parent ifindex: %d\n", zebra_if->link_ifindex);
1412 }
1413
1414 if (HAS_LINK_PARAMS(ifp)) {
1415 int i;
1416 struct if_link_params *iflp = ifp->link_params;
1417 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1418 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1419 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1420 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1421 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1422 iflp->max_bw);
1423 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1424 vty_out(vty,
1425 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1426 iflp->max_rsv_bw);
1427 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1428 vty_out(vty,
1429 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1430 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1431 vty_out(vty,
1432 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1433 i, iflp->unrsv_bw[i], i + 1,
1434 iflp->unrsv_bw[i + 1]);
1435 }
1436
1437 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1438 vty_out(vty, " Administrative Group:%u\n",
1439 iflp->admin_grp);
1440 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1441 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1442 iflp->av_delay);
1443 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1444 vty_out(vty, " Min: %u (micro-sec.)",
1445 iflp->min_delay);
1446 vty_out(vty, " Max: %u (micro-sec.)",
1447 iflp->max_delay);
1448 }
1449 vty_out(vty, "\n");
1450 }
1451 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1452 vty_out(vty,
1453 " Link Delay Variation %u (micro-sec.)\n",
1454 iflp->delay_var);
1455 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1456 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1457 iflp->pkt_loss);
1458 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1459 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1460 iflp->ava_bw);
1461 if (IS_PARAM_SET(iflp, LP_RES_BW))
1462 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1463 iflp->res_bw);
1464 if (IS_PARAM_SET(iflp, LP_USE_BW))
1465 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1466 iflp->use_bw);
1467 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1468 vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n",
1469 inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
1470 }
1471
1472 hook_call(zebra_if_extra_info, vty, ifp);
1473
1474 if (listhead(ifp->nbr_connected))
1475 vty_out(vty, " Neighbor address(s):\n");
1476 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
1477 nbr_connected_dump_vty(vty, nbr_connected);
1478
1479 #ifdef HAVE_PROC_NET_DEV
1480 /* Statistics print out using proc file system. */
1481 vty_out(vty,
1482 " %lu input packets (%lu multicast), %lu bytes, "
1483 "%lu dropped\n",
1484 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1485 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1486
1487 vty_out(vty,
1488 " %lu input errors, %lu length, %lu overrun,"
1489 " %lu CRC, %lu frame\n",
1490 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1491 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1492 ifp->stats.rx_frame_errors);
1493
1494 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1495 ifp->stats.rx_missed_errors);
1496
1497 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1498 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1499 ifp->stats.tx_dropped);
1500
1501 vty_out(vty,
1502 " %lu output errors, %lu aborted, %lu carrier,"
1503 " %lu fifo, %lu heartbeat\n",
1504 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1505 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1506 ifp->stats.tx_heartbeat_errors);
1507
1508 vty_out(vty, " %lu window, %lu collisions\n",
1509 ifp->stats.tx_window_errors, ifp->stats.collisions);
1510 #endif /* HAVE_PROC_NET_DEV */
1511
1512 #ifdef HAVE_NET_RT_IFLIST
1513 /* Statistics print out using sysctl (). */
1514 vty_out(vty,
1515 " input packets %llu, bytes %llu, dropped %llu,"
1516 " multicast packets %llu\n",
1517 (unsigned long long)ifp->stats.ifi_ipackets,
1518 (unsigned long long)ifp->stats.ifi_ibytes,
1519 (unsigned long long)ifp->stats.ifi_iqdrops,
1520 (unsigned long long)ifp->stats.ifi_imcasts);
1521
1522 vty_out(vty, " input errors %llu\n",
1523 (unsigned long long)ifp->stats.ifi_ierrors);
1524
1525 vty_out(vty,
1526 " output packets %llu, bytes %llu,"
1527 " multicast packets %llu\n",
1528 (unsigned long long)ifp->stats.ifi_opackets,
1529 (unsigned long long)ifp->stats.ifi_obytes,
1530 (unsigned long long)ifp->stats.ifi_omcasts);
1531
1532 vty_out(vty, " output errors %llu\n",
1533 (unsigned long long)ifp->stats.ifi_oerrors);
1534
1535 vty_out(vty, " collisions %llu\n",
1536 (unsigned long long)ifp->stats.ifi_collisions);
1537 #endif /* HAVE_NET_RT_IFLIST */
1538 }
1539
1540 static void interface_update_stats(void)
1541 {
1542 #ifdef HAVE_PROC_NET_DEV
1543 /* If system has interface statistics via proc file system, update
1544 statistics. */
1545 ifstat_update_proc();
1546 #endif /* HAVE_PROC_NET_DEV */
1547 #ifdef HAVE_NET_RT_IFLIST
1548 ifstat_update_sysctl();
1549 #endif /* HAVE_NET_RT_IFLIST */
1550 }
1551
1552 struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
1553
1554 #ifndef VTYSH_EXTRACT_PL
1555 #include "zebra/interface_clippy.c"
1556 #endif
1557 /* Show all interfaces to vty. */
1558 DEFPY(show_interface, show_interface_cmd,
1559 "show interface [vrf NAME$name] [brief$brief]",
1560 SHOW_STR
1561 "Interface status and configuration\n"
1562 VRF_CMD_HELP_STR
1563 "Interface status and configuration summary\n")
1564 {
1565 struct vrf *vrf;
1566 struct interface *ifp;
1567 vrf_id_t vrf_id = VRF_DEFAULT;
1568
1569 interface_update_stats();
1570
1571 if (name)
1572 VRF_GET_ID(vrf_id, name, false);
1573
1574 /* All interface print. */
1575 vrf = vrf_lookup_by_id(vrf_id);
1576 if (brief) {
1577 ifs_dump_brief_vty(vty, vrf);
1578 } else {
1579 FOR_ALL_INTERFACES (vrf, ifp) {
1580 if_dump_vty(vty, ifp);
1581 }
1582 }
1583
1584 return CMD_SUCCESS;
1585 }
1586
1587
1588 /* Show all interfaces to vty. */
1589 DEFPY (show_interface_vrf_all,
1590 show_interface_vrf_all_cmd,
1591 "show interface vrf all [brief$brief]",
1592 SHOW_STR
1593 "Interface status and configuration\n"
1594 VRF_ALL_CMD_HELP_STR
1595 "Interface status and configuration summary\n")
1596 {
1597 struct vrf *vrf;
1598 struct interface *ifp;
1599
1600 interface_update_stats();
1601
1602 /* All interface print. */
1603 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1604 if (brief) {
1605 ifs_dump_brief_vty(vty, vrf);
1606 } else {
1607 FOR_ALL_INTERFACES (vrf, ifp)
1608 if_dump_vty(vty, ifp);
1609 }
1610 }
1611
1612 return CMD_SUCCESS;
1613 }
1614
1615 /* Show specified interface to vty. */
1616
1617 DEFUN (show_interface_name_vrf,
1618 show_interface_name_vrf_cmd,
1619 "show interface IFNAME vrf NAME",
1620 SHOW_STR
1621 "Interface status and configuration\n"
1622 "Interface name\n"
1623 VRF_CMD_HELP_STR)
1624 {
1625 int idx_ifname = 2;
1626 int idx_name = 4;
1627 struct interface *ifp;
1628 vrf_id_t vrf_id;
1629
1630 interface_update_stats();
1631
1632 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
1633
1634 /* Specified interface print. */
1635 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1636 if (ifp == NULL) {
1637 vty_out(vty, "%% Can't find interface %s\n",
1638 argv[idx_ifname]->arg);
1639 return CMD_WARNING;
1640 }
1641 if_dump_vty(vty, ifp);
1642
1643 return CMD_SUCCESS;
1644 }
1645
1646 /* Show specified interface to vty. */
1647 DEFUN (show_interface_name_vrf_all,
1648 show_interface_name_vrf_all_cmd,
1649 "show interface IFNAME [vrf all]",
1650 SHOW_STR
1651 "Interface status and configuration\n"
1652 "Interface name\n"
1653 VRF_ALL_CMD_HELP_STR)
1654 {
1655 int idx_ifname = 2;
1656 struct vrf *vrf;
1657 struct interface *ifp;
1658 int found = 0;
1659
1660 interface_update_stats();
1661
1662 /* All interface print. */
1663 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1664 /* Specified interface print. */
1665 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id);
1666 if (ifp) {
1667 if_dump_vty(vty, ifp);
1668 found++;
1669 }
1670 }
1671
1672 if (!found) {
1673 vty_out(vty, "%% Can't find interface %s\n",
1674 argv[idx_ifname]->arg);
1675 return CMD_WARNING;
1676 }
1677
1678 return CMD_SUCCESS;
1679 }
1680
1681
1682 static void if_show_description(struct vty *vty, vrf_id_t vrf_id)
1683 {
1684 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
1685 struct interface *ifp;
1686
1687 vty_out(vty, "Interface Status Protocol Description\n");
1688 FOR_ALL_INTERFACES (vrf, ifp) {
1689 int len;
1690 struct zebra_if *zif;
1691 bool intf_desc;
1692
1693 intf_desc = false;
1694
1695 len = vty_out(vty, "%s", ifp->name);
1696 vty_out(vty, "%*s", (16 - len), " ");
1697
1698 if (if_is_up(ifp)) {
1699 vty_out(vty, "up ");
1700 if (CHECK_FLAG(ifp->status,
1701 ZEBRA_INTERFACE_LINKDETECTION)) {
1702 if (if_is_running(ifp))
1703 vty_out(vty, "up ");
1704 else
1705 vty_out(vty, "down ");
1706 } else {
1707 vty_out(vty, "unknown ");
1708 }
1709 } else {
1710 vty_out(vty, "down down ");
1711 }
1712
1713 if (ifp->desc) {
1714 intf_desc = true;
1715 vty_out(vty, "%s", ifp->desc);
1716 }
1717 zif = ifp->info;
1718 if (zif && zif->desc) {
1719 vty_out(vty, "%s%s",
1720 intf_desc
1721 ? "\n "
1722 : "",
1723 zif->desc);
1724 }
1725
1726 vty_out(vty, "\n");
1727 }
1728 }
1729
1730 DEFUN (show_interface_desc,
1731 show_interface_desc_cmd,
1732 "show interface description [vrf NAME]",
1733 SHOW_STR
1734 "Interface status and configuration\n"
1735 "Interface description\n"
1736 VRF_CMD_HELP_STR)
1737 {
1738 vrf_id_t vrf_id = VRF_DEFAULT;
1739
1740 if (argc > 3)
1741 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1742
1743 if_show_description(vty, vrf_id);
1744
1745 return CMD_SUCCESS;
1746 }
1747
1748
1749 DEFUN (show_interface_desc_vrf_all,
1750 show_interface_desc_vrf_all_cmd,
1751 "show interface description vrf all",
1752 SHOW_STR
1753 "Interface status and configuration\n"
1754 "Interface description\n"
1755 VRF_ALL_CMD_HELP_STR)
1756 {
1757 struct vrf *vrf;
1758
1759 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1760 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
1761 vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
1762 if_show_description(vty, vrf->vrf_id);
1763 }
1764
1765 return CMD_SUCCESS;
1766 }
1767
1768 DEFUN (multicast,
1769 multicast_cmd,
1770 "multicast",
1771 "Set multicast flag to interface\n")
1772 {
1773 VTY_DECLVAR_CONTEXT(interface, ifp);
1774 int ret;
1775 struct zebra_if *if_data;
1776
1777 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1778 ret = if_set_flags(ifp, IFF_MULTICAST);
1779 if (ret < 0) {
1780 vty_out(vty, "Can't set multicast flag\n");
1781 return CMD_WARNING_CONFIG_FAILED;
1782 }
1783 if_refresh(ifp);
1784 }
1785 if_data = ifp->info;
1786 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
1787
1788 return CMD_SUCCESS;
1789 }
1790
1791 DEFUN (no_multicast,
1792 no_multicast_cmd,
1793 "no multicast",
1794 NO_STR
1795 "Unset multicast flag to interface\n")
1796 {
1797 VTY_DECLVAR_CONTEXT(interface, ifp);
1798 int ret;
1799 struct zebra_if *if_data;
1800
1801 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1802 ret = if_unset_flags(ifp, IFF_MULTICAST);
1803 if (ret < 0) {
1804 vty_out(vty, "Can't unset multicast flag\n");
1805 return CMD_WARNING_CONFIG_FAILED;
1806 }
1807 if_refresh(ifp);
1808 }
1809 if_data = ifp->info;
1810 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1811
1812 return CMD_SUCCESS;
1813 }
1814
1815 DEFUN (linkdetect,
1816 linkdetect_cmd,
1817 "link-detect",
1818 "Enable link detection on interface\n")
1819 {
1820 VTY_DECLVAR_CONTEXT(interface, ifp);
1821 int if_was_operative;
1822
1823 if_was_operative = if_is_no_ptm_operative(ifp);
1824 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1825
1826 /* When linkdetection is enabled, if might come down */
1827 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
1828 if_down(ifp);
1829
1830 /* FIXME: Will defer status change forwarding if interface
1831 does not come down! */
1832
1833 return CMD_SUCCESS;
1834 }
1835
1836
1837 DEFUN (no_linkdetect,
1838 no_linkdetect_cmd,
1839 "no link-detect",
1840 NO_STR
1841 "Disable link detection on interface\n")
1842 {
1843 VTY_DECLVAR_CONTEXT(interface, ifp);
1844 int if_was_operative;
1845
1846 if_was_operative = if_is_no_ptm_operative(ifp);
1847 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1848
1849 /* Interface may come up after disabling link detection */
1850 if (if_is_operative(ifp) && !if_was_operative)
1851 if_up(ifp);
1852
1853 /* FIXME: see linkdetect_cmd */
1854
1855 return CMD_SUCCESS;
1856 }
1857
1858 DEFUN (shutdown_if,
1859 shutdown_if_cmd,
1860 "shutdown",
1861 "Shutdown the selected interface\n")
1862 {
1863 VTY_DECLVAR_CONTEXT(interface, ifp);
1864 int ret;
1865 struct zebra_if *if_data;
1866
1867 if (ifp->ifindex != IFINDEX_INTERNAL) {
1868 ret = if_unset_flags(ifp, IFF_UP);
1869 if (ret < 0) {
1870 vty_out(vty, "Can't shutdown interface\n");
1871 return CMD_WARNING_CONFIG_FAILED;
1872 }
1873 if_refresh(ifp);
1874 }
1875 if_data = ifp->info;
1876 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1877
1878 return CMD_SUCCESS;
1879 }
1880
1881 DEFUN (no_shutdown_if,
1882 no_shutdown_if_cmd,
1883 "no shutdown",
1884 NO_STR
1885 "Shutdown the selected interface\n")
1886 {
1887 VTY_DECLVAR_CONTEXT(interface, ifp);
1888 int ret;
1889 struct zebra_if *if_data;
1890
1891 if (ifp->ifindex != IFINDEX_INTERNAL) {
1892 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
1893 if (ret < 0) {
1894 vty_out(vty, "Can't up interface\n");
1895 return CMD_WARNING_CONFIG_FAILED;
1896 }
1897 if_refresh(ifp);
1898
1899 /* Some addresses (in particular, IPv6 addresses on Linux) get
1900 * removed when the interface goes down. They need to be
1901 * readded.
1902 */
1903 if_addr_wakeup(ifp);
1904 }
1905
1906 if_data = ifp->info;
1907 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1908
1909 return CMD_SUCCESS;
1910 }
1911
1912 DEFUN (bandwidth_if,
1913 bandwidth_if_cmd,
1914 "bandwidth (1-100000)",
1915 "Set bandwidth informational parameter\n"
1916 "Bandwidth in megabits\n")
1917 {
1918 int idx_number = 1;
1919 VTY_DECLVAR_CONTEXT(interface, ifp);
1920 unsigned int bandwidth;
1921
1922 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1923
1924 /* bandwidth range is <1-100000> */
1925 if (bandwidth < 1 || bandwidth > 100000) {
1926 vty_out(vty, "Bandwidth is invalid\n");
1927 return CMD_WARNING_CONFIG_FAILED;
1928 }
1929
1930 ifp->bandwidth = bandwidth;
1931
1932 /* force protocols to recalculate routes due to cost change */
1933 if (if_is_operative(ifp))
1934 zebra_interface_up_update(ifp);
1935
1936 return CMD_SUCCESS;
1937 }
1938
1939 DEFUN (no_bandwidth_if,
1940 no_bandwidth_if_cmd,
1941 "no bandwidth [(1-100000)]",
1942 NO_STR
1943 "Set bandwidth informational parameter\n"
1944 "Bandwidth in megabits\n")
1945 {
1946 VTY_DECLVAR_CONTEXT(interface, ifp);
1947
1948 ifp->bandwidth = 0;
1949
1950 /* force protocols to recalculate routes due to cost change */
1951 if (if_is_operative(ifp))
1952 zebra_interface_up_update(ifp);
1953
1954 return CMD_SUCCESS;
1955 }
1956
1957
1958 struct cmd_node link_params_node = {
1959 LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,
1960 };
1961
1962 static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1963 uint32_t type, uint32_t value)
1964 {
1965 /* Update field as needed */
1966 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1967 *field = value;
1968 SET_PARAM(ifp->link_params, type);
1969
1970 /* force protocols to update LINK STATE due to parameters change
1971 */
1972 if (if_is_operative(ifp))
1973 zebra_interface_parameters_update(ifp);
1974 }
1975 }
1976 static void link_param_cmd_set_float(struct interface *ifp, float *field,
1977 uint32_t type, float value)
1978 {
1979
1980 /* Update field as needed */
1981 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1982 *field = value;
1983 SET_PARAM(ifp->link_params, type);
1984
1985 /* force protocols to update LINK STATE due to parameters change
1986 */
1987 if (if_is_operative(ifp))
1988 zebra_interface_parameters_update(ifp);
1989 }
1990 }
1991
1992 static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
1993 {
1994 if (ifp->link_params == NULL)
1995 return;
1996
1997 /* Unset field */
1998 UNSET_PARAM(ifp->link_params, type);
1999
2000 /* force protocols to update LINK STATE due to parameters change */
2001 if (if_is_operative(ifp))
2002 zebra_interface_parameters_update(ifp);
2003 }
2004
2005 DEFUN_NOSH (link_params,
2006 link_params_cmd,
2007 "link-params",
2008 LINK_PARAMS_STR)
2009 {
2010 /* vty->qobj_index stays the same @ interface pointer */
2011 vty->node = LINK_PARAMS_NODE;
2012
2013 return CMD_SUCCESS;
2014 }
2015
2016 DEFUN_NOSH (exit_link_params,
2017 exit_link_params_cmd,
2018 "exit-link-params",
2019 "Exit from Link Params configuration mode\n")
2020 {
2021 if (vty->node == LINK_PARAMS_NODE)
2022 vty->node = INTERFACE_NODE;
2023 return CMD_SUCCESS;
2024 }
2025
2026 /* Specific Traffic Engineering parameters commands */
2027 DEFUN (link_params_enable,
2028 link_params_enable_cmd,
2029 "enable",
2030 "Activate link parameters on this interface\n")
2031 {
2032 VTY_DECLVAR_CONTEXT(interface, ifp);
2033
2034 /* This command could be issue at startup, when activate MPLS TE */
2035 /* on a new interface or after a ON / OFF / ON toggle */
2036 /* In all case, TE parameters are reset to their default factory */
2037 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
2038 zlog_debug(
2039 "Link-params: enable TE link parameters on interface %s",
2040 ifp->name);
2041
2042 if (!if_link_params_get(ifp)) {
2043 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
2044 zlog_debug(
2045 "Link-params: failed to init TE link parameters %s",
2046 ifp->name);
2047
2048 return CMD_WARNING_CONFIG_FAILED;
2049 }
2050
2051 /* force protocols to update LINK STATE due to parameters change */
2052 if (if_is_operative(ifp))
2053 zebra_interface_parameters_update(ifp);
2054
2055 return CMD_SUCCESS;
2056 }
2057
2058 DEFUN (no_link_params_enable,
2059 no_link_params_enable_cmd,
2060 "no enable",
2061 NO_STR
2062 "Disable link parameters on this interface\n")
2063 {
2064 VTY_DECLVAR_CONTEXT(interface, ifp);
2065
2066 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
2067 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2068 ifp->name);
2069
2070 if_link_params_free(ifp);
2071
2072 /* force protocols to update LINK STATE due to parameters change */
2073 if (if_is_operative(ifp))
2074 zebra_interface_parameters_update(ifp);
2075
2076 return CMD_SUCCESS;
2077 }
2078
2079 /* STANDARD TE metrics */
2080 DEFUN (link_params_metric,
2081 link_params_metric_cmd,
2082 "metric (0-4294967295)",
2083 "Link metric for MPLS-TE purpose\n"
2084 "Metric value in decimal\n")
2085 {
2086 int idx_number = 1;
2087 VTY_DECLVAR_CONTEXT(interface, ifp);
2088 struct if_link_params *iflp = if_link_params_get(ifp);
2089 uint32_t metric;
2090
2091 metric = strtoul(argv[idx_number]->arg, NULL, 10);
2092
2093 /* Update TE metric if needed */
2094 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
2095
2096 return CMD_SUCCESS;
2097 }
2098
2099 DEFUN (no_link_params_metric,
2100 no_link_params_metric_cmd,
2101 "no metric",
2102 NO_STR
2103 "Disable Link Metric on this interface\n")
2104 {
2105 VTY_DECLVAR_CONTEXT(interface, ifp);
2106
2107 /* Unset TE Metric */
2108 link_param_cmd_unset(ifp, LP_TE_METRIC);
2109
2110 return CMD_SUCCESS;
2111 }
2112
2113 DEFUN (link_params_maxbw,
2114 link_params_maxbw_cmd,
2115 "max-bw BANDWIDTH",
2116 "Maximum bandwidth that can be used\n"
2117 "Bytes/second (IEEE floating point format)\n")
2118 {
2119 int idx_bandwidth = 1;
2120 VTY_DECLVAR_CONTEXT(interface, ifp);
2121 struct if_link_params *iflp = if_link_params_get(ifp);
2122
2123 float bw;
2124
2125 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2126 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
2127 safe_strerror(errno));
2128 return CMD_WARNING_CONFIG_FAILED;
2129 }
2130
2131 /* Check that Maximum bandwidth is not lower than other bandwidth
2132 * parameters */
2133 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
2134 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
2135 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
2136 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
2137 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
2138 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
2139 vty_out(vty,
2140 "Maximum Bandwidth could not be lower than others bandwidth\n");
2141 return CMD_WARNING_CONFIG_FAILED;
2142 }
2143
2144 /* Update Maximum Bandwidth if needed */
2145 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
2146
2147 return CMD_SUCCESS;
2148 }
2149
2150 DEFUN (link_params_max_rsv_bw,
2151 link_params_max_rsv_bw_cmd,
2152 "max-rsv-bw BANDWIDTH",
2153 "Maximum bandwidth that may be reserved\n"
2154 "Bytes/second (IEEE floating point format)\n")
2155 {
2156 int idx_bandwidth = 1;
2157 VTY_DECLVAR_CONTEXT(interface, ifp);
2158 struct if_link_params *iflp = if_link_params_get(ifp);
2159 float bw;
2160
2161 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2162 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
2163 safe_strerror(errno));
2164 return CMD_WARNING_CONFIG_FAILED;
2165 }
2166
2167 /* Check that bandwidth is not greater than maximum bandwidth parameter
2168 */
2169 if (bw > iflp->max_bw) {
2170 vty_out(vty,
2171 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2172 iflp->max_bw);
2173 return CMD_WARNING_CONFIG_FAILED;
2174 }
2175
2176 /* Update Maximum Reservable Bandwidth if needed */
2177 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
2178
2179 return CMD_SUCCESS;
2180 }
2181
2182 DEFUN (link_params_unrsv_bw,
2183 link_params_unrsv_bw_cmd,
2184 "unrsv-bw (0-7) BANDWIDTH",
2185 "Unreserved bandwidth at each priority level\n"
2186 "Priority\n"
2187 "Bytes/second (IEEE floating point format)\n")
2188 {
2189 int idx_number = 1;
2190 int idx_bandwidth = 2;
2191 VTY_DECLVAR_CONTEXT(interface, ifp);
2192 struct if_link_params *iflp = if_link_params_get(ifp);
2193 int priority;
2194 float bw;
2195
2196 /* We don't have to consider about range check here. */
2197 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2198 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2199 safe_strerror(errno));
2200 return CMD_WARNING_CONFIG_FAILED;
2201 }
2202
2203 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 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 /* Check that bandwidth is not greater than maximum bandwidth parameter
2210 */
2211 if (bw > iflp->max_bw) {
2212 vty_out(vty,
2213 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2214 iflp->max_bw);
2215 return CMD_WARNING_CONFIG_FAILED;
2216 }
2217
2218 /* Update Unreserved Bandwidth if needed */
2219 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2220 bw);
2221
2222 return CMD_SUCCESS;
2223 }
2224
2225 DEFUN (link_params_admin_grp,
2226 link_params_admin_grp_cmd,
2227 "admin-grp BITPATTERN",
2228 "Administrative group membership\n"
2229 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2230 {
2231 int idx_bitpattern = 1;
2232 VTY_DECLVAR_CONTEXT(interface, ifp);
2233 struct if_link_params *iflp = if_link_params_get(ifp);
2234 unsigned long value;
2235
2236 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2237 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2238 safe_strerror(errno));
2239 return CMD_WARNING_CONFIG_FAILED;
2240 }
2241
2242 /* Update Administrative Group if needed */
2243 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
2244
2245 return CMD_SUCCESS;
2246 }
2247
2248 DEFUN (no_link_params_admin_grp,
2249 no_link_params_admin_grp_cmd,
2250 "no admin-grp",
2251 NO_STR
2252 "Disable Administrative group membership on this interface\n")
2253 {
2254 VTY_DECLVAR_CONTEXT(interface, ifp);
2255
2256 /* Unset Admin Group */
2257 link_param_cmd_unset(ifp, LP_ADM_GRP);
2258
2259 return CMD_SUCCESS;
2260 }
2261
2262 /* RFC5392 & RFC5316: INTER-AS */
2263 DEFUN (link_params_inter_as,
2264 link_params_inter_as_cmd,
2265 "neighbor A.B.C.D as (1-4294967295)",
2266 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2267 "Remote IP address in dot decimal A.B.C.D\n"
2268 "Remote AS number\n"
2269 "AS number in the range <1-4294967295>\n")
2270 {
2271 int idx_ipv4 = 1;
2272 int idx_number = 3;
2273
2274 VTY_DECLVAR_CONTEXT(interface, ifp);
2275 struct if_link_params *iflp = if_link_params_get(ifp);
2276 struct in_addr addr;
2277 uint32_t as;
2278
2279 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2280 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2281 return CMD_WARNING_CONFIG_FAILED;
2282 }
2283
2284 as = strtoul(argv[idx_number]->arg, NULL, 10);
2285
2286 /* Update Remote IP and Remote AS fields if needed */
2287 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2288 || iflp->rmt_ip.s_addr != addr.s_addr) {
2289
2290 iflp->rmt_as = as;
2291 iflp->rmt_ip.s_addr = addr.s_addr;
2292 SET_PARAM(iflp, LP_RMT_AS);
2293
2294 /* force protocols to update LINK STATE due to parameters change
2295 */
2296 if (if_is_operative(ifp))
2297 zebra_interface_parameters_update(ifp);
2298 }
2299 return CMD_SUCCESS;
2300 }
2301
2302 DEFUN (no_link_params_inter_as,
2303 no_link_params_inter_as_cmd,
2304 "no neighbor",
2305 NO_STR
2306 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2307 {
2308 VTY_DECLVAR_CONTEXT(interface, ifp);
2309 struct if_link_params *iflp = if_link_params_get(ifp);
2310
2311 /* Reset Remote IP and AS neighbor */
2312 iflp->rmt_as = 0;
2313 iflp->rmt_ip.s_addr = 0;
2314 UNSET_PARAM(iflp, LP_RMT_AS);
2315
2316 /* force protocols to update LINK STATE due to parameters change */
2317 if (if_is_operative(ifp))
2318 zebra_interface_parameters_update(ifp);
2319
2320 return CMD_SUCCESS;
2321 }
2322
2323 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2324 * draft-ietf-isis-metric-extensions-07.txt */
2325 DEFUN (link_params_delay,
2326 link_params_delay_cmd,
2327 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2328 "Unidirectional Average Link Delay\n"
2329 "Average delay in micro-second as decimal (0...16777215)\n"
2330 "Minimum delay\n"
2331 "Minimum delay in micro-second as decimal (0...16777215)\n"
2332 "Maximum delay\n"
2333 "Maximum delay in micro-second as decimal (0...16777215)\n")
2334 {
2335 /* Get and Check new delay values */
2336 uint32_t delay = 0, low = 0, high = 0;
2337 delay = strtoul(argv[1]->arg, NULL, 10);
2338 if (argc == 6) {
2339 low = strtoul(argv[3]->arg, NULL, 10);
2340 high = strtoul(argv[5]->arg, NULL, 10);
2341 }
2342
2343 VTY_DECLVAR_CONTEXT(interface, ifp);
2344 struct if_link_params *iflp = if_link_params_get(ifp);
2345 uint8_t update = 0;
2346
2347 if (argc == 2) {
2348 /* Check new delay value against old Min and Max delays if set
2349 */
2350 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2351 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2352 vty_out(vty,
2353 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2354 iflp->min_delay, iflp->max_delay);
2355 return CMD_WARNING_CONFIG_FAILED;
2356 }
2357 /* Update delay if value is not set or change */
2358 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2359 iflp->av_delay = delay;
2360 SET_PARAM(iflp, LP_DELAY);
2361 update = 1;
2362 }
2363 /* Unset Min and Max delays if already set */
2364 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2365 iflp->min_delay = 0;
2366 iflp->max_delay = 0;
2367 UNSET_PARAM(iflp, LP_MM_DELAY);
2368 update = 1;
2369 }
2370 } else {
2371 /* Check new delays value coherency */
2372 if (delay <= low || delay >= high) {
2373 vty_out(vty,
2374 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2375 low, high);
2376 return CMD_WARNING_CONFIG_FAILED;
2377 }
2378 /* Update Delays if needed */
2379 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2380 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2381 || iflp->av_delay != delay || iflp->min_delay != low
2382 || iflp->max_delay != high) {
2383 iflp->av_delay = delay;
2384 SET_PARAM(iflp, LP_DELAY);
2385 iflp->min_delay = low;
2386 iflp->max_delay = high;
2387 SET_PARAM(iflp, LP_MM_DELAY);
2388 update = 1;
2389 }
2390 }
2391
2392 /* force protocols to update LINK STATE due to parameters change */
2393 if (update == 1 && if_is_operative(ifp))
2394 zebra_interface_parameters_update(ifp);
2395
2396 return CMD_SUCCESS;
2397 }
2398
2399 DEFUN (no_link_params_delay,
2400 no_link_params_delay_cmd,
2401 "no delay",
2402 NO_STR
2403 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2404 {
2405 VTY_DECLVAR_CONTEXT(interface, ifp);
2406 struct if_link_params *iflp = if_link_params_get(ifp);
2407
2408 /* Unset Delays */
2409 iflp->av_delay = 0;
2410 UNSET_PARAM(iflp, LP_DELAY);
2411 iflp->min_delay = 0;
2412 iflp->max_delay = 0;
2413 UNSET_PARAM(iflp, LP_MM_DELAY);
2414
2415 /* force protocols to update LINK STATE due to parameters change */
2416 if (if_is_operative(ifp))
2417 zebra_interface_parameters_update(ifp);
2418
2419 return CMD_SUCCESS;
2420 }
2421
2422 DEFUN (link_params_delay_var,
2423 link_params_delay_var_cmd,
2424 "delay-variation (0-16777215)",
2425 "Unidirectional Link Delay Variation\n"
2426 "delay variation in micro-second as decimal (0...16777215)\n")
2427 {
2428 int idx_number = 1;
2429 VTY_DECLVAR_CONTEXT(interface, ifp);
2430 struct if_link_params *iflp = if_link_params_get(ifp);
2431 uint32_t value;
2432
2433 value = strtoul(argv[idx_number]->arg, NULL, 10);
2434
2435 /* Update Delay Variation if needed */
2436 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2437
2438 return CMD_SUCCESS;
2439 }
2440
2441 DEFUN (no_link_params_delay_var,
2442 no_link_params_delay_var_cmd,
2443 "no delay-variation",
2444 NO_STR
2445 "Disable Unidirectional Delay Variation on this interface\n")
2446 {
2447 VTY_DECLVAR_CONTEXT(interface, ifp);
2448
2449 /* Unset Delay Variation */
2450 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2451
2452 return CMD_SUCCESS;
2453 }
2454
2455 DEFUN (link_params_pkt_loss,
2456 link_params_pkt_loss_cmd,
2457 "packet-loss PERCENTAGE",
2458 "Unidirectional Link Packet Loss\n"
2459 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2460 {
2461 int idx_percentage = 1;
2462 VTY_DECLVAR_CONTEXT(interface, ifp);
2463 struct if_link_params *iflp = if_link_params_get(ifp);
2464 float fval;
2465
2466 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2467 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2468 safe_strerror(errno));
2469 return CMD_WARNING_CONFIG_FAILED;
2470 }
2471
2472 if (fval > MAX_PKT_LOSS)
2473 fval = MAX_PKT_LOSS;
2474
2475 /* Update Packet Loss if needed */
2476 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2477
2478 return CMD_SUCCESS;
2479 }
2480
2481 DEFUN (no_link_params_pkt_loss,
2482 no_link_params_pkt_loss_cmd,
2483 "no packet-loss",
2484 NO_STR
2485 "Disable Unidirectional Link Packet Loss on this interface\n")
2486 {
2487 VTY_DECLVAR_CONTEXT(interface, ifp);
2488
2489 /* Unset Packet Loss */
2490 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2491
2492 return CMD_SUCCESS;
2493 }
2494
2495 DEFUN (link_params_res_bw,
2496 link_params_res_bw_cmd,
2497 "res-bw BANDWIDTH",
2498 "Unidirectional Residual Bandwidth\n"
2499 "Bytes/second (IEEE floating point format)\n")
2500 {
2501 int idx_bandwidth = 1;
2502 VTY_DECLVAR_CONTEXT(interface, ifp);
2503 struct if_link_params *iflp = if_link_params_get(ifp);
2504 float bw;
2505
2506 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2507 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2508 safe_strerror(errno));
2509 return CMD_WARNING_CONFIG_FAILED;
2510 }
2511
2512 /* Check that bandwidth is not greater than maximum bandwidth parameter
2513 */
2514 if (bw > iflp->max_bw) {
2515 vty_out(vty,
2516 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2517 iflp->max_bw);
2518 return CMD_WARNING_CONFIG_FAILED;
2519 }
2520
2521 /* Update Residual Bandwidth if needed */
2522 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
2523
2524 return CMD_SUCCESS;
2525 }
2526
2527 DEFUN (no_link_params_res_bw,
2528 no_link_params_res_bw_cmd,
2529 "no res-bw",
2530 NO_STR
2531 "Disable Unidirectional Residual Bandwidth on this interface\n")
2532 {
2533 VTY_DECLVAR_CONTEXT(interface, ifp);
2534
2535 /* Unset Residual Bandwidth */
2536 link_param_cmd_unset(ifp, LP_RES_BW);
2537
2538 return CMD_SUCCESS;
2539 }
2540
2541 DEFUN (link_params_ava_bw,
2542 link_params_ava_bw_cmd,
2543 "ava-bw BANDWIDTH",
2544 "Unidirectional Available Bandwidth\n"
2545 "Bytes/second (IEEE floating point format)\n")
2546 {
2547 int idx_bandwidth = 1;
2548 VTY_DECLVAR_CONTEXT(interface, ifp);
2549 struct if_link_params *iflp = if_link_params_get(ifp);
2550 float bw;
2551
2552 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2553 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2554 safe_strerror(errno));
2555 return CMD_WARNING_CONFIG_FAILED;
2556 }
2557
2558 /* Check that bandwidth is not greater than maximum bandwidth parameter
2559 */
2560 if (bw > iflp->max_bw) {
2561 vty_out(vty,
2562 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2563 iflp->max_bw);
2564 return CMD_WARNING_CONFIG_FAILED;
2565 }
2566
2567 /* Update Residual Bandwidth if needed */
2568 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2569
2570 return CMD_SUCCESS;
2571 }
2572
2573 DEFUN (no_link_params_ava_bw,
2574 no_link_params_ava_bw_cmd,
2575 "no ava-bw",
2576 NO_STR
2577 "Disable Unidirectional Available Bandwidth on this interface\n")
2578 {
2579 VTY_DECLVAR_CONTEXT(interface, ifp);
2580
2581 /* Unset Available Bandwidth */
2582 link_param_cmd_unset(ifp, LP_AVA_BW);
2583
2584 return CMD_SUCCESS;
2585 }
2586
2587 DEFUN (link_params_use_bw,
2588 link_params_use_bw_cmd,
2589 "use-bw BANDWIDTH",
2590 "Unidirectional Utilised Bandwidth\n"
2591 "Bytes/second (IEEE floating point format)\n")
2592 {
2593 int idx_bandwidth = 1;
2594 VTY_DECLVAR_CONTEXT(interface, ifp);
2595 struct if_link_params *iflp = if_link_params_get(ifp);
2596 float bw;
2597
2598 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2599 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2600 safe_strerror(errno));
2601 return CMD_WARNING_CONFIG_FAILED;
2602 }
2603
2604 /* Check that bandwidth is not greater than maximum bandwidth parameter
2605 */
2606 if (bw > iflp->max_bw) {
2607 vty_out(vty,
2608 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2609 iflp->max_bw);
2610 return CMD_WARNING_CONFIG_FAILED;
2611 }
2612
2613 /* Update Utilized Bandwidth if needed */
2614 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
2615
2616 return CMD_SUCCESS;
2617 }
2618
2619 DEFUN (no_link_params_use_bw,
2620 no_link_params_use_bw_cmd,
2621 "no use-bw",
2622 NO_STR
2623 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2624 {
2625 VTY_DECLVAR_CONTEXT(interface, ifp);
2626
2627 /* Unset Utilised Bandwidth */
2628 link_param_cmd_unset(ifp, LP_USE_BW);
2629
2630 return CMD_SUCCESS;
2631 }
2632
2633 static int ip_address_install(struct vty *vty, struct interface *ifp,
2634 const char *addr_str, const char *peer_str,
2635 const char *label)
2636 {
2637 struct zebra_if *if_data;
2638 struct prefix_ipv4 lp, pp;
2639 struct connected *ifc;
2640 struct prefix_ipv4 *p;
2641 int ret;
2642 enum zebra_dplane_result dplane_res;
2643
2644 if_data = ifp->info;
2645
2646 ret = str2prefix_ipv4(addr_str, &lp);
2647 if (ret <= 0) {
2648 vty_out(vty, "%% Malformed address \n");
2649 return CMD_WARNING_CONFIG_FAILED;
2650 }
2651
2652 if (ipv4_martian(&lp.prefix)) {
2653 vty_out(vty, "%% Invalid address\n");
2654 return CMD_WARNING_CONFIG_FAILED;
2655 }
2656
2657 if (peer_str) {
2658 if (lp.prefixlen != 32) {
2659 vty_out(vty,
2660 "%% Local prefix length for P-t-P address must be /32\n");
2661 return CMD_WARNING_CONFIG_FAILED;
2662 }
2663
2664 ret = str2prefix_ipv4(peer_str, &pp);
2665 if (ret <= 0) {
2666 vty_out(vty, "%% Malformed peer address\n");
2667 return CMD_WARNING_CONFIG_FAILED;
2668 }
2669 }
2670
2671 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
2672 if (!ifc) {
2673 ifc = connected_new();
2674 ifc->ifp = ifp;
2675
2676 /* Address. */
2677 p = prefix_ipv4_new();
2678 *p = lp;
2679 ifc->address = (struct prefix *)p;
2680
2681 if (peer_str) {
2682 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2683 p = prefix_ipv4_new();
2684 *p = pp;
2685 ifc->destination = (struct prefix *)p;
2686 }
2687
2688 /* Label. */
2689 if (label)
2690 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2691
2692 /* Add to linked list. */
2693 listnode_add(ifp->connected, ifc);
2694 }
2695
2696 /* This address is configured from zebra. */
2697 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2698 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2699
2700 /* In case of this route need to install kernel. */
2701 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2702 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2703 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2704 /* Some system need to up the interface to set IP address. */
2705 if (!if_is_up(ifp)) {
2706 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2707 if_refresh(ifp);
2708 }
2709
2710 dplane_res = dplane_intf_addr_set(ifp, ifc);
2711 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2712 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2713 dplane_res2str(dplane_res));
2714 return CMD_WARNING_CONFIG_FAILED;
2715 }
2716
2717 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2718 /* The address will be advertised to zebra clients when the
2719 * notification
2720 * from the kernel has been received.
2721 * It will also be added to the subnet chain list, then. */
2722 }
2723
2724 return CMD_SUCCESS;
2725 }
2726
2727 static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2728 const char *addr_str, const char *peer_str,
2729 const char *label)
2730 {
2731 struct prefix_ipv4 lp, pp;
2732 struct connected *ifc;
2733 int ret;
2734 enum zebra_dplane_result dplane_res;
2735
2736 /* Convert to prefix structure. */
2737 ret = str2prefix_ipv4(addr_str, &lp);
2738 if (ret <= 0) {
2739 vty_out(vty, "%% Malformed address \n");
2740 return CMD_WARNING_CONFIG_FAILED;
2741 }
2742
2743 if (peer_str) {
2744 if (lp.prefixlen != 32) {
2745 vty_out(vty,
2746 "%% Local prefix length for P-t-P address must be /32\n");
2747 return CMD_WARNING_CONFIG_FAILED;
2748 }
2749
2750 ret = str2prefix_ipv4(peer_str, &pp);
2751 if (ret <= 0) {
2752 vty_out(vty, "%% Malformed peer address\n");
2753 return CMD_WARNING_CONFIG_FAILED;
2754 }
2755 }
2756
2757 /* Check current interface address. */
2758 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
2759 if (!ifc) {
2760 vty_out(vty, "%% Can't find address\n");
2761 return CMD_WARNING_CONFIG_FAILED;
2762 }
2763
2764 /* This is not configured address. */
2765 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2766 return CMD_WARNING_CONFIG_FAILED;
2767
2768 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2769
2770 /* This is not real address or interface is not active. */
2771 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2772 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2773 listnode_delete(ifp->connected, ifc);
2774 connected_free(ifc);
2775 return CMD_WARNING_CONFIG_FAILED;
2776 }
2777
2778 /* This is real route. */
2779 dplane_res = dplane_intf_addr_unset(ifp, ifc);
2780 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2781 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2782 dplane_res2str(dplane_res));
2783 return CMD_WARNING_CONFIG_FAILED;
2784 }
2785 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2786 /* we will receive a kernel notification about this route being removed.
2787 * this will trigger its removal from the connected list. */
2788 return CMD_SUCCESS;
2789 }
2790
2791 DEFUN (ip_address,
2792 ip_address_cmd,
2793 "ip address A.B.C.D/M",
2794 "Interface Internet Protocol config commands\n"
2795 "Set the IP address of an interface\n"
2796 "IP address (e.g. 10.0.0.1/8)\n")
2797 {
2798 int idx_ipv4_prefixlen = 2;
2799 VTY_DECLVAR_CONTEXT(interface, ifp);
2800 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2801 NULL);
2802 }
2803
2804 DEFUN (no_ip_address,
2805 no_ip_address_cmd,
2806 "no ip address A.B.C.D/M",
2807 NO_STR
2808 "Interface Internet Protocol config commands\n"
2809 "Set the IP address of an interface\n"
2810 "IP Address (e.g. 10.0.0.1/8)\n")
2811 {
2812 int idx_ipv4_prefixlen = 3;
2813 VTY_DECLVAR_CONTEXT(interface, ifp);
2814 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2815 NULL, NULL);
2816 }
2817
2818 DEFUN(ip_address_peer,
2819 ip_address_peer_cmd,
2820 "ip address A.B.C.D peer A.B.C.D/M",
2821 "Interface Internet Protocol config commands\n"
2822 "Set the IP address of an interface\n"
2823 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2824 "Specify P-t-P address\n"
2825 "Peer IP address (e.g. 10.0.0.1/8)\n")
2826 {
2827 VTY_DECLVAR_CONTEXT(interface, ifp);
2828 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
2829 }
2830
2831 DEFUN(no_ip_address_peer,
2832 no_ip_address_peer_cmd,
2833 "no ip address A.B.C.D peer A.B.C.D/M",
2834 NO_STR
2835 "Interface Internet Protocol config commands\n"
2836 "Set the IP address of an interface\n"
2837 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2838 "Specify P-t-P address\n"
2839 "Peer IP address (e.g. 10.0.0.1/8)\n")
2840 {
2841 VTY_DECLVAR_CONTEXT(interface, ifp);
2842 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
2843 }
2844
2845 #ifdef HAVE_NETLINK
2846 DEFUN (ip_address_label,
2847 ip_address_label_cmd,
2848 "ip address A.B.C.D/M label LINE",
2849 "Interface Internet Protocol config commands\n"
2850 "Set the IP address of an interface\n"
2851 "IP address (e.g. 10.0.0.1/8)\n"
2852 "Label of this address\n"
2853 "Label\n")
2854 {
2855 int idx_ipv4_prefixlen = 2;
2856 int idx_line = 4;
2857 VTY_DECLVAR_CONTEXT(interface, ifp);
2858 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2859 argv[idx_line]->arg);
2860 }
2861
2862 DEFUN (no_ip_address_label,
2863 no_ip_address_label_cmd,
2864 "no ip address A.B.C.D/M label LINE",
2865 NO_STR
2866 "Interface Internet Protocol config commands\n"
2867 "Set the IP address of an interface\n"
2868 "IP address (e.g. 10.0.0.1/8)\n"
2869 "Label of this address\n"
2870 "Label\n")
2871 {
2872 int idx_ipv4_prefixlen = 3;
2873 int idx_line = 5;
2874 VTY_DECLVAR_CONTEXT(interface, ifp);
2875 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2876 NULL, argv[idx_line]->arg);
2877 }
2878 #endif /* HAVE_NETLINK */
2879
2880 static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2881 const char *addr_str, const char *peer_str,
2882 const char *label)
2883 {
2884 struct zebra_if *if_data;
2885 struct prefix_ipv6 cp;
2886 struct connected *ifc;
2887 struct prefix_ipv6 *p;
2888 int ret;
2889 enum zebra_dplane_result dplane_res;
2890
2891 if_data = ifp->info;
2892
2893 ret = str2prefix_ipv6(addr_str, &cp);
2894 if (ret <= 0) {
2895 vty_out(vty, "%% Malformed address \n");
2896 return CMD_WARNING_CONFIG_FAILED;
2897 }
2898
2899 if (ipv6_martian(&cp.prefix)) {
2900 vty_out(vty, "%% Invalid address\n");
2901 return CMD_WARNING_CONFIG_FAILED;
2902 }
2903
2904 ifc = connected_check(ifp, (struct prefix *)&cp);
2905 if (!ifc) {
2906 ifc = connected_new();
2907 ifc->ifp = ifp;
2908
2909 /* Address. */
2910 p = prefix_ipv6_new();
2911 *p = cp;
2912 ifc->address = (struct prefix *)p;
2913
2914 /* Label. */
2915 if (label)
2916 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2917
2918 /* Add to linked list. */
2919 listnode_add(ifp->connected, ifc);
2920 }
2921
2922 /* This address is configured from zebra. */
2923 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2924 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2925
2926 /* In case of this route need to install kernel. */
2927 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2928 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2929 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2930 /* Some system need to up the interface to set IP address. */
2931 if (!if_is_up(ifp)) {
2932 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2933 if_refresh(ifp);
2934 }
2935
2936 dplane_res = dplane_intf_addr_set(ifp, ifc);
2937 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
2938 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2939 dplane_res2str(dplane_res));
2940 return CMD_WARNING_CONFIG_FAILED;
2941 }
2942
2943 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2944 /* The address will be advertised to zebra clients when the
2945 * notification
2946 * from the kernel has been received. */
2947 }
2948
2949 return CMD_SUCCESS;
2950 }
2951
2952 /* Return true if an ipv6 address is configured on ifp */
2953 int ipv6_address_configured(struct interface *ifp)
2954 {
2955 struct connected *connected;
2956 struct listnode *node;
2957
2958 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2959 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2960 && (connected->address->family == AF_INET6))
2961 return 1;
2962
2963 return 0;
2964 }
2965
2966 static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2967 const char *addr_str, const char *peer_str,
2968 const char *label)
2969 {
2970 struct prefix_ipv6 cp;
2971 struct connected *ifc;
2972 int ret;
2973 enum zebra_dplane_result dplane_res;
2974
2975 /* Convert to prefix structure. */
2976 ret = str2prefix_ipv6(addr_str, &cp);
2977 if (ret <= 0) {
2978 vty_out(vty, "%% Malformed address \n");
2979 return CMD_WARNING_CONFIG_FAILED;
2980 }
2981
2982 /* Check current interface address. */
2983 ifc = connected_check(ifp, (struct prefix *)&cp);
2984 if (!ifc) {
2985 vty_out(vty, "%% Can't find address\n");
2986 return CMD_WARNING_CONFIG_FAILED;
2987 }
2988
2989 /* This is not configured address. */
2990 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2991 return CMD_WARNING_CONFIG_FAILED;
2992
2993 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2994
2995 /* This is not real address or interface is not active. */
2996 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2997 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2998 listnode_delete(ifp->connected, ifc);
2999 connected_free(ifc);
3000 return CMD_WARNING_CONFIG_FAILED;
3001 }
3002
3003 /* This is real route. */
3004 dplane_res = dplane_intf_addr_unset(ifp, ifc);
3005 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
3006 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
3007 dplane_res2str(dplane_res));
3008 return CMD_WARNING_CONFIG_FAILED;
3009 }
3010
3011 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3012 /* This information will be propagated to the zclients when the
3013 * kernel notification is received. */
3014 return CMD_SUCCESS;
3015 }
3016
3017 DEFUN (ipv6_address,
3018 ipv6_address_cmd,
3019 "ipv6 address X:X::X:X/M",
3020 "Interface IPv6 config commands\n"
3021 "Set the IP address of an interface\n"
3022 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3023 {
3024 int idx_ipv6_prefixlen = 2;
3025 VTY_DECLVAR_CONTEXT(interface, ifp);
3026 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
3027 NULL, NULL);
3028 }
3029
3030 DEFUN (no_ipv6_address,
3031 no_ipv6_address_cmd,
3032 "no ipv6 address X:X::X:X/M",
3033 NO_STR
3034 "Interface IPv6 config commands\n"
3035 "Set the IP address of an interface\n"
3036 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3037 {
3038 int idx_ipv6_prefixlen = 3;
3039 VTY_DECLVAR_CONTEXT(interface, ifp);
3040 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
3041 NULL, NULL);
3042 }
3043
3044 static int link_params_config_write(struct vty *vty, struct interface *ifp)
3045 {
3046 int i;
3047
3048 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
3049 return -1;
3050
3051 struct if_link_params *iflp = ifp->link_params;
3052
3053 vty_out(vty, " link-params\n");
3054 vty_out(vty, " enable\n");
3055 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
3056 vty_out(vty, " metric %u\n", iflp->te_metric);
3057 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
3058 vty_out(vty, " max-bw %g\n", iflp->max_bw);
3059 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
3060 && iflp->max_rsv_bw != iflp->default_bw)
3061 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
3062 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
3063 for (i = 0; i < 8; i++)
3064 if (iflp->unrsv_bw[i] != iflp->default_bw)
3065 vty_out(vty, " unrsv-bw %d %g\n", i,
3066 iflp->unrsv_bw[i]);
3067 }
3068 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
3069 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
3070 if (IS_PARAM_SET(iflp, LP_DELAY)) {
3071 vty_out(vty, " delay %u", iflp->av_delay);
3072 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
3073 vty_out(vty, " min %u", iflp->min_delay);
3074 vty_out(vty, " max %u", iflp->max_delay);
3075 }
3076 vty_out(vty, "\n");
3077 }
3078 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
3079 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
3080 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
3081 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
3082 if (IS_PARAM_SET(iflp, LP_AVA_BW))
3083 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
3084 if (IS_PARAM_SET(iflp, LP_RES_BW))
3085 vty_out(vty, " res-bw %g\n", iflp->res_bw);
3086 if (IS_PARAM_SET(iflp, LP_USE_BW))
3087 vty_out(vty, " use-bw %g\n", iflp->use_bw);
3088 if (IS_PARAM_SET(iflp, LP_RMT_AS))
3089 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
3090 iflp->rmt_as);
3091 vty_out(vty, " exit-link-params\n");
3092 return 0;
3093 }
3094
3095 static int if_config_write(struct vty *vty)
3096 {
3097 struct vrf *vrf0;
3098 struct interface *ifp;
3099
3100 zebra_ptm_write(vty);
3101
3102 RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
3103 FOR_ALL_INTERFACES (vrf0, ifp) {
3104 struct zebra_if *if_data;
3105 struct listnode *addrnode;
3106 struct connected *ifc;
3107 struct prefix *p;
3108 struct vrf *vrf;
3109
3110 if_data = ifp->info;
3111 vrf = vrf_lookup_by_id(ifp->vrf_id);
3112
3113 if (ifp->vrf_id == VRF_DEFAULT)
3114 vty_frame(vty, "interface %s\n", ifp->name);
3115 else
3116 vty_frame(vty, "interface %s vrf %s\n",
3117 ifp->name, vrf->name);
3118
3119 if (if_data) {
3120 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
3121 vty_out(vty, " shutdown\n");
3122
3123 zebra_ptm_if_write(vty, if_data);
3124 }
3125
3126 if (ifp->desc)
3127 vty_out(vty, " description %s\n", ifp->desc);
3128
3129 /* Assign bandwidth here to avoid unnecessary interface
3130 flap
3131 while processing config script */
3132 if (ifp->bandwidth != 0)
3133 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
3134
3135 if (!CHECK_FLAG(ifp->status,
3136 ZEBRA_INTERFACE_LINKDETECTION))
3137 vty_out(vty, " no link-detect\n");
3138
3139 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
3140 ifc)) {
3141 if (CHECK_FLAG(ifc->conf,
3142 ZEBRA_IFC_CONFIGURED)) {
3143 char buf[INET6_ADDRSTRLEN];
3144 p = ifc->address;
3145 vty_out(vty, " ip%s address %s",
3146 p->family == AF_INET ? ""
3147 : "v6",
3148 inet_ntop(p->family,
3149 &p->u.prefix, buf,
3150 sizeof(buf)));
3151 if (CONNECTED_PEER(ifc)) {
3152 p = ifc->destination;
3153 vty_out(vty, " peer %s",
3154 inet_ntop(p->family,
3155 &p->u.prefix,
3156 buf,
3157 sizeof(buf)));
3158 }
3159 vty_out(vty, "/%d", p->prefixlen);
3160
3161 if (ifc->label)
3162 vty_out(vty, " label %s",
3163 ifc->label);
3164
3165 vty_out(vty, "\n");
3166 }
3167 }
3168
3169 if (if_data) {
3170 if (if_data->multicast
3171 != IF_ZEBRA_MULTICAST_UNSPEC)
3172 vty_out(vty, " %smulticast\n",
3173 if_data->multicast
3174 == IF_ZEBRA_MULTICAST_ON
3175 ? ""
3176 : "no ");
3177 }
3178
3179 hook_call(zebra_if_config_wr, vty, ifp);
3180
3181 link_params_config_write(vty, ifp);
3182
3183 vty_endframe(vty, "!\n");
3184 }
3185 return 0;
3186 }
3187
3188 /* Allocate and initialize interface vector. */
3189 void zebra_if_init(void)
3190 {
3191 /* Initialize interface and new hook. */
3192 hook_register_prio(if_add, 0, if_zebra_new_hook);
3193 hook_register_prio(if_del, 0, if_zebra_delete_hook);
3194
3195 /* Install configuration write function. */
3196 install_node(&interface_node, if_config_write);
3197 install_node(&link_params_node, NULL);
3198 if_cmd_init();
3199
3200 install_element(VIEW_NODE, &show_interface_cmd);
3201 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
3202 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
3203 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
3204
3205 install_element(ENABLE_NODE, &show_interface_desc_cmd);
3206 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
3207 install_element(INTERFACE_NODE, &multicast_cmd);
3208 install_element(INTERFACE_NODE, &no_multicast_cmd);
3209 install_element(INTERFACE_NODE, &linkdetect_cmd);
3210 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
3211 install_element(INTERFACE_NODE, &shutdown_if_cmd);
3212 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
3213 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
3214 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
3215 install_element(INTERFACE_NODE, &ip_address_cmd);
3216 install_element(INTERFACE_NODE, &no_ip_address_cmd);
3217 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
3218 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
3219 install_element(INTERFACE_NODE, &ipv6_address_cmd);
3220 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
3221 #ifdef HAVE_NETLINK
3222 install_element(INTERFACE_NODE, &ip_address_label_cmd);
3223 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
3224 #endif /* HAVE_NETLINK */
3225 install_element(INTERFACE_NODE, &link_params_cmd);
3226 install_default(LINK_PARAMS_NODE);
3227 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
3228 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
3229 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
3230 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
3231 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
3232 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
3233 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
3234 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
3235 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
3236 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
3237 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
3238 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
3239 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
3240 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
3241 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
3242 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
3243 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
3244 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
3245 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
3246 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
3247 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
3248 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
3249 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
3250 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
3251 }