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