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