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