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