blob: 25657e83167185f9b87d3ce0ae1811f70a959896 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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"
Feng Lu471ea392015-05-22 11:40:00 +020035#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "zebra/interface.h"
38#include "zebra/rtadv.h"
39#include "zebra/rib.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000043#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000044
Chris Caputob60668d2009-05-03 04:40:57 +000045#ifdef RTADV
46/* Order is intentional. Matches RFC4191. This array is also used for
47 command matching, so only modify with care. */
48const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
49#endif /* RTADV */
paul718e3742002-12-13 20:15:29 +000050
51/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000052static int
paul718e3742002-12-13 20:15:29 +000053if_zebra_new_hook (struct interface *ifp)
54{
55 struct zebra_if *zebra_if;
56
Stephen Hemminger393deb92008-08-18 14:13:29 -070057 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000058
59 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
Christian Frankebfac8dc2013-01-24 14:04:50 +000060 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
paul718e3742002-12-13 20:15:29 +000061
62#ifdef RTADV
63 {
64 /* Set default router advertise values. */
65 struct rtadvconf *rtadv;
66
67 rtadv = &zebra_if->rtadv;
68
69 rtadv->AdvSendAdvertisements = 0;
70 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
71 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
72 rtadv->AdvIntervalTimer = 0;
73 rtadv->AdvManagedFlag = 0;
74 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000075 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000076 rtadv->AdvLinkMTU = 0;
77 rtadv->AdvReachableTime = 0;
78 rtadv->AdvRetransTimer = 0;
79 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040080 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +000081 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040082 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +000083 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +000084 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +000085
86 rtadv->AdvPrefixList = list_new ();
87 }
88#endif /* RTADV */
89
hassoeef1fe12004-10-03 18:46:08 +000090 /* Initialize installed address chains tree. */
91 zebra_if->ipv4_subnets = route_table_init ();
92
paul718e3742002-12-13 20:15:29 +000093 ifp->info = zebra_if;
94 return 0;
95}
96
97/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000098static int
paul718e3742002-12-13 20:15:29 +000099if_zebra_delete_hook (struct interface *ifp)
100{
hassoeef1fe12004-10-03 18:46:08 +0000101 struct zebra_if *zebra_if;
102
paul718e3742002-12-13 20:15:29 +0000103 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000104 {
105 zebra_if = ifp->info;
106
107 /* Free installed address chains tree. */
108 if (zebra_if->ipv4_subnets)
109 route_table_finish (zebra_if->ipv4_subnets);
110
111 XFREE (MTYPE_TMP, zebra_if);
112 }
113
114 return 0;
115}
116
117/* Tie an interface address to its derived subnet list of addresses. */
118int
119if_subnet_add (struct interface *ifp, struct connected *ifc)
120{
121 struct route_node *rn;
122 struct zebra_if *zebra_if;
123 struct prefix cp;
124 struct list *addr_list;
125
126 assert (ifp && ifp->info && ifc);
127 zebra_if = ifp->info;
128
129 /* Get address derived subnet node and associated address list, while marking
130 address secondary attribute appropriately. */
131 cp = *ifc->address;
132 apply_mask (&cp);
133 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
134
135 if ((addr_list = rn->info))
136 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
137 else
138 {
139 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
140 rn->info = addr_list = list_new ();
141 route_lock_node (rn);
142 }
143
144 /* Tie address at the tail of address list. */
145 listnode_add (addr_list, ifc);
146
147 /* Return list element count. */
148 return (addr_list->count);
149}
150
151/* Untie an interface address from its derived subnet list of addresses. */
152int
153if_subnet_delete (struct interface *ifp, struct connected *ifc)
154{
155 struct route_node *rn;
156 struct zebra_if *zebra_if;
157 struct list *addr_list;
158
159 assert (ifp && ifp->info && ifc);
160 zebra_if = ifp->info;
161
162 /* Get address derived subnet node. */
163 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
164 if (! (rn && rn->info))
Christian Franke9db047f2013-01-24 14:04:44 +0000165 {
166 zlog_warn("Trying to remove an address from an unknown subnet."
167 " (please report this bug)");
168 return -1;
169 }
hassoeef1fe12004-10-03 18:46:08 +0000170 route_unlock_node (rn);
171
172 /* Untie address from subnet's address list. */
173 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000174
175 /* Deleting an address that is not registered is a bug.
176 * In any case, we shouldn't decrement the lock counter if the address
177 * is unknown. */
178 if (!listnode_lookup(addr_list, ifc))
179 {
180 zlog_warn("Trying to remove an address from a subnet where it is not"
181 " currently registered. (please report this bug)");
182 return -1;
183 }
184
hassoeef1fe12004-10-03 18:46:08 +0000185 listnode_delete (addr_list, ifc);
186 route_unlock_node (rn);
187
188 /* Return list element count, if not empty. */
189 if (addr_list->count)
190 {
191 /* If deleted address is primary, mark subsequent one as such and distribute. */
192 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
193 {
paul1eb8ef22005-04-07 07:30:20 +0000194 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000195 zebra_interface_address_delete_update (ifp, ifc);
196 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
Christian Franke02b48052013-01-24 14:04:49 +0000197 /* XXX: Linux kernel removes all the secondary addresses when the primary
198 * address is removed. We could try to work around that, though this is
199 * non-trivial. */
hassoeef1fe12004-10-03 18:46:08 +0000200 zebra_interface_address_add_update (ifp, ifc);
201 }
202
203 return addr_list->count;
204 }
205
206 /* Otherwise, free list and route node. */
207 list_free (addr_list);
208 rn->info = NULL;
209 route_unlock_node (rn);
210
paul718e3742002-12-13 20:15:29 +0000211 return 0;
212}
213
paul5c78b3d2006-01-25 04:31:40 +0000214/* if_flags_mangle: A place for hacks that require mangling
215 * or tweaking the interface flags.
216 *
217 * ******************** Solaris flags hacks **************************
218 *
219 * Solaris IFF_UP flag reflects only the primary interface as the
220 * routing socket only sends IFINFO for the primary interface. Hence
221 * ~IFF_UP does not per se imply all the logical interfaces are also
222 * down - which we only know of as addresses. Instead we must determine
223 * whether the interface really is up or not according to how many
224 * addresses are still attached. (Solaris always sends RTM_DELADDR if
225 * an interface, logical or not, goes ~IFF_UP).
226 *
227 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
228 * are addresses left in struct connected, not just the actual underlying
229 * IFF_UP flag.
230 *
231 * We must hence remember the real state of IFF_UP, which we do in
232 * struct zebra_if.primary_state.
233 *
234 * Setting IFF_UP within zebra to administratively shutdown the
235 * interface will affect only the primary interface/address on Solaris.
236 ************************End Solaris flags hacks ***********************
237 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100238static void
paul5c78b3d2006-01-25 04:31:40 +0000239if_flags_mangle (struct interface *ifp, uint64_t *newflags)
240{
241#ifdef SUNOS_5
242 struct zebra_if *zif = ifp->info;
243
244 zif->primary_state = *newflags & (IFF_UP & 0xff);
245
246 if (CHECK_FLAG (zif->primary_state, IFF_UP)
247 || listcount(ifp->connected) > 0)
248 SET_FLAG (*newflags, IFF_UP);
249 else
250 UNSET_FLAG (*newflags, IFF_UP);
251#endif /* SUNOS_5 */
252}
253
254/* Update the flags field of the ifp with the new flag set provided.
255 * Take whatever actions are required for any changes in flags we care
256 * about.
257 *
258 * newflags should be the raw value, as obtained from the OS.
259 */
260void
261if_flags_update (struct interface *ifp, uint64_t newflags)
262{
263 if_flags_mangle (ifp, &newflags);
264
265 if (if_is_operative (ifp))
266 {
267 /* operative -> inoperative? */
268 ifp->flags = newflags;
269 if (!if_is_operative (ifp))
270 if_down (ifp);
271 }
272 else
273 {
274 /* inoperative -> operative? */
275 ifp->flags = newflags;
276 if (if_is_operative (ifp))
277 if_up (ifp);
278 }
279}
280
paul718e3742002-12-13 20:15:29 +0000281/* Wake up configured address if it is not in current kernel
282 address. */
paula1ac18c2005-06-28 17:17:12 +0000283static void
paul718e3742002-12-13 20:15:29 +0000284if_addr_wakeup (struct interface *ifp)
285{
paul1eb8ef22005-04-07 07:30:20 +0000286 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000287 struct connected *ifc;
288 struct prefix *p;
289 int ret;
290
paul1eb8ef22005-04-07 07:30:20 +0000291 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000292 {
paul718e3742002-12-13 20:15:29 +0000293 p = ifc->address;
294
295 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000296 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000297 {
298 /* Address check. */
299 if (p->family == AF_INET)
300 {
301 if (! if_is_up (ifp))
302 {
Christian Franke02b48052013-01-24 14:04:49 +0000303 /* Assume zebra is configured like following:
304 *
305 * interface gre0
306 * ip addr 192.0.2.1/24
307 * !
308 *
309 * As soon as zebra becomes first aware that gre0 exists in the
310 * kernel, it will set gre0 up and configure its addresses.
311 *
312 * (This may happen at startup when the interface already exists
313 * or during runtime when the interface is added to the kernel)
314 *
315 * XXX: IRDP code is calling here via if_add_update - this seems
316 * somewhat weird.
317 * XXX: RUNNING is not a settable flag on any system
318 * I (paulj) am aware of.
319 */
paul718e3742002-12-13 20:15:29 +0000320 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
321 if_refresh (ifp);
322 }
323
324 ret = if_set_prefix (ifp, ifc);
325 if (ret < 0)
326 {
327 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000328 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000329 continue;
330 }
hassoeef1fe12004-10-03 18:46:08 +0000331
Christian Frankef7f740f2013-01-24 14:04:48 +0000332 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000333 /* The address will be advertised to zebra clients when the notification
334 * from the kernel has been received.
335 * It will also be added to the interface's subnet list then. */
paul718e3742002-12-13 20:15:29 +0000336 }
337#ifdef HAVE_IPV6
338 if (p->family == AF_INET6)
339 {
340 if (! if_is_up (ifp))
341 {
Christian Franke02b48052013-01-24 14:04:49 +0000342 /* See long comment above */
paul718e3742002-12-13 20:15:29 +0000343 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
344 if_refresh (ifp);
345 }
346
347 ret = if_prefix_add_ipv6 (ifp, ifc);
348 if (ret < 0)
349 {
350 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000351 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000352 continue;
353 }
Christian Franke02b48052013-01-24 14:04:49 +0000354
Christian Frankef7f740f2013-01-24 14:04:48 +0000355 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000356 /* The address will be advertised to zebra clients when the notification
357 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +0000358 }
359#endif /* HAVE_IPV6 */
360 }
361 }
362}
363
364/* Handle interface addition */
365void
366if_add_update (struct interface *ifp)
367{
paul48b33aa2002-12-13 20:52:52 +0000368 struct zebra_if *if_data;
369
370 if_data = ifp->info;
371 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
372 if_set_flags (ifp, IFF_MULTICAST);
373 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
374 if_unset_flags (ifp, IFF_MULTICAST);
375
paul718e3742002-12-13 20:15:29 +0000376 zebra_interface_add_update (ifp);
377
378 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
379 {
380 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
381
Christian Frankebfac8dc2013-01-24 14:04:50 +0000382 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
383 {
384 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200385 zlog_debug ("interface %s vrf %u index %d is shutdown. "
386 "Won't wake it up.",
387 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000388 return;
389 }
390
paul718e3742002-12-13 20:15:29 +0000391 if_addr_wakeup (ifp);
392
393 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200394 zlog_debug ("interface %s vrf %u index %d becomes active.",
395 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000396 }
397 else
398 {
399 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200400 zlog_debug ("interface %s vrf %u index %d is added.",
401 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000402 }
403}
404
paul6eb88272005-07-29 14:36:00 +0000405/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000406void
407if_delete_update (struct interface *ifp)
408{
paul718e3742002-12-13 20:15:29 +0000409 struct connected *ifc;
410 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000411 struct route_node *rn;
412 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000413
414 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000415
416 if (if_is_up(ifp))
417 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200418 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
419 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000420 return;
421 }
422
423 /* Mark interface as inactive */
424 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
425
426 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200427 zlog_debug ("interface %s vrf %u index %d is now inactive.",
428 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000429
430 /* Delete connected routes from the kernel. */
431 if (ifp->connected)
432 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000433 struct listnode *node;
434 struct listnode *last = NULL;
435
hassoeef1fe12004-10-03 18:46:08 +0000436 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000437 {
paul1eb8ef22005-04-07 07:30:20 +0000438 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000439 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000440
Paul Jakmabeb56332006-05-11 13:28:05 +0000441 if (p->family == AF_INET
442 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000443 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000444 struct listnode *anode;
445 struct listnode *next;
446 struct listnode *first;
447 struct list *addr_list;
448
hassoeef1fe12004-10-03 18:46:08 +0000449 route_unlock_node (rn);
450 addr_list = (struct list *) rn->info;
451
452 /* Remove addresses, secondaries first. */
453 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000454 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000455 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000456 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000457 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000458 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000459 first = NULL;
460 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000461 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000462
Paul Jakmad9a18f12007-04-10 19:30:20 +0000463 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000464 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000465 connected_down_ipv4 (ifp, ifc);
466
Christian Franke02b48052013-01-24 14:04:49 +0000467 /* XXX: We have to send notifications here explicitly, because we destroy
468 * the ifc before receiving the notification about the address being deleted.
469 */
hassoeef1fe12004-10-03 18:46:08 +0000470 zebra_interface_address_delete_update (ifp, ifc);
471
472 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000473 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000474
475 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000476 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000477 route_unlock_node (rn);
478
479 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000480 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
481 {
482 listnode_delete (ifp->connected, ifc);
483 connected_free (ifc);
484 }
485 else
486 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000487 }
488
489 /* Free chain list and respective route node. */
490 list_delete (addr_list);
491 rn->info = NULL;
492 route_unlock_node (rn);
493 }
paul718e3742002-12-13 20:15:29 +0000494#ifdef HAVE_IPV6
495 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000496 {
497 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000498
hassoeef1fe12004-10-03 18:46:08 +0000499 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000500
hassoeef1fe12004-10-03 18:46:08 +0000501 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000502 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000503
504 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
505 last = node;
506 else
507 {
508 listnode_delete (ifp->connected, ifc);
509 connected_free (ifc);
510 }
paul718e3742002-12-13 20:15:29 +0000511 }
hassoeef1fe12004-10-03 18:46:08 +0000512#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200513 else
514 {
515 last = node;
516 }
paul718e3742002-12-13 20:15:29 +0000517 }
518 }
519 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000520
521 /* Update ifindex after distributing the delete message. This is in
522 case any client needs to have the old value of ifindex available
523 while processing the deletion. Each client daemon is responsible
524 for setting ifindex to IFINDEX_INTERNAL after processing the
525 interface deletion message. */
526 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000527}
528
529/* Interface is up. */
530void
531if_up (struct interface *ifp)
532{
hasso52dc7ee2004-09-23 19:18:23 +0000533 struct listnode *node;
534 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000535 struct connected *ifc;
536 struct prefix *p;
537
538 /* Notify the protocol daemons. */
539 zebra_interface_up_update (ifp);
540
541 /* Install connected routes to the kernel. */
542 if (ifp->connected)
543 {
paul1eb8ef22005-04-07 07:30:20 +0000544 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000545 {
paul718e3742002-12-13 20:15:29 +0000546 p = ifc->address;
547
548 if (p->family == AF_INET)
549 connected_up_ipv4 (ifp, ifc);
550#ifdef HAVE_IPV6
551 else if (p->family == AF_INET6)
552 connected_up_ipv6 (ifp, ifc);
553#endif /* HAVE_IPV6 */
554 }
555 }
556
557 /* Examine all static routes. */
558 rib_update ();
559}
560
561/* Interface goes down. We have to manage different behavior of based
562 OS. */
563void
564if_down (struct interface *ifp)
565{
hasso52dc7ee2004-09-23 19:18:23 +0000566 struct listnode *node;
567 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000568 struct connected *ifc;
569 struct prefix *p;
570
571 /* Notify to the protocol daemons. */
572 zebra_interface_down_update (ifp);
573
574 /* Delete connected routes from the kernel. */
575 if (ifp->connected)
576 {
paul1eb8ef22005-04-07 07:30:20 +0000577 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000578 {
paul718e3742002-12-13 20:15:29 +0000579 p = ifc->address;
580
581 if (p->family == AF_INET)
582 connected_down_ipv4 (ifp, ifc);
583#ifdef HAVE_IPV6
584 else if (p->family == AF_INET6)
585 connected_down_ipv6 (ifp, ifc);
586#endif /* HAVE_IPV6 */
587 }
588 }
589
590 /* Examine all static routes which direct to the interface. */
591 rib_update ();
592}
593
594void
595if_refresh (struct interface *ifp)
596{
paul5c78b3d2006-01-25 04:31:40 +0000597 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000598}
599
paul718e3742002-12-13 20:15:29 +0000600/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000601static int
paul718e3742002-12-13 20:15:29 +0000602prefix_vty_out (struct vty *vty, struct prefix *p)
603{
604 char str[INET6_ADDRSTRLEN];
605
606 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
607 vty_out (vty, "%s", str);
608 return strlen (str);
609}
610
611/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000612static void
paul718e3742002-12-13 20:15:29 +0000613connected_dump_vty (struct vty *vty, struct connected *connected)
614{
615 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000616
617 /* Print interface address. */
618 p = connected->address;
619 vty_out (vty, " %s ", prefix_family_str (p));
620 prefix_vty_out (vty, p);
621 vty_out (vty, "/%d", p->prefixlen);
622
623 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000624 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000625 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000626 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
627 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000628 }
629
630 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
631 vty_out (vty, " secondary");
632
633 if (connected->label)
634 vty_out (vty, " %s", connected->label);
635
636 vty_out (vty, "%s", VTY_NEWLINE);
637}
638
639#ifdef RTADV
640/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000641static void
paul718e3742002-12-13 20:15:29 +0000642nd_dump_vty (struct vty *vty, struct interface *ifp)
643{
644 struct zebra_if *zif;
645 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000646 int interval;
paul718e3742002-12-13 20:15:29 +0000647
648 zif = (struct zebra_if *) ifp->info;
649 rtadv = &zif->rtadv;
650
651 if (rtadv->AdvSendAdvertisements)
652 {
653 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
654 rtadv->AdvReachableTime, VTY_NEWLINE);
655 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
656 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000657 interval = rtadv->MaxRtrAdvInterval;
658 if (interval % 1000)
659 vty_out (vty, " ND router advertisements are sent every "
660 "%d milliseconds%s", interval,
661 VTY_NEWLINE);
662 else
663 vty_out (vty, " ND router advertisements are sent every "
664 "%d seconds%s", interval / 1000,
665 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400666 if (rtadv->AdvDefaultLifetime != -1)
667 vty_out (vty, " ND router advertisements live for %d seconds%s",
668 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
669 else
670 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
671 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000672 vty_out (vty, " ND router advertisement default router preference is "
673 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
674 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000675 if (rtadv->AdvManagedFlag)
676 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
677 VTY_NEWLINE);
678 else
679 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
680 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000681 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400682 {
vincent7cee1bb2005-03-25 13:08:53 +0000683 vty_out (vty, " ND router advertisements with "
684 "Home Agent flag bit set.%s",
685 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400686 if (rtadv->HomeAgentLifetime != -1)
687 vty_out (vty, " Home Agent lifetime is %u seconds%s",
688 rtadv->HomeAgentLifetime, VTY_NEWLINE);
689 else
690 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
691 VTY_NEWLINE);
692 vty_out (vty, " Home Agent preference is %u%s",
693 rtadv->HomeAgentPreference, VTY_NEWLINE);
694 }
vincent7cee1bb2005-03-25 13:08:53 +0000695 if (rtadv->AdvIntervalOption)
696 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
697 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000698 }
699}
700#endif /* RTADV */
701
702/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000703static void
paul718e3742002-12-13 20:15:29 +0000704if_dump_vty (struct vty *vty, struct interface *ifp)
705{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000706#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000707 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000708#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000709 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000710 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000711 struct route_node *rn;
712 struct zebra_if *zebra_if;
713
714 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000715
paul2e3b2e42002-12-13 21:03:13 +0000716 vty_out (vty, "Interface %s is ", ifp->name);
717 if (if_is_up(ifp)) {
718 vty_out (vty, "up, line protocol ");
719
720 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
721 if (if_is_running(ifp))
722 vty_out (vty, "is up%s", VTY_NEWLINE);
723 else
724 vty_out (vty, "is down%s", VTY_NEWLINE);
725 } else {
726 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
727 }
728 } else {
729 vty_out (vty, "down%s", VTY_NEWLINE);
730 }
731
Feng Lu2fc97f62015-05-22 11:39:57 +0200732 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
733
paul718e3742002-12-13 20:15:29 +0000734 if (ifp->desc)
735 vty_out (vty, " Description: %s%s", ifp->desc,
736 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000737 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000738 {
ajsd2fc8892005-04-02 18:38:43 +0000739 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000740 return;
741 }
742 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
743 {
744 vty_out(vty, " index %d inactive interface%s",
745 ifp->ifindex,
746 VTY_NEWLINE);
747 return;
748 }
749
750 vty_out (vty, " index %d metric %d mtu %d ",
751 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000752#ifdef HAVE_IPV6
753 if (ifp->mtu6 != ifp->mtu)
754 vty_out (vty, "mtu6 %d ", ifp->mtu6);
755#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000756 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
757 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000758
paul718e3742002-12-13 20:15:29 +0000759 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000760#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000761 sdl = &ifp->sdl;
762 if (sdl != NULL && sdl->sdl_alen != 0)
763 {
764 int i;
765 u_char *ptr;
766
767 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000768 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
769 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000770 vty_out (vty, "%s", VTY_NEWLINE);
771 }
772#else
773 if (ifp->hw_addr_len != 0)
774 {
775 int i;
776
777 vty_out (vty, " HWaddr: ");
778 for (i = 0; i < ifp->hw_addr_len; i++)
779 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
780 vty_out (vty, "%s", VTY_NEWLINE);
781 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000782#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000783
784 /* Bandwidth in kbps */
785 if (ifp->bandwidth != 0)
786 {
787 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
788 vty_out(vty, "%s", VTY_NEWLINE);
789 }
790
hassoeef1fe12004-10-03 18:46:08 +0000791 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000792 {
hassoeef1fe12004-10-03 18:46:08 +0000793 if (! rn->info)
794 continue;
795
paul1eb8ef22005-04-07 07:30:20 +0000796 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
797 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000798 }
799
paul1eb8ef22005-04-07 07:30:20 +0000800 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000801 {
hasso39db97e2004-10-12 20:50:58 +0000802 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
803 (connected->address->family == AF_INET6))
804 connected_dump_vty (vty, connected);
805 }
806
paul718e3742002-12-13 20:15:29 +0000807#ifdef RTADV
808 nd_dump_vty (vty, ifp);
809#endif /* RTADV */
810
811#ifdef HAVE_PROC_NET_DEV
812 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000813 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
814 "%lu dropped%s",
815 ifp->stats.rx_packets, ifp->stats.rx_multicast,
816 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000817
hasso6f2c27a2005-01-18 13:44:35 +0000818 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000819 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000820 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
821 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000822 ifp->stats.rx_frame_errors, VTY_NEWLINE);
823
824 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000825 ifp->stats.rx_missed_errors, VTY_NEWLINE);
826
hasso6f2c27a2005-01-18 13:44:35 +0000827 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000828 ifp->stats.tx_packets, ifp->stats.tx_bytes,
829 ifp->stats.tx_dropped, VTY_NEWLINE);
830
hasso6f2c27a2005-01-18 13:44:35 +0000831 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
832 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000833 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
834 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000835 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000836
hasso6f2c27a2005-01-18 13:44:35 +0000837 vty_out (vty, " %lu window, %lu collisions%s",
838 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000839#endif /* HAVE_PROC_NET_DEV */
840
841#ifdef HAVE_NET_RT_IFLIST
842#if defined (__bsdi__) || defined (__NetBSD__)
843 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200844 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
845 " multicast packets %llu%s",
846 (unsigned long long)ifp->stats.ifi_ipackets,
847 (unsigned long long)ifp->stats.ifi_ibytes,
848 (unsigned long long)ifp->stats.ifi_iqdrops,
849 (unsigned long long)ifp->stats.ifi_imcasts,
850 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000851
David Lamparter193e78f2015-04-21 10:42:30 +0200852 vty_out (vty, " input errors %llu%s",
853 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000854
David Lamparter193e78f2015-04-21 10:42:30 +0200855 vty_out (vty, " output packets %llu, bytes %llu,"
856 " multicast packets %llu%s",
857 (unsigned long long)ifp->stats.ifi_opackets,
858 (unsigned long long)ifp->stats.ifi_obytes,
859 (unsigned long long)ifp->stats.ifi_omcasts,
860 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000861
David Lamparter193e78f2015-04-21 10:42:30 +0200862 vty_out (vty, " output errors %llu%s",
863 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000864
David Lamparter193e78f2015-04-21 10:42:30 +0200865 vty_out (vty, " collisions %llu%s",
866 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000867#else
868 /* Statistics print out using sysctl (). */
869 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
870 " multicast packets %lu%s",
871 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
872 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
873 VTY_NEWLINE);
874
875 vty_out (vty, " input errors %lu%s",
876 ifp->stats.ifi_ierrors, VTY_NEWLINE);
877
878 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
879 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
880 ifp->stats.ifi_omcasts, VTY_NEWLINE);
881
882 vty_out (vty, " output errors %lu%s",
883 ifp->stats.ifi_oerrors, VTY_NEWLINE);
884
885 vty_out (vty, " collisions %lu%s",
886 ifp->stats.ifi_collisions, VTY_NEWLINE);
887#endif /* __bsdi__ || __NetBSD__ */
888#endif /* HAVE_NET_RT_IFLIST */
889}
890
paul718e3742002-12-13 20:15:29 +0000891/* Wrapper hook point for zebra daemon so that ifindex can be set
892 * DEFUN macro not used as extract.pl HAS to ignore this
893 * See also interface_cmd in lib/if.c
894 */
895DEFUN_NOSH (zebra_interface,
896 zebra_interface_cmd,
897 "interface IFNAME",
898 "Select an interface to configure\n"
899 "Interface's name\n")
900{
901 int ret;
902 struct interface * ifp;
903
904 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000905 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
906 return ret;
paul718e3742002-12-13 20:15:29 +0000907
908 ifp = vty->index;
909
ajsd2fc8892005-04-02 18:38:43 +0000910 if (ifp->ifindex == IFINDEX_INTERNAL)
911 /* Is this really necessary? Shouldn't status be initialized to 0
912 in that case? */
913 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000914
915 return ret;
916}
917
Feng Lu471ea392015-05-22 11:40:00 +0200918ALIAS (zebra_interface,
919 zebra_interface_vrf_cmd,
920 "interface IFNAME " VRF_CMD_STR,
921 "Select an interface to configure\n"
922 "Interface's name\n"
923 VRF_CMD_HELP_STR)
924
paul718e3742002-12-13 20:15:29 +0000925struct cmd_node interface_node =
926{
927 INTERFACE_NODE,
928 "%s(config-if)# ",
929 1
930};
931
Feng Lua2854772015-05-22 11:40:01 +0200932/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +0000933DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +0200934 "show interface",
paul718e3742002-12-13 20:15:29 +0000935 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +0200936 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +0000937{
hasso52dc7ee2004-09-23 19:18:23 +0000938 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000939 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +0200940 vrf_id_t vrf_id = VRF_DEFAULT;
941
paul718e3742002-12-13 20:15:29 +0000942#ifdef HAVE_PROC_NET_DEV
943 /* If system has interface statistics via proc file system, update
944 statistics. */
945 ifstat_update_proc ();
946#endif /* HAVE_PROC_NET_DEV */
947#ifdef HAVE_NET_RT_IFLIST
948 ifstat_update_sysctl ();
949#endif /* HAVE_NET_RT_IFLIST */
950
Feng Lua2854772015-05-22 11:40:01 +0200951 if (argc > 0)
952 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +0000953
954 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +0200955 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +0000956 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000957
958 return CMD_SUCCESS;
959}
960
Feng Lua2854772015-05-22 11:40:01 +0200961ALIAS (show_interface,
962 show_interface_vrf_cmd,
963 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +0000964 SHOW_STR
965 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +0200966 VRF_CMD_HELP_STR)
967
968/* Show all interfaces to vty. */
969DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
970 "show interface " VRF_ALL_CMD_STR,
971 SHOW_STR
972 "Interface status and configuration\n"
973 VRF_ALL_CMD_HELP_STR)
974{
975 struct listnode *node;
976 struct interface *ifp;
977 vrf_iter_t iter;
978
979#ifdef HAVE_PROC_NET_DEV
980 /* If system has interface statistics via proc file system, update
981 statistics. */
982 ifstat_update_proc ();
983#endif /* HAVE_PROC_NET_DEV */
984#ifdef HAVE_NET_RT_IFLIST
985 ifstat_update_sysctl ();
986#endif /* HAVE_NET_RT_IFLIST */
987
988 /* All interface print. */
989 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
990 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
991 if_dump_vty (vty, ifp);
992
993 return CMD_SUCCESS;
994}
995
996/* Show specified interface to vty. */
997DEFUN (show_interface_name, show_interface_name_cmd,
998 "show interface IFNAME",
999 SHOW_STR
1000 "Interface status and configuration\n"
1001 "Inteface name\n")
1002{
1003 struct interface *ifp;
1004 vrf_id_t vrf_id = VRF_DEFAULT;
1005
1006#ifdef HAVE_PROC_NET_DEV
1007 /* If system has interface statistics via proc file system, update
1008 statistics. */
1009 ifstat_update_proc ();
1010#endif /* HAVE_PROC_NET_DEV */
1011#ifdef HAVE_NET_RT_IFLIST
1012 ifstat_update_sysctl ();
1013#endif /* HAVE_NET_RT_IFLIST */
1014
1015 if (argc > 1)
1016 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1017
1018 /* Specified interface print. */
1019 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1020 if (ifp == NULL)
1021 {
1022 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1023 VTY_NEWLINE);
1024 return CMD_WARNING;
1025 }
1026 if_dump_vty (vty, ifp);
1027
1028 return CMD_SUCCESS;
1029}
1030
1031ALIAS (show_interface_name,
1032 show_interface_name_vrf_cmd,
1033 "show interface IFNAME " VRF_CMD_STR,
1034 SHOW_STR
1035 "Interface status and configuration\n"
1036 "Inteface name\n"
1037 VRF_CMD_HELP_STR)
1038
1039/* Show specified interface to vty. */
1040DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1041 "show interface IFNAME " VRF_ALL_CMD_STR,
1042 SHOW_STR
1043 "Interface status and configuration\n"
1044 "Inteface name\n"
1045 VRF_ALL_CMD_HELP_STR)
1046{
1047 struct interface *ifp;
1048 vrf_iter_t iter;
1049 int found = 0;
1050
1051#ifdef HAVE_PROC_NET_DEV
1052 /* If system has interface statistics via proc file system, update
1053 statistics. */
1054 ifstat_update_proc ();
1055#endif /* HAVE_PROC_NET_DEV */
1056#ifdef HAVE_NET_RT_IFLIST
1057 ifstat_update_sysctl ();
1058#endif /* HAVE_NET_RT_IFLIST */
1059
1060 /* All interface print. */
1061 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1062 {
1063 /* Specified interface print. */
1064 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1065 if (ifp)
1066 {
1067 if_dump_vty (vty, ifp);
1068 found++;
1069 }
1070 }
1071
1072 if (!found)
1073 {
1074 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1075 return CMD_WARNING;
1076 }
1077
1078 return CMD_SUCCESS;
1079}
1080
1081static void
1082if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001083{
1084 struct listnode *node;
1085 struct interface *ifp;
1086
1087 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001088 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001089 {
1090 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001091
1092 len = vty_out (vty, "%s", ifp->name);
1093 vty_out (vty, "%*s", (16 - len), " ");
1094
1095 if (if_is_up(ifp))
1096 {
1097 vty_out (vty, "up ");
1098 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1099 {
1100 if (if_is_running(ifp))
1101 vty_out (vty, "up ");
1102 else
1103 vty_out (vty, "down ");
1104 }
1105 else
1106 {
1107 vty_out (vty, "unknown ");
1108 }
1109 }
1110 else
1111 {
1112 vty_out (vty, "down down ");
1113 }
1114
1115 if (ifp->desc)
1116 vty_out (vty, "%s", ifp->desc);
1117 vty_out (vty, "%s", VTY_NEWLINE);
1118 }
Feng Lua2854772015-05-22 11:40:01 +02001119}
1120
1121DEFUN (show_interface_desc,
1122 show_interface_desc_cmd,
1123 "show interface description",
1124 SHOW_STR
1125 "Interface status and configuration\n"
1126 "Interface description\n")
1127{
1128 vrf_id_t vrf_id = VRF_DEFAULT;
1129
1130 if (argc > 0)
1131 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1132
1133 if_show_description (vty, vrf_id);
1134
1135 return CMD_SUCCESS;
1136}
1137
1138ALIAS (show_interface_desc,
1139 show_interface_desc_vrf_cmd,
1140 "show interface description " VRF_CMD_STR,
1141 SHOW_STR
1142 "Interface status and configuration\n"
1143 "Interface description\n"
1144 VRF_CMD_HELP_STR)
1145
1146DEFUN (show_interface_desc_vrf_all,
1147 show_interface_desc_vrf_all_cmd,
1148 "show interface description " VRF_ALL_CMD_STR,
1149 SHOW_STR
1150 "Interface status and configuration\n"
1151 "Interface description\n"
1152 VRF_ALL_CMD_HELP_STR)
1153{
1154 vrf_iter_t iter;
1155
1156 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1157 if (!list_isempty (vrf_iter2iflist (iter)))
1158 {
1159 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1160 vrf_iter2id (iter),
1161 VTY_NEWLINE, VTY_NEWLINE);
1162 if_show_description (vty, vrf_iter2id (iter));
1163 }
1164
hassoed9bb6d2005-03-13 19:17:21 +00001165 return CMD_SUCCESS;
1166}
1167
paul718e3742002-12-13 20:15:29 +00001168DEFUN (multicast,
1169 multicast_cmd,
1170 "multicast",
1171 "Set multicast flag to interface\n")
1172{
1173 int ret;
1174 struct interface *ifp;
1175 struct zebra_if *if_data;
1176
1177 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001178 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001179 {
paul48b33aa2002-12-13 20:52:52 +00001180 ret = if_set_flags (ifp, IFF_MULTICAST);
1181 if (ret < 0)
1182 {
1183 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1184 return CMD_WARNING;
1185 }
1186 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001187 }
paul718e3742002-12-13 20:15:29 +00001188 if_data = ifp->info;
1189 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001190
paul718e3742002-12-13 20:15:29 +00001191 return CMD_SUCCESS;
1192}
1193
1194DEFUN (no_multicast,
1195 no_multicast_cmd,
1196 "no multicast",
1197 NO_STR
1198 "Unset multicast flag to interface\n")
1199{
1200 int ret;
1201 struct interface *ifp;
1202 struct zebra_if *if_data;
1203
1204 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001205 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001206 {
paul48b33aa2002-12-13 20:52:52 +00001207 ret = if_unset_flags (ifp, IFF_MULTICAST);
1208 if (ret < 0)
1209 {
1210 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1211 return CMD_WARNING;
1212 }
1213 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001214 }
paul718e3742002-12-13 20:15:29 +00001215 if_data = ifp->info;
1216 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1217
1218 return CMD_SUCCESS;
1219}
1220
paul2e3b2e42002-12-13 21:03:13 +00001221DEFUN (linkdetect,
1222 linkdetect_cmd,
1223 "link-detect",
1224 "Enable link detection on interface\n")
1225{
paul2e3b2e42002-12-13 21:03:13 +00001226 struct interface *ifp;
1227 int if_was_operative;
1228
1229 ifp = (struct interface *) vty->index;
1230 if_was_operative = if_is_operative(ifp);
1231 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1232
1233 /* When linkdetection is enabled, if might come down */
1234 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1235
1236 /* FIXME: Will defer status change forwarding if interface
1237 does not come down! */
1238
1239 return CMD_SUCCESS;
1240}
1241
1242
1243DEFUN (no_linkdetect,
1244 no_linkdetect_cmd,
1245 "no link-detect",
1246 NO_STR
1247 "Disable link detection on interface\n")
1248{
paul2e3b2e42002-12-13 21:03:13 +00001249 struct interface *ifp;
1250 int if_was_operative;
1251
1252 ifp = (struct interface *) vty->index;
1253 if_was_operative = if_is_operative(ifp);
1254 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1255
1256 /* Interface may come up after disabling link detection */
1257 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1258
1259 /* FIXME: see linkdetect_cmd */
1260
1261 return CMD_SUCCESS;
1262}
1263
paul718e3742002-12-13 20:15:29 +00001264DEFUN (shutdown_if,
1265 shutdown_if_cmd,
1266 "shutdown",
1267 "Shutdown the selected interface\n")
1268{
1269 int ret;
1270 struct interface *ifp;
1271 struct zebra_if *if_data;
1272
1273 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001274 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001275 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001276 ret = if_unset_flags (ifp, IFF_UP);
1277 if (ret < 0)
1278 {
1279 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1280 return CMD_WARNING;
1281 }
1282 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001283 }
paul718e3742002-12-13 20:15:29 +00001284 if_data = ifp->info;
1285 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1286
1287 return CMD_SUCCESS;
1288}
1289
1290DEFUN (no_shutdown_if,
1291 no_shutdown_if_cmd,
1292 "no shutdown",
1293 NO_STR
1294 "Shutdown the selected interface\n")
1295{
1296 int ret;
1297 struct interface *ifp;
1298 struct zebra_if *if_data;
1299
1300 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001301
1302 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001303 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001304 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1305 if (ret < 0)
1306 {
1307 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1308 return CMD_WARNING;
1309 }
1310 if_refresh (ifp);
1311
1312 /* Some addresses (in particular, IPv6 addresses on Linux) get
1313 * removed when the interface goes down. They need to be readded.
1314 */
1315 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001316 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001317
paul718e3742002-12-13 20:15:29 +00001318 if_data = ifp->info;
1319 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1320
1321 return CMD_SUCCESS;
1322}
1323
1324DEFUN (bandwidth_if,
1325 bandwidth_if_cmd,
1326 "bandwidth <1-10000000>",
1327 "Set bandwidth informational parameter\n"
1328 "Bandwidth in kilobits\n")
1329{
1330 struct interface *ifp;
1331 unsigned int bandwidth;
1332
1333 ifp = (struct interface *) vty->index;
1334 bandwidth = strtol(argv[0], NULL, 10);
1335
1336 /* bandwidth range is <1-10000000> */
1337 if (bandwidth < 1 || bandwidth > 10000000)
1338 {
1339 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1340 return CMD_WARNING;
1341 }
1342
1343 ifp->bandwidth = bandwidth;
1344
1345 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001346 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001347 zebra_interface_up_update (ifp);
1348
1349 return CMD_SUCCESS;
1350}
1351
1352DEFUN (no_bandwidth_if,
1353 no_bandwidth_if_cmd,
1354 "no bandwidth",
1355 NO_STR
1356 "Set bandwidth informational parameter\n")
1357{
1358 struct interface *ifp;
1359
1360 ifp = (struct interface *) vty->index;
1361
1362 ifp->bandwidth = 0;
1363
1364 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001365 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001366 zebra_interface_up_update (ifp);
1367
1368 return CMD_SUCCESS;
1369}
1370
1371ALIAS (no_bandwidth_if,
1372 no_bandwidth_if_val_cmd,
1373 "no bandwidth <1-10000000>",
1374 NO_STR
1375 "Set bandwidth informational parameter\n"
1376 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001377
paula1ac18c2005-06-28 17:17:12 +00001378static int
hasso39db97e2004-10-12 20:50:58 +00001379ip_address_install (struct vty *vty, struct interface *ifp,
1380 const char *addr_str, const char *peer_str,
1381 const char *label)
paul718e3742002-12-13 20:15:29 +00001382{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001383 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001384 struct prefix_ipv4 cp;
1385 struct connected *ifc;
1386 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001387 int ret;
1388
Christian Frankebfac8dc2013-01-24 14:04:50 +00001389 if_data = ifp->info;
1390
paul718e3742002-12-13 20:15:29 +00001391 ret = str2prefix_ipv4 (addr_str, &cp);
1392 if (ret <= 0)
1393 {
1394 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1395 return CMD_WARNING;
1396 }
1397
paulca162182005-09-12 16:58:52 +00001398 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001399 if (! ifc)
1400 {
1401 ifc = connected_new ();
1402 ifc->ifp = ifp;
1403
1404 /* Address. */
1405 p = prefix_ipv4_new ();
1406 *p = cp;
1407 ifc->address = (struct prefix *) p;
1408
1409 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001410 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001411 {
1412 p = prefix_ipv4_new ();
1413 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001414 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001415 ifc->destination = (struct prefix *) p;
1416 }
1417
paul718e3742002-12-13 20:15:29 +00001418 /* Label. */
1419 if (label)
paul0752ef02005-11-03 12:35:21 +00001420 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001421
1422 /* Add to linked list. */
1423 listnode_add (ifp->connected, ifc);
1424 }
1425
1426 /* This address is configured from zebra. */
1427 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1428 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1429
1430 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001431 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001432 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1433 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001434 {
1435 /* Some system need to up the interface to set IP address. */
1436 if (! if_is_up (ifp))
1437 {
1438 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1439 if_refresh (ifp);
1440 }
1441
1442 ret = if_set_prefix (ifp, ifc);
1443 if (ret < 0)
1444 {
1445 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001446 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001447 return CMD_WARNING;
1448 }
1449
Christian Frankef7f740f2013-01-24 14:04:48 +00001450 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001451 /* The address will be advertised to zebra clients when the notification
1452 * from the kernel has been received.
1453 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001454 }
1455
1456 return CMD_SUCCESS;
1457}
1458
paula1ac18c2005-06-28 17:17:12 +00001459static int
hasso39db97e2004-10-12 20:50:58 +00001460ip_address_uninstall (struct vty *vty, struct interface *ifp,
1461 const char *addr_str, const char *peer_str,
1462 const char *label)
paul718e3742002-12-13 20:15:29 +00001463{
1464 struct prefix_ipv4 cp;
1465 struct connected *ifc;
1466 int ret;
1467
1468 /* Convert to prefix structure. */
1469 ret = str2prefix_ipv4 (addr_str, &cp);
1470 if (ret <= 0)
1471 {
1472 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1473 return CMD_WARNING;
1474 }
1475
1476 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001477 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001478 if (! ifc)
1479 {
1480 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1481 return CMD_WARNING;
1482 }
1483
1484 /* This is not configured address. */
1485 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1486 return CMD_WARNING;
1487
Paul Jakma74ecdc92006-06-15 18:10:47 +00001488 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1489
paul718e3742002-12-13 20:15:29 +00001490 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001491 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001492 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1493 {
1494 listnode_delete (ifp->connected, ifc);
1495 connected_free (ifc);
1496 return CMD_WARNING;
1497 }
1498
1499 /* This is real route. */
1500 ret = if_unset_prefix (ifp, ifc);
1501 if (ret < 0)
1502 {
1503 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001504 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001505 return CMD_WARNING;
1506 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001507 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001508 /* we will receive a kernel notification about this route being removed.
1509 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001510 return CMD_SUCCESS;
1511}
1512
1513DEFUN (ip_address,
1514 ip_address_cmd,
1515 "ip address A.B.C.D/M",
1516 "Interface Internet Protocol config commands\n"
1517 "Set the IP address of an interface\n"
1518 "IP address (e.g. 10.0.0.1/8)\n")
1519{
hassoeef1fe12004-10-03 18:46:08 +00001520 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001521}
1522
1523DEFUN (no_ip_address,
1524 no_ip_address_cmd,
1525 "no ip address A.B.C.D/M",
1526 NO_STR
1527 "Interface Internet Protocol config commands\n"
1528 "Set the IP address of an interface\n"
1529 "IP Address (e.g. 10.0.0.1/8)")
1530{
hassoeef1fe12004-10-03 18:46:08 +00001531 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001532}
1533
1534#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001535DEFUN (ip_address_label,
1536 ip_address_label_cmd,
1537 "ip address A.B.C.D/M label LINE",
1538 "Interface Internet Protocol config commands\n"
1539 "Set the IP address of an interface\n"
1540 "IP address (e.g. 10.0.0.1/8)\n"
1541 "Label of this address\n"
1542 "Label\n")
1543{
hassoeef1fe12004-10-03 18:46:08 +00001544 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001545}
1546
1547DEFUN (no_ip_address_label,
1548 no_ip_address_label_cmd,
1549 "no ip address A.B.C.D/M label LINE",
1550 NO_STR
1551 "Interface Internet Protocol config commands\n"
1552 "Set the IP address of an interface\n"
1553 "IP address (e.g. 10.0.0.1/8)\n"
1554 "Label of this address\n"
1555 "Label\n")
1556{
hassoeef1fe12004-10-03 18:46:08 +00001557 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001558}
1559#endif /* HAVE_NETLINK */
1560
1561#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001562static int
hasso39db97e2004-10-12 20:50:58 +00001563ipv6_address_install (struct vty *vty, struct interface *ifp,
1564 const char *addr_str, const char *peer_str,
1565 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001566{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001567 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001568 struct prefix_ipv6 cp;
1569 struct connected *ifc;
1570 struct prefix_ipv6 *p;
1571 int ret;
1572
Christian Frankebfac8dc2013-01-24 14:04:50 +00001573 if_data = ifp->info;
1574
paul718e3742002-12-13 20:15:29 +00001575 ret = str2prefix_ipv6 (addr_str, &cp);
1576 if (ret <= 0)
1577 {
1578 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1579 return CMD_WARNING;
1580 }
1581
paulca162182005-09-12 16:58:52 +00001582 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001583 if (! ifc)
1584 {
1585 ifc = connected_new ();
1586 ifc->ifp = ifp;
1587
1588 /* Address. */
1589 p = prefix_ipv6_new ();
1590 *p = cp;
1591 ifc->address = (struct prefix *) p;
1592
1593 /* Secondary. */
1594 if (secondary)
1595 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1596
1597 /* Label. */
1598 if (label)
paul0752ef02005-11-03 12:35:21 +00001599 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001600
1601 /* Add to linked list. */
1602 listnode_add (ifp->connected, ifc);
1603 }
1604
1605 /* This address is configured from zebra. */
1606 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1607 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1608
1609 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001610 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001611 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1612 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001613 {
1614 /* Some system need to up the interface to set IP address. */
1615 if (! if_is_up (ifp))
1616 {
1617 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1618 if_refresh (ifp);
1619 }
1620
1621 ret = if_prefix_add_ipv6 (ifp, ifc);
1622
1623 if (ret < 0)
1624 {
1625 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001626 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001627 return CMD_WARNING;
1628 }
1629
Christian Frankef7f740f2013-01-24 14:04:48 +00001630 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001631 /* The address will be advertised to zebra clients when the notification
1632 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001633 }
1634
1635 return CMD_SUCCESS;
1636}
1637
paula1ac18c2005-06-28 17:17:12 +00001638static int
hasso39db97e2004-10-12 20:50:58 +00001639ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1640 const char *addr_str, const char *peer_str,
1641 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001642{
1643 struct prefix_ipv6 cp;
1644 struct connected *ifc;
1645 int ret;
1646
1647 /* Convert to prefix structure. */
1648 ret = str2prefix_ipv6 (addr_str, &cp);
1649 if (ret <= 0)
1650 {
1651 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1652 return CMD_WARNING;
1653 }
1654
1655 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001656 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001657 if (! ifc)
1658 {
1659 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1660 return CMD_WARNING;
1661 }
1662
1663 /* This is not configured address. */
1664 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1665 return CMD_WARNING;
1666
Christian Franke676e1a02013-01-24 14:04:45 +00001667 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1668
paul718e3742002-12-13 20:15:29 +00001669 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001670 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001671 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1672 {
1673 listnode_delete (ifp->connected, ifc);
1674 connected_free (ifc);
1675 return CMD_WARNING;
1676 }
1677
1678 /* This is real route. */
1679 ret = if_prefix_delete_ipv6 (ifp, ifc);
1680 if (ret < 0)
1681 {
1682 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001683 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001684 return CMD_WARNING;
1685 }
1686
Christian Frankef7f740f2013-01-24 14:04:48 +00001687 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001688 /* This information will be propagated to the zclients when the
1689 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001690 return CMD_SUCCESS;
1691}
1692
1693DEFUN (ipv6_address,
1694 ipv6_address_cmd,
1695 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001696 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001697 "Set the IP address of an interface\n"
1698 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1699{
1700 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1701}
1702
1703DEFUN (no_ipv6_address,
1704 no_ipv6_address_cmd,
1705 "no ipv6 address X:X::X:X/M",
1706 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001707 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001708 "Set the IP address of an interface\n"
1709 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1710{
1711 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1712}
1713#endif /* HAVE_IPV6 */
1714
paula1ac18c2005-06-28 17:17:12 +00001715static int
paul718e3742002-12-13 20:15:29 +00001716if_config_write (struct vty *vty)
1717{
hasso52dc7ee2004-09-23 19:18:23 +00001718 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001719 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02001720 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00001721
Feng Lu471ea392015-05-22 11:40:00 +02001722 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1723 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00001724 {
1725 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001726 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001727 struct connected *ifc;
1728 struct prefix *p;
1729
paul718e3742002-12-13 20:15:29 +00001730 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02001731
1732 if (ifp->vrf_id == VRF_DEFAULT)
1733 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1734 else
1735 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1736 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001737
Christian Frankebfac8dc2013-01-24 14:04:50 +00001738 if (if_data)
1739 {
1740 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1741 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1742 }
1743
paul718e3742002-12-13 20:15:29 +00001744 if (ifp->desc)
1745 vty_out (vty, " description %s%s", ifp->desc,
1746 VTY_NEWLINE);
1747
1748 /* Assign bandwidth here to avoid unnecessary interface flap
1749 while processing config script */
1750 if (ifp->bandwidth != 0)
1751 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1752
paul2e3b2e42002-12-13 21:03:13 +00001753 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1754 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001755 else
1756 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001757
paul1eb8ef22005-04-07 07:30:20 +00001758 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001759 {
paul718e3742002-12-13 20:15:29 +00001760 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1761 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001762 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001763 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001764 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001765 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001766 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001767
paul718e3742002-12-13 20:15:29 +00001768 if (ifc->label)
1769 vty_out (vty, " label %s", ifc->label);
1770
1771 vty_out (vty, "%s", VTY_NEWLINE);
1772 }
1773 }
1774
1775 if (if_data)
1776 {
paul718e3742002-12-13 20:15:29 +00001777 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1778 vty_out (vty, " %smulticast%s",
1779 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1780 VTY_NEWLINE);
1781 }
1782
1783#ifdef RTADV
1784 rtadv_config_write (vty, ifp);
1785#endif /* RTADV */
1786
hassoca776982004-06-12 14:33:05 +00001787#ifdef HAVE_IRDP
1788 irdp_config_write (vty, ifp);
1789#endif /* IRDP */
1790
paul718e3742002-12-13 20:15:29 +00001791 vty_out (vty, "!%s", VTY_NEWLINE);
1792 }
1793 return 0;
1794}
1795
1796/* Allocate and initialize interface vector. */
1797void
paula1ac18c2005-06-28 17:17:12 +00001798zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001799{
1800 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001801 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1802 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1803
1804 /* Install configuration write function. */
1805 install_node (&interface_node, if_config_write);
1806
1807 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001808 install_element (VIEW_NODE, &show_interface_vrf_cmd);
1809 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
1810 install_element (VIEW_NODE, &show_interface_name_cmd);
1811 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
1812 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001813 install_element (ENABLE_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001814 install_element (ENABLE_NODE, &show_interface_vrf_cmd);
1815 install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
1816 install_element (ENABLE_NODE, &show_interface_name_cmd);
1817 install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
1818 install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001819 install_element (ENABLE_NODE, &show_interface_desc_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001820 install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
1821 install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001822 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001823 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00001824 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001825 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
paul718e3742002-12-13 20:15:29 +00001826 install_default (INTERFACE_NODE);
1827 install_element (INTERFACE_NODE, &interface_desc_cmd);
1828 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1829 install_element (INTERFACE_NODE, &multicast_cmd);
1830 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001831 install_element (INTERFACE_NODE, &linkdetect_cmd);
1832 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001833 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1834 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1835 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1836 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1837 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1838 install_element (INTERFACE_NODE, &ip_address_cmd);
1839 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1840#ifdef HAVE_IPV6
1841 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1842 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1843#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001844#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001845 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001846 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001847#endif /* HAVE_NETLINK */
1848}