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