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