]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
[zebra] Retain configured IPv4 address upon removal by kernel
[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"
35
36#include "zebra/interface.h"
37#include "zebra/rtadv.h"
38#include "zebra/rib.h"
39#include "zebra/zserv.h"
40#include "zebra/redistribute.h"
41#include "zebra/debug.h"
ca776988 42#include "zebra/irdp.h"
718e3744 43
718e3744 44
45/* Called when new interface is added. */
a1ac18c4 46static int
718e3744 47if_zebra_new_hook (struct interface *ifp)
48{
49 struct zebra_if *zebra_if;
50
51 zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
52 memset (zebra_if, 0, sizeof (struct zebra_if));
53
54 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
55 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
56
57#ifdef RTADV
58 {
59 /* Set default router advertise values. */
60 struct rtadvconf *rtadv;
61
62 rtadv = &zebra_if->rtadv;
63
64 rtadv->AdvSendAdvertisements = 0;
65 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
66 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
67 rtadv->AdvIntervalTimer = 0;
68 rtadv->AdvManagedFlag = 0;
69 rtadv->AdvOtherConfigFlag = 0;
7cee1bb1 70 rtadv->AdvHomeAgentFlag = 0;
718e3744 71 rtadv->AdvLinkMTU = 0;
72 rtadv->AdvReachableTime = 0;
73 rtadv->AdvRetransTimer = 0;
74 rtadv->AdvCurHopLimit = 0;
75 rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
7cee1bb1 76 rtadv->HomeAgentPreference = 0;
77 rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
78 rtadv->AdvIntervalOption = 0;
718e3744 79
80 rtadv->AdvPrefixList = list_new ();
81 }
82#endif /* RTADV */
83
eef1fe11 84 /* Initialize installed address chains tree. */
85 zebra_if->ipv4_subnets = route_table_init ();
86
718e3744 87 ifp->info = zebra_if;
88 return 0;
89}
90
91/* Called when interface is deleted. */
a1ac18c4 92static int
718e3744 93if_zebra_delete_hook (struct interface *ifp)
94{
eef1fe11 95 struct zebra_if *zebra_if;
96
718e3744 97 if (ifp->info)
eef1fe11 98 {
99 zebra_if = ifp->info;
100
101 /* Free installed address chains tree. */
102 if (zebra_if->ipv4_subnets)
103 route_table_finish (zebra_if->ipv4_subnets);
104
105 XFREE (MTYPE_TMP, zebra_if);
106 }
107
108 return 0;
109}
110
111/* Tie an interface address to its derived subnet list of addresses. */
112int
113if_subnet_add (struct interface *ifp, struct connected *ifc)
114{
115 struct route_node *rn;
116 struct zebra_if *zebra_if;
117 struct prefix cp;
118 struct list *addr_list;
119
120 assert (ifp && ifp->info && ifc);
121 zebra_if = ifp->info;
122
123 /* Get address derived subnet node and associated address list, while marking
124 address secondary attribute appropriately. */
125 cp = *ifc->address;
126 apply_mask (&cp);
127 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
128
129 if ((addr_list = rn->info))
130 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
131 else
132 {
133 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
134 rn->info = addr_list = list_new ();
135 route_lock_node (rn);
136 }
137
138 /* Tie address at the tail of address list. */
139 listnode_add (addr_list, ifc);
140
141 /* Return list element count. */
142 return (addr_list->count);
143}
144
145/* Untie an interface address from its derived subnet list of addresses. */
146int
147if_subnet_delete (struct interface *ifp, struct connected *ifc)
148{
149 struct route_node *rn;
150 struct zebra_if *zebra_if;
151 struct list *addr_list;
152
153 assert (ifp && ifp->info && ifc);
154 zebra_if = ifp->info;
155
156 /* Get address derived subnet node. */
157 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
158 if (! (rn && rn->info))
159 return -1;
160 route_unlock_node (rn);
161
162 /* Untie address from subnet's address list. */
163 addr_list = rn->info;
164 listnode_delete (addr_list, ifc);
165 route_unlock_node (rn);
166
167 /* Return list element count, if not empty. */
168 if (addr_list->count)
169 {
170 /* If deleted address is primary, mark subsequent one as such and distribute. */
171 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
172 {
1eb8ef25 173 ifc = listgetdata (listhead (addr_list));
eef1fe11 174 zebra_interface_address_delete_update (ifp, ifc);
175 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
176 zebra_interface_address_add_update (ifp, ifc);
177 }
178
179 return addr_list->count;
180 }
181
182 /* Otherwise, free list and route node. */
183 list_free (addr_list);
184 rn->info = NULL;
185 route_unlock_node (rn);
186
718e3744 187 return 0;
188}
189
5c78b3d0 190/* if_flags_mangle: A place for hacks that require mangling
191 * or tweaking the interface flags.
192 *
193 * ******************** Solaris flags hacks **************************
194 *
195 * Solaris IFF_UP flag reflects only the primary interface as the
196 * routing socket only sends IFINFO for the primary interface. Hence
197 * ~IFF_UP does not per se imply all the logical interfaces are also
198 * down - which we only know of as addresses. Instead we must determine
199 * whether the interface really is up or not according to how many
200 * addresses are still attached. (Solaris always sends RTM_DELADDR if
201 * an interface, logical or not, goes ~IFF_UP).
202 *
203 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
204 * are addresses left in struct connected, not just the actual underlying
205 * IFF_UP flag.
206 *
207 * We must hence remember the real state of IFF_UP, which we do in
208 * struct zebra_if.primary_state.
209 *
210 * Setting IFF_UP within zebra to administratively shutdown the
211 * interface will affect only the primary interface/address on Solaris.
212 ************************End Solaris flags hacks ***********************
213 */
214static inline void
215if_flags_mangle (struct interface *ifp, uint64_t *newflags)
216{
217#ifdef SUNOS_5
218 struct zebra_if *zif = ifp->info;
219
220 zif->primary_state = *newflags & (IFF_UP & 0xff);
221
222 if (CHECK_FLAG (zif->primary_state, IFF_UP)
223 || listcount(ifp->connected) > 0)
224 SET_FLAG (*newflags, IFF_UP);
225 else
226 UNSET_FLAG (*newflags, IFF_UP);
227#endif /* SUNOS_5 */
228}
229
230/* Update the flags field of the ifp with the new flag set provided.
231 * Take whatever actions are required for any changes in flags we care
232 * about.
233 *
234 * newflags should be the raw value, as obtained from the OS.
235 */
236void
237if_flags_update (struct interface *ifp, uint64_t newflags)
238{
239 if_flags_mangle (ifp, &newflags);
240
241 if (if_is_operative (ifp))
242 {
243 /* operative -> inoperative? */
244 ifp->flags = newflags;
245 if (!if_is_operative (ifp))
246 if_down (ifp);
247 }
248 else
249 {
250 /* inoperative -> operative? */
251 ifp->flags = newflags;
252 if (if_is_operative (ifp))
253 if_up (ifp);
254 }
255}
256
718e3744 257/* Wake up configured address if it is not in current kernel
258 address. */
a1ac18c4 259static void
718e3744 260if_addr_wakeup (struct interface *ifp)
261{
1eb8ef25 262 struct listnode *node, *nnode;
718e3744 263 struct connected *ifc;
264 struct prefix *p;
265 int ret;
266
1eb8ef25 267 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
718e3744 268 {
718e3744 269 p = ifc->address;
270
271 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
272 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
273 {
274 /* Address check. */
275 if (p->family == AF_INET)
276 {
277 if (! if_is_up (ifp))
278 {
0752ef0b 279 /* XXX: WTF is it trying to set flags here?
280 * caller has just gotten a new interface, has been
281 * handed the flags already. This code has no business
282 * trying to override administrative status of the interface.
283 * The only call path to here which doesn't originate from
284 * kernel event is irdp - what on earth is it trying to do?
285 *
286 * further RUNNING is not a settable flag on any system
287 * I (paulj) am aware of.
288 */
718e3744 289 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
290 if_refresh (ifp);
291 }
292
293 ret = if_set_prefix (ifp, ifc);
294 if (ret < 0)
295 {
296 zlog_warn ("Can't set interface's address: %s",
6099b3b5 297 safe_strerror(errno));
718e3744 298 continue;
299 }
eef1fe11 300
301 /* Add to subnet chain list. */
302 if_subnet_add (ifp, ifc);
303
718e3744 304 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
305
306 zebra_interface_address_add_update (ifp, ifc);
307
2e3b2e47 308 if (if_is_operative(ifp))
718e3744 309 connected_up_ipv4 (ifp, ifc);
310 }
311#ifdef HAVE_IPV6
312 if (p->family == AF_INET6)
313 {
314 if (! if_is_up (ifp))
315 {
0752ef0b 316 /* XXX: See long comment above */
718e3744 317 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
318 if_refresh (ifp);
319 }
320
321 ret = if_prefix_add_ipv6 (ifp, ifc);
322 if (ret < 0)
323 {
324 zlog_warn ("Can't set interface's address: %s",
6099b3b5 325 safe_strerror(errno));
718e3744 326 continue;
327 }
328 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
329
330 zebra_interface_address_add_update (ifp, ifc);
331
2e3b2e47 332 if (if_is_operative(ifp))
718e3744 333 connected_up_ipv6 (ifp, ifc);
334 }
335#endif /* HAVE_IPV6 */
336 }
337 }
338}
339
340/* Handle interface addition */
341void
342if_add_update (struct interface *ifp)
343{
48b33aaf 344 struct zebra_if *if_data;
345
346 if_data = ifp->info;
347 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
348 if_set_flags (ifp, IFF_MULTICAST);
349 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
350 if_unset_flags (ifp, IFF_MULTICAST);
351
718e3744 352 zebra_interface_add_update (ifp);
353
354 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
355 {
356 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
357
358 if_addr_wakeup (ifp);
359
360 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 361 zlog_debug ("interface %s index %d becomes active.",
362 ifp->name, ifp->ifindex);
718e3744 363 }
364 else
365 {
366 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 367 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
718e3744 368 }
369}
370
6eb8827d 371/* Handle an interface delete event */
718e3744 372void
373if_delete_update (struct interface *ifp)
374{
718e3744 375 struct connected *ifc;
376 struct prefix *p;
eef1fe11 377 struct route_node *rn;
378 struct zebra_if *zebra_if;
eef1fe11 379
380 zebra_if = ifp->info;
718e3744 381
382 if (if_is_up(ifp))
383 {
384 zlog_err ("interface %s index %d is still up while being deleted.",
385 ifp->name, ifp->ifindex);
386 return;
387 }
388
389 /* Mark interface as inactive */
390 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
391
392 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 393 zlog_debug ("interface %s index %d is now inactive.",
718e3744 394 ifp->name, ifp->ifindex);
395
396 /* Delete connected routes from the kernel. */
397 if (ifp->connected)
398 {
d9a18f11
PJ
399 struct listnode *node;
400 struct listnode *last = NULL;
401
eef1fe11 402 while ((node = (last ? last->next : listhead (ifp->connected))))
718e3744 403 {
1eb8ef25 404 ifc = listgetdata (node);
718e3744 405 p = ifc->address;
eef1fe11 406
beb56336
PJ
407 if (p->family == AF_INET
408 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
eef1fe11 409 {
d9a18f11
PJ
410 struct listnode *anode;
411 struct listnode *next;
412 struct listnode *first;
413 struct list *addr_list;
414
eef1fe11 415 route_unlock_node (rn);
416 addr_list = (struct list *) rn->info;
417
418 /* Remove addresses, secondaries first. */
419 first = listhead (addr_list);
d9a18f11 420 for (anode = first->next; anode || first; anode = next)
eef1fe11 421 {
d9a18f11 422 if (!anode)
eef1fe11 423 {
d9a18f11 424 anode = first;
eef1fe11 425 first = NULL;
426 }
d9a18f11 427 next = anode->next;
eef1fe11 428
d9a18f11 429 ifc = listgetdata (anode);
eef1fe11 430 p = ifc->address;
431
432 connected_down_ipv4 (ifp, ifc);
433
434 zebra_interface_address_delete_update (ifp, ifc);
435
436 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
437
438 /* Remove from subnet chain. */
d9a18f11 439 list_delete_node (addr_list, anode);
eef1fe11 440 route_unlock_node (rn);
441
442 /* Remove from interface address list (unconditionally). */
d9a18f11
PJ
443 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
444 {
445 listnode_delete (ifp->connected, ifc);
446 connected_free (ifc);
447 }
448 else
449 last = node;
eef1fe11 450 }
451
452 /* Free chain list and respective route node. */
453 list_delete (addr_list);
454 rn->info = NULL;
455 route_unlock_node (rn);
456 }
718e3744 457#ifdef HAVE_IPV6
458 else if (p->family == AF_INET6)
eef1fe11 459 {
460 connected_down_ipv6 (ifp, ifc);
718e3744 461
eef1fe11 462 zebra_interface_address_delete_update (ifp, ifc);
718e3744 463
eef1fe11 464 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
465
466 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
467 last = node;
468 else
469 {
470 listnode_delete (ifp->connected, ifc);
471 connected_free (ifc);
472 }
718e3744 473 }
eef1fe11 474#endif /* HAVE_IPV6 */
718e3744 475 }
476 }
477 zebra_interface_delete_update (ifp);
d2fc8896 478
479 /* Update ifindex after distributing the delete message. This is in
480 case any client needs to have the old value of ifindex available
481 while processing the deletion. Each client daemon is responsible
482 for setting ifindex to IFINDEX_INTERNAL after processing the
483 interface deletion message. */
484 ifp->ifindex = IFINDEX_INTERNAL;
718e3744 485}
486
487/* Interface is up. */
488void
489if_up (struct interface *ifp)
490{
52dc7ee6 491 struct listnode *node;
492 struct listnode *next;
718e3744 493 struct connected *ifc;
494 struct prefix *p;
495
496 /* Notify the protocol daemons. */
497 zebra_interface_up_update (ifp);
498
499 /* Install connected routes to the kernel. */
500 if (ifp->connected)
501 {
1eb8ef25 502 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
718e3744 503 {
718e3744 504 p = ifc->address;
505
506 if (p->family == AF_INET)
507 connected_up_ipv4 (ifp, ifc);
508#ifdef HAVE_IPV6
509 else if (p->family == AF_INET6)
510 connected_up_ipv6 (ifp, ifc);
511#endif /* HAVE_IPV6 */
512 }
513 }
514
515 /* Examine all static routes. */
516 rib_update ();
517}
518
519/* Interface goes down. We have to manage different behavior of based
520 OS. */
521void
522if_down (struct interface *ifp)
523{
52dc7ee6 524 struct listnode *node;
525 struct listnode *next;
718e3744 526 struct connected *ifc;
527 struct prefix *p;
528
529 /* Notify to the protocol daemons. */
530 zebra_interface_down_update (ifp);
531
532 /* Delete connected routes from the kernel. */
533 if (ifp->connected)
534 {
1eb8ef25 535 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
718e3744 536 {
718e3744 537 p = ifc->address;
538
539 if (p->family == AF_INET)
540 connected_down_ipv4 (ifp, ifc);
541#ifdef HAVE_IPV6
542 else if (p->family == AF_INET6)
543 connected_down_ipv6 (ifp, ifc);
544#endif /* HAVE_IPV6 */
545 }
546 }
547
548 /* Examine all static routes which direct to the interface. */
549 rib_update ();
550}
551
552void
553if_refresh (struct interface *ifp)
554{
5c78b3d0 555 if_get_flags (ifp);
718e3744 556}
557
718e3744 558/* Output prefix string to vty. */
a1ac18c4 559static int
718e3744 560prefix_vty_out (struct vty *vty, struct prefix *p)
561{
562 char str[INET6_ADDRSTRLEN];
563
564 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
565 vty_out (vty, "%s", str);
566 return strlen (str);
567}
568
569/* Dump if address information to vty. */
a1ac18c4 570static void
718e3744 571connected_dump_vty (struct vty *vty, struct connected *connected)
572{
573 struct prefix *p;
718e3744 574
575 /* Print interface address. */
576 p = connected->address;
577 vty_out (vty, " %s ", prefix_family_str (p));
578 prefix_vty_out (vty, p);
579 vty_out (vty, "/%d", p->prefixlen);
580
581 /* If there is destination address, print it. */
e4529636 582 if (connected->destination)
718e3744 583 {
e4529636
AS
584 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
585 prefix_vty_out (vty, connected->destination);
718e3744 586 }
587
588 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
589 vty_out (vty, " secondary");
590
591 if (connected->label)
592 vty_out (vty, " %s", connected->label);
593
594 vty_out (vty, "%s", VTY_NEWLINE);
595}
596
597#ifdef RTADV
598/* Dump interface ND information to vty. */
a1ac18c4 599static void
718e3744 600nd_dump_vty (struct vty *vty, struct interface *ifp)
601{
602 struct zebra_if *zif;
603 struct rtadvconf *rtadv;
7cee1bb1 604 int interval;
718e3744 605
606 zif = (struct zebra_if *) ifp->info;
607 rtadv = &zif->rtadv;
608
609 if (rtadv->AdvSendAdvertisements)
610 {
611 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
612 rtadv->AdvReachableTime, VTY_NEWLINE);
613 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
614 rtadv->AdvRetransTimer, VTY_NEWLINE);
7cee1bb1 615 interval = rtadv->MaxRtrAdvInterval;
616 if (interval % 1000)
617 vty_out (vty, " ND router advertisements are sent every "
618 "%d milliseconds%s", interval,
619 VTY_NEWLINE);
620 else
621 vty_out (vty, " ND router advertisements are sent every "
622 "%d seconds%s", interval / 1000,
623 VTY_NEWLINE);
718e3744 624 vty_out (vty, " ND router advertisements live for %d seconds%s",
625 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
626 if (rtadv->AdvManagedFlag)
627 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
628 VTY_NEWLINE);
629 else
630 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
631 VTY_NEWLINE);
7cee1bb1 632 if (rtadv->AdvHomeAgentFlag)
633 vty_out (vty, " ND router advertisements with "
634 "Home Agent flag bit set.%s",
635 VTY_NEWLINE);
636 if (rtadv->AdvIntervalOption)
637 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
638 VTY_NEWLINE);
718e3744 639 }
640}
641#endif /* RTADV */
642
643/* Interface's information print out to vty interface. */
a1ac18c4 644static void
718e3744 645if_dump_vty (struct vty *vty, struct interface *ifp)
646{
647#ifdef HAVE_SOCKADDR_DL
648 struct sockaddr_dl *sdl;
649#endif /* HAVE_SOCKADDR_DL */
650 struct connected *connected;
52dc7ee6 651 struct listnode *node;
eef1fe11 652 struct route_node *rn;
653 struct zebra_if *zebra_if;
654
655 zebra_if = ifp->info;
718e3744 656
2e3b2e47 657 vty_out (vty, "Interface %s is ", ifp->name);
658 if (if_is_up(ifp)) {
659 vty_out (vty, "up, line protocol ");
660
661 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
662 if (if_is_running(ifp))
663 vty_out (vty, "is up%s", VTY_NEWLINE);
664 else
665 vty_out (vty, "is down%s", VTY_NEWLINE);
666 } else {
667 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
668 }
669 } else {
670 vty_out (vty, "down%s", VTY_NEWLINE);
671 }
672
718e3744 673 if (ifp->desc)
674 vty_out (vty, " Description: %s%s", ifp->desc,
675 VTY_NEWLINE);
d2fc8896 676 if (ifp->ifindex == IFINDEX_INTERNAL)
718e3744 677 {
d2fc8896 678 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
718e3744 679 return;
680 }
681 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
682 {
683 vty_out(vty, " index %d inactive interface%s",
684 ifp->ifindex,
685 VTY_NEWLINE);
686 return;
687 }
688
689 vty_out (vty, " index %d metric %d mtu %d ",
690 ifp->ifindex, ifp->metric, ifp->mtu);
44145db3 691#ifdef HAVE_IPV6
692 if (ifp->mtu6 != ifp->mtu)
693 vty_out (vty, "mtu6 %d ", ifp->mtu6);
694#endif
630c97ce
PJ
695 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
696 if_flag_dump (ifp->flags), VTY_NEWLINE);
3a570c8b 697
718e3744 698 /* Hardware address. */
699#ifdef HAVE_SOCKADDR_DL
700 sdl = &ifp->sdl;
701 if (sdl != NULL && sdl->sdl_alen != 0)
702 {
703 int i;
704 u_char *ptr;
705
706 vty_out (vty, " HWaddr: ");
5b73a671 707 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
708 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
718e3744 709 vty_out (vty, "%s", VTY_NEWLINE);
710 }
711#else
712 if (ifp->hw_addr_len != 0)
713 {
714 int i;
715
716 vty_out (vty, " HWaddr: ");
717 for (i = 0; i < ifp->hw_addr_len; i++)
718 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
719 vty_out (vty, "%s", VTY_NEWLINE);
720 }
721#endif /* HAVE_SOCKADDR_DL */
722
723 /* Bandwidth in kbps */
724 if (ifp->bandwidth != 0)
725 {
726 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
727 vty_out(vty, "%s", VTY_NEWLINE);
728 }
729
eef1fe11 730 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
718e3744 731 {
eef1fe11 732 if (! rn->info)
733 continue;
734
1eb8ef25 735 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
736 connected_dump_vty (vty, connected);
718e3744 737 }
738
1eb8ef25 739 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
39db97e4 740 {
39db97e4 741 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
742 (connected->address->family == AF_INET6))
743 connected_dump_vty (vty, connected);
744 }
745
718e3744 746#ifdef RTADV
747 nd_dump_vty (vty, ifp);
748#endif /* RTADV */
749
750#ifdef HAVE_PROC_NET_DEV
751 /* Statistics print out using proc file system. */
6f2c27af 752 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
753 "%lu dropped%s",
754 ifp->stats.rx_packets, ifp->stats.rx_multicast,
755 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
718e3744 756
6f2c27af 757 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
3452d475 758 " %lu CRC, %lu frame%s",
718e3744 759 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
760 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
6f2c27af 761 ifp->stats.rx_frame_errors, VTY_NEWLINE);
762
763 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
718e3744 764 ifp->stats.rx_missed_errors, VTY_NEWLINE);
765
6f2c27af 766 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
718e3744 767 ifp->stats.tx_packets, ifp->stats.tx_bytes,
768 ifp->stats.tx_dropped, VTY_NEWLINE);
769
6f2c27af 770 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
771 " %lu fifo, %lu heartbeat%s",
718e3744 772 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
773 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
6f2c27af 774 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
718e3744 775
6f2c27af 776 vty_out (vty, " %lu window, %lu collisions%s",
777 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
718e3744 778#endif /* HAVE_PROC_NET_DEV */
779
780#ifdef HAVE_NET_RT_IFLIST
781#if defined (__bsdi__) || defined (__NetBSD__)
782 /* Statistics print out using sysctl (). */
783 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
784 " multicast packets %qu%s",
785 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
786 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
787 VTY_NEWLINE);
788
789 vty_out (vty, " input errors %qu%s",
790 ifp->stats.ifi_ierrors, VTY_NEWLINE);
791
792 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
793 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
794 ifp->stats.ifi_omcasts, VTY_NEWLINE);
795
796 vty_out (vty, " output errors %qu%s",
797 ifp->stats.ifi_oerrors, VTY_NEWLINE);
798
799 vty_out (vty, " collisions %qu%s",
800 ifp->stats.ifi_collisions, VTY_NEWLINE);
801#else
802 /* Statistics print out using sysctl (). */
803 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
804 " multicast packets %lu%s",
805 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
806 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
807 VTY_NEWLINE);
808
809 vty_out (vty, " input errors %lu%s",
810 ifp->stats.ifi_ierrors, VTY_NEWLINE);
811
812 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
813 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
814 ifp->stats.ifi_omcasts, VTY_NEWLINE);
815
816 vty_out (vty, " output errors %lu%s",
817 ifp->stats.ifi_oerrors, VTY_NEWLINE);
818
819 vty_out (vty, " collisions %lu%s",
820 ifp->stats.ifi_collisions, VTY_NEWLINE);
821#endif /* __bsdi__ || __NetBSD__ */
822#endif /* HAVE_NET_RT_IFLIST */
823}
824
825/* Check supported address family. */
a1ac18c4 826static int
718e3744 827if_supported_family (int family)
828{
829 if (family == AF_INET)
830 return 1;
831#ifdef HAVE_IPV6
832 if (family == AF_INET6)
833 return 1;
834#endif /* HAVE_IPV6 */
835 return 0;
836}
837
838/* Wrapper hook point for zebra daemon so that ifindex can be set
839 * DEFUN macro not used as extract.pl HAS to ignore this
840 * See also interface_cmd in lib/if.c
841 */
842DEFUN_NOSH (zebra_interface,
843 zebra_interface_cmd,
844 "interface IFNAME",
845 "Select an interface to configure\n"
846 "Interface's name\n")
847{
848 int ret;
849 struct interface * ifp;
850
851 /* Call lib interface() */
d2fc8896 852 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
853 return ret;
718e3744 854
855 ifp = vty->index;
856
d2fc8896 857 if (ifp->ifindex == IFINDEX_INTERNAL)
858 /* Is this really necessary? Shouldn't status be initialized to 0
859 in that case? */
860 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
718e3744 861
862 return ret;
863}
864
718e3744 865struct cmd_node interface_node =
866{
867 INTERFACE_NODE,
868 "%s(config-if)# ",
869 1
870};
871
872/* Show all or specified interface to vty. */
873DEFUN (show_interface, show_interface_cmd,
874 "show interface [IFNAME]",
875 SHOW_STR
876 "Interface status and configuration\n"
877 "Inteface name\n")
878{
52dc7ee6 879 struct listnode *node;
718e3744 880 struct interface *ifp;
881
882#ifdef HAVE_PROC_NET_DEV
883 /* If system has interface statistics via proc file system, update
884 statistics. */
885 ifstat_update_proc ();
886#endif /* HAVE_PROC_NET_DEV */
887#ifdef HAVE_NET_RT_IFLIST
888 ifstat_update_sysctl ();
889#endif /* HAVE_NET_RT_IFLIST */
890
891 /* Specified interface print. */
892 if (argc != 0)
893 {
894 ifp = if_lookup_by_name (argv[0]);
895 if (ifp == NULL)
896 {
897 vty_out (vty, "%% Can't find interface %s%s", argv[0],
898 VTY_NEWLINE);
899 return CMD_WARNING;
900 }
901 if_dump_vty (vty, ifp);
902 return CMD_SUCCESS;
903 }
904
905 /* All interface print. */
1eb8ef25 906 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
907 if_dump_vty (vty, ifp);
718e3744 908
909 return CMD_SUCCESS;
910}
911
ed9bb6d5 912DEFUN (show_interface_desc,
913 show_interface_desc_cmd,
914 "show interface description",
915 SHOW_STR
916 "Interface status and configuration\n"
917 "Interface description\n")
918{
919 struct listnode *node;
920 struct interface *ifp;
921
922 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
1eb8ef25 923 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
ed9bb6d5 924 {
925 int len;
ed9bb6d5 926
927 len = vty_out (vty, "%s", ifp->name);
928 vty_out (vty, "%*s", (16 - len), " ");
929
930 if (if_is_up(ifp))
931 {
932 vty_out (vty, "up ");
933 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
934 {
935 if (if_is_running(ifp))
936 vty_out (vty, "up ");
937 else
938 vty_out (vty, "down ");
939 }
940 else
941 {
942 vty_out (vty, "unknown ");
943 }
944 }
945 else
946 {
947 vty_out (vty, "down down ");
948 }
949
950 if (ifp->desc)
951 vty_out (vty, "%s", ifp->desc);
952 vty_out (vty, "%s", VTY_NEWLINE);
953 }
954 return CMD_SUCCESS;
955}
956
718e3744 957DEFUN (multicast,
958 multicast_cmd,
959 "multicast",
960 "Set multicast flag to interface\n")
961{
962 int ret;
963 struct interface *ifp;
964 struct zebra_if *if_data;
965
966 ifp = (struct interface *) vty->index;
48b33aaf 967 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 968 {
48b33aaf 969 ret = if_set_flags (ifp, IFF_MULTICAST);
970 if (ret < 0)
971 {
972 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
973 return CMD_WARNING;
974 }
975 if_refresh (ifp);
718e3744 976 }
718e3744 977 if_data = ifp->info;
978 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 979
718e3744 980 return CMD_SUCCESS;
981}
982
983DEFUN (no_multicast,
984 no_multicast_cmd,
985 "no multicast",
986 NO_STR
987 "Unset multicast flag to interface\n")
988{
989 int ret;
990 struct interface *ifp;
991 struct zebra_if *if_data;
992
993 ifp = (struct interface *) vty->index;
48b33aaf 994 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 995 {
48b33aaf 996 ret = if_unset_flags (ifp, IFF_MULTICAST);
997 if (ret < 0)
998 {
999 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1000 return CMD_WARNING;
1001 }
1002 if_refresh (ifp);
718e3744 1003 }
718e3744 1004 if_data = ifp->info;
1005 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1006
1007 return CMD_SUCCESS;
1008}
1009
2e3b2e47 1010DEFUN (linkdetect,
1011 linkdetect_cmd,
1012 "link-detect",
1013 "Enable link detection on interface\n")
1014{
2e3b2e47 1015 struct interface *ifp;
1016 int if_was_operative;
1017
1018 ifp = (struct interface *) vty->index;
1019 if_was_operative = if_is_operative(ifp);
1020 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1021
1022 /* When linkdetection is enabled, if might come down */
1023 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1024
1025 /* FIXME: Will defer status change forwarding if interface
1026 does not come down! */
1027
1028 return CMD_SUCCESS;
1029}
1030
1031
1032DEFUN (no_linkdetect,
1033 no_linkdetect_cmd,
1034 "no link-detect",
1035 NO_STR
1036 "Disable link detection on interface\n")
1037{
2e3b2e47 1038 struct interface *ifp;
1039 int if_was_operative;
1040
1041 ifp = (struct interface *) vty->index;
1042 if_was_operative = if_is_operative(ifp);
1043 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1044
1045 /* Interface may come up after disabling link detection */
1046 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1047
1048 /* FIXME: see linkdetect_cmd */
1049
1050 return CMD_SUCCESS;
1051}
1052
718e3744 1053DEFUN (shutdown_if,
1054 shutdown_if_cmd,
1055 "shutdown",
1056 "Shutdown the selected interface\n")
1057{
1058 int ret;
1059 struct interface *ifp;
1060 struct zebra_if *if_data;
1061
1062 ifp = (struct interface *) vty->index;
1063 ret = if_unset_flags (ifp, IFF_UP);
1064 if (ret < 0)
1065 {
1066 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1067 return CMD_WARNING;
1068 }
1069 if_refresh (ifp);
1070 if_data = ifp->info;
1071 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1072
1073 return CMD_SUCCESS;
1074}
1075
1076DEFUN (no_shutdown_if,
1077 no_shutdown_if_cmd,
1078 "no shutdown",
1079 NO_STR
1080 "Shutdown the selected interface\n")
1081{
1082 int ret;
1083 struct interface *ifp;
1084 struct zebra_if *if_data;
1085
1086 ifp = (struct interface *) vty->index;
1087 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1088 if (ret < 0)
1089 {
1090 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093 if_refresh (ifp);
1094 if_data = ifp->info;
1095 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1096
1097 return CMD_SUCCESS;
1098}
1099
1100DEFUN (bandwidth_if,
1101 bandwidth_if_cmd,
1102 "bandwidth <1-10000000>",
1103 "Set bandwidth informational parameter\n"
1104 "Bandwidth in kilobits\n")
1105{
1106 struct interface *ifp;
1107 unsigned int bandwidth;
1108
1109 ifp = (struct interface *) vty->index;
1110 bandwidth = strtol(argv[0], NULL, 10);
1111
1112 /* bandwidth range is <1-10000000> */
1113 if (bandwidth < 1 || bandwidth > 10000000)
1114 {
1115 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1116 return CMD_WARNING;
1117 }
1118
1119 ifp->bandwidth = bandwidth;
1120
1121 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1122 if (if_is_operative (ifp))
718e3744 1123 zebra_interface_up_update (ifp);
1124
1125 return CMD_SUCCESS;
1126}
1127
1128DEFUN (no_bandwidth_if,
1129 no_bandwidth_if_cmd,
1130 "no bandwidth",
1131 NO_STR
1132 "Set bandwidth informational parameter\n")
1133{
1134 struct interface *ifp;
1135
1136 ifp = (struct interface *) vty->index;
1137
1138 ifp->bandwidth = 0;
1139
1140 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1141 if (if_is_operative (ifp))
718e3744 1142 zebra_interface_up_update (ifp);
1143
1144 return CMD_SUCCESS;
1145}
1146
1147ALIAS (no_bandwidth_if,
1148 no_bandwidth_if_val_cmd,
1149 "no bandwidth <1-10000000>",
1150 NO_STR
1151 "Set bandwidth informational parameter\n"
1152 "Bandwidth in kilobits\n")
1153\f
a1ac18c4 1154static int
39db97e4 1155ip_address_install (struct vty *vty, struct interface *ifp,
1156 const char *addr_str, const char *peer_str,
1157 const char *label)
718e3744 1158{
1159 struct prefix_ipv4 cp;
1160 struct connected *ifc;
1161 struct prefix_ipv4 *p;
718e3744 1162 int ret;
1163
1164 ret = str2prefix_ipv4 (addr_str, &cp);
1165 if (ret <= 0)
1166 {
1167 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1168 return CMD_WARNING;
1169 }
1170
ca16218d 1171 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1172 if (! ifc)
1173 {
1174 ifc = connected_new ();
1175 ifc->ifp = ifp;
1176
1177 /* Address. */
1178 p = prefix_ipv4_new ();
1179 *p = cp;
1180 ifc->address = (struct prefix *) p;
1181
1182 /* Broadcast. */
3fb9cd6e 1183 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
718e3744 1184 {
1185 p = prefix_ipv4_new ();
1186 *p = cp;
3fb9cd6e 1187 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
718e3744 1188 ifc->destination = (struct prefix *) p;
1189 }
1190
718e3744 1191 /* Label. */
1192 if (label)
0752ef0b 1193 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1194
1195 /* Add to linked list. */
1196 listnode_add (ifp->connected, ifc);
1197 }
1198
1199 /* This address is configured from zebra. */
1200 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1201 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1202
1203 /* In case of this route need to install kernel. */
1204 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1205 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1206 {
1207 /* Some system need to up the interface to set IP address. */
1208 if (! if_is_up (ifp))
1209 {
1210 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1211 if_refresh (ifp);
1212 }
1213
1214 ret = if_set_prefix (ifp, ifc);
1215 if (ret < 0)
1216 {
1217 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1218 safe_strerror(errno), VTY_NEWLINE);
718e3744 1219 return CMD_WARNING;
1220 }
1221
eef1fe11 1222 /* Add to subnet chain list (while marking secondary attribute). */
1223 if_subnet_add (ifp, ifc);
1224
718e3744 1225 /* IP address propery set. */
1226 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1227
1228 /* Update interface address information to protocol daemon. */
1229 zebra_interface_address_add_update (ifp, ifc);
1230
1231 /* If interface is up register connected route. */
2e3b2e47 1232 if (if_is_operative(ifp))
718e3744 1233 connected_up_ipv4 (ifp, ifc);
1234 }
1235
1236 return CMD_SUCCESS;
1237}
1238
a1ac18c4 1239static int
39db97e4 1240ip_address_uninstall (struct vty *vty, struct interface *ifp,
1241 const char *addr_str, const char *peer_str,
1242 const char *label)
718e3744 1243{
1244 struct prefix_ipv4 cp;
1245 struct connected *ifc;
1246 int ret;
1247
1248 /* Convert to prefix structure. */
1249 ret = str2prefix_ipv4 (addr_str, &cp);
1250 if (ret <= 0)
1251 {
1252 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1253 return CMD_WARNING;
1254 }
1255
1256 /* Check current interface address. */
ca16218d 1257 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1258 if (! ifc)
1259 {
1260 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1261 return CMD_WARNING;
1262 }
1263
1264 /* This is not configured address. */
1265 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1266 return CMD_WARNING;
1267
74ecdc9e
PJ
1268 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1269
718e3744 1270 /* This is not real address or interface is not active. */
1271 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1272 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1273 {
1274 listnode_delete (ifp->connected, ifc);
1275 connected_free (ifc);
1276 return CMD_WARNING;
1277 }
1278
1279 /* This is real route. */
1280 ret = if_unset_prefix (ifp, ifc);
1281 if (ret < 0)
1282 {
1283 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 1284 safe_strerror(errno), VTY_NEWLINE);
718e3744 1285 return CMD_WARNING;
1286 }
1287
eef1fe11 1288#if 0
718e3744 1289 /* Redistribute this information. */
1290 zebra_interface_address_delete_update (ifp, ifc);
1291
1292 /* Remove connected route. */
1293 connected_down_ipv4 (ifp, ifc);
1294
1295 /* Free address information. */
1296 listnode_delete (ifp->connected, ifc);
1297 connected_free (ifc);
eef1fe11 1298#endif
718e3744 1299
1300 return CMD_SUCCESS;
1301}
1302
1303DEFUN (ip_address,
1304 ip_address_cmd,
1305 "ip address A.B.C.D/M",
1306 "Interface Internet Protocol config commands\n"
1307 "Set the IP address of an interface\n"
1308 "IP address (e.g. 10.0.0.1/8)\n")
1309{
eef1fe11 1310 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
718e3744 1311}
1312
1313DEFUN (no_ip_address,
1314 no_ip_address_cmd,
1315 "no ip address A.B.C.D/M",
1316 NO_STR
1317 "Interface Internet Protocol config commands\n"
1318 "Set the IP address of an interface\n"
1319 "IP Address (e.g. 10.0.0.1/8)")
1320{
eef1fe11 1321 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
718e3744 1322}
1323
1324#ifdef HAVE_NETLINK
718e3744 1325DEFUN (ip_address_label,
1326 ip_address_label_cmd,
1327 "ip address A.B.C.D/M label LINE",
1328 "Interface Internet Protocol config commands\n"
1329 "Set the IP address of an interface\n"
1330 "IP address (e.g. 10.0.0.1/8)\n"
1331 "Label of this address\n"
1332 "Label\n")
1333{
eef1fe11 1334 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1335}
1336
1337DEFUN (no_ip_address_label,
1338 no_ip_address_label_cmd,
1339 "no ip address A.B.C.D/M label LINE",
1340 NO_STR
1341 "Interface Internet Protocol config commands\n"
1342 "Set the IP address of an interface\n"
1343 "IP address (e.g. 10.0.0.1/8)\n"
1344 "Label of this address\n"
1345 "Label\n")
1346{
eef1fe11 1347 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1348}
1349#endif /* HAVE_NETLINK */
1350
1351#ifdef HAVE_IPV6
a1ac18c4 1352static int
39db97e4 1353ipv6_address_install (struct vty *vty, struct interface *ifp,
1354 const char *addr_str, const char *peer_str,
1355 const char *label, int secondary)
718e3744 1356{
1357 struct prefix_ipv6 cp;
1358 struct connected *ifc;
1359 struct prefix_ipv6 *p;
1360 int ret;
1361
1362 ret = str2prefix_ipv6 (addr_str, &cp);
1363 if (ret <= 0)
1364 {
1365 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1366 return CMD_WARNING;
1367 }
1368
ca16218d 1369 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1370 if (! ifc)
1371 {
1372 ifc = connected_new ();
1373 ifc->ifp = ifp;
1374
1375 /* Address. */
1376 p = prefix_ipv6_new ();
1377 *p = cp;
1378 ifc->address = (struct prefix *) p;
1379
1380 /* Secondary. */
1381 if (secondary)
1382 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1383
1384 /* Label. */
1385 if (label)
0752ef0b 1386 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1387
1388 /* Add to linked list. */
1389 listnode_add (ifp->connected, ifc);
1390 }
1391
1392 /* This address is configured from zebra. */
1393 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1394 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1395
1396 /* In case of this route need to install kernel. */
1397 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1398 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1399 {
1400 /* Some system need to up the interface to set IP address. */
1401 if (! if_is_up (ifp))
1402 {
1403 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1404 if_refresh (ifp);
1405 }
1406
1407 ret = if_prefix_add_ipv6 (ifp, ifc);
1408
1409 if (ret < 0)
1410 {
1411 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1412 safe_strerror(errno), VTY_NEWLINE);
718e3744 1413 return CMD_WARNING;
1414 }
1415
1416 /* IP address propery set. */
1417 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1418
1419 /* Update interface address information to protocol daemon. */
1420 zebra_interface_address_add_update (ifp, ifc);
1421
1422 /* If interface is up register connected route. */
2e3b2e47 1423 if (if_is_operative(ifp))
718e3744 1424 connected_up_ipv6 (ifp, ifc);
1425 }
1426
1427 return CMD_SUCCESS;
1428}
1429
a1ac18c4 1430static int
39db97e4 1431ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1432 const char *addr_str, const char *peer_str,
1433 const char *label, int secondry)
718e3744 1434{
1435 struct prefix_ipv6 cp;
1436 struct connected *ifc;
1437 int ret;
1438
1439 /* Convert to prefix structure. */
1440 ret = str2prefix_ipv6 (addr_str, &cp);
1441 if (ret <= 0)
1442 {
1443 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1444 return CMD_WARNING;
1445 }
1446
1447 /* Check current interface address. */
ca16218d 1448 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1449 if (! ifc)
1450 {
1451 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1452 return CMD_WARNING;
1453 }
1454
1455 /* This is not configured address. */
1456 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1457 return CMD_WARNING;
1458
1459 /* This is not real address or interface is not active. */
1460 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1461 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1462 {
1463 listnode_delete (ifp->connected, ifc);
1464 connected_free (ifc);
1465 return CMD_WARNING;
1466 }
1467
1468 /* This is real route. */
1469 ret = if_prefix_delete_ipv6 (ifp, ifc);
1470 if (ret < 0)
1471 {
1472 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 1473 safe_strerror(errno), VTY_NEWLINE);
718e3744 1474 return CMD_WARNING;
1475 }
1476
1477 /* Redistribute this information. */
1478 zebra_interface_address_delete_update (ifp, ifc);
1479
1480 /* Remove connected route. */
1481 connected_down_ipv6 (ifp, ifc);
1482
1483 /* Free address information. */
1484 listnode_delete (ifp->connected, ifc);
1485 connected_free (ifc);
1486
1487 return CMD_SUCCESS;
1488}
1489
1490DEFUN (ipv6_address,
1491 ipv6_address_cmd,
1492 "ipv6 address X:X::X:X/M",
e23949c0 1493 "Interface IPv6 config commands\n"
718e3744 1494 "Set the IP address of an interface\n"
1495 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1496{
1497 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1498}
1499
1500DEFUN (no_ipv6_address,
1501 no_ipv6_address_cmd,
1502 "no ipv6 address X:X::X:X/M",
1503 NO_STR
e23949c0 1504 "Interface IPv6 config commands\n"
718e3744 1505 "Set the IP address of an interface\n"
1506 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1507{
1508 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1509}
1510#endif /* HAVE_IPV6 */
1511
a1ac18c4 1512static int
718e3744 1513if_config_write (struct vty *vty)
1514{
52dc7ee6 1515 struct listnode *node;
718e3744 1516 struct interface *ifp;
1517 char buf[BUFSIZ];
1518
1eb8ef25 1519 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
718e3744 1520 {
1521 struct zebra_if *if_data;
52dc7ee6 1522 struct listnode *addrnode;
718e3744 1523 struct connected *ifc;
1524 struct prefix *p;
1525
718e3744 1526 if_data = ifp->info;
1527
1528 vty_out (vty, "interface %s%s", ifp->name,
1529 VTY_NEWLINE);
1530
1531 if (ifp->desc)
1532 vty_out (vty, " description %s%s", ifp->desc,
1533 VTY_NEWLINE);
1534
1535 /* Assign bandwidth here to avoid unnecessary interface flap
1536 while processing config script */
1537 if (ifp->bandwidth != 0)
1538 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1539
2e3b2e47 1540 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1541 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1542
1eb8ef25 1543 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
718e3744 1544 {
718e3744 1545 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1546 {
1547 p = ifc->address;
1548 vty_out (vty, " ip%s address %s/%d",
1549 p->family == AF_INET ? "" : "v6",
1550 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1551 p->prefixlen);
1552
718e3744 1553 if (ifc->label)
1554 vty_out (vty, " label %s", ifc->label);
1555
1556 vty_out (vty, "%s", VTY_NEWLINE);
1557 }
1558 }
1559
1560 if (if_data)
1561 {
1562 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1563 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1564
1565 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1566 vty_out (vty, " %smulticast%s",
1567 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1568 VTY_NEWLINE);
1569 }
1570
1571#ifdef RTADV
1572 rtadv_config_write (vty, ifp);
1573#endif /* RTADV */
1574
ca776988 1575#ifdef HAVE_IRDP
1576 irdp_config_write (vty, ifp);
1577#endif /* IRDP */
1578
718e3744 1579 vty_out (vty, "!%s", VTY_NEWLINE);
1580 }
1581 return 0;
1582}
1583
1584/* Allocate and initialize interface vector. */
1585void
a1ac18c4 1586zebra_if_init (void)
718e3744 1587{
1588 /* Initialize interface and new hook. */
1589 if_init ();
1590 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1591 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1592
1593 /* Install configuration write function. */
1594 install_node (&interface_node, if_config_write);
1595
1596 install_element (VIEW_NODE, &show_interface_cmd);
1597 install_element (ENABLE_NODE, &show_interface_cmd);
ed9bb6d5 1598 install_element (ENABLE_NODE, &show_interface_desc_cmd);
718e3744 1599 install_element (CONFIG_NODE, &zebra_interface_cmd);
bfc13532 1600 install_element (CONFIG_NODE, &no_interface_cmd);
718e3744 1601 install_default (INTERFACE_NODE);
1602 install_element (INTERFACE_NODE, &interface_desc_cmd);
1603 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1604 install_element (INTERFACE_NODE, &multicast_cmd);
1605 install_element (INTERFACE_NODE, &no_multicast_cmd);
2e3b2e47 1606 install_element (INTERFACE_NODE, &linkdetect_cmd);
1607 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
718e3744 1608 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1609 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1610 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1611 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1612 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1613 install_element (INTERFACE_NODE, &ip_address_cmd);
1614 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1615#ifdef HAVE_IPV6
1616 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1617 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1618#endif /* HAVE_IPV6 */
718e3744 1619#ifdef HAVE_NETLINK
718e3744 1620 install_element (INTERFACE_NODE, &ip_address_label_cmd);
718e3744 1621 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
1622#endif /* HAVE_NETLINK */
1623}