]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
pimd: Fix register receive pointer arithmetic
[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 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "if.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "command.h"
30#include "memory.h"
31#include "ioctl.h"
32#include "connected.h"
33#include "log.h"
34#include "zclient.h"
cd2a8a42 35#include "vrf.h"
718e3744 36
718e3744 37#include "zebra/rtadv.h"
7c551956 38#include "zebra_ns.h"
c1c747a8 39#include "zebra_vrf.h"
7c551956 40#include "zebra/interface.h"
718e3744 41#include "zebra/rib.h"
42#include "zebra/zserv.h"
43#include "zebra/redistribute.h"
44#include "zebra/debug.h"
ca776988 45#include "zebra/irdp.h"
244c1cdc 46#include "zebra/zebra_ptm.h"
5c610faf 47#include "zebra/rt_netlink.h"
88177fe3 48#include "zebra/interface.h"
244c1cdc
DS
49
50#define ZEBRA_PTM_SUPPORT
718e3744 51
8da4e946 52#if defined (HAVE_RTADV)
b60668d0
CC
53/* Order is intentional. Matches RFC4191. This array is also used for
54 command matching, so only modify with care. */
55const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
8da4e946 56#endif /* HAVE_RTADV */
718e3744 57
c8e264b6 58static void if_down_del_nbr_connected (struct interface *ifp);
59
718e3744 60/* Called when new interface is added. */
a1ac18c4 61static int
718e3744 62if_zebra_new_hook (struct interface *ifp)
63{
64 struct zebra_if *zebra_if;
65
393deb9b 66 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
718e3744 67
68 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
bfac8dcd 69 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
986aa00f 70 zebra_ptm_if_init(zebra_if);
718e3744 71
c8ed14dd 72 ifp->ptm_enable = zebra_ptm_get_enable_state();
8da4e946 73#if defined (HAVE_RTADV)
718e3744 74 {
75 /* Set default router advertise values. */
76 struct rtadvconf *rtadv;
77
78 rtadv = &zebra_if->rtadv;
79
80 rtadv->AdvSendAdvertisements = 0;
81 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
82 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
83 rtadv->AdvIntervalTimer = 0;
84 rtadv->AdvManagedFlag = 0;
85 rtadv->AdvOtherConfigFlag = 0;
7cee1bb1 86 rtadv->AdvHomeAgentFlag = 0;
718e3744 87 rtadv->AdvLinkMTU = 0;
88 rtadv->AdvReachableTime = 0;
89 rtadv->AdvRetransTimer = 0;
90 rtadv->AdvCurHopLimit = 0;
d660f698 91 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
7cee1bb1 92 rtadv->HomeAgentPreference = 0;
d660f698 93 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
7cee1bb1 94 rtadv->AdvIntervalOption = 0;
b60668d0 95 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
718e3744 96
97 rtadv->AdvPrefixList = list_new ();
98 }
8da4e946 99#endif /* HAVE_RTADV */
718e3744 100
eef1fe11 101 /* Initialize installed address chains tree. */
102 zebra_if->ipv4_subnets = route_table_init ();
103
718e3744 104 ifp->info = zebra_if;
a3d21ef3
DS
105
106 zebra_vrf_static_route_interface_fixup (ifp);
718e3744 107 return 0;
108}
109
110/* Called when interface is deleted. */
a1ac18c4 111static int
718e3744 112if_zebra_delete_hook (struct interface *ifp)
113{
eef1fe11 114 struct zebra_if *zebra_if;
115
718e3744 116 if (ifp->info)
eef1fe11 117 {
118 zebra_if = ifp->info;
119
120 /* Free installed address chains tree. */
121 if (zebra_if->ipv4_subnets)
122 route_table_finish (zebra_if->ipv4_subnets);
123
124 XFREE (MTYPE_TMP, zebra_if);
125 }
126
127 return 0;
128}
129
12f6fb97
DS
130/* Build the table key */
131static void
132if_build_key (u_int32_t ifindex, struct prefix *p)
133{
134 p->family = AF_INET;
135 p->prefixlen = IPV4_MAX_BITLEN;
136 p->u.prefix4.s_addr = ifindex;
137}
138
139/* Link an interface in a per NS interface tree */
140struct interface *
141if_link_per_ns (struct zebra_ns *ns, struct interface *ifp)
142{
143 struct prefix p;
144 struct route_node *rn;
145
146 if (ifp->ifindex == IFINDEX_INTERNAL)
147 return NULL;
148
149 if_build_key (ifp->ifindex, &p);
150 rn = route_node_get (ns->if_table, &p);
151 if (rn->info)
152 {
153 ifp = (struct interface *)rn->info;
154 route_unlock_node (rn); /* get */
155 return ifp;
156 }
157
158 rn->info = ifp;
159 ifp->node = rn;
160
161 return ifp;
162}
163
164/* Delete a VRF. This is called in vrf_terminate(). */
165void
166if_unlink_per_ns (struct interface *ifp)
167{
168 ifp->node->info = NULL;
169 route_unlock_node(ifp->node);
170}
171
172/* Look up an interface by identifier within a NS */
173struct interface *
174if_lookup_by_index_per_ns (struct zebra_ns *ns, u_int32_t ifindex)
175{
176 struct prefix p;
177 struct route_node *rn;
178 struct interface *ifp = NULL;
179
180 if_build_key (ifindex, &p);
181 rn = route_node_lookup (ns->if_table, &p);
182 if (rn)
183 {
184 ifp = (struct interface *)rn->info;
185 route_unlock_node (rn); /* lookup */
186 }
187 return ifp;
188}
189
a815b788 190const char *
191ifindex2ifname_per_ns (struct zebra_ns *zns, unsigned int ifindex)
192{
193 struct interface *ifp;
194
195 return ((ifp = if_lookup_by_index_per_ns (zns, ifindex)) != NULL) ?
196 ifp->name : "unknown";
197}
12f6fb97 198
eef1fe11 199/* Tie an interface address to its derived subnet list of addresses. */
200int
201if_subnet_add (struct interface *ifp, struct connected *ifc)
202{
203 struct route_node *rn;
204 struct zebra_if *zebra_if;
205 struct prefix cp;
206 struct list *addr_list;
207
208 assert (ifp && ifp->info && ifc);
209 zebra_if = ifp->info;
210
211 /* Get address derived subnet node and associated address list, while marking
212 address secondary attribute appropriately. */
213 cp = *ifc->address;
214 apply_mask (&cp);
215 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
216
217 if ((addr_list = rn->info))
218 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
219 else
220 {
221 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
222 rn->info = addr_list = list_new ();
223 route_lock_node (rn);
224 }
225
226 /* Tie address at the tail of address list. */
227 listnode_add (addr_list, ifc);
228
229 /* Return list element count. */
230 return (addr_list->count);
231}
232
233/* Untie an interface address from its derived subnet list of addresses. */
234int
235if_subnet_delete (struct interface *ifp, struct connected *ifc)
236{
237 struct route_node *rn;
238 struct zebra_if *zebra_if;
239 struct list *addr_list;
240
241 assert (ifp && ifp->info && ifc);
242 zebra_if = ifp->info;
243
244 /* Get address derived subnet node. */
245 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
246 if (! (rn && rn->info))
9db047fc
CF
247 {
248 zlog_warn("Trying to remove an address from an unknown subnet."
249 " (please report this bug)");
250 return -1;
251 }
eef1fe11 252 route_unlock_node (rn);
253
254 /* Untie address from subnet's address list. */
255 addr_list = rn->info;
9db047fc
CF
256
257 /* Deleting an address that is not registered is a bug.
258 * In any case, we shouldn't decrement the lock counter if the address
259 * is unknown. */
260 if (!listnode_lookup(addr_list, ifc))
261 {
262 zlog_warn("Trying to remove an address from a subnet where it is not"
263 " currently registered. (please report this bug)");
264 return -1;
265 }
266
eef1fe11 267 listnode_delete (addr_list, ifc);
268 route_unlock_node (rn);
269
270 /* Return list element count, if not empty. */
271 if (addr_list->count)
272 {
273 /* If deleted address is primary, mark subsequent one as such and distribute. */
274 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
275 {
1eb8ef25 276 ifc = listgetdata (listhead (addr_list));
eef1fe11 277 zebra_interface_address_delete_update (ifp, ifc);
278 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
02b4805f
CF
279 /* XXX: Linux kernel removes all the secondary addresses when the primary
280 * address is removed. We could try to work around that, though this is
281 * non-trivial. */
eef1fe11 282 zebra_interface_address_add_update (ifp, ifc);
283 }
284
285 return addr_list->count;
286 }
287
288 /* Otherwise, free list and route node. */
289 list_free (addr_list);
290 rn->info = NULL;
291 route_unlock_node (rn);
292
718e3744 293 return 0;
294}
295
5c78b3d0 296/* if_flags_mangle: A place for hacks that require mangling
297 * or tweaking the interface flags.
298 *
299 * ******************** Solaris flags hacks **************************
300 *
301 * Solaris IFF_UP flag reflects only the primary interface as the
302 * routing socket only sends IFINFO for the primary interface. Hence
303 * ~IFF_UP does not per se imply all the logical interfaces are also
304 * down - which we only know of as addresses. Instead we must determine
305 * whether the interface really is up or not according to how many
306 * addresses are still attached. (Solaris always sends RTM_DELADDR if
307 * an interface, logical or not, goes ~IFF_UP).
308 *
309 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
310 * are addresses left in struct connected, not just the actual underlying
311 * IFF_UP flag.
312 *
313 * We must hence remember the real state of IFF_UP, which we do in
314 * struct zebra_if.primary_state.
315 *
316 * Setting IFF_UP within zebra to administratively shutdown the
317 * interface will affect only the primary interface/address on Solaris.
318 ************************End Solaris flags hacks ***********************
319 */
f63f06da 320static void
5c78b3d0 321if_flags_mangle (struct interface *ifp, uint64_t *newflags)
322{
323#ifdef SUNOS_5
324 struct zebra_if *zif = ifp->info;
325
326 zif->primary_state = *newflags & (IFF_UP & 0xff);
327
328 if (CHECK_FLAG (zif->primary_state, IFF_UP)
329 || listcount(ifp->connected) > 0)
330 SET_FLAG (*newflags, IFF_UP);
331 else
332 UNSET_FLAG (*newflags, IFF_UP);
333#endif /* SUNOS_5 */
334}
335
336/* Update the flags field of the ifp with the new flag set provided.
337 * Take whatever actions are required for any changes in flags we care
338 * about.
339 *
340 * newflags should be the raw value, as obtained from the OS.
341 */
342void
343if_flags_update (struct interface *ifp, uint64_t newflags)
344{
345 if_flags_mangle (ifp, &newflags);
346
244c1cdc 347 if (if_is_no_ptm_operative (ifp))
5c78b3d0 348 {
349 /* operative -> inoperative? */
350 ifp->flags = newflags;
351 if (!if_is_operative (ifp))
352 if_down (ifp);
353 }
354 else
355 {
356 /* inoperative -> operative? */
357 ifp->flags = newflags;
358 if (if_is_operative (ifp))
359 if_up (ifp);
360 }
361}
362
718e3744 363/* Wake up configured address if it is not in current kernel
364 address. */
a1ac18c4 365static void
718e3744 366if_addr_wakeup (struct interface *ifp)
367{
1eb8ef25 368 struct listnode *node, *nnode;
718e3744 369 struct connected *ifc;
370 struct prefix *p;
371 int ret;
372
1eb8ef25 373 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
718e3744 374 {
718e3744 375 p = ifc->address;
376
377 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
f7f740fe 378 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
718e3744 379 {
380 /* Address check. */
381 if (p->family == AF_INET)
382 {
383 if (! if_is_up (ifp))
384 {
02b4805f
CF
385 /* Assume zebra is configured like following:
386 *
387 * interface gre0
388 * ip addr 192.0.2.1/24
389 * !
390 *
391 * As soon as zebra becomes first aware that gre0 exists in the
392 * kernel, it will set gre0 up and configure its addresses.
393 *
394 * (This may happen at startup when the interface already exists
395 * or during runtime when the interface is added to the kernel)
396 *
397 * XXX: IRDP code is calling here via if_add_update - this seems
398 * somewhat weird.
399 * XXX: RUNNING is not a settable flag on any system
400 * I (paulj) am aware of.
401 */
718e3744 402 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
403 if_refresh (ifp);
404 }
405
406 ret = if_set_prefix (ifp, ifc);
407 if (ret < 0)
408 {
409 zlog_warn ("Can't set interface's address: %s",
6099b3b5 410 safe_strerror(errno));
718e3744 411 continue;
412 }
eef1fe11 413
f7f740fe 414 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
415 /* The address will be advertised to zebra clients when the notification
416 * from the kernel has been received.
417 * It will also be added to the interface's subnet list then. */
718e3744 418 }
419#ifdef HAVE_IPV6
420 if (p->family == AF_INET6)
421 {
422 if (! if_is_up (ifp))
423 {
02b4805f 424 /* See long comment above */
718e3744 425 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
426 if_refresh (ifp);
427 }
428
429 ret = if_prefix_add_ipv6 (ifp, ifc);
430 if (ret < 0)
431 {
432 zlog_warn ("Can't set interface's address: %s",
6099b3b5 433 safe_strerror(errno));
718e3744 434 continue;
435 }
718e3744 436
02b4805f
CF
437 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
438 /* The address will be advertised to zebra clients when the notification
439 * from the kernel has been received. */
718e3744 440 }
441#endif /* HAVE_IPV6 */
442 }
443 }
444}
445
446/* Handle interface addition */
447void
448if_add_update (struct interface *ifp)
449{
48b33aaf 450 struct zebra_if *if_data;
451
fe18ee2d 452 if_link_per_ns(zebra_ns_lookup (NS_DEFAULT), ifp);
12f6fb97 453
48b33aaf 454 if_data = ifp->info;
06b420a4
MS
455 assert(if_data);
456
48b33aaf 457 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
458 if_set_flags (ifp, IFF_MULTICAST);
459 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
460 if_unset_flags (ifp, IFF_MULTICAST);
461
986aa00f 462 zebra_ptm_if_set_ptm_state(ifp, if_data);
463
718e3744 464 zebra_interface_add_update (ifp);
465
466 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
467 {
468 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
469
bfac8dcd
CF
470 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
471 {
472 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
473 zlog_debug ("interface %s vrf %u index %d is shutdown. "
474 "Won't wake it up.",
475 ifp->name, ifp->vrf_id, ifp->ifindex);
bfac8dcd
CF
476 return;
477 }
478
718e3744 479 if_addr_wakeup (ifp);
480
481 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
482 zlog_debug ("interface %s vrf %u index %d becomes active.",
483 ifp->name, ifp->vrf_id, ifp->ifindex);
718e3744 484 }
485 else
486 {
487 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
488 zlog_debug ("interface %s vrf %u index %d is added.",
489 ifp->name, ifp->vrf_id, ifp->ifindex);
718e3744 490 }
491}
492
c8e264b6 493/* Install connected routes corresponding to an interface. */
494static void
495if_install_connected (struct interface *ifp)
718e3744 496{
c8e264b6 497 struct listnode *node;
498 struct listnode *next;
718e3744 499 struct connected *ifc;
500 struct prefix *p;
eef1fe11 501
c8e264b6 502 if (ifp->connected)
503 {
504 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
505 {
506 p = ifc->address;
99ffac18 507 zebra_interface_address_add_update (ifp, ifc);
718e3744 508
c8e264b6 509 if (p->family == AF_INET)
510 connected_up_ipv4 (ifp, ifc);
511 else if (p->family == AF_INET6)
512 connected_up_ipv6 (ifp, ifc);
513 }
514 }
515}
516
517/* Uninstall connected routes corresponding to an interface. */
518static void
519if_uninstall_connected (struct interface *ifp)
520{
521 struct listnode *node;
522 struct listnode *next;
523 struct connected *ifc;
524 struct prefix *p;
525
526 if (ifp->connected)
718e3744 527 {
c8e264b6 528 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
529 {
530 p = ifc->address;
99ffac18 531 zebra_interface_address_delete_update (ifp, ifc);
c8e264b6 532
533 if (p->family == AF_INET)
534 connected_down_ipv4 (ifp, ifc);
535 else if (p->family == AF_INET6)
536 connected_down_ipv6 (ifp, ifc);
537 }
718e3744 538 }
c8e264b6 539}
718e3744 540
c8e264b6 541/* Uninstall and delete connected routes corresponding to an interface. */
542/* TODO - Check why IPv4 handling here is different from install or if_down */
543static void
544if_delete_connected (struct interface *ifp)
545{
546 struct connected *ifc;
547 struct prefix *p;
548 struct route_node *rn;
549 struct zebra_if *zebra_if;
550
551 zebra_if = ifp->info;
718e3744 552
718e3744 553 if (ifp->connected)
554 {
d9a18f11
PJ
555 struct listnode *node;
556 struct listnode *last = NULL;
557
eef1fe11 558 while ((node = (last ? last->next : listhead (ifp->connected))))
718e3744 559 {
1eb8ef25 560 ifc = listgetdata (node);
718e3744 561 p = ifc->address;
eef1fe11 562
beb56336
PJ
563 if (p->family == AF_INET
564 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
eef1fe11 565 {
d9a18f11
PJ
566 struct listnode *anode;
567 struct listnode *next;
568 struct listnode *first;
569 struct list *addr_list;
570
eef1fe11 571 route_unlock_node (rn);
572 addr_list = (struct list *) rn->info;
573
574 /* Remove addresses, secondaries first. */
575 first = listhead (addr_list);
d9a18f11 576 for (anode = first->next; anode || first; anode = next)
eef1fe11 577 {
d9a18f11 578 if (!anode)
eef1fe11 579 {
d9a18f11 580 anode = first;
eef1fe11 581 first = NULL;
582 }
d9a18f11 583 next = anode->next;
eef1fe11 584
d9a18f11 585 ifc = listgetdata (anode);
eef1fe11 586 connected_down_ipv4 (ifp, ifc);
587
02b4805f
CF
588 /* XXX: We have to send notifications here explicitly, because we destroy
589 * the ifc before receiving the notification about the address being deleted.
590 */
eef1fe11 591 zebra_interface_address_delete_update (ifp, ifc);
592
593 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 594 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 595
596 /* Remove from subnet chain. */
d9a18f11 597 list_delete_node (addr_list, anode);
eef1fe11 598 route_unlock_node (rn);
599
600 /* Remove from interface address list (unconditionally). */
d9a18f11
PJ
601 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
602 {
603 listnode_delete (ifp->connected, ifc);
604 connected_free (ifc);
605 }
606 else
607 last = node;
eef1fe11 608 }
609
610 /* Free chain list and respective route node. */
611 list_delete (addr_list);
612 rn->info = NULL;
613 route_unlock_node (rn);
614 }
718e3744 615 else if (p->family == AF_INET6)
eef1fe11 616 {
617 connected_down_ipv6 (ifp, ifc);
718e3744 618
eef1fe11 619 zebra_interface_address_delete_update (ifp, ifc);
718e3744 620
eef1fe11 621 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 622 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 623
624 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
625 last = node;
626 else
627 {
628 listnode_delete (ifp->connected, ifc);
629 connected_free (ifc);
630 }
718e3744 631 }
e26873fd
RHA
632 else
633 {
634 last = node;
635 }
718e3744 636 }
637 }
c8e264b6 638}
639
640/* Handle an interface delete event */
641void
642if_delete_update (struct interface *ifp)
643{
644 if (if_is_up(ifp))
645 {
646 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
647 ifp->name, ifp->vrf_id, ifp->ifindex);
648 return;
649 }
650
651 /* Mark interface as inactive */
652 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
653
654 if (IS_ZEBRA_DEBUG_KERNEL)
655 zlog_debug ("interface %s vrf %u index %d is now inactive.",
656 ifp->name, ifp->vrf_id, ifp->ifindex);
657
658 /* Delete connected routes from the kernel. */
659 if_delete_connected (ifp);
660
661 /* Send out notification on interface delete. */
718e3744 662 zebra_interface_delete_update (ifp);
d2fc8896 663
12f6fb97
DS
664 if_unlink_per_ns(ifp);
665
d2fc8896 666 /* Update ifindex after distributing the delete message. This is in
667 case any client needs to have the old value of ifindex available
668 while processing the deletion. Each client daemon is responsible
669 for setting ifindex to IFINDEX_INTERNAL after processing the
670 interface deletion message. */
671 ifp->ifindex = IFINDEX_INTERNAL;
718e3744 672}
673
c8e264b6 674/* VRF change for an interface */
675void
676if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
677{
678 vrf_id_t old_vrf_id;
679
680 old_vrf_id = ifp->vrf_id;
681
682 /* Uninstall connected routes. */
683 if_uninstall_connected (ifp);
684
685 /* Delete any IPv4 neighbors created to implement RFC 5549 */
686 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
687
688 /* Delete all neighbor addresses learnt through IPv6 RA */
689 if_down_del_nbr_connected (ifp);
690
c8e264b6 691 /* Send out notification on interface VRF change. */
692 /* This is to issue an UPDATE or a DELETE, as appropriate. */
693 zebra_interface_vrf_update_del (ifp, vrf_id);
694
695 /* update VRF */
696 if_update_vrf (ifp, ifp->name, strlen (ifp->name), vrf_id);
697
698 /* Send out notification on interface VRF change. */
699 /* This is to issue an ADD, if needed. */
700 zebra_interface_vrf_update_add (ifp, old_vrf_id);
701
702 /* Install connected routes (in new VRF). */
703 if_install_connected (ifp);
704
c8e264b6 705 /* Due to connected route change, schedule RIB processing for both old
706 * and new VRF.
707 */
708 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
709 zlog_debug ("%u: IF %s VRF change, scheduling RIB processing",
710 ifp->vrf_id, ifp->name);
711 rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE);
712 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
fb148af4
DS
713
714 zebra_vrf_static_route_interface_fixup (ifp);
c8e264b6 715}
716
88177fe3 717static void
5c610faf
DS
718ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac)
719{
eb4b1830 720 mac[0] = address->s6_addr[8] ^ 0x02;
5c610faf
DS
721 mac[1] = address->s6_addr[9];
722 mac[2] = address->s6_addr[10];
723 mac[3] = address->s6_addr[13];
724 mac[4] = address->s6_addr[14];
725 mac[5] = address->s6_addr[15];
726}
727
728void
729if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
730 struct in6_addr *address,
731 int add)
732{
733 char buf[16] = "169.254.0.1";
734 struct in_addr ipv4_ll;
88177fe3 735 char mac[6];
5c610faf
DS
736
737 inet_pton (AF_INET, buf, &ipv4_ll);
738
88177fe3 739 ipv6_ll_address_to_mac(address, (u_char *)mac);
5c610faf
DS
740 netlink_neigh_update (add ? RTM_NEWNEIGH : RTM_DELNEIGH,
741 ifp->ifindex, ipv4_ll.s_addr, mac, 6);
742}
743
88177fe3 744static void
5c610faf
DS
745if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp)
746{
747 if (listhead(ifp->nbr_connected))
748 {
749 struct nbr_connected *nbr_connected;
750 struct listnode *node;
751
752 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
753 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
754 &nbr_connected->address->u.prefix6,
755 1);
756 }
757}
758
759void
760if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp)
761{
762 if (listhead(ifp->nbr_connected))
763 {
764 struct nbr_connected *nbr_connected;
765 struct listnode *node;
766
767 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
768 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
769 &nbr_connected->address->u.prefix6,
770 0);
771 }
772}
773
88177fe3 774static void
a197c47c
DS
775if_down_del_nbr_connected (struct interface *ifp)
776{
777 struct nbr_connected *nbr_connected;
778 struct listnode *node, *nnode;
779
780 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nbr_connected))
781 {
782 listnode_delete (ifp->nbr_connected, nbr_connected);
783 nbr_connected_free (nbr_connected);
784 }
785}
786
718e3744 787/* Interface is up. */
788void
789if_up (struct interface *ifp)
790{
55ce4d3a
CF
791 struct zebra_if *zif;
792
793 zif = ifp->info;
794 zif->up_count++;
795 quagga_timestamp (2, zif->up_last, sizeof (zif->up_last));
796
718e3744 797 /* Notify the protocol daemons. */
950bd436 798 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
244c1cdc
DS
799 zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
800 ifp->name);
801 return;
802 }
718e3744 803 zebra_interface_up_update (ifp);
804
5c610faf 805 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
244c1cdc 806
6c9678b4
DD
807 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
808 if (zif->rtadv.AdvSendAdvertisements &&
809 (zif->rtadv.MaxRtrAdvInterval >= 1000))
810 {
811 zif->rtadv.inFastRexmit = 1;
812 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
813 }
814
718e3744 815 /* Install connected routes to the kernel. */
c8e264b6 816 if_install_connected (ifp);
718e3744 817
41ec9222 818 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1c848137 819 zlog_debug ("%u: IF %s up, scheduling RIB processing",
820 ifp->vrf_id, ifp->name);
821 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
a3d21ef3
DS
822
823 zebra_vrf_static_route_interface_fixup (ifp);
718e3744 824}
825
826/* Interface goes down. We have to manage different behavior of based
827 OS. */
828void
829if_down (struct interface *ifp)
830{
55ce4d3a
CF
831 struct zebra_if *zif;
832
833 zif = ifp->info;
834 zif->down_count++;
835 quagga_timestamp (2, zif->down_last, sizeof (zif->down_last));
836
718e3744 837 /* Notify to the protocol daemons. */
838 zebra_interface_down_update (ifp);
839
c8e264b6 840 /* Uninstall connected routes from the kernel. */
841 if_uninstall_connected (ifp);
718e3744 842
41ec9222 843 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1c848137 844 zlog_debug ("%u: IF %s down, scheduling RIB processing",
845 ifp->vrf_id, ifp->name);
846 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
5c610faf
DS
847
848 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
a197c47c
DS
849
850 /* Delete all neighbor addresses learnt through IPv6 RA */
851 if_down_del_nbr_connected (ifp);
718e3744 852}
853
854void
855if_refresh (struct interface *ifp)
856{
5c78b3d0 857 if_get_flags (ifp);
718e3744 858}
859
d5a5c8f0 860
718e3744 861/* Output prefix string to vty. */
a1ac18c4 862static int
718e3744 863prefix_vty_out (struct vty *vty, struct prefix *p)
864{
865 char str[INET6_ADDRSTRLEN];
866
867 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
868 vty_out (vty, "%s", str);
869 return strlen (str);
870}
871
872/* Dump if address information to vty. */
a1ac18c4 873static void
718e3744 874connected_dump_vty (struct vty *vty, struct connected *connected)
875{
876 struct prefix *p;
718e3744 877
878 /* Print interface address. */
879 p = connected->address;
880 vty_out (vty, " %s ", prefix_family_str (p));
881 prefix_vty_out (vty, p);
882 vty_out (vty, "/%d", p->prefixlen);
883
884 /* If there is destination address, print it. */
e4529636 885 if (connected->destination)
718e3744 886 {
e4529636
AS
887 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
888 prefix_vty_out (vty, connected->destination);
718e3744 889 }
890
891 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
892 vty_out (vty, " secondary");
893
525c1839
DS
894 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED))
895 vty_out (vty, " unnumbered");
896
718e3744 897 if (connected->label)
898 vty_out (vty, " %s", connected->label);
899
900 vty_out (vty, "%s", VTY_NEWLINE);
901}
902
a80beece
DS
903/* Dump interface neighbor address information to vty. */
904static void
905nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected)
906{
907 struct prefix *p;
908
909 /* Print interface address. */
910 p = connected->address;
911 vty_out (vty, " %s ", prefix_family_str (p));
912 prefix_vty_out (vty, p);
913 vty_out (vty, "/%d", p->prefixlen);
914
915 vty_out (vty, "%s", VTY_NEWLINE);
916}
917
8da4e946 918#if defined (HAVE_RTADV)
718e3744 919/* Dump interface ND information to vty. */
a1ac18c4 920static void
718e3744 921nd_dump_vty (struct vty *vty, struct interface *ifp)
922{
923 struct zebra_if *zif;
924 struct rtadvconf *rtadv;
7cee1bb1 925 int interval;
718e3744 926
927 zif = (struct zebra_if *) ifp->info;
928 rtadv = &zif->rtadv;
929
930 if (rtadv->AdvSendAdvertisements)
931 {
932 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
933 rtadv->AdvReachableTime, VTY_NEWLINE);
934 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
935 rtadv->AdvRetransTimer, VTY_NEWLINE);
795b5abf
QY
936 vty_out (vty, " ND router advertisements sent: %d rcvd: %d%s",
937 zif->ra_sent, zif->ra_rcvd, VTY_NEWLINE);
7cee1bb1 938 interval = rtadv->MaxRtrAdvInterval;
939 if (interval % 1000)
940 vty_out (vty, " ND router advertisements are sent every "
941 "%d milliseconds%s", interval,
942 VTY_NEWLINE);
943 else
944 vty_out (vty, " ND router advertisements are sent every "
945 "%d seconds%s", interval / 1000,
946 VTY_NEWLINE);
d660f698
DO
947 if (rtadv->AdvDefaultLifetime != -1)
948 vty_out (vty, " ND router advertisements live for %d seconds%s",
949 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
950 else
951 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
952 VTY_NEWLINE);
b60668d0
CC
953 vty_out (vty, " ND router advertisement default router preference is "
954 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
955 VTY_NEWLINE);
718e3744 956 if (rtadv->AdvManagedFlag)
957 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
958 VTY_NEWLINE);
959 else
960 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
961 VTY_NEWLINE);
7cee1bb1 962 if (rtadv->AdvHomeAgentFlag)
d660f698 963 {
7cee1bb1 964 vty_out (vty, " ND router advertisements with "
965 "Home Agent flag bit set.%s",
966 VTY_NEWLINE);
d660f698
DO
967 if (rtadv->HomeAgentLifetime != -1)
968 vty_out (vty, " Home Agent lifetime is %u seconds%s",
969 rtadv->HomeAgentLifetime, VTY_NEWLINE);
970 else
971 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
972 VTY_NEWLINE);
973 vty_out (vty, " Home Agent preference is %u%s",
974 rtadv->HomeAgentPreference, VTY_NEWLINE);
975 }
7cee1bb1 976 if (rtadv->AdvIntervalOption)
977 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
978 VTY_NEWLINE);
718e3744 979 }
980}
8da4e946 981#endif /* HAVE_RTADV */
718e3744 982
983/* Interface's information print out to vty interface. */
a1ac18c4 984static void
718e3744 985if_dump_vty (struct vty *vty, struct interface *ifp)
986{
6f0e3f6e 987#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 988 struct sockaddr_dl *sdl;
6f0e3f6e 989#endif /* HAVE_STRUCT_SOCKADDR_DL */
718e3744 990 struct connected *connected;
a80beece 991 struct nbr_connected *nbr_connected;
52dc7ee6 992 struct listnode *node;
eef1fe11 993 struct route_node *rn;
994 struct zebra_if *zebra_if;
e6a59b35 995 struct vrf *vrf;
eef1fe11 996
997 zebra_if = ifp->info;
718e3744 998
2e3b2e47 999 vty_out (vty, "Interface %s is ", ifp->name);
1000 if (if_is_up(ifp)) {
1001 vty_out (vty, "up, line protocol ");
1002
1003 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1004 if (if_is_running(ifp))
1005 vty_out (vty, "is up%s", VTY_NEWLINE);
1006 else
1007 vty_out (vty, "is down%s", VTY_NEWLINE);
1008 } else {
1009 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
1010 }
1011 } else {
1012 vty_out (vty, "down%s", VTY_NEWLINE);
1013 }
1014
55ce4d3a
CF
1015 vty_out (vty, " Link ups: %5u last: %s%s", zebra_if->up_count,
1016 zebra_if->up_last[0] ? zebra_if->up_last : "(never)", VTY_NEWLINE);
1017 vty_out (vty, " Link downs: %5u last: %s%s", zebra_if->down_count,
1018 zebra_if->down_last[0] ? zebra_if->down_last : "(never)", VTY_NEWLINE);
1019
950bd436 1020 zebra_ptm_show_status(vty, ifp);
244c1cdc 1021
e6a59b35
DS
1022 vrf = vrf_lookup(ifp->vrf_id);
1023 vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
3968dbf8 1024
718e3744 1025 if (ifp->desc)
1026 vty_out (vty, " Description: %s%s", ifp->desc,
1027 VTY_NEWLINE);
d2fc8896 1028 if (ifp->ifindex == IFINDEX_INTERNAL)
718e3744 1029 {
d2fc8896 1030 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
718e3744 1031 return;
1032 }
1033 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1034 {
1035 vty_out(vty, " index %d inactive interface%s",
1036 ifp->ifindex,
1037 VTY_NEWLINE);
1038 return;
1039 }
1040
1041 vty_out (vty, " index %d metric %d mtu %d ",
1042 ifp->ifindex, ifp->metric, ifp->mtu);
44145db3 1043#ifdef HAVE_IPV6
1044 if (ifp->mtu6 != ifp->mtu)
1045 vty_out (vty, "mtu6 %d ", ifp->mtu6);
1046#endif
630c97ce
PJ
1047 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
1048 if_flag_dump (ifp->flags), VTY_NEWLINE);
3a570c8b 1049
718e3744 1050 /* Hardware address. */
6f0e3f6e 1051#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 1052 sdl = &ifp->sdl;
1053 if (sdl != NULL && sdl->sdl_alen != 0)
1054 {
1055 int i;
1056 u_char *ptr;
1057
1058 vty_out (vty, " HWaddr: ");
5b73a671 1059 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
1060 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
718e3744 1061 vty_out (vty, "%s", VTY_NEWLINE);
1062 }
1063#else
1064 if (ifp->hw_addr_len != 0)
1065 {
1066 int i;
1067
1068 vty_out (vty, " HWaddr: ");
1069 for (i = 0; i < ifp->hw_addr_len; i++)
1070 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
1071 vty_out (vty, "%s", VTY_NEWLINE);
1072 }
6f0e3f6e 1073#endif /* HAVE_STRUCT_SOCKADDR_DL */
718e3744 1074
70bd3c43 1075 /* Bandwidth in Mbps */
718e3744 1076 if (ifp->bandwidth != 0)
1077 {
70bd3c43 1078 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
718e3744 1079 vty_out(vty, "%s", VTY_NEWLINE);
1080 }
1081
eef1fe11 1082 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
718e3744 1083 {
eef1fe11 1084 if (! rn->info)
1085 continue;
1086
1eb8ef25 1087 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
1088 connected_dump_vty (vty, connected);
718e3744 1089 }
1090
1eb8ef25 1091 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
39db97e4 1092 {
39db97e4 1093 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
1094 (connected->address->family == AF_INET6))
1095 connected_dump_vty (vty, connected);
1096 }
1097
8da4e946 1098#if defined (HAVE_RTADV)
718e3744 1099 nd_dump_vty (vty, ifp);
8da4e946 1100#endif /* HAVE_RTADV */
a80beece
DS
1101 if (listhead(ifp->nbr_connected))
1102 vty_out (vty, " Neighbor address(s):%s", VTY_NEWLINE);
1103 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
1104 nbr_connected_dump_vty (vty, nbr_connected);
718e3744 1105
1106#ifdef HAVE_PROC_NET_DEV
1107 /* Statistics print out using proc file system. */
6f2c27af 1108 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
1109 "%lu dropped%s",
1110 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1111 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
718e3744 1112
6f2c27af 1113 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
3452d475 1114 " %lu CRC, %lu frame%s",
718e3744 1115 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1116 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
6f2c27af 1117 ifp->stats.rx_frame_errors, VTY_NEWLINE);
1118
1119 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
718e3744 1120 ifp->stats.rx_missed_errors, VTY_NEWLINE);
1121
6f2c27af 1122 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
718e3744 1123 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1124 ifp->stats.tx_dropped, VTY_NEWLINE);
1125
6f2c27af 1126 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
1127 " %lu fifo, %lu heartbeat%s",
718e3744 1128 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1129 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
6f2c27af 1130 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
718e3744 1131
6f2c27af 1132 vty_out (vty, " %lu window, %lu collisions%s",
1133 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
718e3744 1134#endif /* HAVE_PROC_NET_DEV */
1135
1136#ifdef HAVE_NET_RT_IFLIST
1137#if defined (__bsdi__) || defined (__NetBSD__)
1138 /* Statistics print out using sysctl (). */
24b46333
DL
1139 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
1140 " multicast packets %llu%s",
1141 (unsigned long long)ifp->stats.ifi_ipackets,
1142 (unsigned long long)ifp->stats.ifi_ibytes,
1143 (unsigned long long)ifp->stats.ifi_iqdrops,
1144 (unsigned long long)ifp->stats.ifi_imcasts,
1145 VTY_NEWLINE);
1146
1147 vty_out (vty, " input errors %llu%s",
1148 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
1149
1150 vty_out (vty, " output packets %llu, bytes %llu,"
1151 " multicast packets %llu%s",
1152 (unsigned long long)ifp->stats.ifi_opackets,
1153 (unsigned long long)ifp->stats.ifi_obytes,
1154 (unsigned long long)ifp->stats.ifi_omcasts,
1155 VTY_NEWLINE);
1156
1157 vty_out (vty, " output errors %llu%s",
1158 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
1159
1160 vty_out (vty, " collisions %llu%s",
1161 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
718e3744 1162#else
1163 /* Statistics print out using sysctl (). */
1164 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
1165 " multicast packets %lu%s",
1166 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1167 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1168 VTY_NEWLINE);
1169
1170 vty_out (vty, " input errors %lu%s",
1171 ifp->stats.ifi_ierrors, VTY_NEWLINE);
1172
1173 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
1174 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1175 ifp->stats.ifi_omcasts, VTY_NEWLINE);
1176
1177 vty_out (vty, " output errors %lu%s",
1178 ifp->stats.ifi_oerrors, VTY_NEWLINE);
1179
1180 vty_out (vty, " collisions %lu%s",
1181 ifp->stats.ifi_collisions, VTY_NEWLINE);
1182#endif /* __bsdi__ || __NetBSD__ */
1183#endif /* HAVE_NET_RT_IFLIST */
1184}
1185
718e3744 1186/* Wrapper hook point for zebra daemon so that ifindex can be set
1187 * DEFUN macro not used as extract.pl HAS to ignore this
1188 * See also interface_cmd in lib/if.c
1189 */
1190DEFUN_NOSH (zebra_interface,
1191 zebra_interface_cmd,
1192 "interface IFNAME",
1193 "Select an interface to configure\n"
1194 "Interface's name\n")
1195{
1196 int ret;
1197 struct interface * ifp;
1198
1199 /* Call lib interface() */
d2fc8896 1200 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
1201 return ret;
718e3744 1202
1203 ifp = vty->index;
1204
d2fc8896 1205 if (ifp->ifindex == IFINDEX_INTERNAL)
1206 /* Is this really necessary? Shouldn't status be initialized to 0
1207 in that case? */
1208 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
718e3744 1209
1210 return ret;
1211}
1212
cd2a8a42
FL
1213ALIAS (zebra_interface,
1214 zebra_interface_vrf_cmd,
1215 "interface IFNAME " VRF_CMD_STR,
1216 "Select an interface to configure\n"
1217 "Interface's name\n"
1218 VRF_CMD_HELP_STR)
1219
718e3744 1220struct cmd_node interface_node =
1221{
1222 INTERFACE_NODE,
1223 "%s(config-if)# ",
1224 1
1225};
1226
12f6fb97
DS
1227/* Wrapper hook point for zebra daemon so that ifindex can be set
1228 * DEFUN macro not used as extract.pl HAS to ignore this
1229 * See also interface_cmd in lib/if.c
1230 */
1231DEFUN_NOSH (zebra_vrf,
1232 zebra_vrf_cmd,
1233 "vrf NAME",
1234 "Select a VRF to configure\n"
1235 "VRF's name\n")
1236{
1237 int ret;
1238
1239 /* Call lib vrf() */
1240 if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
1241 return ret;
1242
1243 // vrfp = vty->index;
1244
1245 return ret;
1246}
1247
1248struct cmd_node vrf_node =
1249{
1250 VRF_NODE,
1251 "%s(config-vrf)# ",
1252 1
1253};
1254
8b87bdf4 1255/* Show all interfaces to vty. */
718e3744 1256DEFUN (show_interface, show_interface_cmd,
8b87bdf4
FL
1257 "show interface",
1258 SHOW_STR
1259 "Interface status and configuration\n")
1260{
1261 struct listnode *node;
1262 struct interface *ifp;
1263 vrf_id_t vrf_id = VRF_DEFAULT;
1264
1265#ifdef HAVE_PROC_NET_DEV
1266 /* If system has interface statistics via proc file system, update
1267 statistics. */
1268 ifstat_update_proc ();
1269#endif /* HAVE_PROC_NET_DEV */
1270#ifdef HAVE_NET_RT_IFLIST
1271 ifstat_update_sysctl ();
1272#endif /* HAVE_NET_RT_IFLIST */
1273
1274 if (argc > 0)
12f6fb97 1275 VRF_GET_ID (vrf_id, argv[0]);
8b87bdf4
FL
1276
1277 /* All interface print. */
1278 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1279 if_dump_vty (vty, ifp);
1280
1281 return CMD_SUCCESS;
1282}
1283
1284ALIAS (show_interface,
1285 show_interface_vrf_cmd,
1286 "show interface " VRF_CMD_STR,
718e3744 1287 SHOW_STR
1288 "Interface status and configuration\n"
8b87bdf4
FL
1289 VRF_CMD_HELP_STR)
1290
1291/* Show all interfaces to vty. */
1292DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
1293 "show interface " VRF_ALL_CMD_STR,
1294 SHOW_STR
1295 "Interface status and configuration\n"
1296 VRF_ALL_CMD_HELP_STR)
718e3744 1297{
52dc7ee6 1298 struct listnode *node;
718e3744 1299 struct interface *ifp;
8b87bdf4
FL
1300 vrf_iter_t iter;
1301
718e3744 1302#ifdef HAVE_PROC_NET_DEV
1303 /* If system has interface statistics via proc file system, update
1304 statistics. */
1305 ifstat_update_proc ();
1306#endif /* HAVE_PROC_NET_DEV */
1307#ifdef HAVE_NET_RT_IFLIST
1308 ifstat_update_sysctl ();
1309#endif /* HAVE_NET_RT_IFLIST */
1310
8b87bdf4
FL
1311 /* All interface print. */
1312 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1313 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1314 if_dump_vty (vty, ifp);
1315
1316 return CMD_SUCCESS;
1317}
1318
1319/* Show specified interface to vty. */
1721646e
DS
1320
1321DEFUN (show_interface_name_vrf,
1322 show_interface_name_vrf_cmd,
1323 "show interface IFNAME " VRF_CMD_STR,
8b87bdf4
FL
1324 SHOW_STR
1325 "Interface status and configuration\n"
1721646e
DS
1326 "Interface name\n"
1327 VRF_CMD_HELP_STR)
8b87bdf4
FL
1328{
1329 struct interface *ifp;
1330 vrf_id_t vrf_id = VRF_DEFAULT;
1331
1332#ifdef HAVE_PROC_NET_DEV
1333 /* If system has interface statistics via proc file system, update
1334 statistics. */
1335 ifstat_update_proc ();
1336#endif /* HAVE_PROC_NET_DEV */
1337#ifdef HAVE_NET_RT_IFLIST
1338 ifstat_update_sysctl ();
1339#endif /* HAVE_NET_RT_IFLIST */
1340
1341 if (argc > 1)
12f6fb97 1342 VRF_GET_ID (vrf_id, argv[1]);
8b87bdf4 1343
718e3744 1344 /* Specified interface print. */
8b87bdf4
FL
1345 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1346 if (ifp == NULL)
718e3744 1347 {
8b87bdf4
FL
1348 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1349 VTY_NEWLINE);
1350 return CMD_WARNING;
718e3744 1351 }
8b87bdf4 1352 if_dump_vty (vty, ifp);
718e3744 1353
1354 return CMD_SUCCESS;
1355}
1356
8b87bdf4
FL
1357/* Show specified interface to vty. */
1358DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1359 "show interface IFNAME " VRF_ALL_CMD_STR,
1360 SHOW_STR
1361 "Interface status and configuration\n"
1721646e 1362 "Interface name\n"
8b87bdf4
FL
1363 VRF_ALL_CMD_HELP_STR)
1364{
1365 struct interface *ifp;
1366 vrf_iter_t iter;
1367 int found = 0;
1368
1369#ifdef HAVE_PROC_NET_DEV
1370 /* If system has interface statistics via proc file system, update
1371 statistics. */
1372 ifstat_update_proc ();
1373#endif /* HAVE_PROC_NET_DEV */
1374#ifdef HAVE_NET_RT_IFLIST
1375 ifstat_update_sysctl ();
1376#endif /* HAVE_NET_RT_IFLIST */
1377
1378 /* All interface print. */
1379 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1380 {
1381 /* Specified interface print. */
1382 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1383 if (ifp)
1384 {
1385 if_dump_vty (vty, ifp);
1386 found++;
1387 }
1388 }
1389
1390 if (!found)
1391 {
1392 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1393 return CMD_WARNING;
1394 }
1395
1396 return CMD_SUCCESS;
1397}
1398
1721646e
DS
1399ALIAS (show_interface_name_vrf_all, show_interface_name_cmd,
1400 "show interface IFNAME",
1401 SHOW_STR
1402 "Interface status and configuration\n"
1403 "Interface name\n")
1404
8b87bdf4
FL
1405static void
1406if_show_description (struct vty *vty, vrf_id_t vrf_id)
ed9bb6d5 1407{
1408 struct listnode *node;
1409 struct interface *ifp;
1410
1411 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
8b87bdf4 1412 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
ed9bb6d5 1413 {
1414 int len;
ed9bb6d5 1415
1416 len = vty_out (vty, "%s", ifp->name);
1417 vty_out (vty, "%*s", (16 - len), " ");
1418
1419 if (if_is_up(ifp))
1420 {
1421 vty_out (vty, "up ");
1422 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1423 {
1424 if (if_is_running(ifp))
1425 vty_out (vty, "up ");
1426 else
1427 vty_out (vty, "down ");
1428 }
1429 else
1430 {
1431 vty_out (vty, "unknown ");
1432 }
1433 }
1434 else
1435 {
1436 vty_out (vty, "down down ");
1437 }
1438
1439 if (ifp->desc)
1440 vty_out (vty, "%s", ifp->desc);
1441 vty_out (vty, "%s", VTY_NEWLINE);
1442 }
8b87bdf4
FL
1443}
1444
1445DEFUN (show_interface_desc,
1446 show_interface_desc_cmd,
1447 "show interface description",
1448 SHOW_STR
1449 "Interface status and configuration\n"
1450 "Interface description\n")
1451{
1452 vrf_id_t vrf_id = VRF_DEFAULT;
1453
1454 if (argc > 0)
12f6fb97 1455 VRF_GET_ID (vrf_id, argv[0]);
8b87bdf4
FL
1456
1457 if_show_description (vty, vrf_id);
1458
1459 return CMD_SUCCESS;
1460}
1461
1462ALIAS (show_interface_desc,
1463 show_interface_desc_vrf_cmd,
1464 "show interface description " VRF_CMD_STR,
1465 SHOW_STR
1466 "Interface status and configuration\n"
1467 "Interface description\n"
1468 VRF_CMD_HELP_STR)
1469
1470DEFUN (show_interface_desc_vrf_all,
1471 show_interface_desc_vrf_all_cmd,
1472 "show interface description " VRF_ALL_CMD_STR,
1473 SHOW_STR
1474 "Interface status and configuration\n"
1475 "Interface description\n"
1476 VRF_ALL_CMD_HELP_STR)
1477{
1478 vrf_iter_t iter;
1479
1480 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1481 if (!list_isempty (vrf_iter2iflist (iter)))
1482 {
1483 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1484 vrf_iter2id (iter),
1485 VTY_NEWLINE, VTY_NEWLINE);
1486 if_show_description (vty, vrf_iter2id (iter));
1487 }
1488
ed9bb6d5 1489 return CMD_SUCCESS;
1490}
1491
718e3744 1492DEFUN (multicast,
1493 multicast_cmd,
1494 "multicast",
1495 "Set multicast flag to interface\n")
1496{
1497 int ret;
1498 struct interface *ifp;
1499 struct zebra_if *if_data;
1500
1501 ifp = (struct interface *) vty->index;
48b33aaf 1502 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1503 {
48b33aaf 1504 ret = if_set_flags (ifp, IFF_MULTICAST);
1505 if (ret < 0)
1506 {
1507 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1508 return CMD_WARNING;
1509 }
1510 if_refresh (ifp);
718e3744 1511 }
718e3744 1512 if_data = ifp->info;
1513 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1514
718e3744 1515 return CMD_SUCCESS;
1516}
1517
1518DEFUN (no_multicast,
1519 no_multicast_cmd,
1520 "no multicast",
1521 NO_STR
1522 "Unset multicast flag to interface\n")
1523{
1524 int ret;
1525 struct interface *ifp;
1526 struct zebra_if *if_data;
1527
1528 ifp = (struct interface *) vty->index;
48b33aaf 1529 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1530 {
48b33aaf 1531 ret = if_unset_flags (ifp, IFF_MULTICAST);
1532 if (ret < 0)
1533 {
1534 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1535 return CMD_WARNING;
1536 }
1537 if_refresh (ifp);
718e3744 1538 }
718e3744 1539 if_data = ifp->info;
1540 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1541
1542 return CMD_SUCCESS;
1543}
1544
2e3b2e47 1545DEFUN (linkdetect,
1546 linkdetect_cmd,
1547 "link-detect",
1548 "Enable link detection on interface\n")
1549{
2e3b2e47 1550 struct interface *ifp;
1551 int if_was_operative;
1552
1553 ifp = (struct interface *) vty->index;
244c1cdc 1554 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1555 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1556
1557 /* When linkdetection is enabled, if might come down */
244c1cdc 1558 if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp);
2e3b2e47 1559
1560 /* FIXME: Will defer status change forwarding if interface
1561 does not come down! */
1562
1563 return CMD_SUCCESS;
1564}
1565
1566
1567DEFUN (no_linkdetect,
1568 no_linkdetect_cmd,
1569 "no link-detect",
1570 NO_STR
1571 "Disable link detection on interface\n")
1572{
2e3b2e47 1573 struct interface *ifp;
1574 int if_was_operative;
1575
1576 ifp = (struct interface *) vty->index;
244c1cdc 1577 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1578 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1579
1580 /* Interface may come up after disabling link detection */
1581 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1582
1583 /* FIXME: see linkdetect_cmd */
1584
1585 return CMD_SUCCESS;
1586}
1587
718e3744 1588DEFUN (shutdown_if,
1589 shutdown_if_cmd,
1590 "shutdown",
1591 "Shutdown the selected interface\n")
1592{
1593 int ret;
1594 struct interface *ifp;
1595 struct zebra_if *if_data;
1596
1597 ifp = (struct interface *) vty->index;
bfac8dcd 1598 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1599 {
bfac8dcd
CF
1600 ret = if_unset_flags (ifp, IFF_UP);
1601 if (ret < 0)
1602 {
1603 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1604 return CMD_WARNING;
1605 }
1606 if_refresh (ifp);
718e3744 1607 }
718e3744 1608 if_data = ifp->info;
1609 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1610
1611 return CMD_SUCCESS;
1612}
1613
1614DEFUN (no_shutdown_if,
1615 no_shutdown_if_cmd,
1616 "no shutdown",
1617 NO_STR
1618 "Shutdown the selected interface\n")
1619{
1620 int ret;
1621 struct interface *ifp;
1622 struct zebra_if *if_data;
1623
1624 ifp = (struct interface *) vty->index;
bfac8dcd
CF
1625
1626 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1627 {
bfac8dcd
CF
1628 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1629 if (ret < 0)
1630 {
1631 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1632 return CMD_WARNING;
1633 }
1634 if_refresh (ifp);
1635
1636 /* Some addresses (in particular, IPv6 addresses on Linux) get
1637 * removed when the interface goes down. They need to be readded.
1638 */
1639 if_addr_wakeup(ifp);
718e3744 1640 }
bfac8dcd 1641
718e3744 1642 if_data = ifp->info;
1643 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1644
1645 return CMD_SUCCESS;
1646}
1647
1648DEFUN (bandwidth_if,
1649 bandwidth_if_cmd,
70bd3c43 1650 "bandwidth <1-100000>",
718e3744 1651 "Set bandwidth informational parameter\n"
70bd3c43 1652 "Bandwidth in megabits\n")
718e3744 1653{
1654 struct interface *ifp;
1655 unsigned int bandwidth;
1656
1657 ifp = (struct interface *) vty->index;
1658 bandwidth = strtol(argv[0], NULL, 10);
1659
70bd3c43
DS
1660 /* bandwidth range is <1-100000> */
1661 if (bandwidth < 1 || bandwidth > 100000)
718e3744 1662 {
1663 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1664 return CMD_WARNING;
1665 }
1666
1667 ifp->bandwidth = bandwidth;
1668
1669 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1670 if (if_is_operative (ifp))
718e3744 1671 zebra_interface_up_update (ifp);
1672
1673 return CMD_SUCCESS;
1674}
1675
1676DEFUN (no_bandwidth_if,
1677 no_bandwidth_if_cmd,
1678 "no bandwidth",
1679 NO_STR
1680 "Set bandwidth informational parameter\n")
1681{
1682 struct interface *ifp;
1683
1684 ifp = (struct interface *) vty->index;
1685
1686 ifp->bandwidth = 0;
1687
1688 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1689 if (if_is_operative (ifp))
718e3744 1690 zebra_interface_up_update (ifp);
1691
1692 return CMD_SUCCESS;
1693}
1694
1695ALIAS (no_bandwidth_if,
1696 no_bandwidth_if_val_cmd,
70bd3c43 1697 "no bandwidth <1-100000>",
718e3744 1698 NO_STR
1699 "Set bandwidth informational parameter\n"
70bd3c43 1700 "Bandwidth in megabits\n")
6b0655a2 1701
a1ac18c4 1702static int
39db97e4 1703ip_address_install (struct vty *vty, struct interface *ifp,
1704 const char *addr_str, const char *peer_str,
1705 const char *label)
718e3744 1706{
bfac8dcd 1707 struct zebra_if *if_data;
718e3744 1708 struct prefix_ipv4 cp;
1709 struct connected *ifc;
1710 struct prefix_ipv4 *p;
718e3744 1711 int ret;
1712
bfac8dcd
CF
1713 if_data = ifp->info;
1714
718e3744 1715 ret = str2prefix_ipv4 (addr_str, &cp);
1716 if (ret <= 0)
1717 {
1718 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1719 return CMD_WARNING;
1720 }
1721
d914d5ff
DS
1722 if (ipv4_martian(&cp.prefix))
1723 {
1724 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
1725 return CMD_WARNING;
1726 }
1727
ca16218d 1728 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1729 if (! ifc)
1730 {
1731 ifc = connected_new ();
1732 ifc->ifp = ifp;
1733
1734 /* Address. */
1735 p = prefix_ipv4_new ();
1736 *p = cp;
1737 ifc->address = (struct prefix *) p;
1738
1739 /* Broadcast. */
3fb9cd6e 1740 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
718e3744 1741 {
1742 p = prefix_ipv4_new ();
1743 *p = cp;
3fb9cd6e 1744 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
718e3744 1745 ifc->destination = (struct prefix *) p;
1746 }
1747
718e3744 1748 /* Label. */
1749 if (label)
0752ef0b 1750 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1751
1752 /* Add to linked list. */
1753 listnode_add (ifp->connected, ifc);
1754 }
1755
1756 /* This address is configured from zebra. */
1757 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1758 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1759
1760 /* In case of this route need to install kernel. */
f7f740fe 1761 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
1762 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1763 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 1764 {
1765 /* Some system need to up the interface to set IP address. */
1766 if (! if_is_up (ifp))
1767 {
1768 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1769 if_refresh (ifp);
1770 }
1771
1772 ret = if_set_prefix (ifp, ifc);
1773 if (ret < 0)
1774 {
1775 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1776 safe_strerror(errno), VTY_NEWLINE);
718e3744 1777 return CMD_WARNING;
1778 }
1779
f7f740fe 1780 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1781 /* The address will be advertised to zebra clients when the notification
1782 * from the kernel has been received.
1783 * It will also be added to the subnet chain list, then. */
718e3744 1784 }
1785
1786 return CMD_SUCCESS;
1787}
1788
a1ac18c4 1789static int
39db97e4 1790ip_address_uninstall (struct vty *vty, struct interface *ifp,
1791 const char *addr_str, const char *peer_str,
1792 const char *label)
718e3744 1793{
1794 struct prefix_ipv4 cp;
1795 struct connected *ifc;
1796 int ret;
1797
1798 /* Convert to prefix structure. */
1799 ret = str2prefix_ipv4 (addr_str, &cp);
1800 if (ret <= 0)
1801 {
1802 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1803 return CMD_WARNING;
1804 }
1805
1806 /* Check current interface address. */
ca16218d 1807 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1808 if (! ifc)
1809 {
1810 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1811 return CMD_WARNING;
1812 }
1813
1814 /* This is not configured address. */
1815 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1816 return CMD_WARNING;
1817
74ecdc9e
PJ
1818 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1819
718e3744 1820 /* This is not real address or interface is not active. */
f7f740fe 1821 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 1822 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1823 {
1824 listnode_delete (ifp->connected, ifc);
1825 connected_free (ifc);
1826 return CMD_WARNING;
1827 }
1828
1829 /* This is real route. */
1830 ret = if_unset_prefix (ifp, ifc);
1831 if (ret < 0)
1832 {
1833 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 1834 safe_strerror(errno), VTY_NEWLINE);
718e3744 1835 return CMD_WARNING;
1836 }
f7f740fe 1837 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1838 /* we will receive a kernel notification about this route being removed.
1839 * this will trigger its removal from the connected list. */
718e3744 1840 return CMD_SUCCESS;
1841}
1842
1843DEFUN (ip_address,
1844 ip_address_cmd,
1845 "ip address A.B.C.D/M",
1846 "Interface Internet Protocol config commands\n"
1847 "Set the IP address of an interface\n"
1848 "IP address (e.g. 10.0.0.1/8)\n")
1849{
eef1fe11 1850 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
718e3744 1851}
1852
1853DEFUN (no_ip_address,
1854 no_ip_address_cmd,
1855 "no ip address A.B.C.D/M",
1856 NO_STR
1857 "Interface Internet Protocol config commands\n"
1858 "Set the IP address of an interface\n"
1859 "IP Address (e.g. 10.0.0.1/8)")
1860{
eef1fe11 1861 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
718e3744 1862}
1863
986aa00f 1864
718e3744 1865#ifdef HAVE_NETLINK
718e3744 1866DEFUN (ip_address_label,
1867 ip_address_label_cmd,
1868 "ip address A.B.C.D/M label LINE",
1869 "Interface Internet Protocol config commands\n"
1870 "Set the IP address of an interface\n"
1871 "IP address (e.g. 10.0.0.1/8)\n"
1872 "Label of this address\n"
1873 "Label\n")
1874{
eef1fe11 1875 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1876}
1877
1878DEFUN (no_ip_address_label,
1879 no_ip_address_label_cmd,
1880 "no ip address A.B.C.D/M label LINE",
1881 NO_STR
1882 "Interface Internet Protocol config commands\n"
1883 "Set the IP address of an interface\n"
1884 "IP address (e.g. 10.0.0.1/8)\n"
1885 "Label of this address\n"
1886 "Label\n")
1887{
eef1fe11 1888 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1889}
1890#endif /* HAVE_NETLINK */
1891
1892#ifdef HAVE_IPV6
a1ac18c4 1893static int
39db97e4 1894ipv6_address_install (struct vty *vty, struct interface *ifp,
1895 const char *addr_str, const char *peer_str,
1896 const char *label, int secondary)
718e3744 1897{
bfac8dcd 1898 struct zebra_if *if_data;
718e3744 1899 struct prefix_ipv6 cp;
1900 struct connected *ifc;
1901 struct prefix_ipv6 *p;
1902 int ret;
1903
bfac8dcd
CF
1904 if_data = ifp->info;
1905
718e3744 1906 ret = str2prefix_ipv6 (addr_str, &cp);
1907 if (ret <= 0)
1908 {
1909 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1910 return CMD_WARNING;
1911 }
1912
d914d5ff
DS
1913 if (ipv6_martian(&cp.prefix))
1914 {
1915 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
1916 return CMD_WARNING;
1917 }
1918
ca16218d 1919 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1920 if (! ifc)
1921 {
1922 ifc = connected_new ();
1923 ifc->ifp = ifp;
1924
1925 /* Address. */
1926 p = prefix_ipv6_new ();
1927 *p = cp;
1928 ifc->address = (struct prefix *) p;
1929
1930 /* Secondary. */
1931 if (secondary)
1932 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1933
1934 /* Label. */
1935 if (label)
0752ef0b 1936 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1937
1938 /* Add to linked list. */
1939 listnode_add (ifp->connected, ifc);
1940 }
1941
1942 /* This address is configured from zebra. */
1943 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1944 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1945
1946 /* In case of this route need to install kernel. */
f7f740fe 1947 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
1948 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1949 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 1950 {
1951 /* Some system need to up the interface to set IP address. */
1952 if (! if_is_up (ifp))
1953 {
1954 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1955 if_refresh (ifp);
1956 }
1957
1958 ret = if_prefix_add_ipv6 (ifp, ifc);
1959
1960 if (ret < 0)
1961 {
1962 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1963 safe_strerror(errno), VTY_NEWLINE);
718e3744 1964 return CMD_WARNING;
1965 }
1966
f7f740fe 1967 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1968 /* The address will be advertised to zebra clients when the notification
1969 * from the kernel has been received. */
718e3744 1970 }
1971
1972 return CMD_SUCCESS;
1973}
1974
b6120505
DW
1975/* Return true if an ipv6 address is configured on ifp */
1976int
1977ipv6_address_configured (struct interface *ifp)
1978{
1979 struct connected *connected;
1980 struct listnode *node;
1981
1982 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
1983 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && (connected->address->family == AF_INET6))
1984 return 1;
1985
1986 return 0;
1987}
1988
a1ac18c4 1989static int
39db97e4 1990ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1991 const char *addr_str, const char *peer_str,
1992 const char *label, int secondry)
718e3744 1993{
1994 struct prefix_ipv6 cp;
1995 struct connected *ifc;
1996 int ret;
1997
1998 /* Convert to prefix structure. */
1999 ret = str2prefix_ipv6 (addr_str, &cp);
2000 if (ret <= 0)
2001 {
2002 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2003 return CMD_WARNING;
2004 }
2005
2006 /* Check current interface address. */
ca16218d 2007 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 2008 if (! ifc)
2009 {
2010 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2011 return CMD_WARNING;
2012 }
2013
2014 /* This is not configured address. */
2015 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2016 return CMD_WARNING;
2017
676e1a01
CF
2018 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2019
718e3744 2020 /* This is not real address or interface is not active. */
f7f740fe 2021 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 2022 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2023 {
2024 listnode_delete (ifp->connected, ifc);
2025 connected_free (ifc);
2026 return CMD_WARNING;
2027 }
2028
2029 /* This is real route. */
2030 ret = if_prefix_delete_ipv6 (ifp, ifc);
2031 if (ret < 0)
2032 {
2033 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 2034 safe_strerror(errno), VTY_NEWLINE);
718e3744 2035 return CMD_WARNING;
2036 }
2037
f7f740fe 2038 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
2039 /* This information will be propagated to the zclients when the
2040 * kernel notification is received. */
718e3744 2041 return CMD_SUCCESS;
2042}
2043
2044DEFUN (ipv6_address,
2045 ipv6_address_cmd,
2046 "ipv6 address X:X::X:X/M",
e23949c0 2047 "Interface IPv6 config commands\n"
718e3744 2048 "Set the IP address of an interface\n"
2049 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2050{
2051 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
2052}
2053
2054DEFUN (no_ipv6_address,
2055 no_ipv6_address_cmd,
2056 "no ipv6 address X:X::X:X/M",
2057 NO_STR
e23949c0 2058 "Interface IPv6 config commands\n"
718e3744 2059 "Set the IP address of an interface\n"
2060 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2061{
2062 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
2063}
2064#endif /* HAVE_IPV6 */
2065
a1ac18c4 2066static int
718e3744 2067if_config_write (struct vty *vty)
2068{
52dc7ee6 2069 struct listnode *node;
718e3744 2070 struct interface *ifp;
cd2a8a42 2071 vrf_iter_t iter;
718e3744 2072
244c1cdc
DS
2073 zebra_ptm_write (vty);
2074
cd2a8a42
FL
2075 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2076 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
718e3744 2077 {
2078 struct zebra_if *if_data;
52dc7ee6 2079 struct listnode *addrnode;
718e3744 2080 struct connected *ifc;
2081 struct prefix *p;
12f6fb97 2082 struct vrf *vrf;
718e3744 2083
718e3744 2084 if_data = ifp->info;
12f6fb97 2085 vrf = vrf_lookup(ifp->vrf_id);
cd2a8a42
FL
2086
2087 if (ifp->vrf_id == VRF_DEFAULT)
2088 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2089 else
12f6fb97 2090 vty_out (vty, "interface %s vrf %s%s", ifp->name, vrf->name,
cd2a8a42 2091 VTY_NEWLINE);
718e3744 2092
bfac8dcd
CF
2093 if (if_data)
2094 {
2095 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2096 vty_out (vty, " shutdown%s", VTY_NEWLINE);
986aa00f 2097
2098 zebra_ptm_if_write(vty, if_data);
bfac8dcd
CF
2099 }
2100
718e3744 2101 if (ifp->desc)
2102 vty_out (vty, " description %s%s", ifp->desc,
2103 VTY_NEWLINE);
2104
2105 /* Assign bandwidth here to avoid unnecessary interface flap
2106 while processing config script */
2107 if (ifp->bandwidth != 0)
2108 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
2109
2e3b2e47 2110 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
2111 vty_out(vty, " link-detect%s", VTY_NEWLINE);
b71cd0fc
DL
2112 else
2113 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2e3b2e47 2114
1eb8ef25 2115 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
718e3744 2116 {
718e3744 2117 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2118 {
81cce018 2119 char buf[INET6_ADDRSTRLEN];
718e3744 2120 p = ifc->address;
35d921cc 2121 vty_out (vty, " ip%s address %s",
718e3744 2122 p->family == AF_INET ? "" : "v6",
35d921cc 2123 prefix2str (p, buf, sizeof(buf)));
718e3744 2124
718e3744 2125 if (ifc->label)
2126 vty_out (vty, " label %s", ifc->label);
2127
2128 vty_out (vty, "%s", VTY_NEWLINE);
2129 }
2130 }
2131
2132 if (if_data)
2133 {
718e3744 2134 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2135 vty_out (vty, " %smulticast%s",
2136 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2137 VTY_NEWLINE);
2138 }
2139
8da4e946 2140#if defined (HAVE_RTADV)
718e3744 2141 rtadv_config_write (vty, ifp);
8da4e946 2142#endif /* HAVE_RTADV */
718e3744 2143
ca776988 2144#ifdef HAVE_IRDP
2145 irdp_config_write (vty, ifp);
2146#endif /* IRDP */
2147
718e3744 2148 vty_out (vty, "!%s", VTY_NEWLINE);
2149 }
2150 return 0;
2151}
2152
12f6fb97
DS
2153static int
2154vrf_config_write (struct vty *vty)
2155{
2156 struct listnode *node;
c1c747a8 2157 struct zebra_vrf *zvrf;
12f6fb97 2158
c1c747a8 2159 for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
12f6fb97 2160 {
c1c747a8 2161 if (strcmp(zvrf->name, VRF_DEFAULT_NAME))
12f6fb97 2162 {
c1c747a8 2163 vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE);
12f6fb97
DS
2164 vty_out (vty, "!%s", VTY_NEWLINE);
2165 }
2166 }
2167 return 0;
2168}
2169
718e3744 2170/* Allocate and initialize interface vector. */
2171void
a1ac18c4 2172zebra_if_init (void)
718e3744 2173{
2174 /* Initialize interface and new hook. */
718e3744 2175 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2176 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2177
2178 /* Install configuration write function. */
2179 install_node (&interface_node, if_config_write);
12f6fb97 2180 install_node (&vrf_node, vrf_config_write);
718e3744 2181
2182 install_element (VIEW_NODE, &show_interface_cmd);
8b87bdf4
FL
2183 install_element (VIEW_NODE, &show_interface_vrf_cmd);
2184 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
2185 install_element (VIEW_NODE, &show_interface_name_cmd);
2186 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2187 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
718e3744 2188 install_element (ENABLE_NODE, &show_interface_cmd);
8b87bdf4
FL
2189 install_element (ENABLE_NODE, &show_interface_vrf_cmd);
2190 install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
2191 install_element (ENABLE_NODE, &show_interface_name_cmd);
2192 install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
2193 install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
ed9bb6d5 2194 install_element (ENABLE_NODE, &show_interface_desc_cmd);
8b87bdf4
FL
2195 install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
2196 install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
718e3744 2197 install_element (CONFIG_NODE, &zebra_interface_cmd);
cd2a8a42 2198 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
bfc13532 2199 install_element (CONFIG_NODE, &no_interface_cmd);
cd2a8a42 2200 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
718e3744 2201 install_default (INTERFACE_NODE);
2202 install_element (INTERFACE_NODE, &interface_desc_cmd);
2203 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2204 install_element (INTERFACE_NODE, &multicast_cmd);
2205 install_element (INTERFACE_NODE, &no_multicast_cmd);
2e3b2e47 2206 install_element (INTERFACE_NODE, &linkdetect_cmd);
2207 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
718e3744 2208 install_element (INTERFACE_NODE, &shutdown_if_cmd);
2209 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2210 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2211 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
2212 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
2213 install_element (INTERFACE_NODE, &ip_address_cmd);
2214 install_element (INTERFACE_NODE, &no_ip_address_cmd);
2215#ifdef HAVE_IPV6
2216 install_element (INTERFACE_NODE, &ipv6_address_cmd);
2217 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
2218#endif /* HAVE_IPV6 */
718e3744 2219#ifdef HAVE_NETLINK
718e3744 2220 install_element (INTERFACE_NODE, &ip_address_label_cmd);
718e3744 2221 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
2222#endif /* HAVE_NETLINK */
12f6fb97
DS
2223
2224 install_element (CONFIG_NODE, &zebra_vrf_cmd);
2225 install_element (CONFIG_NODE, &no_vrf_cmd);
2226 install_default (VRF_NODE);
2227
718e3744 2228}