]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
*: add git-reindent-branch.py
[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.
c14777c6 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 = {
c14777c6 1760 LINK_PARAMS_NODE,
1761 "%s(config-link-params)# ",
1762 1,
16f1b9ee
OD
1763};
1764
d62a17ae 1765static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1766 uint32_t type, uint32_t value)
16f1b9ee 1767{
d62a17ae 1768 /* Update field as needed */
1769 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1770 *field = value;
1771 SET_PARAM(ifp->link_params, type);
16f1b9ee 1772
d62a17ae 1773 /* force protocols to update LINK STATE due to parameters change
1774 */
1775 if (if_is_operative(ifp))
1776 zebra_interface_parameters_update(ifp);
1777 }
16f1b9ee 1778}
d62a17ae 1779static void link_param_cmd_set_float(struct interface *ifp, float *field,
1780 uint32_t type, float value)
16f1b9ee
OD
1781{
1782
d62a17ae 1783 /* Update field as needed */
1784 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1785 *field = value;
1786 SET_PARAM(ifp->link_params, type);
16f1b9ee 1787
d62a17ae 1788 /* force protocols to update LINK STATE due to parameters change
1789 */
1790 if (if_is_operative(ifp))
1791 zebra_interface_parameters_update(ifp);
1792 }
16f1b9ee
OD
1793}
1794
d62a17ae 1795static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
16f1b9ee 1796{
d62a17ae 1797 if (ifp->link_params == NULL)
1798 return;
16f1b9ee 1799
d62a17ae 1800 /* Unset field */
1801 UNSET_PARAM(ifp->link_params, type);
16f1b9ee 1802
d62a17ae 1803 /* force protocols to update LINK STATE due to parameters change */
1804 if (if_is_operative(ifp))
1805 zebra_interface_parameters_update(ifp);
16f1b9ee
OD
1806}
1807
505e5056 1808DEFUN_NOSH (link_params,
16f1b9ee
OD
1809 link_params_cmd,
1810 "link-params",
1811 LINK_PARAMS_STR)
1812{
d62a17ae 1813 /* vty->qobj_index stays the same @ interface pointer */
1814 vty->node = LINK_PARAMS_NODE;
16f1b9ee 1815
d62a17ae 1816 return CMD_SUCCESS;
16f1b9ee
OD
1817}
1818
505e5056 1819DEFUN_NOSH (exit_link_params,
03f99d9a
DS
1820 exit_link_params_cmd,
1821 "exit-link-params",
1822 "Exit from Link Params configuration mode\n")
1823{
d62a17ae 1824 if (vty->node == LINK_PARAMS_NODE)
1825 vty->node = INTERFACE_NODE;
1826 return CMD_SUCCESS;
03f99d9a
DS
1827}
1828
16f1b9ee
OD
1829/* Specific Traffic Engineering parameters commands */
1830DEFUN (link_params_enable,
1831 link_params_enable_cmd,
1832 "enable",
1833 "Activate link parameters on this interface\n")
1834{
d62a17ae 1835 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1836
d62a17ae 1837 /* This command could be issue at startup, when activate MPLS TE */
1838 /* on a new interface or after a ON / OFF / ON toggle */
1839 /* In all case, TE parameters are reset to their default factory */
1840 if (IS_ZEBRA_DEBUG_EVENT)
1841 zlog_debug(
1842 "Link-params: enable TE link parameters on interface %s",
1843 ifp->name);
16f1b9ee 1844
d62a17ae 1845 if (!if_link_params_get(ifp)) {
1846 if (IS_ZEBRA_DEBUG_EVENT)
1847 zlog_debug(
1848 "Link-params: failed to init TE link parameters %s",
1849 ifp->name);
16f1b9ee 1850
d62a17ae 1851 return CMD_WARNING_CONFIG_FAILED;
1852 }
16f1b9ee 1853
d62a17ae 1854 /* force protocols to update LINK STATE due to parameters change */
1855 if (if_is_operative(ifp))
1856 zebra_interface_parameters_update(ifp);
16f1b9ee 1857
d62a17ae 1858 return CMD_SUCCESS;
16f1b9ee
OD
1859}
1860
1861DEFUN (no_link_params_enable,
1862 no_link_params_enable_cmd,
1863 "no enable",
1864 NO_STR
1865 "Disable link parameters on this interface\n")
1866{
d62a17ae 1867 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1868
d62a17ae 1869 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
1870 ifp->name);
16f1b9ee 1871
d62a17ae 1872 if_link_params_free(ifp);
16f1b9ee 1873
d62a17ae 1874 /* force protocols to update LINK STATE due to parameters change */
1875 if (if_is_operative(ifp))
1876 zebra_interface_parameters_update(ifp);
16f1b9ee 1877
d62a17ae 1878 return CMD_SUCCESS;
16f1b9ee
OD
1879}
1880
1881/* STANDARD TE metrics */
1882DEFUN (link_params_metric,
1883 link_params_metric_cmd,
6147e2c6 1884 "metric (0-4294967295)",
16f1b9ee
OD
1885 "Link metric for MPLS-TE purpose\n"
1886 "Metric value in decimal\n")
1887{
d62a17ae 1888 int idx_number = 1;
1889 VTY_DECLVAR_CONTEXT(interface, ifp);
1890 struct if_link_params *iflp = if_link_params_get(ifp);
1891 u_int32_t metric;
16f1b9ee 1892
d62a17ae 1893 metric = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 1894
d62a17ae 1895 /* Update TE metric if needed */
1896 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee 1897
d62a17ae 1898 return CMD_SUCCESS;
16f1b9ee
OD
1899}
1900
1901DEFUN (no_link_params_metric,
1902 no_link_params_metric_cmd,
1903 "no metric",
1904 NO_STR
3ddccf18 1905 "Disable Link Metric on this interface\n")
16f1b9ee 1906{
d62a17ae 1907 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1908
d62a17ae 1909 /* Unset TE Metric */
1910 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee 1911
d62a17ae 1912 return CMD_SUCCESS;
16f1b9ee
OD
1913}
1914
1915DEFUN (link_params_maxbw,
1916 link_params_maxbw_cmd,
1917 "max-bw BANDWIDTH",
1918 "Maximum bandwidth that can be used\n"
1919 "Bytes/second (IEEE floating point format)\n")
1920{
d62a17ae 1921 int idx_bandwidth = 1;
1922 VTY_DECLVAR_CONTEXT(interface, ifp);
1923 struct if_link_params *iflp = if_link_params_get(ifp);
1924
1925 float bw;
1926
1927 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
1928 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
1929 safe_strerror(errno));
1930 return CMD_WARNING_CONFIG_FAILED;
1931 }
1932
1933 /* Check that Maximum bandwidth is not lower than other bandwidth
1934 * parameters */
1935 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
1936 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
1937 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
1938 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
1939 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
1940 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
1941 vty_out(vty,
1942 "Maximum Bandwidth could not be lower than others bandwidth\n");
1943 return CMD_WARNING_CONFIG_FAILED;
1944 }
1945
1946 /* Update Maximum Bandwidth if needed */
1947 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
1948
1949 return CMD_SUCCESS;
16f1b9ee
OD
1950}
1951
1952DEFUN (link_params_max_rsv_bw,
1953 link_params_max_rsv_bw_cmd,
1954 "max-rsv-bw BANDWIDTH",
1955 "Maximum bandwidth that may be reserved\n"
1956 "Bytes/second (IEEE floating point format)\n")
1957{
d62a17ae 1958 int idx_bandwidth = 1;
1959 VTY_DECLVAR_CONTEXT(interface, ifp);
1960 struct if_link_params *iflp = if_link_params_get(ifp);
1961 float bw;
16f1b9ee 1962
d62a17ae 1963 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
1964 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
1965 safe_strerror(errno));
1966 return CMD_WARNING_CONFIG_FAILED;
1967 }
16f1b9ee 1968
d62a17ae 1969 /* Check that bandwidth is not greater than maximum bandwidth parameter
1970 */
1971 if (bw > iflp->max_bw) {
1972 vty_out(vty,
1973 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
1974 iflp->max_bw);
1975 return CMD_WARNING_CONFIG_FAILED;
1976 }
16f1b9ee 1977
d62a17ae 1978 /* Update Maximum Reservable Bandwidth if needed */
1979 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
16f1b9ee 1980
d62a17ae 1981 return CMD_SUCCESS;
16f1b9ee
OD
1982}
1983
1984DEFUN (link_params_unrsv_bw,
1985 link_params_unrsv_bw_cmd,
6147e2c6 1986 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
1987 "Unreserved bandwidth at each priority level\n"
1988 "Priority\n"
1989 "Bytes/second (IEEE floating point format)\n")
1990{
d62a17ae 1991 int idx_number = 1;
1992 int idx_bandwidth = 2;
1993 VTY_DECLVAR_CONTEXT(interface, ifp);
1994 struct if_link_params *iflp = if_link_params_get(ifp);
1995 int priority;
1996 float bw;
1997
1998 /* We don't have to consider about range check here. */
1999 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2000 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2001 safe_strerror(errno));
2002 return CMD_WARNING_CONFIG_FAILED;
2003 }
2004
2005 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2006 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2007 safe_strerror(errno));
2008 return CMD_WARNING_CONFIG_FAILED;
2009 }
2010
2011 /* Check that bandwidth is not greater than maximum bandwidth parameter
2012 */
2013 if (bw > iflp->max_bw) {
2014 vty_out(vty,
2015 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2016 iflp->max_bw);
2017 return CMD_WARNING_CONFIG_FAILED;
2018 }
2019
2020 /* Update Unreserved Bandwidth if needed */
2021 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2022 bw);
2023
2024 return CMD_SUCCESS;
16f1b9ee
OD
2025}
2026
2027DEFUN (link_params_admin_grp,
2028 link_params_admin_grp_cmd,
2029 "admin-grp BITPATTERN",
2030 "Administrative group membership\n"
2031 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2032{
d62a17ae 2033 int idx_bitpattern = 1;
2034 VTY_DECLVAR_CONTEXT(interface, ifp);
2035 struct if_link_params *iflp = if_link_params_get(ifp);
2036 unsigned long value;
16f1b9ee 2037
d62a17ae 2038 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2039 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2040 safe_strerror(errno));
2041 return CMD_WARNING_CONFIG_FAILED;
2042 }
16f1b9ee 2043
d62a17ae 2044 /* Update Administrative Group if needed */
2045 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
16f1b9ee 2046
d62a17ae 2047 return CMD_SUCCESS;
16f1b9ee
OD
2048}
2049
2050DEFUN (no_link_params_admin_grp,
2051 no_link_params_admin_grp_cmd,
2052 "no admin-grp",
2053 NO_STR
3ddccf18 2054 "Disable Administrative group membership on this interface\n")
16f1b9ee 2055{
d62a17ae 2056 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2057
d62a17ae 2058 /* Unset Admin Group */
2059 link_param_cmd_unset(ifp, LP_ADM_GRP);
16f1b9ee 2060
d62a17ae 2061 return CMD_SUCCESS;
16f1b9ee
OD
2062}
2063
2064/* RFC5392 & RFC5316: INTER-AS */
2065DEFUN (link_params_inter_as,
2066 link_params_inter_as_cmd,
6147e2c6 2067 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
2068 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2069 "Remote IP address in dot decimal A.B.C.D\n"
2070 "Remote AS number\n"
2071 "AS number in the range <1-4294967295>\n")
2072{
d62a17ae 2073 int idx_ipv4 = 1;
2074 int idx_number = 3;
16f1b9ee 2075
d62a17ae 2076 VTY_DECLVAR_CONTEXT(interface, ifp);
2077 struct if_link_params *iflp = if_link_params_get(ifp);
2078 struct in_addr addr;
2079 u_int32_t as;
16f1b9ee 2080
d62a17ae 2081 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2082 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2083 return CMD_WARNING_CONFIG_FAILED;
2084 }
16f1b9ee 2085
d62a17ae 2086 as = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2087
d62a17ae 2088 /* Update Remote IP and Remote AS fields if needed */
2089 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2090 || iflp->rmt_ip.s_addr != addr.s_addr) {
16f1b9ee 2091
d62a17ae 2092 iflp->rmt_as = as;
2093 iflp->rmt_ip.s_addr = addr.s_addr;
2094 SET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2095
d62a17ae 2096 /* force protocols to update LINK STATE due to parameters change
2097 */
2098 if (if_is_operative(ifp))
2099 zebra_interface_parameters_update(ifp);
2100 }
2101 return CMD_SUCCESS;
16f1b9ee
OD
2102}
2103
2104DEFUN (no_link_params_inter_as,
2105 no_link_params_inter_as_cmd,
2106 "no neighbor",
2107 NO_STR
2108 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2109{
d62a17ae 2110 VTY_DECLVAR_CONTEXT(interface, ifp);
2111 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2112
d62a17ae 2113 /* Reset Remote IP and AS neighbor */
2114 iflp->rmt_as = 0;
2115 iflp->rmt_ip.s_addr = 0;
2116 UNSET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2117
d62a17ae 2118 /* force protocols to update LINK STATE due to parameters change */
2119 if (if_is_operative(ifp))
2120 zebra_interface_parameters_update(ifp);
16f1b9ee 2121
d62a17ae 2122 return CMD_SUCCESS;
16f1b9ee
OD
2123}
2124
d62a17ae 2125/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2126 * draft-ietf-isis-metric-extensions-07.txt */
16f1b9ee
OD
2127DEFUN (link_params_delay,
2128 link_params_delay_cmd,
b62ecea5 2129 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 2130 "Unidirectional Average Link Delay\n"
b62ecea5
QY
2131 "Average delay in micro-second as decimal (0...16777215)\n"
2132 "Minimum delay\n"
2133 "Minimum delay in micro-second as decimal (0...16777215)\n"
2134 "Maximum delay\n"
2135 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 2136{
d62a17ae 2137 /* Get and Check new delay values */
2138 u_int32_t delay = 0, low = 0, high = 0;
2139 delay = strtoul(argv[1]->arg, NULL, 10);
2140 if (argc == 6) {
2141 low = strtoul(argv[3]->arg, NULL, 10);
2142 high = strtoul(argv[5]->arg, NULL, 10);
2143 }
2144
2145 VTY_DECLVAR_CONTEXT(interface, ifp);
2146 struct if_link_params *iflp = if_link_params_get(ifp);
2147 u_int8_t update = 0;
2148
2149 if (argc == 2) {
2150 /* Check new delay value against old Min and Max delays if set
2151 */
2152 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2153 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2154 vty_out(vty,
2155 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2156 iflp->min_delay, iflp->max_delay);
2157 return CMD_WARNING_CONFIG_FAILED;
2158 }
2159 /* Update delay if value is not set or change */
2160 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2161 iflp->av_delay = delay;
2162 SET_PARAM(iflp, LP_DELAY);
2163 update = 1;
2164 }
2165 /* Unset Min and Max delays if already set */
2166 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2167 iflp->min_delay = 0;
2168 iflp->max_delay = 0;
2169 UNSET_PARAM(iflp, LP_MM_DELAY);
2170 update = 1;
2171 }
2172 } else {
2173 /* Check new delays value coherency */
2174 if (delay <= low || delay >= high) {
2175 vty_out(vty,
2176 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2177 low, high);
2178 return CMD_WARNING_CONFIG_FAILED;
2179 }
2180 /* Update Delays if needed */
2181 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2182 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2183 || iflp->av_delay != delay || iflp->min_delay != low
2184 || iflp->max_delay != high) {
2185 iflp->av_delay = delay;
2186 SET_PARAM(iflp, LP_DELAY);
2187 iflp->min_delay = low;
2188 iflp->max_delay = high;
2189 SET_PARAM(iflp, LP_MM_DELAY);
2190 update = 1;
2191 }
2192 }
2193
2194 /* force protocols to update LINK STATE due to parameters change */
2195 if (update == 1 && if_is_operative(ifp))
2196 zebra_interface_parameters_update(ifp);
2197
2198 return CMD_SUCCESS;
16f1b9ee
OD
2199}
2200
16f1b9ee
OD
2201DEFUN (no_link_params_delay,
2202 no_link_params_delay_cmd,
2203 "no delay",
2204 NO_STR
3ddccf18 2205 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 2206{
d62a17ae 2207 VTY_DECLVAR_CONTEXT(interface, ifp);
2208 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2209
d62a17ae 2210 /* Unset Delays */
2211 iflp->av_delay = 0;
2212 UNSET_PARAM(iflp, LP_DELAY);
2213 iflp->min_delay = 0;
2214 iflp->max_delay = 0;
2215 UNSET_PARAM(iflp, LP_MM_DELAY);
16f1b9ee 2216
d62a17ae 2217 /* force protocols to update LINK STATE due to parameters change */
2218 if (if_is_operative(ifp))
2219 zebra_interface_parameters_update(ifp);
16f1b9ee 2220
d62a17ae 2221 return CMD_SUCCESS;
16f1b9ee
OD
2222}
2223
2224DEFUN (link_params_delay_var,
2225 link_params_delay_var_cmd,
6147e2c6 2226 "delay-variation (0-16777215)",
16f1b9ee
OD
2227 "Unidirectional Link Delay Variation\n"
2228 "delay variation in micro-second as decimal (0...16777215)\n")
2229{
d62a17ae 2230 int idx_number = 1;
2231 VTY_DECLVAR_CONTEXT(interface, ifp);
2232 struct if_link_params *iflp = if_link_params_get(ifp);
2233 u_int32_t value;
16f1b9ee 2234
d62a17ae 2235 value = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2236
d62a17ae 2237 /* Update Delay Variation if needed */
2238 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
16f1b9ee 2239
d62a17ae 2240 return CMD_SUCCESS;
16f1b9ee
OD
2241}
2242
2243DEFUN (no_link_params_delay_var,
2244 no_link_params_delay_var_cmd,
2245 "no delay-variation",
2246 NO_STR
3ddccf18 2247 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 2248{
d62a17ae 2249 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2250
d62a17ae 2251 /* Unset Delay Variation */
2252 link_param_cmd_unset(ifp, LP_DELAY_VAR);
16f1b9ee 2253
d62a17ae 2254 return CMD_SUCCESS;
16f1b9ee
OD
2255}
2256
2257DEFUN (link_params_pkt_loss,
2258 link_params_pkt_loss_cmd,
2259 "packet-loss PERCENTAGE",
2260 "Unidirectional Link Packet Loss\n"
2261 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2262{
d62a17ae 2263 int idx_percentage = 1;
2264 VTY_DECLVAR_CONTEXT(interface, ifp);
2265 struct if_link_params *iflp = if_link_params_get(ifp);
2266 float fval;
16f1b9ee 2267
d62a17ae 2268 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2269 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2270 safe_strerror(errno));
2271 return CMD_WARNING_CONFIG_FAILED;
2272 }
16f1b9ee 2273
d62a17ae 2274 if (fval > MAX_PKT_LOSS)
2275 fval = MAX_PKT_LOSS;
16f1b9ee 2276
d62a17ae 2277 /* Update Packet Loss if needed */
2278 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
16f1b9ee 2279
d62a17ae 2280 return CMD_SUCCESS;
16f1b9ee
OD
2281}
2282
2283DEFUN (no_link_params_pkt_loss,
2284 no_link_params_pkt_loss_cmd,
2285 "no packet-loss",
2286 NO_STR
3ddccf18 2287 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 2288{
d62a17ae 2289 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2290
d62a17ae 2291 /* Unset Packet Loss */
2292 link_param_cmd_unset(ifp, LP_PKT_LOSS);
16f1b9ee 2293
d62a17ae 2294 return CMD_SUCCESS;
16f1b9ee
OD
2295}
2296
2297DEFUN (link_params_res_bw,
2298 link_params_res_bw_cmd,
2299 "res-bw BANDWIDTH",
2300 "Unidirectional Residual Bandwidth\n"
2301 "Bytes/second (IEEE floating point format)\n")
2302{
d62a17ae 2303 int idx_bandwidth = 1;
2304 VTY_DECLVAR_CONTEXT(interface, ifp);
2305 struct if_link_params *iflp = if_link_params_get(ifp);
2306 float bw;
16f1b9ee 2307
d62a17ae 2308 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2309 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2310 safe_strerror(errno));
2311 return CMD_WARNING_CONFIG_FAILED;
2312 }
16f1b9ee 2313
d62a17ae 2314 /* Check that bandwidth is not greater than maximum bandwidth parameter
2315 */
2316 if (bw > iflp->max_bw) {
2317 vty_out(vty,
2318 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2319 iflp->max_bw);
2320 return CMD_WARNING_CONFIG_FAILED;
2321 }
16f1b9ee 2322
d62a17ae 2323 /* Update Residual Bandwidth if needed */
2324 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
16f1b9ee 2325
d62a17ae 2326 return CMD_SUCCESS;
16f1b9ee
OD
2327}
2328
2329DEFUN (no_link_params_res_bw,
2330 no_link_params_res_bw_cmd,
2331 "no res-bw",
2332 NO_STR
3ddccf18 2333 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 2334{
d62a17ae 2335 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2336
d62a17ae 2337 /* Unset Residual Bandwidth */
2338 link_param_cmd_unset(ifp, LP_RES_BW);
16f1b9ee 2339
d62a17ae 2340 return CMD_SUCCESS;
16f1b9ee
OD
2341}
2342
2343DEFUN (link_params_ava_bw,
2344 link_params_ava_bw_cmd,
2345 "ava-bw BANDWIDTH",
2346 "Unidirectional Available Bandwidth\n"
2347 "Bytes/second (IEEE floating point format)\n")
2348{
d62a17ae 2349 int idx_bandwidth = 1;
2350 VTY_DECLVAR_CONTEXT(interface, ifp);
2351 struct if_link_params *iflp = if_link_params_get(ifp);
2352 float bw;
16f1b9ee 2353
d62a17ae 2354 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2355 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2356 safe_strerror(errno));
2357 return CMD_WARNING_CONFIG_FAILED;
2358 }
16f1b9ee 2359
d62a17ae 2360 /* Check that bandwidth is not greater than maximum bandwidth parameter
2361 */
2362 if (bw > iflp->max_bw) {
2363 vty_out(vty,
2364 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2365 iflp->max_bw);
2366 return CMD_WARNING_CONFIG_FAILED;
2367 }
16f1b9ee 2368
d62a17ae 2369 /* Update Residual Bandwidth if needed */
2370 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
16f1b9ee 2371
d62a17ae 2372 return CMD_SUCCESS;
16f1b9ee
OD
2373}
2374
2375DEFUN (no_link_params_ava_bw,
2376 no_link_params_ava_bw_cmd,
2377 "no ava-bw",
2378 NO_STR
3ddccf18 2379 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 2380{
d62a17ae 2381 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2382
d62a17ae 2383 /* Unset Available Bandwidth */
2384 link_param_cmd_unset(ifp, LP_AVA_BW);
16f1b9ee 2385
d62a17ae 2386 return CMD_SUCCESS;
16f1b9ee
OD
2387}
2388
2389DEFUN (link_params_use_bw,
2390 link_params_use_bw_cmd,
2391 "use-bw BANDWIDTH",
2392 "Unidirectional Utilised Bandwidth\n"
2393 "Bytes/second (IEEE floating point format)\n")
2394{
d62a17ae 2395 int idx_bandwidth = 1;
2396 VTY_DECLVAR_CONTEXT(interface, ifp);
2397 struct if_link_params *iflp = if_link_params_get(ifp);
2398 float bw;
16f1b9ee 2399
d62a17ae 2400 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2401 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2402 safe_strerror(errno));
2403 return CMD_WARNING_CONFIG_FAILED;
2404 }
16f1b9ee 2405
d62a17ae 2406 /* Check that bandwidth is not greater than maximum bandwidth parameter
2407 */
2408 if (bw > iflp->max_bw) {
2409 vty_out(vty,
2410 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2411 iflp->max_bw);
2412 return CMD_WARNING_CONFIG_FAILED;
2413 }
16f1b9ee 2414
d62a17ae 2415 /* Update Utilized Bandwidth if needed */
2416 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
16f1b9ee 2417
d62a17ae 2418 return CMD_SUCCESS;
16f1b9ee
OD
2419}
2420
2421DEFUN (no_link_params_use_bw,
2422 no_link_params_use_bw_cmd,
2423 "no use-bw",
2424 NO_STR
3ddccf18 2425 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 2426{
d62a17ae 2427 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2428
d62a17ae 2429 /* Unset Utilised Bandwidth */
2430 link_param_cmd_unset(ifp, LP_USE_BW);
16f1b9ee 2431
d62a17ae 2432 return CMD_SUCCESS;
16f1b9ee
OD
2433}
2434
d62a17ae 2435static int ip_address_install(struct vty *vty, struct interface *ifp,
2436 const char *addr_str, const char *peer_str,
2437 const char *label)
718e3744 2438{
d62a17ae 2439 struct zebra_if *if_data;
2440 struct prefix_ipv4 cp;
2441 struct connected *ifc;
2442 struct prefix_ipv4 *p;
2443 int ret;
718e3744 2444
d62a17ae 2445 if_data = ifp->info;
bfac8dcd 2446
d62a17ae 2447 ret = str2prefix_ipv4(addr_str, &cp);
2448 if (ret <= 0) {
2449 vty_out(vty, "%% Malformed address \n");
2450 return CMD_WARNING_CONFIG_FAILED;
2451 }
718e3744 2452
d62a17ae 2453 if (ipv4_martian(&cp.prefix)) {
2454 vty_out(vty, "%% Invalid address\n");
2455 return CMD_WARNING_CONFIG_FAILED;
2456 }
d914d5ff 2457
d62a17ae 2458 ifc = connected_check(ifp, (struct prefix *)&cp);
2459 if (!ifc) {
2460 ifc = connected_new();
2461 ifc->ifp = ifp;
2462
2463 /* Address. */
2464 p = prefix_ipv4_new();
2465 *p = cp;
2466 ifc->address = (struct prefix *)p;
2467
2468 /* Broadcast. */
2469 if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
2470 p = prefix_ipv4_new();
2471 *p = cp;
2472 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
2473 p->prefixlen);
2474 ifc->destination = (struct prefix *)p;
2475 }
718e3744 2476
d62a17ae 2477 /* Label. */
2478 if (label)
2479 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
718e3744 2480
d62a17ae 2481 /* Add to linked list. */
2482 listnode_add(ifp->connected, ifc);
718e3744 2483 }
2484
d62a17ae 2485 /* This address is configured from zebra. */
2486 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2487 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2488
2489 /* In case of this route need to install kernel. */
2490 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2491 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2492 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2493 /* Some system need to up the interface to set IP address. */
2494 if (!if_is_up(ifp)) {
2495 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2496 if_refresh(ifp);
2497 }
2498
2499 ret = if_set_prefix(ifp, ifc);
2500 if (ret < 0) {
2501 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2502 safe_strerror(errno));
2503 return CMD_WARNING_CONFIG_FAILED;
2504 }
2505
2506 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2507 /* The address will be advertised to zebra clients when the
2508 * notification
2509 * from the kernel has been received.
2510 * It will also be added to the subnet chain list, then. */
2511 }
2512
2513 return CMD_SUCCESS;
2514}
2515
2516static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2517 const char *addr_str, const char *peer_str,
2518 const char *label)
2519{
2520 struct prefix_ipv4 cp;
2521 struct connected *ifc;
2522 int ret;
2523
2524 /* Convert to prefix structure. */
2525 ret = str2prefix_ipv4(addr_str, &cp);
2526 if (ret <= 0) {
2527 vty_out(vty, "%% Malformed address \n");
2528 return CMD_WARNING_CONFIG_FAILED;
2529 }
2530
2531 /* Check current interface address. */
2532 ifc = connected_check(ifp, (struct prefix *)&cp);
2533 if (!ifc) {
2534 vty_out(vty, "%% Can't find address\n");
2535 return CMD_WARNING_CONFIG_FAILED;
2536 }
2537
2538 /* This is not configured address. */
2539 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2540 return CMD_WARNING_CONFIG_FAILED;
2541
2542 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2543
2544 /* This is not real address or interface is not active. */
2545 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2546 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2547 listnode_delete(ifp->connected, ifc);
2548 connected_free(ifc);
2549 return CMD_WARNING_CONFIG_FAILED;
2550 }
2551
2552 /* This is real route. */
2553 ret = if_unset_prefix(ifp, ifc);
2554 if (ret < 0) {
2555 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2556 safe_strerror(errno));
2557 return CMD_WARNING_CONFIG_FAILED;
2558 }
2559 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2560 /* we will receive a kernel notification about this route being removed.
2561 * this will trigger its removal from the connected list. */
2562 return CMD_SUCCESS;
718e3744 2563}
2564
2565DEFUN (ip_address,
2566 ip_address_cmd,
2567 "ip address A.B.C.D/M",
2568 "Interface Internet Protocol config commands\n"
2569 "Set the IP address of an interface\n"
2570 "IP address (e.g. 10.0.0.1/8)\n")
2571{
d62a17ae 2572 int idx_ipv4_prefixlen = 2;
2573 VTY_DECLVAR_CONTEXT(interface, ifp);
2574 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2575 NULL);
718e3744 2576}
2577
2578DEFUN (no_ip_address,
2579 no_ip_address_cmd,
2580 "no ip address A.B.C.D/M",
2581 NO_STR
2582 "Interface Internet Protocol config commands\n"
2583 "Set the IP address of an interface\n"
2584 "IP Address (e.g. 10.0.0.1/8)")
2585{
d62a17ae 2586 int idx_ipv4_prefixlen = 3;
2587 VTY_DECLVAR_CONTEXT(interface, ifp);
2588 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2589 NULL, NULL);
718e3744 2590}
2591
986aa00f 2592
718e3744 2593#ifdef HAVE_NETLINK
718e3744 2594DEFUN (ip_address_label,
2595 ip_address_label_cmd,
2596 "ip address A.B.C.D/M label LINE",
2597 "Interface Internet Protocol config commands\n"
2598 "Set the IP address of an interface\n"
2599 "IP address (e.g. 10.0.0.1/8)\n"
2600 "Label of this address\n"
2601 "Label\n")
2602{
d62a17ae 2603 int idx_ipv4_prefixlen = 2;
2604 int idx_line = 4;
2605 VTY_DECLVAR_CONTEXT(interface, ifp);
2606 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2607 argv[idx_line]->arg);
718e3744 2608}
2609
2610DEFUN (no_ip_address_label,
2611 no_ip_address_label_cmd,
2612 "no ip address A.B.C.D/M label LINE",
2613 NO_STR
2614 "Interface Internet Protocol config commands\n"
2615 "Set the IP address of an interface\n"
2616 "IP address (e.g. 10.0.0.1/8)\n"
2617 "Label of this address\n"
2618 "Label\n")
2619{
d62a17ae 2620 int idx_ipv4_prefixlen = 3;
2621 int idx_line = 5;
2622 VTY_DECLVAR_CONTEXT(interface, ifp);
2623 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2624 NULL, argv[idx_line]->arg);
718e3744 2625}
2626#endif /* HAVE_NETLINK */
2627
d62a17ae 2628static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2629 const char *addr_str, const char *peer_str,
2630 const char *label, int secondary)
2631{
2632 struct zebra_if *if_data;
2633 struct prefix_ipv6 cp;
2634 struct connected *ifc;
2635 struct prefix_ipv6 *p;
2636 int ret;
2637
2638 if_data = ifp->info;
2639
2640 ret = str2prefix_ipv6(addr_str, &cp);
2641 if (ret <= 0) {
2642 vty_out(vty, "%% Malformed address \n");
2643 return CMD_WARNING_CONFIG_FAILED;
718e3744 2644 }
2645
d62a17ae 2646 if (ipv6_martian(&cp.prefix)) {
2647 vty_out(vty, "%% Invalid address\n");
2648 return CMD_WARNING_CONFIG_FAILED;
2649 }
718e3744 2650
d62a17ae 2651 ifc = connected_check(ifp, (struct prefix *)&cp);
2652 if (!ifc) {
2653 ifc = connected_new();
2654 ifc->ifp = ifp;
2655
2656 /* Address. */
2657 p = prefix_ipv6_new();
2658 *p = cp;
2659 ifc->address = (struct prefix *)p;
2660
2661 /* Secondary. */
2662 if (secondary)
2663 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
2664
2665 /* Label. */
2666 if (label)
2667 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2668
2669 /* Add to linked list. */
2670 listnode_add(ifp->connected, ifc);
718e3744 2671 }
2672
d62a17ae 2673 /* This address is configured from zebra. */
2674 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2675 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2676
2677 /* In case of this route need to install kernel. */
2678 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2679 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2680 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2681 /* Some system need to up the interface to set IP address. */
2682 if (!if_is_up(ifp)) {
2683 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2684 if_refresh(ifp);
2685 }
2686
2687 ret = if_prefix_add_ipv6(ifp, ifc);
2688
2689 if (ret < 0) {
2690 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2691 safe_strerror(errno));
2692 return CMD_WARNING_CONFIG_FAILED;
2693 }
2694
2695 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2696 /* The address will be advertised to zebra clients when the
2697 * notification
2698 * from the kernel has been received. */
2699 }
718e3744 2700
d62a17ae 2701 return CMD_SUCCESS;
718e3744 2702}
2703
b6120505 2704/* Return true if an ipv6 address is configured on ifp */
d62a17ae 2705int ipv6_address_configured(struct interface *ifp)
2706{
2707 struct connected *connected;
2708 struct listnode *node;
2709
2710 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2711 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2712 && (connected->address->family == AF_INET6))
2713 return 1;
2714
2715 return 0;
2716}
2717
2718static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2719 const char *addr_str, const char *peer_str,
2720 const char *label, int secondry)
2721{
2722 struct prefix_ipv6 cp;
2723 struct connected *ifc;
2724 int ret;
2725
2726 /* Convert to prefix structure. */
2727 ret = str2prefix_ipv6(addr_str, &cp);
2728 if (ret <= 0) {
2729 vty_out(vty, "%% Malformed address \n");
2730 return CMD_WARNING_CONFIG_FAILED;
2731 }
2732
2733 /* Check current interface address. */
2734 ifc = connected_check(ifp, (struct prefix *)&cp);
2735 if (!ifc) {
2736 vty_out(vty, "%% Can't find address\n");
2737 return CMD_WARNING_CONFIG_FAILED;
2738 }
2739
2740 /* This is not configured address. */
2741 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2742 return CMD_WARNING_CONFIG_FAILED;
2743
2744 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2745
2746 /* This is not real address or interface is not active. */
2747 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2748 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2749 listnode_delete(ifp->connected, ifc);
2750 connected_free(ifc);
2751 return CMD_WARNING_CONFIG_FAILED;
2752 }
2753
2754 /* This is real route. */
2755 ret = if_prefix_delete_ipv6(ifp, ifc);
2756 if (ret < 0) {
2757 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2758 safe_strerror(errno));
2759 return CMD_WARNING_CONFIG_FAILED;
2760 }
2761
2762 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2763 /* This information will be propagated to the zclients when the
2764 * kernel notification is received. */
2765 return CMD_SUCCESS;
718e3744 2766}
2767
2768DEFUN (ipv6_address,
2769 ipv6_address_cmd,
2770 "ipv6 address X:X::X:X/M",
e23949c0 2771 "Interface IPv6 config commands\n"
718e3744 2772 "Set the IP address of an interface\n"
2773 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2774{
d62a17ae 2775 int idx_ipv6_prefixlen = 2;
2776 VTY_DECLVAR_CONTEXT(interface, ifp);
2777 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2778 NULL, NULL, 0);
718e3744 2779}
2780
2781DEFUN (no_ipv6_address,
2782 no_ipv6_address_cmd,
2783 "no ipv6 address X:X::X:X/M",
2784 NO_STR
e23949c0 2785 "Interface IPv6 config commands\n"
718e3744 2786 "Set the IP address of an interface\n"
2787 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2788{
d62a17ae 2789 int idx_ipv6_prefixlen = 3;
2790 VTY_DECLVAR_CONTEXT(interface, ifp);
2791 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2792 NULL, NULL, 0);
2793}
2794
2795static int link_params_config_write(struct vty *vty, struct interface *ifp)
2796{
2797 int i;
2798
2799 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2800 return -1;
986aa00f 2801
d62a17ae 2802 struct if_link_params *iflp = ifp->link_params;
2803
2804 vty_out(vty, " link-params\n");
2805 vty_out(vty, " enable\n");
2806 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
2807 vty_out(vty, " metric %u\n", iflp->te_metric);
2808 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
2809 vty_out(vty, " max-bw %g\n", iflp->max_bw);
2810 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
2811 && iflp->max_rsv_bw != iflp->default_bw)
2812 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
2813 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2814 for (i = 0; i < 8; i++)
2815 if (iflp->unrsv_bw[i] != iflp->default_bw)
2816 vty_out(vty, " unrsv-bw %d %g\n", i,
2817 iflp->unrsv_bw[i]);
2818 }
2819 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2820 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
2821 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2822 vty_out(vty, " delay %u", iflp->av_delay);
2823 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2824 vty_out(vty, " min %u", iflp->min_delay);
2825 vty_out(vty, " max %u", iflp->max_delay);
2826 }
2827 vty_out(vty, "\n");
bfac8dcd 2828 }
d62a17ae 2829 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2830 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
2831 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2832 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
2833 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2834 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
2835 if (IS_PARAM_SET(iflp, LP_RES_BW))
2836 vty_out(vty, " res-bw %g\n", iflp->res_bw);
2837 if (IS_PARAM_SET(iflp, LP_USE_BW))
2838 vty_out(vty, " use-bw %g\n", iflp->use_bw);
2839 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2840 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
2841 iflp->rmt_as);
2842 vty_out(vty, " exit-link-params\n");
2843 return 0;
2844}
2845
2846static int if_config_write(struct vty *vty)
2847{
2848 struct vrf *vrf;
2849 struct listnode *node;
2850 struct interface *ifp;
2851
2852 zebra_ptm_write(vty);
2853
2854 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
2855 for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) {
2856 struct zebra_if *if_data;
2857 struct listnode *addrnode;
2858 struct connected *ifc;
2859 struct prefix *p;
2860 struct vrf *vrf;
2861
2862 if_data = ifp->info;
2863 vrf = vrf_lookup_by_id(ifp->vrf_id);
2864
2865 if (ifp->vrf_id == VRF_DEFAULT)
2866 vty_out(vty, "interface %s\n", ifp->name);
2867 else
2868 vty_out(vty, "interface %s vrf %s\n", ifp->name,
2869 vrf->name);
2870
2871 if (if_data) {
2872 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2873 vty_out(vty, " shutdown\n");
2874
2875 zebra_ptm_if_write(vty, if_data);
2876 }
bfac8dcd 2877
d62a17ae 2878 if (ifp->desc)
2879 vty_out(vty, " description %s\n", ifp->desc);
718e3744 2880
d62a17ae 2881 /* Assign bandwidth here to avoid unnecessary interface flap
2882 while processing config script */
2883 if (ifp->bandwidth != 0)
2884 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
718e3744 2885
d62a17ae 2886 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
2887 vty_out(vty, " no link-detect\n");
2e3b2e47 2888
d62a17ae 2889 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode, ifc)) {
2890 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
2891 char buf[INET6_ADDRSTRLEN];
2892 p = ifc->address;
2893 vty_out(vty, " ip%s address %s",
2894 p->family == AF_INET ? "" : "v6",
2895 prefix2str(p, buf, sizeof(buf)));
718e3744 2896
d62a17ae 2897 if (ifc->label)
2898 vty_out(vty, " label %s", ifc->label);
718e3744 2899
d62a17ae 2900 vty_out(vty, "\n");
2901 }
2902 }
718e3744 2903
d62a17ae 2904 if (if_data) {
2905 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2906 vty_out(vty, " %smulticast\n",
2907 if_data->multicast
2908 == IF_ZEBRA_MULTICAST_ON
2909 ? ""
2910 : "no ");
2911 }
718e3744 2912
d62a17ae 2913#if defined(HAVE_RTADV)
2914 rtadv_config_write(vty, ifp);
8da4e946 2915#endif /* HAVE_RTADV */
718e3744 2916
ca776988 2917#ifdef HAVE_IRDP
d62a17ae 2918 irdp_config_write(vty, ifp);
ca776988 2919#endif /* IRDP */
2920
d62a17ae 2921 link_params_config_write(vty, ifp);
16f1b9ee 2922
d62a17ae 2923 vty_out(vty, "!\n");
2924 }
2925 return 0;
718e3744 2926}
2927
2928/* Allocate and initialize interface vector. */
d62a17ae 2929void zebra_if_init(void)
2930{
2931 /* Initialize interface and new hook. */
2932 if_add_hook(IF_NEW_HOOK, if_zebra_new_hook);
2933 if_add_hook(IF_DELETE_HOOK, if_zebra_delete_hook);
2934
2935 /* Install configuration write function. */
2936 install_node(&interface_node, if_config_write);
2937 install_node(&link_params_node, NULL);
2938 if_cmd_init();
2939
2940 install_element(VIEW_NODE, &show_interface_cmd);
2941 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
2942 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
2943 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
2944
2945 install_element(ENABLE_NODE, &show_interface_desc_cmd);
2946 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
2947 install_element(INTERFACE_NODE, &multicast_cmd);
2948 install_element(INTERFACE_NODE, &no_multicast_cmd);
2949 install_element(INTERFACE_NODE, &linkdetect_cmd);
2950 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
2951 install_element(INTERFACE_NODE, &shutdown_if_cmd);
2952 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
2953 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
2954 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
2955 install_element(INTERFACE_NODE, &ip_address_cmd);
2956 install_element(INTERFACE_NODE, &no_ip_address_cmd);
2957 install_element(INTERFACE_NODE, &ipv6_address_cmd);
2958 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 2959#ifdef HAVE_NETLINK
d62a17ae 2960 install_element(INTERFACE_NODE, &ip_address_label_cmd);
2961 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
718e3744 2962#endif /* HAVE_NETLINK */
d62a17ae 2963 install_element(INTERFACE_NODE, &link_params_cmd);
2964 install_default(LINK_PARAMS_NODE);
2965 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2966 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2967 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
2968 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
2969 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2970 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2971 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2972 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
2973 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
2974 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2975 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2976 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
2977 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
2978 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
2979 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
2980 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
2981 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
2982 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
2983 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
2984 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
2985 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
2986 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
2987 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
2988 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
718e3744 2989}