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