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