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