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