]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
ospfd: Convert ospf_sr.c to use error-card subsystem.
[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
680c278f
PG
1005void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1006 ns_id_t ns_id)
6675513d 1007{
d62a17ae 1008 struct zebra_if *zif;
6675513d 1009
0e4864ea
PG
1010 if (IS_ZEBRA_IF_VETH(ifp))
1011 return;
d62a17ae 1012 zif = (struct zebra_if *)ifp->info;
1013 zif->link_ifindex = link_ifindex;
680c278f 1014 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
d62a17ae 1015 link_ifindex);
6675513d 1016}
1017
d5a5c8f0 1018
718e3744 1019/* Output prefix string to vty. */
d62a17ae 1020static int prefix_vty_out(struct vty *vty, struct prefix *p)
718e3744 1021{
d62a17ae 1022 char str[INET6_ADDRSTRLEN];
718e3744 1023
d62a17ae 1024 inet_ntop(p->family, &p->u.prefix, str, sizeof(str));
1025 vty_out(vty, "%s", str);
1026 return strlen(str);
718e3744 1027}
1028
1029/* Dump if address information to vty. */
d62a17ae 1030static void connected_dump_vty(struct vty *vty, struct connected *connected)
718e3744 1031{
d62a17ae 1032 struct prefix *p;
718e3744 1033
d62a17ae 1034 /* Print interface address. */
1035 p = connected->address;
1036 vty_out(vty, " %s ", prefix_family_str(p));
1037 prefix_vty_out(vty, p);
1038 vty_out(vty, "/%d", p->prefixlen);
718e3744 1039
d62a17ae 1040 /* If there is destination address, print it. */
1041 if (connected->destination) {
1042 vty_out(vty,
1043 (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
1044 prefix_vty_out(vty, connected->destination);
abffde07
DL
1045 if (CONNECTED_PEER(connected))
1046 vty_out(vty, "/%d", connected->destination->prefixlen);
d62a17ae 1047 }
718e3744 1048
d62a17ae 1049 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
1050 vty_out(vty, " secondary");
718e3744 1051
d62a17ae 1052 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
1053 vty_out(vty, " unnumbered");
525c1839 1054
d62a17ae 1055 if (connected->label)
1056 vty_out(vty, " %s", connected->label);
718e3744 1057
d62a17ae 1058 vty_out(vty, "\n");
718e3744 1059}
1060
a80beece 1061/* Dump interface neighbor address information to vty. */
d62a17ae 1062static void nbr_connected_dump_vty(struct vty *vty,
1063 struct nbr_connected *connected)
a80beece 1064{
d62a17ae 1065 struct prefix *p;
a80beece 1066
d62a17ae 1067 /* Print interface address. */
1068 p = connected->address;
1069 vty_out(vty, " %s ", prefix_family_str(p));
1070 prefix_vty_out(vty, p);
1071 vty_out(vty, "/%d", p->prefixlen);
a80beece 1072
d62a17ae 1073 vty_out(vty, "\n");
a80beece
DS
1074}
1075
d62a17ae 1076static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
6675513d 1077{
d62a17ae 1078 switch (zif_type) {
1079 case ZEBRA_IF_OTHER:
1080 return "Other";
1081 break;
6675513d 1082
d62a17ae 1083 case ZEBRA_IF_BRIDGE:
1084 return "Bridge";
1085 break;
6675513d 1086
d62a17ae 1087 case ZEBRA_IF_VLAN:
1088 return "Vlan";
1089 break;
6675513d 1090
d62a17ae 1091 case ZEBRA_IF_VXLAN:
1092 return "Vxlan";
1093 break;
6675513d 1094
d62a17ae 1095 case ZEBRA_IF_VRF:
1096 return "VRF";
1097 break;
6675513d 1098
0e4864ea
PG
1099 case ZEBRA_IF_VETH:
1100 return "VETH";
1101 break;
1102
d62a17ae 1103 default:
1104 return "Unknown";
1105 break;
1106 }
6675513d 1107}
1108
718e3744 1109/* Interface's information print out to vty interface. */
d62a17ae 1110static void if_dump_vty(struct vty *vty, struct interface *ifp)
1111{
1112 struct connected *connected;
1113 struct nbr_connected *nbr_connected;
1114 struct listnode *node;
1115 struct route_node *rn;
1116 struct zebra_if *zebra_if;
1117 struct vrf *vrf;
1118
1119 zebra_if = ifp->info;
1120
1121 vty_out(vty, "Interface %s is ", ifp->name);
1122 if (if_is_up(ifp)) {
1123 vty_out(vty, "up, line protocol ");
1124
1125 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1126 if (if_is_running(ifp))
1127 vty_out(vty, "is up\n");
1128 else
1129 vty_out(vty, "is down\n");
1130 } else {
1131 vty_out(vty, "detection is disabled\n");
1132 }
1133 } else {
1134 vty_out(vty, "down\n");
1135 }
1136
1137 vty_out(vty, " Link ups: %5u last: %s\n", zebra_if->up_count,
1138 zebra_if->up_last[0] ? zebra_if->up_last : "(never)");
1139 vty_out(vty, " Link downs: %5u last: %s\n", zebra_if->down_count,
1140 zebra_if->down_last[0] ? zebra_if->down_last : "(never)");
1141
1142 zebra_ptm_show_status(vty, ifp);
1143
1144 vrf = vrf_lookup_by_id(ifp->vrf_id);
1145 vty_out(vty, " vrf: %s\n", vrf->name);
1146
1147 if (ifp->desc)
1148 vty_out(vty, " Description: %s\n", ifp->desc);
1149 if (ifp->ifindex == IFINDEX_INTERNAL) {
1150 vty_out(vty, " pseudo interface\n");
1151 return;
1152 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1153 vty_out(vty, " index %d inactive interface\n", ifp->ifindex);
1154 return;
1155 }
1156
1157 vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
1158 ifp->metric, ifp->mtu, ifp->speed);
1159 if (ifp->mtu6 != ifp->mtu)
1160 vty_out(vty, "mtu6 %d ", ifp->mtu6);
1161 vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
1162
1163 /* Hardware address. */
1164 vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
1165 if (ifp->hw_addr_len != 0) {
1166 int i;
1167
1168 vty_out(vty, " HWaddr: ");
1169 for (i = 0; i < ifp->hw_addr_len; i++)
1170 vty_out(vty, "%s%02x", i == 0 ? "" : ":",
1171 ifp->hw_addr[i]);
1172 vty_out(vty, "\n");
1173 }
1174
1175 /* Bandwidth in Mbps */
1176 if (ifp->bandwidth != 0) {
1177 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1178 vty_out(vty, "\n");
1179 }
1180
1181 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
1182 if (!rn->info)
1183 continue;
1184
1185 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1186 connected))
1187 connected_dump_vty(vty, connected);
1188 }
1189
1190 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1191 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1192 && (connected->address->family == AF_INET6))
1193 connected_dump_vty(vty, connected);
1194 }
1195
1196 vty_out(vty, " Interface Type %s\n",
1197 zebra_ziftype_2str(zebra_if->zif_type));
1198 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1199 struct zebra_l2info_bridge *bridge_info;
1200
1201 bridge_info = &zebra_if->l2info.br;
1202 vty_out(vty, " Bridge VLAN-aware: %s\n",
1203 bridge_info->vlan_aware ? "yes" : "no");
1204 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1205 struct zebra_l2info_vlan *vlan_info;
1206
1207 vlan_info = &zebra_if->l2info.vl;
1208 vty_out(vty, " VLAN Id %u\n", vlan_info->vid);
1209 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
1210 struct zebra_l2info_vxlan *vxlan_info;
1211
1212 vxlan_info = &zebra_if->l2info.vxl;
1213 vty_out(vty, " VxLAN Id %u", vxlan_info->vni);
1214 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
1215 vty_out(vty, " VTEP IP: %s",
1216 inet_ntoa(vxlan_info->vtep_ip));
1217 if (vxlan_info->access_vlan)
1218 vty_out(vty, " Access VLAN Id %u",
1219 vxlan_info->access_vlan);
1220 vty_out(vty, "\n");
1221 }
1222
1223 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
1224 struct zebra_l2info_brslave *br_slave;
1225
1226 br_slave = &zebra_if->brslave_info;
1227 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL)
1228 vty_out(vty, " Master (bridge) ifindex %u\n",
1229 br_slave->bridge_ifindex);
1230 }
1231
8cb73ba4
DS
1232 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
1233 vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
1234 if (zebra_if->link)
1235 vty_out(vty, "(%s)\n", zebra_if->link->name);
1236 else
1237 vty_out(vty, "(Unknown)\n");
1238 }
d62a17ae 1239
1240 if (HAS_LINK_PARAMS(ifp)) {
1241 int i;
1242 struct if_link_params *iflp = ifp->link_params;
1243 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1244 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1245 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1246 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1247 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1248 iflp->max_bw);
1249 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1250 vty_out(vty,
1251 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1252 iflp->max_rsv_bw);
1253 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1254 vty_out(vty,
1255 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1256 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1257 vty_out(vty,
1258 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1259 i, iflp->unrsv_bw[i], i + 1,
1260 iflp->unrsv_bw[i + 1]);
1261 }
1262
1263 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1264 vty_out(vty, " Administrative Group:%u\n",
1265 iflp->admin_grp);
1266 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1267 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1268 iflp->av_delay);
1269 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1270 vty_out(vty, " Min: %u (micro-sec.)",
1271 iflp->min_delay);
1272 vty_out(vty, " Max: %u (micro-sec.)",
1273 iflp->max_delay);
1274 }
1275 vty_out(vty, "\n");
1276 }
1277 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1278 vty_out(vty,
1279 " Link Delay Variation %u (micro-sec.)\n",
1280 iflp->delay_var);
1281 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1282 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1283 iflp->pkt_loss);
1284 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1285 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1286 iflp->ava_bw);
1287 if (IS_PARAM_SET(iflp, LP_RES_BW))
1288 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1289 iflp->res_bw);
1290 if (IS_PARAM_SET(iflp, LP_USE_BW))
1291 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1292 iflp->use_bw);
1293 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1294 vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n",
1295 inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
1296 }
1297
2eb27eec
DL
1298 hook_call(zebra_if_extra_info, vty, ifp);
1299
d62a17ae 1300 if (listhead(ifp->nbr_connected))
1301 vty_out(vty, " Neighbor address(s):\n");
1302 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
1303 nbr_connected_dump_vty(vty, nbr_connected);
718e3744 1304
1305#ifdef HAVE_PROC_NET_DEV
d62a17ae 1306 /* Statistics print out using proc file system. */
1307 vty_out(vty,
1308 " %lu input packets (%lu multicast), %lu bytes, "
1309 "%lu dropped\n",
1310 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1311 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1312
1313 vty_out(vty,
1314 " %lu input errors, %lu length, %lu overrun,"
1315 " %lu CRC, %lu frame\n",
1316 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1317 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1318 ifp->stats.rx_frame_errors);
1319
1320 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1321 ifp->stats.rx_missed_errors);
1322
1323 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1324 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1325 ifp->stats.tx_dropped);
1326
1327 vty_out(vty,
1328 " %lu output errors, %lu aborted, %lu carrier,"
1329 " %lu fifo, %lu heartbeat\n",
1330 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1331 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1332 ifp->stats.tx_heartbeat_errors);
1333
1334 vty_out(vty, " %lu window, %lu collisions\n",
1335 ifp->stats.tx_window_errors, ifp->stats.collisions);
718e3744 1336#endif /* HAVE_PROC_NET_DEV */
1337
1338#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1339#if defined(__bsdi__) || defined(__NetBSD__)
1340 /* Statistics print out using sysctl (). */
1341 vty_out(vty,
1342 " input packets %llu, bytes %llu, dropped %llu,"
1343 " multicast packets %llu\n",
1344 (unsigned long long)ifp->stats.ifi_ipackets,
1345 (unsigned long long)ifp->stats.ifi_ibytes,
1346 (unsigned long long)ifp->stats.ifi_iqdrops,
1347 (unsigned long long)ifp->stats.ifi_imcasts);
1348
1349 vty_out(vty, " input errors %llu\n",
1350 (unsigned long long)ifp->stats.ifi_ierrors);
1351
1352 vty_out(vty,
1353 " output packets %llu, bytes %llu,"
1354 " multicast packets %llu\n",
1355 (unsigned long long)ifp->stats.ifi_opackets,
1356 (unsigned long long)ifp->stats.ifi_obytes,
1357 (unsigned long long)ifp->stats.ifi_omcasts);
1358
1359 vty_out(vty, " output errors %llu\n",
1360 (unsigned long long)ifp->stats.ifi_oerrors);
1361
1362 vty_out(vty, " collisions %llu\n",
1363 (unsigned long long)ifp->stats.ifi_collisions);
718e3744 1364#else
d62a17ae 1365 /* Statistics print out using sysctl (). */
1366 vty_out(vty,
1367 " input packets %lu, bytes %lu, dropped %lu,"
1368 " multicast packets %lu\n",
1369 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1370 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts);
718e3744 1371
d62a17ae 1372 vty_out(vty, " input errors %lu\n", ifp->stats.ifi_ierrors);
718e3744 1373
d62a17ae 1374 vty_out(vty,
1375 " output packets %lu, bytes %lu, multicast packets %lu\n",
1376 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1377 ifp->stats.ifi_omcasts);
718e3744 1378
d62a17ae 1379 vty_out(vty, " output errors %lu\n", ifp->stats.ifi_oerrors);
718e3744 1380
d62a17ae 1381 vty_out(vty, " collisions %lu\n", ifp->stats.ifi_collisions);
718e3744 1382#endif /* __bsdi__ || __NetBSD__ */
1383#endif /* HAVE_NET_RT_IFLIST */
1384}
1385
d62a17ae 1386static void interface_update_stats(void)
78860b9f
DS
1387{
1388#ifdef HAVE_PROC_NET_DEV
d62a17ae 1389 /* If system has interface statistics via proc file system, update
1390 statistics. */
1391 ifstat_update_proc();
78860b9f
DS
1392#endif /* HAVE_PROC_NET_DEV */
1393#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1394 ifstat_update_sysctl();
78860b9f
DS
1395#endif /* HAVE_NET_RT_IFLIST */
1396}
1397
d62a17ae 1398struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
718e3744 1399
8b87bdf4 1400/* Show all interfaces to vty. */
8b3f0677
DW
1401DEFUN (show_interface,
1402 show_interface_cmd,
b62ecea5 1403 "show interface [vrf NAME]",
8b87bdf4 1404 SHOW_STR
b62ecea5
QY
1405 "Interface status and configuration\n"
1406 VRF_CMD_HELP_STR)
8b87bdf4 1407{
f4e14fdb 1408 struct vrf *vrf;
d62a17ae 1409 struct interface *ifp;
1410 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1411
d62a17ae 1412 interface_update_stats();
8b87bdf4 1413
d62a17ae 1414 if (argc > 2)
ec1db588 1415 VRF_GET_ID(vrf_id, argv[3]->arg, false);
8b87bdf4 1416
d62a17ae 1417 /* All interface print. */
f4e14fdb 1418 vrf = vrf_lookup_by_id(vrf_id);
451fda4f 1419 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1420 if_dump_vty(vty, ifp);
8b87bdf4 1421
d62a17ae 1422 return CMD_SUCCESS;
8b87bdf4
FL
1423}
1424
8b87bdf4
FL
1425
1426/* Show all interfaces to vty. */
8b3f0677
DW
1427DEFUN (show_interface_vrf_all,
1428 show_interface_vrf_all_cmd,
9ccf14f7 1429 "show interface vrf all",
8b87bdf4
FL
1430 SHOW_STR
1431 "Interface status and configuration\n"
1432 VRF_ALL_CMD_HELP_STR)
718e3744 1433{
d62a17ae 1434 struct vrf *vrf;
d62a17ae 1435 struct interface *ifp;
8b87bdf4 1436
d62a17ae 1437 interface_update_stats();
718e3744 1438
d62a17ae 1439 /* All interface print. */
a2addae8 1440 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
451fda4f 1441 FOR_ALL_INTERFACES (vrf, ifp)
a2addae8 1442 if_dump_vty(vty, ifp);
8b87bdf4 1443
d62a17ae 1444 return CMD_SUCCESS;
8b87bdf4
FL
1445}
1446
1447/* Show specified interface to vty. */
1721646e
DS
1448
1449DEFUN (show_interface_name_vrf,
1450 show_interface_name_vrf_cmd,
9ccf14f7 1451 "show interface IFNAME vrf NAME",
8b87bdf4
FL
1452 SHOW_STR
1453 "Interface status and configuration\n"
1721646e
DS
1454 "Interface name\n"
1455 VRF_CMD_HELP_STR)
8b87bdf4 1456{
d62a17ae 1457 int idx_ifname = 2;
1458 int idx_name = 4;
1459 struct interface *ifp;
0439cb9d 1460 vrf_id_t vrf_id;
8b87bdf4 1461
d62a17ae 1462 interface_update_stats();
8b87bdf4 1463
ec1db588 1464 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
8b87bdf4 1465
d62a17ae 1466 /* Specified interface print. */
1467 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1468 if (ifp == NULL) {
1469 vty_out(vty, "%% Can't find interface %s\n",
1470 argv[idx_ifname]->arg);
1471 return CMD_WARNING;
1472 }
1473 if_dump_vty(vty, ifp);
718e3744 1474
d62a17ae 1475 return CMD_SUCCESS;
718e3744 1476}
1477
8b87bdf4 1478/* Show specified interface to vty. */
8b3f0677
DW
1479DEFUN (show_interface_name_vrf_all,
1480 show_interface_name_vrf_all_cmd,
b62ecea5 1481 "show interface IFNAME [vrf all]",
8b87bdf4
FL
1482 SHOW_STR
1483 "Interface status and configuration\n"
1721646e 1484 "Interface name\n"
8b87bdf4
FL
1485 VRF_ALL_CMD_HELP_STR)
1486{
d62a17ae 1487 int idx_ifname = 2;
1488 struct vrf *vrf;
1489 struct interface *ifp;
1490 int found = 0;
8b87bdf4 1491
d62a17ae 1492 interface_update_stats();
8b87bdf4 1493
d62a17ae 1494 /* All interface print. */
a2addae8 1495 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1496 /* Specified interface print. */
1497 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id);
1498 if (ifp) {
1499 if_dump_vty(vty, ifp);
1500 found++;
1501 }
1502 }
8b87bdf4 1503
d62a17ae 1504 if (!found) {
1505 vty_out(vty, "%% Can't find interface %s\n",
1506 argv[idx_ifname]->arg);
1507 return CMD_WARNING;
1508 }
8b87bdf4 1509
d62a17ae 1510 return CMD_SUCCESS;
8b87bdf4
FL
1511}
1512
1721646e 1513
d62a17ae 1514static void if_show_description(struct vty *vty, vrf_id_t vrf_id)
ed9bb6d5 1515{
f4e14fdb 1516 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
d62a17ae 1517 struct interface *ifp;
ed9bb6d5 1518
d62a17ae 1519 vty_out(vty, "Interface Status Protocol Description\n");
451fda4f 1520 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1521 int len;
ed9bb6d5 1522
d62a17ae 1523 len = vty_out(vty, "%s", ifp->name);
1524 vty_out(vty, "%*s", (16 - len), " ");
1525
1526 if (if_is_up(ifp)) {
1527 vty_out(vty, "up ");
1528 if (CHECK_FLAG(ifp->status,
1529 ZEBRA_INTERFACE_LINKDETECTION)) {
1530 if (if_is_running(ifp))
1531 vty_out(vty, "up ");
1532 else
1533 vty_out(vty, "down ");
1534 } else {
1535 vty_out(vty, "unknown ");
1536 }
1537 } else {
1538 vty_out(vty, "down down ");
1539 }
ed9bb6d5 1540
d62a17ae 1541 if (ifp->desc)
1542 vty_out(vty, "%s", ifp->desc);
1543 vty_out(vty, "\n");
1544 }
8b87bdf4
FL
1545}
1546
1547DEFUN (show_interface_desc,
1548 show_interface_desc_cmd,
b62ecea5 1549 "show interface description [vrf NAME]",
8b87bdf4
FL
1550 SHOW_STR
1551 "Interface status and configuration\n"
b62ecea5
QY
1552 "Interface description\n"
1553 VRF_CMD_HELP_STR)
8b87bdf4 1554{
d62a17ae 1555 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1556
d62a17ae 1557 if (argc > 3)
ec1db588 1558 VRF_GET_ID(vrf_id, argv[4]->arg, false);
8b87bdf4 1559
d62a17ae 1560 if_show_description(vty, vrf_id);
8b87bdf4 1561
d62a17ae 1562 return CMD_SUCCESS;
8b87bdf4
FL
1563}
1564
8b87bdf4
FL
1565
1566DEFUN (show_interface_desc_vrf_all,
1567 show_interface_desc_vrf_all_cmd,
9ccf14f7 1568 "show interface description vrf all",
8b87bdf4
FL
1569 SHOW_STR
1570 "Interface status and configuration\n"
1571 "Interface description\n"
1572 VRF_ALL_CMD_HELP_STR)
1573{
d62a17ae 1574 struct vrf *vrf;
8b87bdf4 1575
a2addae8 1576 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
996c9314 1577 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
a2addae8
RW
1578 vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
1579 if_show_description(vty, vrf->vrf_id);
1580 }
8b87bdf4 1581
d62a17ae 1582 return CMD_SUCCESS;
ed9bb6d5 1583}
1584
718e3744 1585DEFUN (multicast,
1586 multicast_cmd,
1587 "multicast",
1588 "Set multicast flag to interface\n")
1589{
d62a17ae 1590 VTY_DECLVAR_CONTEXT(interface, ifp);
1591 int ret;
1592 struct zebra_if *if_data;
718e3744 1593
d62a17ae 1594 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1595 ret = if_set_flags(ifp, IFF_MULTICAST);
1596 if (ret < 0) {
1597 vty_out(vty, "Can't set multicast flag\n");
1598 return CMD_WARNING_CONFIG_FAILED;
1599 }
1600 if_refresh(ifp);
48b33aaf 1601 }
d62a17ae 1602 if_data = ifp->info;
1603 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1604
d62a17ae 1605 return CMD_SUCCESS;
718e3744 1606}
1607
1608DEFUN (no_multicast,
1609 no_multicast_cmd,
1610 "no multicast",
1611 NO_STR
1612 "Unset multicast flag to interface\n")
1613{
d62a17ae 1614 VTY_DECLVAR_CONTEXT(interface, ifp);
1615 int ret;
1616 struct zebra_if *if_data;
718e3744 1617
d62a17ae 1618 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1619 ret = if_unset_flags(ifp, IFF_MULTICAST);
1620 if (ret < 0) {
1621 vty_out(vty, "Can't unset multicast flag\n");
1622 return CMD_WARNING_CONFIG_FAILED;
1623 }
1624 if_refresh(ifp);
48b33aaf 1625 }
d62a17ae 1626 if_data = ifp->info;
1627 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
718e3744 1628
d62a17ae 1629 return CMD_SUCCESS;
718e3744 1630}
1631
2e3b2e47 1632DEFUN (linkdetect,
1633 linkdetect_cmd,
1634 "link-detect",
1635 "Enable link detection on interface\n")
1636{
d62a17ae 1637 VTY_DECLVAR_CONTEXT(interface, ifp);
1638 int if_was_operative;
2e3b2e47 1639
d62a17ae 1640 if_was_operative = if_is_no_ptm_operative(ifp);
1641 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1642
d62a17ae 1643 /* When linkdetection is enabled, if might come down */
1644 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
1645 if_down(ifp);
2e3b2e47 1646
d62a17ae 1647 /* FIXME: Will defer status change forwarding if interface
1648 does not come down! */
1649
1650 return CMD_SUCCESS;
2e3b2e47 1651}
1652
1653
1654DEFUN (no_linkdetect,
1655 no_linkdetect_cmd,
1656 "no link-detect",
1657 NO_STR
1658 "Disable link detection on interface\n")
1659{
d62a17ae 1660 VTY_DECLVAR_CONTEXT(interface, ifp);
1661 int if_was_operative;
1662
1663 if_was_operative = if_is_no_ptm_operative(ifp);
1664 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1665
d62a17ae 1666 /* Interface may come up after disabling link detection */
1667 if (if_is_operative(ifp) && !if_was_operative)
1668 if_up(ifp);
2e3b2e47 1669
d62a17ae 1670 /* FIXME: see linkdetect_cmd */
2e3b2e47 1671
d62a17ae 1672 return CMD_SUCCESS;
2e3b2e47 1673}
1674
718e3744 1675DEFUN (shutdown_if,
1676 shutdown_if_cmd,
1677 "shutdown",
1678 "Shutdown the selected interface\n")
1679{
d62a17ae 1680 VTY_DECLVAR_CONTEXT(interface, ifp);
1681 int ret;
1682 struct zebra_if *if_data;
718e3744 1683
d62a17ae 1684 if (ifp->ifindex != IFINDEX_INTERNAL) {
1685 ret = if_unset_flags(ifp, IFF_UP);
1686 if (ret < 0) {
1687 vty_out(vty, "Can't shutdown interface\n");
1688 return CMD_WARNING_CONFIG_FAILED;
1689 }
1690 if_refresh(ifp);
1691 }
1692 if_data = ifp->info;
1693 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
718e3744 1694
d62a17ae 1695 return CMD_SUCCESS;
718e3744 1696}
1697
1698DEFUN (no_shutdown_if,
1699 no_shutdown_if_cmd,
1700 "no shutdown",
1701 NO_STR
1702 "Shutdown the selected interface\n")
1703{
d62a17ae 1704 VTY_DECLVAR_CONTEXT(interface, ifp);
1705 int ret;
1706 struct zebra_if *if_data;
718e3744 1707
d62a17ae 1708 if (ifp->ifindex != IFINDEX_INTERNAL) {
1709 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
1710 if (ret < 0) {
1711 vty_out(vty, "Can't up interface\n");
1712 return CMD_WARNING_CONFIG_FAILED;
1713 }
1714 if_refresh(ifp);
bfac8dcd 1715
d62a17ae 1716 /* Some addresses (in particular, IPv6 addresses on Linux) get
1717 * removed when the interface goes down. They need to be
1718 * readded.
1719 */
1720 if_addr_wakeup(ifp);
1721 }
bfac8dcd 1722
d62a17ae 1723 if_data = ifp->info;
1724 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
718e3744 1725
d62a17ae 1726 return CMD_SUCCESS;
718e3744 1727}
1728
1729DEFUN (bandwidth_if,
1730 bandwidth_if_cmd,
6147e2c6 1731 "bandwidth (1-100000)",
718e3744 1732 "Set bandwidth informational parameter\n"
70bd3c43 1733 "Bandwidth in megabits\n")
718e3744 1734{
d62a17ae 1735 int idx_number = 1;
1736 VTY_DECLVAR_CONTEXT(interface, ifp);
1737 unsigned int bandwidth;
1738
1739 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1740
1741 /* bandwidth range is <1-100000> */
1742 if (bandwidth < 1 || bandwidth > 100000) {
1743 vty_out(vty, "Bandwidth is invalid\n");
1744 return CMD_WARNING_CONFIG_FAILED;
1745 }
1746
1747 ifp->bandwidth = bandwidth;
718e3744 1748
d62a17ae 1749 /* force protocols to recalculate routes due to cost change */
1750 if (if_is_operative(ifp))
1751 zebra_interface_up_update(ifp);
718e3744 1752
d62a17ae 1753 return CMD_SUCCESS;
718e3744 1754}
1755
1756DEFUN (no_bandwidth_if,
1757 no_bandwidth_if_cmd,
b62ecea5 1758 "no bandwidth [(1-100000)]",
718e3744 1759 NO_STR
b62ecea5
QY
1760 "Set bandwidth informational parameter\n"
1761 "Bandwidth in megabits\n")
718e3744 1762{
d62a17ae 1763 VTY_DECLVAR_CONTEXT(interface, ifp);
718e3744 1764
d62a17ae 1765 ifp->bandwidth = 0;
718e3744 1766
d62a17ae 1767 /* force protocols to recalculate routes due to cost change */
1768 if (if_is_operative(ifp))
1769 zebra_interface_up_update(ifp);
1770
1771 return CMD_SUCCESS;
718e3744 1772}
1773
6b0655a2 1774
d62a17ae 1775struct cmd_node link_params_node = {
9d303b37 1776 LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,
16f1b9ee
OD
1777};
1778
d62a17ae 1779static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1780 uint32_t type, uint32_t value)
16f1b9ee 1781{
d62a17ae 1782 /* Update field as needed */
1783 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1784 *field = value;
1785 SET_PARAM(ifp->link_params, type);
16f1b9ee 1786
d62a17ae 1787 /* force protocols to update LINK STATE due to parameters change
1788 */
1789 if (if_is_operative(ifp))
1790 zebra_interface_parameters_update(ifp);
1791 }
16f1b9ee 1792}
d62a17ae 1793static void link_param_cmd_set_float(struct interface *ifp, float *field,
1794 uint32_t type, float value)
16f1b9ee
OD
1795{
1796
d62a17ae 1797 /* Update field as needed */
1798 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1799 *field = value;
1800 SET_PARAM(ifp->link_params, type);
16f1b9ee 1801
d62a17ae 1802 /* force protocols to update LINK STATE due to parameters change
1803 */
1804 if (if_is_operative(ifp))
1805 zebra_interface_parameters_update(ifp);
1806 }
16f1b9ee
OD
1807}
1808
d62a17ae 1809static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
16f1b9ee 1810{
d62a17ae 1811 if (ifp->link_params == NULL)
1812 return;
16f1b9ee 1813
d62a17ae 1814 /* Unset field */
1815 UNSET_PARAM(ifp->link_params, type);
16f1b9ee 1816
d62a17ae 1817 /* force protocols to update LINK STATE due to parameters change */
1818 if (if_is_operative(ifp))
1819 zebra_interface_parameters_update(ifp);
16f1b9ee
OD
1820}
1821
505e5056 1822DEFUN_NOSH (link_params,
16f1b9ee
OD
1823 link_params_cmd,
1824 "link-params",
1825 LINK_PARAMS_STR)
1826{
d62a17ae 1827 /* vty->qobj_index stays the same @ interface pointer */
1828 vty->node = LINK_PARAMS_NODE;
16f1b9ee 1829
d62a17ae 1830 return CMD_SUCCESS;
16f1b9ee
OD
1831}
1832
505e5056 1833DEFUN_NOSH (exit_link_params,
03f99d9a
DS
1834 exit_link_params_cmd,
1835 "exit-link-params",
1836 "Exit from Link Params configuration mode\n")
1837{
d62a17ae 1838 if (vty->node == LINK_PARAMS_NODE)
1839 vty->node = INTERFACE_NODE;
1840 return CMD_SUCCESS;
03f99d9a
DS
1841}
1842
16f1b9ee
OD
1843/* Specific Traffic Engineering parameters commands */
1844DEFUN (link_params_enable,
1845 link_params_enable_cmd,
1846 "enable",
1847 "Activate link parameters on this interface\n")
1848{
d62a17ae 1849 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1850
d62a17ae 1851 /* This command could be issue at startup, when activate MPLS TE */
1852 /* on a new interface or after a ON / OFF / ON toggle */
1853 /* In all case, TE parameters are reset to their default factory */
1854 if (IS_ZEBRA_DEBUG_EVENT)
1855 zlog_debug(
1856 "Link-params: enable TE link parameters on interface %s",
1857 ifp->name);
16f1b9ee 1858
d62a17ae 1859 if (!if_link_params_get(ifp)) {
1860 if (IS_ZEBRA_DEBUG_EVENT)
1861 zlog_debug(
1862 "Link-params: failed to init TE link parameters %s",
1863 ifp->name);
16f1b9ee 1864
d62a17ae 1865 return CMD_WARNING_CONFIG_FAILED;
1866 }
16f1b9ee 1867
d62a17ae 1868 /* force protocols to update LINK STATE due to parameters change */
1869 if (if_is_operative(ifp))
1870 zebra_interface_parameters_update(ifp);
16f1b9ee 1871
d62a17ae 1872 return CMD_SUCCESS;
16f1b9ee
OD
1873}
1874
1875DEFUN (no_link_params_enable,
1876 no_link_params_enable_cmd,
1877 "no enable",
1878 NO_STR
1879 "Disable link parameters on this interface\n")
1880{
d62a17ae 1881 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1882
d62a17ae 1883 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
1884 ifp->name);
16f1b9ee 1885
d62a17ae 1886 if_link_params_free(ifp);
16f1b9ee 1887
d62a17ae 1888 /* force protocols to update LINK STATE due to parameters change */
1889 if (if_is_operative(ifp))
1890 zebra_interface_parameters_update(ifp);
16f1b9ee 1891
d62a17ae 1892 return CMD_SUCCESS;
16f1b9ee
OD
1893}
1894
1895/* STANDARD TE metrics */
1896DEFUN (link_params_metric,
1897 link_params_metric_cmd,
6147e2c6 1898 "metric (0-4294967295)",
16f1b9ee
OD
1899 "Link metric for MPLS-TE purpose\n"
1900 "Metric value in decimal\n")
1901{
d62a17ae 1902 int idx_number = 1;
1903 VTY_DECLVAR_CONTEXT(interface, ifp);
1904 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 1905 uint32_t metric;
16f1b9ee 1906
d62a17ae 1907 metric = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 1908
d62a17ae 1909 /* Update TE metric if needed */
1910 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee 1911
d62a17ae 1912 return CMD_SUCCESS;
16f1b9ee
OD
1913}
1914
1915DEFUN (no_link_params_metric,
1916 no_link_params_metric_cmd,
1917 "no metric",
1918 NO_STR
3ddccf18 1919 "Disable Link Metric on this interface\n")
16f1b9ee 1920{
d62a17ae 1921 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1922
d62a17ae 1923 /* Unset TE Metric */
1924 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee 1925
d62a17ae 1926 return CMD_SUCCESS;
16f1b9ee
OD
1927}
1928
1929DEFUN (link_params_maxbw,
1930 link_params_maxbw_cmd,
1931 "max-bw BANDWIDTH",
1932 "Maximum bandwidth that can be used\n"
1933 "Bytes/second (IEEE floating point format)\n")
1934{
d62a17ae 1935 int idx_bandwidth = 1;
1936 VTY_DECLVAR_CONTEXT(interface, ifp);
1937 struct if_link_params *iflp = if_link_params_get(ifp);
1938
1939 float bw;
1940
1941 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
1942 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
1943 safe_strerror(errno));
1944 return CMD_WARNING_CONFIG_FAILED;
1945 }
1946
1947 /* Check that Maximum bandwidth is not lower than other bandwidth
1948 * parameters */
1949 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
1950 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
1951 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
1952 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
1953 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
1954 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
1955 vty_out(vty,
1956 "Maximum Bandwidth could not be lower than others bandwidth\n");
1957 return CMD_WARNING_CONFIG_FAILED;
1958 }
1959
1960 /* Update Maximum Bandwidth if needed */
1961 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
1962
1963 return CMD_SUCCESS;
16f1b9ee
OD
1964}
1965
1966DEFUN (link_params_max_rsv_bw,
1967 link_params_max_rsv_bw_cmd,
1968 "max-rsv-bw BANDWIDTH",
1969 "Maximum bandwidth that may be reserved\n"
1970 "Bytes/second (IEEE floating point format)\n")
1971{
d62a17ae 1972 int idx_bandwidth = 1;
1973 VTY_DECLVAR_CONTEXT(interface, ifp);
1974 struct if_link_params *iflp = if_link_params_get(ifp);
1975 float bw;
16f1b9ee 1976
d62a17ae 1977 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
1978 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
1979 safe_strerror(errno));
1980 return CMD_WARNING_CONFIG_FAILED;
1981 }
16f1b9ee 1982
d62a17ae 1983 /* Check that bandwidth is not greater than maximum bandwidth parameter
1984 */
1985 if (bw > iflp->max_bw) {
1986 vty_out(vty,
1987 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
1988 iflp->max_bw);
1989 return CMD_WARNING_CONFIG_FAILED;
1990 }
16f1b9ee 1991
d62a17ae 1992 /* Update Maximum Reservable Bandwidth if needed */
1993 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
16f1b9ee 1994
d62a17ae 1995 return CMD_SUCCESS;
16f1b9ee
OD
1996}
1997
1998DEFUN (link_params_unrsv_bw,
1999 link_params_unrsv_bw_cmd,
6147e2c6 2000 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
2001 "Unreserved bandwidth at each priority level\n"
2002 "Priority\n"
2003 "Bytes/second (IEEE floating point format)\n")
2004{
d62a17ae 2005 int idx_number = 1;
2006 int idx_bandwidth = 2;
2007 VTY_DECLVAR_CONTEXT(interface, ifp);
2008 struct if_link_params *iflp = if_link_params_get(ifp);
2009 int priority;
2010 float bw;
2011
2012 /* We don't have to consider about range check here. */
2013 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2014 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2015 safe_strerror(errno));
2016 return CMD_WARNING_CONFIG_FAILED;
2017 }
2018
2019 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2020 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2021 safe_strerror(errno));
2022 return CMD_WARNING_CONFIG_FAILED;
2023 }
2024
2025 /* Check that bandwidth is not greater than maximum bandwidth parameter
2026 */
2027 if (bw > iflp->max_bw) {
2028 vty_out(vty,
2029 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2030 iflp->max_bw);
2031 return CMD_WARNING_CONFIG_FAILED;
2032 }
2033
2034 /* Update Unreserved Bandwidth if needed */
2035 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2036 bw);
2037
2038 return CMD_SUCCESS;
16f1b9ee
OD
2039}
2040
2041DEFUN (link_params_admin_grp,
2042 link_params_admin_grp_cmd,
2043 "admin-grp BITPATTERN",
2044 "Administrative group membership\n"
2045 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2046{
d62a17ae 2047 int idx_bitpattern = 1;
2048 VTY_DECLVAR_CONTEXT(interface, ifp);
2049 struct if_link_params *iflp = if_link_params_get(ifp);
2050 unsigned long value;
16f1b9ee 2051
d62a17ae 2052 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2053 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2054 safe_strerror(errno));
2055 return CMD_WARNING_CONFIG_FAILED;
2056 }
16f1b9ee 2057
d62a17ae 2058 /* Update Administrative Group if needed */
2059 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
16f1b9ee 2060
d62a17ae 2061 return CMD_SUCCESS;
16f1b9ee
OD
2062}
2063
2064DEFUN (no_link_params_admin_grp,
2065 no_link_params_admin_grp_cmd,
2066 "no admin-grp",
2067 NO_STR
3ddccf18 2068 "Disable Administrative group membership on this interface\n")
16f1b9ee 2069{
d62a17ae 2070 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2071
d62a17ae 2072 /* Unset Admin Group */
2073 link_param_cmd_unset(ifp, LP_ADM_GRP);
16f1b9ee 2074
d62a17ae 2075 return CMD_SUCCESS;
16f1b9ee
OD
2076}
2077
2078/* RFC5392 & RFC5316: INTER-AS */
2079DEFUN (link_params_inter_as,
2080 link_params_inter_as_cmd,
6147e2c6 2081 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
2082 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2083 "Remote IP address in dot decimal A.B.C.D\n"
2084 "Remote AS number\n"
2085 "AS number in the range <1-4294967295>\n")
2086{
d62a17ae 2087 int idx_ipv4 = 1;
2088 int idx_number = 3;
16f1b9ee 2089
d62a17ae 2090 VTY_DECLVAR_CONTEXT(interface, ifp);
2091 struct if_link_params *iflp = if_link_params_get(ifp);
2092 struct in_addr addr;
d7c0a89a 2093 uint32_t as;
16f1b9ee 2094
d62a17ae 2095 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2096 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2097 return CMD_WARNING_CONFIG_FAILED;
2098 }
16f1b9ee 2099
d62a17ae 2100 as = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2101
d62a17ae 2102 /* Update Remote IP and Remote AS fields if needed */
2103 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2104 || iflp->rmt_ip.s_addr != addr.s_addr) {
16f1b9ee 2105
d62a17ae 2106 iflp->rmt_as = as;
2107 iflp->rmt_ip.s_addr = addr.s_addr;
2108 SET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2109
d62a17ae 2110 /* force protocols to update LINK STATE due to parameters change
2111 */
2112 if (if_is_operative(ifp))
2113 zebra_interface_parameters_update(ifp);
2114 }
2115 return CMD_SUCCESS;
16f1b9ee
OD
2116}
2117
2118DEFUN (no_link_params_inter_as,
2119 no_link_params_inter_as_cmd,
2120 "no neighbor",
2121 NO_STR
2122 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2123{
d62a17ae 2124 VTY_DECLVAR_CONTEXT(interface, ifp);
2125 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2126
d62a17ae 2127 /* Reset Remote IP and AS neighbor */
2128 iflp->rmt_as = 0;
2129 iflp->rmt_ip.s_addr = 0;
2130 UNSET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2131
d62a17ae 2132 /* force protocols to update LINK STATE due to parameters change */
2133 if (if_is_operative(ifp))
2134 zebra_interface_parameters_update(ifp);
16f1b9ee 2135
d62a17ae 2136 return CMD_SUCCESS;
16f1b9ee
OD
2137}
2138
d62a17ae 2139/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2140 * draft-ietf-isis-metric-extensions-07.txt */
16f1b9ee
OD
2141DEFUN (link_params_delay,
2142 link_params_delay_cmd,
b62ecea5 2143 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 2144 "Unidirectional Average Link Delay\n"
b62ecea5
QY
2145 "Average delay in micro-second as decimal (0...16777215)\n"
2146 "Minimum delay\n"
2147 "Minimum delay in micro-second as decimal (0...16777215)\n"
2148 "Maximum delay\n"
2149 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 2150{
d62a17ae 2151 /* Get and Check new delay values */
d7c0a89a 2152 uint32_t delay = 0, low = 0, high = 0;
d62a17ae 2153 delay = strtoul(argv[1]->arg, NULL, 10);
2154 if (argc == 6) {
2155 low = strtoul(argv[3]->arg, NULL, 10);
2156 high = strtoul(argv[5]->arg, NULL, 10);
2157 }
2158
2159 VTY_DECLVAR_CONTEXT(interface, ifp);
2160 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2161 uint8_t update = 0;
d62a17ae 2162
2163 if (argc == 2) {
2164 /* Check new delay value against old Min and Max delays if set
2165 */
2166 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2167 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2168 vty_out(vty,
2169 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2170 iflp->min_delay, iflp->max_delay);
2171 return CMD_WARNING_CONFIG_FAILED;
2172 }
2173 /* Update delay if value is not set or change */
2174 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2175 iflp->av_delay = delay;
2176 SET_PARAM(iflp, LP_DELAY);
2177 update = 1;
2178 }
2179 /* Unset Min and Max delays if already set */
2180 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2181 iflp->min_delay = 0;
2182 iflp->max_delay = 0;
2183 UNSET_PARAM(iflp, LP_MM_DELAY);
2184 update = 1;
2185 }
2186 } else {
2187 /* Check new delays value coherency */
2188 if (delay <= low || delay >= high) {
2189 vty_out(vty,
2190 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2191 low, high);
2192 return CMD_WARNING_CONFIG_FAILED;
2193 }
2194 /* Update Delays if needed */
2195 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2196 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2197 || iflp->av_delay != delay || iflp->min_delay != low
2198 || iflp->max_delay != high) {
2199 iflp->av_delay = delay;
2200 SET_PARAM(iflp, LP_DELAY);
2201 iflp->min_delay = low;
2202 iflp->max_delay = high;
2203 SET_PARAM(iflp, LP_MM_DELAY);
2204 update = 1;
2205 }
2206 }
2207
2208 /* force protocols to update LINK STATE due to parameters change */
2209 if (update == 1 && if_is_operative(ifp))
2210 zebra_interface_parameters_update(ifp);
2211
2212 return CMD_SUCCESS;
16f1b9ee
OD
2213}
2214
16f1b9ee
OD
2215DEFUN (no_link_params_delay,
2216 no_link_params_delay_cmd,
2217 "no delay",
2218 NO_STR
3ddccf18 2219 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 2220{
d62a17ae 2221 VTY_DECLVAR_CONTEXT(interface, ifp);
2222 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2223
d62a17ae 2224 /* Unset Delays */
2225 iflp->av_delay = 0;
2226 UNSET_PARAM(iflp, LP_DELAY);
2227 iflp->min_delay = 0;
2228 iflp->max_delay = 0;
2229 UNSET_PARAM(iflp, LP_MM_DELAY);
16f1b9ee 2230
d62a17ae 2231 /* force protocols to update LINK STATE due to parameters change */
2232 if (if_is_operative(ifp))
2233 zebra_interface_parameters_update(ifp);
16f1b9ee 2234
d62a17ae 2235 return CMD_SUCCESS;
16f1b9ee
OD
2236}
2237
2238DEFUN (link_params_delay_var,
2239 link_params_delay_var_cmd,
6147e2c6 2240 "delay-variation (0-16777215)",
16f1b9ee
OD
2241 "Unidirectional Link Delay Variation\n"
2242 "delay variation in micro-second as decimal (0...16777215)\n")
2243{
d62a17ae 2244 int idx_number = 1;
2245 VTY_DECLVAR_CONTEXT(interface, ifp);
2246 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2247 uint32_t value;
16f1b9ee 2248
d62a17ae 2249 value = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2250
d62a17ae 2251 /* Update Delay Variation if needed */
2252 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
16f1b9ee 2253
d62a17ae 2254 return CMD_SUCCESS;
16f1b9ee
OD
2255}
2256
2257DEFUN (no_link_params_delay_var,
2258 no_link_params_delay_var_cmd,
2259 "no delay-variation",
2260 NO_STR
3ddccf18 2261 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 2262{
d62a17ae 2263 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2264
d62a17ae 2265 /* Unset Delay Variation */
2266 link_param_cmd_unset(ifp, LP_DELAY_VAR);
16f1b9ee 2267
d62a17ae 2268 return CMD_SUCCESS;
16f1b9ee
OD
2269}
2270
2271DEFUN (link_params_pkt_loss,
2272 link_params_pkt_loss_cmd,
2273 "packet-loss PERCENTAGE",
2274 "Unidirectional Link Packet Loss\n"
2275 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2276{
d62a17ae 2277 int idx_percentage = 1;
2278 VTY_DECLVAR_CONTEXT(interface, ifp);
2279 struct if_link_params *iflp = if_link_params_get(ifp);
2280 float fval;
16f1b9ee 2281
d62a17ae 2282 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2283 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2284 safe_strerror(errno));
2285 return CMD_WARNING_CONFIG_FAILED;
2286 }
16f1b9ee 2287
d62a17ae 2288 if (fval > MAX_PKT_LOSS)
2289 fval = MAX_PKT_LOSS;
16f1b9ee 2290
d62a17ae 2291 /* Update Packet Loss if needed */
2292 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
16f1b9ee 2293
d62a17ae 2294 return CMD_SUCCESS;
16f1b9ee
OD
2295}
2296
2297DEFUN (no_link_params_pkt_loss,
2298 no_link_params_pkt_loss_cmd,
2299 "no packet-loss",
2300 NO_STR
3ddccf18 2301 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 2302{
d62a17ae 2303 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2304
d62a17ae 2305 /* Unset Packet Loss */
2306 link_param_cmd_unset(ifp, LP_PKT_LOSS);
16f1b9ee 2307
d62a17ae 2308 return CMD_SUCCESS;
16f1b9ee
OD
2309}
2310
2311DEFUN (link_params_res_bw,
2312 link_params_res_bw_cmd,
2313 "res-bw BANDWIDTH",
2314 "Unidirectional Residual Bandwidth\n"
2315 "Bytes/second (IEEE floating point format)\n")
2316{
d62a17ae 2317 int idx_bandwidth = 1;
2318 VTY_DECLVAR_CONTEXT(interface, ifp);
2319 struct if_link_params *iflp = if_link_params_get(ifp);
2320 float bw;
16f1b9ee 2321
d62a17ae 2322 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2323 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2324 safe_strerror(errno));
2325 return CMD_WARNING_CONFIG_FAILED;
2326 }
16f1b9ee 2327
d62a17ae 2328 /* Check that bandwidth is not greater than maximum bandwidth parameter
2329 */
2330 if (bw > iflp->max_bw) {
2331 vty_out(vty,
2332 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2333 iflp->max_bw);
2334 return CMD_WARNING_CONFIG_FAILED;
2335 }
16f1b9ee 2336
d62a17ae 2337 /* Update Residual Bandwidth if needed */
2338 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
16f1b9ee 2339
d62a17ae 2340 return CMD_SUCCESS;
16f1b9ee
OD
2341}
2342
2343DEFUN (no_link_params_res_bw,
2344 no_link_params_res_bw_cmd,
2345 "no res-bw",
2346 NO_STR
3ddccf18 2347 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 2348{
d62a17ae 2349 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2350
d62a17ae 2351 /* Unset Residual Bandwidth */
2352 link_param_cmd_unset(ifp, LP_RES_BW);
16f1b9ee 2353
d62a17ae 2354 return CMD_SUCCESS;
16f1b9ee
OD
2355}
2356
2357DEFUN (link_params_ava_bw,
2358 link_params_ava_bw_cmd,
2359 "ava-bw BANDWIDTH",
2360 "Unidirectional Available Bandwidth\n"
2361 "Bytes/second (IEEE floating point format)\n")
2362{
d62a17ae 2363 int idx_bandwidth = 1;
2364 VTY_DECLVAR_CONTEXT(interface, ifp);
2365 struct if_link_params *iflp = if_link_params_get(ifp);
2366 float bw;
16f1b9ee 2367
d62a17ae 2368 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2369 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2370 safe_strerror(errno));
2371 return CMD_WARNING_CONFIG_FAILED;
2372 }
16f1b9ee 2373
d62a17ae 2374 /* Check that bandwidth is not greater than maximum bandwidth parameter
2375 */
2376 if (bw > iflp->max_bw) {
2377 vty_out(vty,
2378 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2379 iflp->max_bw);
2380 return CMD_WARNING_CONFIG_FAILED;
2381 }
16f1b9ee 2382
d62a17ae 2383 /* Update Residual Bandwidth if needed */
2384 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
16f1b9ee 2385
d62a17ae 2386 return CMD_SUCCESS;
16f1b9ee
OD
2387}
2388
2389DEFUN (no_link_params_ava_bw,
2390 no_link_params_ava_bw_cmd,
2391 "no ava-bw",
2392 NO_STR
3ddccf18 2393 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 2394{
d62a17ae 2395 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2396
d62a17ae 2397 /* Unset Available Bandwidth */
2398 link_param_cmd_unset(ifp, LP_AVA_BW);
16f1b9ee 2399
d62a17ae 2400 return CMD_SUCCESS;
16f1b9ee
OD
2401}
2402
2403DEFUN (link_params_use_bw,
2404 link_params_use_bw_cmd,
2405 "use-bw BANDWIDTH",
2406 "Unidirectional Utilised Bandwidth\n"
2407 "Bytes/second (IEEE floating point format)\n")
2408{
d62a17ae 2409 int idx_bandwidth = 1;
2410 VTY_DECLVAR_CONTEXT(interface, ifp);
2411 struct if_link_params *iflp = if_link_params_get(ifp);
2412 float bw;
16f1b9ee 2413
d62a17ae 2414 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2415 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2416 safe_strerror(errno));
2417 return CMD_WARNING_CONFIG_FAILED;
2418 }
16f1b9ee 2419
d62a17ae 2420 /* Check that bandwidth is not greater than maximum bandwidth parameter
2421 */
2422 if (bw > iflp->max_bw) {
2423 vty_out(vty,
2424 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2425 iflp->max_bw);
2426 return CMD_WARNING_CONFIG_FAILED;
2427 }
16f1b9ee 2428
d62a17ae 2429 /* Update Utilized Bandwidth if needed */
2430 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
16f1b9ee 2431
d62a17ae 2432 return CMD_SUCCESS;
16f1b9ee
OD
2433}
2434
2435DEFUN (no_link_params_use_bw,
2436 no_link_params_use_bw_cmd,
2437 "no use-bw",
2438 NO_STR
3ddccf18 2439 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 2440{
d62a17ae 2441 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2442
d62a17ae 2443 /* Unset Utilised Bandwidth */
2444 link_param_cmd_unset(ifp, LP_USE_BW);
16f1b9ee 2445
d62a17ae 2446 return CMD_SUCCESS;
16f1b9ee
OD
2447}
2448
d62a17ae 2449static int ip_address_install(struct vty *vty, struct interface *ifp,
2450 const char *addr_str, const char *peer_str,
2451 const char *label)
718e3744 2452{
d62a17ae 2453 struct zebra_if *if_data;
a07df329 2454 struct prefix_ipv4 lp, pp;
d62a17ae 2455 struct connected *ifc;
2456 struct prefix_ipv4 *p;
2457 int ret;
718e3744 2458
d62a17ae 2459 if_data = ifp->info;
bfac8dcd 2460
a07df329 2461 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2462 if (ret <= 0) {
2463 vty_out(vty, "%% Malformed address \n");
2464 return CMD_WARNING_CONFIG_FAILED;
2465 }
718e3744 2466
a07df329 2467 if (ipv4_martian(&lp.prefix)) {
d62a17ae 2468 vty_out(vty, "%% Invalid address\n");
2469 return CMD_WARNING_CONFIG_FAILED;
2470 }
d914d5ff 2471
a07df329
DL
2472 if (peer_str) {
2473 if (lp.prefixlen != 32) {
2474 vty_out(vty,
2475 "%% Local prefix length for P-t-P address must be /32\n");
2476 return CMD_WARNING_CONFIG_FAILED;
2477 }
2478
2479 ret = str2prefix_ipv4(peer_str, &pp);
2480 if (ret <= 0) {
2481 vty_out(vty, "%% Malformed peer address\n");
2482 return CMD_WARNING_CONFIG_FAILED;
2483 }
2484 }
2485
2486 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2487 if (!ifc) {
2488 ifc = connected_new();
2489 ifc->ifp = ifp;
2490
2491 /* Address. */
2492 p = prefix_ipv4_new();
a07df329 2493 *p = lp;
d62a17ae 2494 ifc->address = (struct prefix *)p;
2495
a07df329
DL
2496 if (peer_str) {
2497 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2498 p = prefix_ipv4_new();
2499 *p = pp;
2500 ifc->destination = (struct prefix *)p;
2501 } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
d62a17ae 2502 p = prefix_ipv4_new();
a07df329 2503 *p = lp;
d62a17ae 2504 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
2505 p->prefixlen);
2506 ifc->destination = (struct prefix *)p;
2507 }
718e3744 2508
d62a17ae 2509 /* Label. */
2510 if (label)
2511 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
718e3744 2512
d62a17ae 2513 /* Add to linked list. */
2514 listnode_add(ifp->connected, ifc);
718e3744 2515 }
2516
d62a17ae 2517 /* This address is configured from zebra. */
2518 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2519 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2520
2521 /* In case of this route need to install kernel. */
2522 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2523 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2524 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2525 /* Some system need to up the interface to set IP address. */
2526 if (!if_is_up(ifp)) {
2527 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2528 if_refresh(ifp);
2529 }
2530
2531 ret = if_set_prefix(ifp, ifc);
2532 if (ret < 0) {
2533 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2534 safe_strerror(errno));
2535 return CMD_WARNING_CONFIG_FAILED;
2536 }
2537
2538 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2539 /* The address will be advertised to zebra clients when the
2540 * notification
2541 * from the kernel has been received.
2542 * It will also be added to the subnet chain list, then. */
2543 }
2544
2545 return CMD_SUCCESS;
2546}
2547
2548static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2549 const char *addr_str, const char *peer_str,
2550 const char *label)
2551{
a07df329 2552 struct prefix_ipv4 lp, pp;
d62a17ae 2553 struct connected *ifc;
2554 int ret;
2555
2556 /* Convert to prefix structure. */
a07df329 2557 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2558 if (ret <= 0) {
2559 vty_out(vty, "%% Malformed address \n");
2560 return CMD_WARNING_CONFIG_FAILED;
2561 }
2562
a07df329
DL
2563 if (peer_str) {
2564 if (lp.prefixlen != 32) {
2565 vty_out(vty,
2566 "%% Local prefix length for P-t-P address must be /32\n");
2567 return CMD_WARNING_CONFIG_FAILED;
2568 }
2569
2570 ret = str2prefix_ipv4(peer_str, &pp);
2571 if (ret <= 0) {
2572 vty_out(vty, "%% Malformed peer address\n");
2573 return CMD_WARNING_CONFIG_FAILED;
2574 }
2575 }
2576
d62a17ae 2577 /* Check current interface address. */
a07df329 2578 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2579 if (!ifc) {
2580 vty_out(vty, "%% Can't find address\n");
2581 return CMD_WARNING_CONFIG_FAILED;
2582 }
2583
2584 /* This is not configured address. */
2585 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2586 return CMD_WARNING_CONFIG_FAILED;
2587
2588 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2589
2590 /* This is not real address or interface is not active. */
2591 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2592 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2593 listnode_delete(ifp->connected, ifc);
2594 connected_free(ifc);
2595 return CMD_WARNING_CONFIG_FAILED;
2596 }
2597
2598 /* This is real route. */
2599 ret = if_unset_prefix(ifp, ifc);
2600 if (ret < 0) {
2601 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2602 safe_strerror(errno));
2603 return CMD_WARNING_CONFIG_FAILED;
2604 }
2605 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2606 /* we will receive a kernel notification about this route being removed.
2607 * this will trigger its removal from the connected list. */
2608 return CMD_SUCCESS;
718e3744 2609}
2610
2611DEFUN (ip_address,
2612 ip_address_cmd,
2613 "ip address A.B.C.D/M",
2614 "Interface Internet Protocol config commands\n"
2615 "Set the IP address of an interface\n"
2616 "IP address (e.g. 10.0.0.1/8)\n")
2617{
d62a17ae 2618 int idx_ipv4_prefixlen = 2;
2619 VTY_DECLVAR_CONTEXT(interface, ifp);
2620 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2621 NULL);
718e3744 2622}
2623
2624DEFUN (no_ip_address,
2625 no_ip_address_cmd,
2626 "no ip address A.B.C.D/M",
2627 NO_STR
2628 "Interface Internet Protocol config commands\n"
2629 "Set the IP address of an interface\n"
efd7904e 2630 "IP Address (e.g. 10.0.0.1/8)\n")
718e3744 2631{
d62a17ae 2632 int idx_ipv4_prefixlen = 3;
2633 VTY_DECLVAR_CONTEXT(interface, ifp);
2634 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2635 NULL, NULL);
718e3744 2636}
2637
60466a63
QY
2638DEFUN(ip_address_peer,
2639 ip_address_peer_cmd,
2640 "ip address A.B.C.D peer A.B.C.D/M",
2641 "Interface Internet Protocol config commands\n"
2642 "Set the IP address of an interface\n"
2643 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2644 "Specify P-t-P address\n"
2645 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2646{
2647 VTY_DECLVAR_CONTEXT(interface, ifp);
2648 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
2649}
2650
60466a63
QY
2651DEFUN(no_ip_address_peer,
2652 no_ip_address_peer_cmd,
2653 "no ip address A.B.C.D peer A.B.C.D/M",
2654 NO_STR
2655 "Interface Internet Protocol config commands\n"
2656 "Set the IP address of an interface\n"
2657 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2658 "Specify P-t-P address\n"
2659 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2660{
2661 VTY_DECLVAR_CONTEXT(interface, ifp);
2662 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
2663}
986aa00f 2664
718e3744 2665#ifdef HAVE_NETLINK
718e3744 2666DEFUN (ip_address_label,
2667 ip_address_label_cmd,
2668 "ip address A.B.C.D/M label LINE",
2669 "Interface Internet Protocol config commands\n"
2670 "Set the IP address of an interface\n"
2671 "IP address (e.g. 10.0.0.1/8)\n"
2672 "Label of this address\n"
2673 "Label\n")
2674{
d62a17ae 2675 int idx_ipv4_prefixlen = 2;
2676 int idx_line = 4;
2677 VTY_DECLVAR_CONTEXT(interface, ifp);
2678 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2679 argv[idx_line]->arg);
718e3744 2680}
2681
2682DEFUN (no_ip_address_label,
2683 no_ip_address_label_cmd,
2684 "no ip address A.B.C.D/M label LINE",
2685 NO_STR
2686 "Interface Internet Protocol config commands\n"
2687 "Set the IP address of an interface\n"
2688 "IP address (e.g. 10.0.0.1/8)\n"
2689 "Label of this address\n"
2690 "Label\n")
2691{
d62a17ae 2692 int idx_ipv4_prefixlen = 3;
2693 int idx_line = 5;
2694 VTY_DECLVAR_CONTEXT(interface, ifp);
2695 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2696 NULL, argv[idx_line]->arg);
718e3744 2697}
2698#endif /* HAVE_NETLINK */
2699
d62a17ae 2700static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2701 const char *addr_str, const char *peer_str,
2702 const char *label, int secondary)
2703{
2704 struct zebra_if *if_data;
2705 struct prefix_ipv6 cp;
2706 struct connected *ifc;
2707 struct prefix_ipv6 *p;
2708 int ret;
2709
2710 if_data = ifp->info;
2711
2712 ret = str2prefix_ipv6(addr_str, &cp);
2713 if (ret <= 0) {
2714 vty_out(vty, "%% Malformed address \n");
2715 return CMD_WARNING_CONFIG_FAILED;
718e3744 2716 }
2717
d62a17ae 2718 if (ipv6_martian(&cp.prefix)) {
2719 vty_out(vty, "%% Invalid address\n");
2720 return CMD_WARNING_CONFIG_FAILED;
2721 }
718e3744 2722
d62a17ae 2723 ifc = connected_check(ifp, (struct prefix *)&cp);
2724 if (!ifc) {
2725 ifc = connected_new();
2726 ifc->ifp = ifp;
2727
2728 /* Address. */
2729 p = prefix_ipv6_new();
2730 *p = cp;
2731 ifc->address = (struct prefix *)p;
2732
2733 /* Secondary. */
2734 if (secondary)
2735 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
2736
2737 /* Label. */
2738 if (label)
2739 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2740
2741 /* Add to linked list. */
2742 listnode_add(ifp->connected, ifc);
718e3744 2743 }
2744
d62a17ae 2745 /* This address is configured from zebra. */
2746 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2747 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2748
2749 /* In case of this route need to install kernel. */
2750 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2751 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2752 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2753 /* Some system need to up the interface to set IP address. */
2754 if (!if_is_up(ifp)) {
2755 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2756 if_refresh(ifp);
2757 }
2758
2759 ret = if_prefix_add_ipv6(ifp, ifc);
2760
2761 if (ret < 0) {
2762 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2763 safe_strerror(errno));
2764 return CMD_WARNING_CONFIG_FAILED;
2765 }
2766
2767 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2768 /* The address will be advertised to zebra clients when the
2769 * notification
2770 * from the kernel has been received. */
2771 }
718e3744 2772
d62a17ae 2773 return CMD_SUCCESS;
718e3744 2774}
2775
b6120505 2776/* Return true if an ipv6 address is configured on ifp */
d62a17ae 2777int ipv6_address_configured(struct interface *ifp)
2778{
2779 struct connected *connected;
2780 struct listnode *node;
2781
2782 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2783 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2784 && (connected->address->family == AF_INET6))
2785 return 1;
2786
2787 return 0;
2788}
2789
2790static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2791 const char *addr_str, const char *peer_str,
2792 const char *label, int secondry)
2793{
2794 struct prefix_ipv6 cp;
2795 struct connected *ifc;
2796 int ret;
2797
2798 /* Convert to prefix structure. */
2799 ret = str2prefix_ipv6(addr_str, &cp);
2800 if (ret <= 0) {
2801 vty_out(vty, "%% Malformed address \n");
2802 return CMD_WARNING_CONFIG_FAILED;
2803 }
2804
2805 /* Check current interface address. */
2806 ifc = connected_check(ifp, (struct prefix *)&cp);
2807 if (!ifc) {
2808 vty_out(vty, "%% Can't find address\n");
2809 return CMD_WARNING_CONFIG_FAILED;
2810 }
2811
2812 /* This is not configured address. */
2813 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2814 return CMD_WARNING_CONFIG_FAILED;
2815
2816 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2817
2818 /* This is not real address or interface is not active. */
2819 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2820 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2821 listnode_delete(ifp->connected, ifc);
2822 connected_free(ifc);
2823 return CMD_WARNING_CONFIG_FAILED;
2824 }
2825
2826 /* This is real route. */
2827 ret = if_prefix_delete_ipv6(ifp, ifc);
2828 if (ret < 0) {
2829 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2830 safe_strerror(errno));
2831 return CMD_WARNING_CONFIG_FAILED;
2832 }
2833
2834 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2835 /* This information will be propagated to the zclients when the
2836 * kernel notification is received. */
2837 return CMD_SUCCESS;
718e3744 2838}
2839
2840DEFUN (ipv6_address,
2841 ipv6_address_cmd,
2842 "ipv6 address X:X::X:X/M",
e23949c0 2843 "Interface IPv6 config commands\n"
718e3744 2844 "Set the IP address of an interface\n"
2845 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2846{
d62a17ae 2847 int idx_ipv6_prefixlen = 2;
2848 VTY_DECLVAR_CONTEXT(interface, ifp);
2849 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2850 NULL, NULL, 0);
718e3744 2851}
2852
2853DEFUN (no_ipv6_address,
2854 no_ipv6_address_cmd,
2855 "no ipv6 address X:X::X:X/M",
2856 NO_STR
e23949c0 2857 "Interface IPv6 config commands\n"
718e3744 2858 "Set the IP address of an interface\n"
2859 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2860{
d62a17ae 2861 int idx_ipv6_prefixlen = 3;
2862 VTY_DECLVAR_CONTEXT(interface, ifp);
2863 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2864 NULL, NULL, 0);
2865}
2866
2867static int link_params_config_write(struct vty *vty, struct interface *ifp)
2868{
2869 int i;
2870
2871 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2872 return -1;
986aa00f 2873
d62a17ae 2874 struct if_link_params *iflp = ifp->link_params;
2875
2876 vty_out(vty, " link-params\n");
2877 vty_out(vty, " enable\n");
2878 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
2879 vty_out(vty, " metric %u\n", iflp->te_metric);
2880 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
2881 vty_out(vty, " max-bw %g\n", iflp->max_bw);
2882 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
2883 && iflp->max_rsv_bw != iflp->default_bw)
2884 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
2885 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2886 for (i = 0; i < 8; i++)
2887 if (iflp->unrsv_bw[i] != iflp->default_bw)
2888 vty_out(vty, " unrsv-bw %d %g\n", i,
2889 iflp->unrsv_bw[i]);
2890 }
2891 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2892 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
2893 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2894 vty_out(vty, " delay %u", iflp->av_delay);
2895 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2896 vty_out(vty, " min %u", iflp->min_delay);
2897 vty_out(vty, " max %u", iflp->max_delay);
2898 }
2899 vty_out(vty, "\n");
bfac8dcd 2900 }
d62a17ae 2901 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2902 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
2903 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2904 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
2905 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2906 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
2907 if (IS_PARAM_SET(iflp, LP_RES_BW))
2908 vty_out(vty, " res-bw %g\n", iflp->res_bw);
2909 if (IS_PARAM_SET(iflp, LP_USE_BW))
2910 vty_out(vty, " use-bw %g\n", iflp->use_bw);
2911 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2912 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
2913 iflp->rmt_as);
2914 vty_out(vty, " exit-link-params\n");
2915 return 0;
2916}
2917
2918static int if_config_write(struct vty *vty)
2919{
2920 struct vrf *vrf;
d62a17ae 2921 struct interface *ifp;
2922
2923 zebra_ptm_write(vty);
2924
a2addae8 2925 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
451fda4f 2926 FOR_ALL_INTERFACES (vrf, ifp) {
a2addae8
RW
2927 struct zebra_if *if_data;
2928 struct listnode *addrnode;
2929 struct connected *ifc;
2930 struct prefix *p;
2931 struct vrf *vrf;
d62a17ae 2932
a2addae8
RW
2933 if_data = ifp->info;
2934 vrf = vrf_lookup_by_id(ifp->vrf_id);
d62a17ae 2935
a2addae8
RW
2936 if (ifp->vrf_id == VRF_DEFAULT)
2937 vty_frame(vty, "interface %s\n", ifp->name);
2938 else
2939 vty_frame(vty, "interface %s vrf %s\n",
2940 ifp->name, vrf->name);
d62a17ae 2941
a2addae8
RW
2942 if (if_data) {
2943 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2944 vty_out(vty, " shutdown\n");
d62a17ae 2945
a2addae8
RW
2946 zebra_ptm_if_write(vty, if_data);
2947 }
bfac8dcd 2948
a2addae8
RW
2949 if (ifp->desc)
2950 vty_out(vty, " description %s\n", ifp->desc);
2951
2952 /* Assign bandwidth here to avoid unnecessary interface
2953 flap
2954 while processing config script */
2955 if (ifp->bandwidth != 0)
2956 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
2957
2958 if (!CHECK_FLAG(ifp->status,
2959 ZEBRA_INTERFACE_LINKDETECTION))
2960 vty_out(vty, " no link-detect\n");
2961
2962 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
2963 ifc)) {
2964 if (CHECK_FLAG(ifc->conf,
2965 ZEBRA_IFC_CONFIGURED)) {
2966 char buf[INET6_ADDRSTRLEN];
2967 p = ifc->address;
2968 vty_out(vty, " ip%s address %s",
2969 p->family == AF_INET ? ""
2970 : "v6",
a07df329 2971 inet_ntop(p->family,
60466a63
QY
2972 &p->u.prefix, buf,
2973 sizeof(buf)));
a2addae8
RW
2974 if (CONNECTED_PEER(ifc)) {
2975 p = ifc->destination;
2976 vty_out(vty, " peer %s",
2977 inet_ntop(p->family,
2978 &p->u.prefix,
2979 buf,
2980 sizeof(buf)));
2981 }
2982 vty_out(vty, "/%d", p->prefixlen);
718e3744 2983
a2addae8
RW
2984 if (ifc->label)
2985 vty_out(vty, " label %s",
2986 ifc->label);
718e3744 2987
a2addae8
RW
2988 vty_out(vty, "\n");
2989 }
d62a17ae 2990 }
718e3744 2991
a2addae8
RW
2992 if (if_data) {
2993 if (if_data->multicast
2994 != IF_ZEBRA_MULTICAST_UNSPEC)
2995 vty_out(vty, " %smulticast\n",
2996 if_data->multicast
2997 == IF_ZEBRA_MULTICAST_ON
2998 ? ""
2999 : "no ");
3000 }
718e3744 3001
a2addae8 3002 hook_call(zebra_if_config_wr, vty, ifp);
ca776988 3003
a2addae8 3004 link_params_config_write(vty, ifp);
16f1b9ee 3005
a2addae8
RW
3006 vty_endframe(vty, "!\n");
3007 }
d62a17ae 3008 return 0;
718e3744 3009}
3010
3011/* Allocate and initialize interface vector. */
d62a17ae 3012void zebra_if_init(void)
3013{
3014 /* Initialize interface and new hook. */
ce19a04a
DL
3015 hook_register_prio(if_add, 0, if_zebra_new_hook);
3016 hook_register_prio(if_del, 0, if_zebra_delete_hook);
d62a17ae 3017
3018 /* Install configuration write function. */
3019 install_node(&interface_node, if_config_write);
3020 install_node(&link_params_node, NULL);
3021 if_cmd_init();
3022
3023 install_element(VIEW_NODE, &show_interface_cmd);
3024 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
3025 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
3026 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
3027
3028 install_element(ENABLE_NODE, &show_interface_desc_cmd);
3029 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
3030 install_element(INTERFACE_NODE, &multicast_cmd);
3031 install_element(INTERFACE_NODE, &no_multicast_cmd);
3032 install_element(INTERFACE_NODE, &linkdetect_cmd);
3033 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
3034 install_element(INTERFACE_NODE, &shutdown_if_cmd);
3035 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
3036 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
3037 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
3038 install_element(INTERFACE_NODE, &ip_address_cmd);
3039 install_element(INTERFACE_NODE, &no_ip_address_cmd);
a07df329
DL
3040 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
3041 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
d62a17ae 3042 install_element(INTERFACE_NODE, &ipv6_address_cmd);
3043 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 3044#ifdef HAVE_NETLINK
d62a17ae 3045 install_element(INTERFACE_NODE, &ip_address_label_cmd);
3046 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
718e3744 3047#endif /* HAVE_NETLINK */
d62a17ae 3048 install_element(INTERFACE_NODE, &link_params_cmd);
3049 install_default(LINK_PARAMS_NODE);
3050 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
3051 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
3052 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
3053 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
3054 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
3055 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
3056 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
3057 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
3058 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
3059 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
3060 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
3061 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
3062 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
3063 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
3064 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
3065 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
3066 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
3067 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
3068 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
3069 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
3070 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
3071 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
3072 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
3073 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
718e3744 3074}