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