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