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