blob: 14dc5898f8867867b94c63b08693e3346ace5c45 [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"
Christian Franke581ecbf2016-05-03 19:59:43 +020036#include "command.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/interface.h"
39#include "zebra/rtadv.h"
40#include "zebra/rib.h"
41#include "zebra/zserv.h"
42#include "zebra/redistribute.h"
43#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000044#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000045
Donald Sharp64257732015-11-20 08:33:30 -050046#if defined (HAVE_RTADV)
Chris Caputob60668d2009-05-03 04:40:57 +000047/* Order is intentional. Matches RFC4191. This array is also used for
48 command matching, so only modify with care. */
49const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
Donald Sharp64257732015-11-20 08:33:30 -050050#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +000051
52/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000053static int
paul718e3742002-12-13 20:15:29 +000054if_zebra_new_hook (struct interface *ifp)
55{
56 struct zebra_if *zebra_if;
57
Stephen Hemminger393deb92008-08-18 14:13:29 -070058 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000059
60 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
Christian Frankebfac8dc2013-01-24 14:04:50 +000061 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
paul718e3742002-12-13 20:15:29 +000062
Donald Sharp64257732015-11-20 08:33:30 -050063#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +000064 {
65 /* Set default router advertise values. */
66 struct rtadvconf *rtadv;
67
68 rtadv = &zebra_if->rtadv;
69
70 rtadv->AdvSendAdvertisements = 0;
71 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
72 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
73 rtadv->AdvIntervalTimer = 0;
74 rtadv->AdvManagedFlag = 0;
75 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000076 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000077 rtadv->AdvLinkMTU = 0;
78 rtadv->AdvReachableTime = 0;
79 rtadv->AdvRetransTimer = 0;
80 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040081 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +000082 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040083 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +000084 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +000085 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +000086
87 rtadv->AdvPrefixList = list_new ();
88 }
Donald Sharp64257732015-11-20 08:33:30 -050089#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +000090
hassoeef1fe12004-10-03 18:46:08 +000091 /* Initialize installed address chains tree. */
92 zebra_if->ipv4_subnets = route_table_init ();
93
paul718e3742002-12-13 20:15:29 +000094 ifp->info = zebra_if;
95 return 0;
96}
97
98/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000099static int
paul718e3742002-12-13 20:15:29 +0000100if_zebra_delete_hook (struct interface *ifp)
101{
hassoeef1fe12004-10-03 18:46:08 +0000102 struct zebra_if *zebra_if;
103
paul718e3742002-12-13 20:15:29 +0000104 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000105 {
106 zebra_if = ifp->info;
107
108 /* Free installed address chains tree. */
109 if (zebra_if->ipv4_subnets)
110 route_table_finish (zebra_if->ipv4_subnets);
111
112 XFREE (MTYPE_TMP, zebra_if);
113 }
114
115 return 0;
116}
117
118/* Tie an interface address to its derived subnet list of addresses. */
119int
120if_subnet_add (struct interface *ifp, struct connected *ifc)
121{
122 struct route_node *rn;
123 struct zebra_if *zebra_if;
124 struct prefix cp;
125 struct list *addr_list;
126
127 assert (ifp && ifp->info && ifc);
128 zebra_if = ifp->info;
129
130 /* Get address derived subnet node and associated address list, while marking
131 address secondary attribute appropriately. */
132 cp = *ifc->address;
133 apply_mask (&cp);
134 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
135
136 if ((addr_list = rn->info))
137 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
138 else
139 {
140 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
141 rn->info = addr_list = list_new ();
142 route_lock_node (rn);
143 }
144
145 /* Tie address at the tail of address list. */
146 listnode_add (addr_list, ifc);
147
148 /* Return list element count. */
149 return (addr_list->count);
150}
151
152/* Untie an interface address from its derived subnet list of addresses. */
153int
154if_subnet_delete (struct interface *ifp, struct connected *ifc)
155{
156 struct route_node *rn;
157 struct zebra_if *zebra_if;
158 struct list *addr_list;
159
160 assert (ifp && ifp->info && ifc);
161 zebra_if = ifp->info;
162
163 /* Get address derived subnet node. */
164 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
165 if (! (rn && rn->info))
Christian Franke9db047f2013-01-24 14:04:44 +0000166 {
167 zlog_warn("Trying to remove an address from an unknown subnet."
168 " (please report this bug)");
169 return -1;
170 }
hassoeef1fe12004-10-03 18:46:08 +0000171 route_unlock_node (rn);
172
173 /* Untie address from subnet's address list. */
174 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000175
176 /* Deleting an address that is not registered is a bug.
177 * In any case, we shouldn't decrement the lock counter if the address
178 * is unknown. */
179 if (!listnode_lookup(addr_list, ifc))
180 {
181 zlog_warn("Trying to remove an address from a subnet where it is not"
182 " currently registered. (please report this bug)");
183 return -1;
184 }
185
hassoeef1fe12004-10-03 18:46:08 +0000186 listnode_delete (addr_list, ifc);
187 route_unlock_node (rn);
188
189 /* Return list element count, if not empty. */
190 if (addr_list->count)
191 {
192 /* If deleted address is primary, mark subsequent one as such and distribute. */
193 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
194 {
paul1eb8ef22005-04-07 07:30:20 +0000195 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000196 zebra_interface_address_delete_update (ifp, ifc);
197 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
Christian Franke02b48052013-01-24 14:04:49 +0000198 /* XXX: Linux kernel removes all the secondary addresses when the primary
199 * address is removed. We could try to work around that, though this is
200 * non-trivial. */
hassoeef1fe12004-10-03 18:46:08 +0000201 zebra_interface_address_add_update (ifp, ifc);
202 }
203
204 return addr_list->count;
205 }
206
207 /* Otherwise, free list and route node. */
208 list_free (addr_list);
209 rn->info = NULL;
210 route_unlock_node (rn);
211
paul718e3742002-12-13 20:15:29 +0000212 return 0;
213}
214
paul5c78b3d2006-01-25 04:31:40 +0000215/* if_flags_mangle: A place for hacks that require mangling
216 * or tweaking the interface flags.
217 *
218 * ******************** Solaris flags hacks **************************
219 *
220 * Solaris IFF_UP flag reflects only the primary interface as the
221 * routing socket only sends IFINFO for the primary interface. Hence
222 * ~IFF_UP does not per se imply all the logical interfaces are also
223 * down - which we only know of as addresses. Instead we must determine
224 * whether the interface really is up or not according to how many
225 * addresses are still attached. (Solaris always sends RTM_DELADDR if
226 * an interface, logical or not, goes ~IFF_UP).
227 *
228 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
229 * are addresses left in struct connected, not just the actual underlying
230 * IFF_UP flag.
231 *
232 * We must hence remember the real state of IFF_UP, which we do in
233 * struct zebra_if.primary_state.
234 *
235 * Setting IFF_UP within zebra to administratively shutdown the
236 * interface will affect only the primary interface/address on Solaris.
237 ************************End Solaris flags hacks ***********************
238 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100239static void
paul5c78b3d2006-01-25 04:31:40 +0000240if_flags_mangle (struct interface *ifp, uint64_t *newflags)
241{
242#ifdef SUNOS_5
243 struct zebra_if *zif = ifp->info;
244
245 zif->primary_state = *newflags & (IFF_UP & 0xff);
246
247 if (CHECK_FLAG (zif->primary_state, IFF_UP)
248 || listcount(ifp->connected) > 0)
249 SET_FLAG (*newflags, IFF_UP);
250 else
251 UNSET_FLAG (*newflags, IFF_UP);
252#endif /* SUNOS_5 */
253}
254
255/* Update the flags field of the ifp with the new flag set provided.
256 * Take whatever actions are required for any changes in flags we care
257 * about.
258 *
259 * newflags should be the raw value, as obtained from the OS.
260 */
261void
262if_flags_update (struct interface *ifp, uint64_t newflags)
263{
264 if_flags_mangle (ifp, &newflags);
265
266 if (if_is_operative (ifp))
267 {
268 /* operative -> inoperative? */
269 ifp->flags = newflags;
270 if (!if_is_operative (ifp))
271 if_down (ifp);
272 }
273 else
274 {
275 /* inoperative -> operative? */
276 ifp->flags = newflags;
277 if (if_is_operative (ifp))
278 if_up (ifp);
279 }
280}
281
paul718e3742002-12-13 20:15:29 +0000282/* Wake up configured address if it is not in current kernel
283 address. */
paula1ac18c2005-06-28 17:17:12 +0000284static void
paul718e3742002-12-13 20:15:29 +0000285if_addr_wakeup (struct interface *ifp)
286{
paul1eb8ef22005-04-07 07:30:20 +0000287 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000288 struct connected *ifc;
289 struct prefix *p;
290 int ret;
291
paul1eb8ef22005-04-07 07:30:20 +0000292 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000293 {
paul718e3742002-12-13 20:15:29 +0000294 p = ifc->address;
295
296 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000297 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000298 {
299 /* Address check. */
300 if (p->family == AF_INET)
301 {
302 if (! if_is_up (ifp))
303 {
Christian Franke02b48052013-01-24 14:04:49 +0000304 /* Assume zebra is configured like following:
305 *
306 * interface gre0
307 * ip addr 192.0.2.1/24
308 * !
309 *
310 * As soon as zebra becomes first aware that gre0 exists in the
311 * kernel, it will set gre0 up and configure its addresses.
312 *
313 * (This may happen at startup when the interface already exists
314 * or during runtime when the interface is added to the kernel)
315 *
316 * XXX: IRDP code is calling here via if_add_update - this seems
317 * somewhat weird.
318 * XXX: RUNNING is not a settable flag on any system
319 * I (paulj) am aware of.
320 */
paul718e3742002-12-13 20:15:29 +0000321 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
322 if_refresh (ifp);
323 }
324
325 ret = if_set_prefix (ifp, ifc);
326 if (ret < 0)
327 {
328 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000329 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000330 continue;
331 }
hassoeef1fe12004-10-03 18:46:08 +0000332
Christian Frankef7f740f2013-01-24 14:04:48 +0000333 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000334 /* The address will be advertised to zebra clients when the notification
335 * from the kernel has been received.
336 * It will also be added to the interface's subnet list then. */
paul718e3742002-12-13 20:15:29 +0000337 }
338#ifdef HAVE_IPV6
339 if (p->family == AF_INET6)
340 {
341 if (! if_is_up (ifp))
342 {
Christian Franke02b48052013-01-24 14:04:49 +0000343 /* See long comment above */
paul718e3742002-12-13 20:15:29 +0000344 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
345 if_refresh (ifp);
346 }
347
348 ret = if_prefix_add_ipv6 (ifp, ifc);
349 if (ret < 0)
350 {
351 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000352 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000353 continue;
354 }
Christian Franke02b48052013-01-24 14:04:49 +0000355
Christian Frankef7f740f2013-01-24 14:04:48 +0000356 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000357 /* The address will be advertised to zebra clients when the notification
358 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +0000359 }
360#endif /* HAVE_IPV6 */
361 }
362 }
363}
364
Christian Franke581ecbf2016-05-03 19:59:43 +0200365static void if_count_up(struct zebra_if *zif)
366{
367 event_counter_inc(&zif->up_events);
368}
369
370static void if_count_down(struct zebra_if *zif)
371{
372 event_counter_inc(&zif->down_events);
373}
374
375void
376if_startup_count_up (void)
377{
378 vrf_iter_t iter;
379 struct interface *ifp;
380 struct zebra_if *zif;
381 struct listnode *node;
382
383 for (iter = vrf_first(); iter != VRF_ITER_INVALID; iter = vrf_next(iter))
384 {
385 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist(iter), node, ifp))
386 {
387 zif = ifp->info;
388 if (!zif->up_events.count && if_is_operative(ifp))
389 if_count_up(zif);
390 }
391 }
392}
393
paul718e3742002-12-13 20:15:29 +0000394/* Handle interface addition */
395void
396if_add_update (struct interface *ifp)
397{
paul48b33aa2002-12-13 20:52:52 +0000398 struct zebra_if *if_data;
399
400 if_data = ifp->info;
Morgan Stewartc8394ac2015-09-17 19:04:30 -0400401 assert(if_data);
402
paul48b33aa2002-12-13 20:52:52 +0000403 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
404 if_set_flags (ifp, IFF_MULTICAST);
405 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
406 if_unset_flags (ifp, IFF_MULTICAST);
407
paul718e3742002-12-13 20:15:29 +0000408 zebra_interface_add_update (ifp);
409
410 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
411 {
412 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
413
Christian Frankebfac8dc2013-01-24 14:04:50 +0000414 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
415 {
416 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200417 zlog_debug ("interface %s vrf %u index %d is shutdown. "
418 "Won't wake it up.",
419 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000420 return;
421 }
422
paul718e3742002-12-13 20:15:29 +0000423 if_addr_wakeup (ifp);
424
425 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200426 zlog_debug ("interface %s vrf %u index %d becomes active.",
427 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000428 }
429 else
430 {
431 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200432 zlog_debug ("interface %s vrf %u index %d is added.",
433 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000434 }
Christian Franke581ecbf2016-05-03 19:59:43 +0200435
436 if (host_config_get())
437 {
438 /* If configuration and therefore link-detect have already been
439 * loaded, count an initial up event when new interfaces are added
440 * in up state.
441 * If configuration has not been loaded yet, this is handled by
442 * if_startup_count_up which is called after reading the config. */
443 if (!if_data->up_events.count && if_is_operative(ifp))
444 if_count_up(if_data);
445 }
paul718e3742002-12-13 20:15:29 +0000446}
447
paul6eb88272005-07-29 14:36:00 +0000448/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000449void
450if_delete_update (struct interface *ifp)
451{
paul718e3742002-12-13 20:15:29 +0000452 struct connected *ifc;
453 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000454 struct route_node *rn;
455 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000456
457 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000458
459 if (if_is_up(ifp))
460 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200461 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
462 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000463 return;
464 }
465
466 /* Mark interface as inactive */
467 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
468
469 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200470 zlog_debug ("interface %s vrf %u index %d is now inactive.",
471 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000472
473 /* Delete connected routes from the kernel. */
474 if (ifp->connected)
475 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000476 struct listnode *node;
477 struct listnode *last = NULL;
478
hassoeef1fe12004-10-03 18:46:08 +0000479 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000480 {
paul1eb8ef22005-04-07 07:30:20 +0000481 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000482 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000483
Paul Jakmabeb56332006-05-11 13:28:05 +0000484 if (p->family == AF_INET
485 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000486 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000487 struct listnode *anode;
488 struct listnode *next;
489 struct listnode *first;
490 struct list *addr_list;
491
hassoeef1fe12004-10-03 18:46:08 +0000492 route_unlock_node (rn);
493 addr_list = (struct list *) rn->info;
494
495 /* Remove addresses, secondaries first. */
496 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000497 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000498 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000499 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000500 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000501 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000502 first = NULL;
503 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000504 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000505
Paul Jakmad9a18f12007-04-10 19:30:20 +0000506 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000507 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000508 connected_down_ipv4 (ifp, ifc);
509
Christian Franke02b48052013-01-24 14:04:49 +0000510 /* XXX: We have to send notifications here explicitly, because we destroy
511 * the ifc before receiving the notification about the address being deleted.
512 */
hassoeef1fe12004-10-03 18:46:08 +0000513 zebra_interface_address_delete_update (ifp, ifc);
514
515 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000516 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000517
518 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000519 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000520 route_unlock_node (rn);
521
522 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000523 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
524 {
525 listnode_delete (ifp->connected, ifc);
526 connected_free (ifc);
527 }
528 else
529 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000530 }
531
532 /* Free chain list and respective route node. */
533 list_delete (addr_list);
534 rn->info = NULL;
535 route_unlock_node (rn);
536 }
paul718e3742002-12-13 20:15:29 +0000537#ifdef HAVE_IPV6
538 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000539 {
540 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000541
hassoeef1fe12004-10-03 18:46:08 +0000542 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000543
hassoeef1fe12004-10-03 18:46:08 +0000544 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000545 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000546
547 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
548 last = node;
549 else
550 {
551 listnode_delete (ifp->connected, ifc);
552 connected_free (ifc);
553 }
paul718e3742002-12-13 20:15:29 +0000554 }
hassoeef1fe12004-10-03 18:46:08 +0000555#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200556 else
557 {
558 last = node;
559 }
paul718e3742002-12-13 20:15:29 +0000560 }
561 }
562 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000563
564 /* Update ifindex after distributing the delete message. This is in
565 case any client needs to have the old value of ifindex available
566 while processing the deletion. Each client daemon is responsible
567 for setting ifindex to IFINDEX_INTERNAL after processing the
568 interface deletion message. */
569 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000570}
571
572/* Interface is up. */
573void
574if_up (struct interface *ifp)
575{
hasso52dc7ee2004-09-23 19:18:23 +0000576 struct listnode *node;
577 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000578 struct connected *ifc;
579 struct prefix *p;
580
Christian Franke581ecbf2016-05-03 19:59:43 +0200581 if_count_up(ifp->info);
582
paul718e3742002-12-13 20:15:29 +0000583 /* Notify the protocol daemons. */
584 zebra_interface_up_update (ifp);
585
586 /* Install connected routes to the kernel. */
587 if (ifp->connected)
588 {
paul1eb8ef22005-04-07 07:30:20 +0000589 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000590 {
paul718e3742002-12-13 20:15:29 +0000591 p = ifc->address;
592
593 if (p->family == AF_INET)
594 connected_up_ipv4 (ifp, ifc);
595#ifdef HAVE_IPV6
596 else if (p->family == AF_INET6)
597 connected_up_ipv6 (ifp, ifc);
598#endif /* HAVE_IPV6 */
599 }
600 }
601
602 /* Examine all static routes. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200603 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000604}
605
606/* Interface goes down. We have to manage different behavior of based
607 OS. */
608void
609if_down (struct interface *ifp)
610{
hasso52dc7ee2004-09-23 19:18:23 +0000611 struct listnode *node;
612 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000613 struct connected *ifc;
614 struct prefix *p;
Christian Franke581ecbf2016-05-03 19:59:43 +0200615 struct zebra_if *zif;
616
617 zif = ifp->info;
618 if (zif->up_events.count)
619 if_count_down(zif);
paul718e3742002-12-13 20:15:29 +0000620
621 /* Notify to the protocol daemons. */
622 zebra_interface_down_update (ifp);
623
624 /* Delete connected routes from the kernel. */
625 if (ifp->connected)
626 {
paul1eb8ef22005-04-07 07:30:20 +0000627 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000628 {
paul718e3742002-12-13 20:15:29 +0000629 p = ifc->address;
630
631 if (p->family == AF_INET)
632 connected_down_ipv4 (ifp, ifc);
633#ifdef HAVE_IPV6
634 else if (p->family == AF_INET6)
635 connected_down_ipv6 (ifp, ifc);
636#endif /* HAVE_IPV6 */
637 }
638 }
639
640 /* Examine all static routes which direct to the interface. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200641 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000642}
643
644void
645if_refresh (struct interface *ifp)
646{
paul5c78b3d2006-01-25 04:31:40 +0000647 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000648}
649
paul718e3742002-12-13 20:15:29 +0000650/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000651static int
paul718e3742002-12-13 20:15:29 +0000652prefix_vty_out (struct vty *vty, struct prefix *p)
653{
654 char str[INET6_ADDRSTRLEN];
655
656 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
657 vty_out (vty, "%s", str);
658 return strlen (str);
659}
660
661/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000662static void
paul718e3742002-12-13 20:15:29 +0000663connected_dump_vty (struct vty *vty, struct connected *connected)
664{
665 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000666
667 /* Print interface address. */
668 p = connected->address;
669 vty_out (vty, " %s ", prefix_family_str (p));
670 prefix_vty_out (vty, p);
671 vty_out (vty, "/%d", p->prefixlen);
672
673 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000674 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000675 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000676 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
677 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000678 }
679
680 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
681 vty_out (vty, " secondary");
682
683 if (connected->label)
684 vty_out (vty, " %s", connected->label);
685
686 vty_out (vty, "%s", VTY_NEWLINE);
687}
688
Donald Sharp64257732015-11-20 08:33:30 -0500689#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000690/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000691static void
paul718e3742002-12-13 20:15:29 +0000692nd_dump_vty (struct vty *vty, struct interface *ifp)
693{
694 struct zebra_if *zif;
695 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000696 int interval;
paul718e3742002-12-13 20:15:29 +0000697
698 zif = (struct zebra_if *) ifp->info;
699 rtadv = &zif->rtadv;
700
701 if (rtadv->AdvSendAdvertisements)
702 {
703 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
704 rtadv->AdvReachableTime, VTY_NEWLINE);
705 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
706 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000707 interval = rtadv->MaxRtrAdvInterval;
708 if (interval % 1000)
709 vty_out (vty, " ND router advertisements are sent every "
710 "%d milliseconds%s", interval,
711 VTY_NEWLINE);
712 else
713 vty_out (vty, " ND router advertisements are sent every "
714 "%d seconds%s", interval / 1000,
715 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400716 if (rtadv->AdvDefaultLifetime != -1)
717 vty_out (vty, " ND router advertisements live for %d seconds%s",
718 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
719 else
720 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
721 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000722 vty_out (vty, " ND router advertisement default router preference is "
723 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
724 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000725 if (rtadv->AdvManagedFlag)
726 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
727 VTY_NEWLINE);
728 else
729 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
730 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000731 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400732 {
vincent7cee1bb2005-03-25 13:08:53 +0000733 vty_out (vty, " ND router advertisements with "
734 "Home Agent flag bit set.%s",
735 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400736 if (rtadv->HomeAgentLifetime != -1)
737 vty_out (vty, " Home Agent lifetime is %u seconds%s",
738 rtadv->HomeAgentLifetime, VTY_NEWLINE);
739 else
740 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
741 VTY_NEWLINE);
742 vty_out (vty, " Home Agent preference is %u%s",
743 rtadv->HomeAgentPreference, VTY_NEWLINE);
744 }
vincent7cee1bb2005-03-25 13:08:53 +0000745 if (rtadv->AdvIntervalOption)
746 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
747 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000748 }
749}
Donald Sharp64257732015-11-20 08:33:30 -0500750#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000751
752/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000753static void
paul718e3742002-12-13 20:15:29 +0000754if_dump_vty (struct vty *vty, struct interface *ifp)
755{
paul718e3742002-12-13 20:15:29 +0000756 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000757 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000758 struct route_node *rn;
759 struct zebra_if *zebra_if;
760
761 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000762
paul2e3b2e42002-12-13 21:03:13 +0000763 vty_out (vty, "Interface %s is ", ifp->name);
764 if (if_is_up(ifp)) {
765 vty_out (vty, "up, line protocol ");
766
767 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
768 if (if_is_running(ifp))
769 vty_out (vty, "is up%s", VTY_NEWLINE);
770 else
771 vty_out (vty, "is down%s", VTY_NEWLINE);
772 } else {
773 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
774 }
775 } else {
776 vty_out (vty, "down%s", VTY_NEWLINE);
777 }
778
Christian Franke581ecbf2016-05-03 19:59:43 +0200779 vty_out (vty, " Link ups: %s%s",
780 event_counter_format(&zebra_if->up_events), VTY_NEWLINE);
781 vty_out (vty, " Link downs: %s%s",
782 event_counter_format(&zebra_if->down_events), VTY_NEWLINE);
783
Feng Lu2fc97f62015-05-22 11:39:57 +0200784 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
785
paul718e3742002-12-13 20:15:29 +0000786 if (ifp->desc)
787 vty_out (vty, " Description: %s%s", ifp->desc,
788 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000789 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000790 {
ajsd2fc8892005-04-02 18:38:43 +0000791 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000792 return;
793 }
794 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
795 {
796 vty_out(vty, " index %d inactive interface%s",
797 ifp->ifindex,
798 VTY_NEWLINE);
799 return;
800 }
801
802 vty_out (vty, " index %d metric %d mtu %d ",
803 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000804#ifdef HAVE_IPV6
805 if (ifp->mtu6 != ifp->mtu)
806 vty_out (vty, "mtu6 %d ", ifp->mtu6);
807#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000808 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
809 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000810
paul718e3742002-12-13 20:15:29 +0000811 /* Hardware address. */
Timo Teräs954c7d62016-01-15 17:36:33 +0200812 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000813 if (ifp->hw_addr_len != 0)
814 {
815 int i;
816
817 vty_out (vty, " HWaddr: ");
818 for (i = 0; i < ifp->hw_addr_len; i++)
819 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
820 vty_out (vty, "%s", VTY_NEWLINE);
821 }
paul718e3742002-12-13 20:15:29 +0000822
823 /* Bandwidth in kbps */
824 if (ifp->bandwidth != 0)
825 {
826 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
827 vty_out(vty, "%s", VTY_NEWLINE);
828 }
829
hassoeef1fe12004-10-03 18:46:08 +0000830 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000831 {
hassoeef1fe12004-10-03 18:46:08 +0000832 if (! rn->info)
833 continue;
834
paul1eb8ef22005-04-07 07:30:20 +0000835 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
836 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000837 }
838
paul1eb8ef22005-04-07 07:30:20 +0000839 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000840 {
hasso39db97e2004-10-12 20:50:58 +0000841 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
842 (connected->address->family == AF_INET6))
843 connected_dump_vty (vty, connected);
844 }
845
Donald Sharp64257732015-11-20 08:33:30 -0500846#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000847 nd_dump_vty (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -0500848#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000849
850#ifdef HAVE_PROC_NET_DEV
851 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000852 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
853 "%lu dropped%s",
854 ifp->stats.rx_packets, ifp->stats.rx_multicast,
855 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000856
hasso6f2c27a2005-01-18 13:44:35 +0000857 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000858 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000859 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
860 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000861 ifp->stats.rx_frame_errors, VTY_NEWLINE);
862
863 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000864 ifp->stats.rx_missed_errors, VTY_NEWLINE);
865
hasso6f2c27a2005-01-18 13:44:35 +0000866 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000867 ifp->stats.tx_packets, ifp->stats.tx_bytes,
868 ifp->stats.tx_dropped, VTY_NEWLINE);
869
hasso6f2c27a2005-01-18 13:44:35 +0000870 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
871 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000872 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
873 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000874 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000875
hasso6f2c27a2005-01-18 13:44:35 +0000876 vty_out (vty, " %lu window, %lu collisions%s",
877 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000878#endif /* HAVE_PROC_NET_DEV */
879
880#ifdef HAVE_NET_RT_IFLIST
881#if defined (__bsdi__) || defined (__NetBSD__)
882 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200883 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
884 " multicast packets %llu%s",
885 (unsigned long long)ifp->stats.ifi_ipackets,
886 (unsigned long long)ifp->stats.ifi_ibytes,
887 (unsigned long long)ifp->stats.ifi_iqdrops,
888 (unsigned long long)ifp->stats.ifi_imcasts,
889 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000890
David Lamparter193e78f2015-04-21 10:42:30 +0200891 vty_out (vty, " input errors %llu%s",
892 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000893
David Lamparter193e78f2015-04-21 10:42:30 +0200894 vty_out (vty, " output packets %llu, bytes %llu,"
895 " multicast packets %llu%s",
896 (unsigned long long)ifp->stats.ifi_opackets,
897 (unsigned long long)ifp->stats.ifi_obytes,
898 (unsigned long long)ifp->stats.ifi_omcasts,
899 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000900
David Lamparter193e78f2015-04-21 10:42:30 +0200901 vty_out (vty, " output errors %llu%s",
902 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000903
David Lamparter193e78f2015-04-21 10:42:30 +0200904 vty_out (vty, " collisions %llu%s",
905 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000906#else
907 /* Statistics print out using sysctl (). */
908 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
909 " multicast packets %lu%s",
910 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
911 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
912 VTY_NEWLINE);
913
914 vty_out (vty, " input errors %lu%s",
915 ifp->stats.ifi_ierrors, VTY_NEWLINE);
916
917 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
918 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
919 ifp->stats.ifi_omcasts, VTY_NEWLINE);
920
921 vty_out (vty, " output errors %lu%s",
922 ifp->stats.ifi_oerrors, VTY_NEWLINE);
923
924 vty_out (vty, " collisions %lu%s",
925 ifp->stats.ifi_collisions, VTY_NEWLINE);
926#endif /* __bsdi__ || __NetBSD__ */
927#endif /* HAVE_NET_RT_IFLIST */
928}
929
paul718e3742002-12-13 20:15:29 +0000930/* Wrapper hook point for zebra daemon so that ifindex can be set
931 * DEFUN macro not used as extract.pl HAS to ignore this
932 * See also interface_cmd in lib/if.c
933 */
934DEFUN_NOSH (zebra_interface,
935 zebra_interface_cmd,
936 "interface IFNAME",
937 "Select an interface to configure\n"
938 "Interface's name\n")
939{
940 int ret;
941 struct interface * ifp;
942
943 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000944 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
945 return ret;
paul718e3742002-12-13 20:15:29 +0000946
947 ifp = vty->index;
948
ajsd2fc8892005-04-02 18:38:43 +0000949 if (ifp->ifindex == IFINDEX_INTERNAL)
950 /* Is this really necessary? Shouldn't status be initialized to 0
951 in that case? */
952 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000953
954 return ret;
955}
956
Feng Lu471ea392015-05-22 11:40:00 +0200957ALIAS (zebra_interface,
958 zebra_interface_vrf_cmd,
959 "interface IFNAME " VRF_CMD_STR,
960 "Select an interface to configure\n"
961 "Interface's name\n"
962 VRF_CMD_HELP_STR)
963
paul718e3742002-12-13 20:15:29 +0000964struct cmd_node interface_node =
965{
966 INTERFACE_NODE,
967 "%s(config-if)# ",
968 1
969};
970
Feng Lua2854772015-05-22 11:40:01 +0200971/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +0000972DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +0200973 "show interface",
paul718e3742002-12-13 20:15:29 +0000974 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +0200975 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +0000976{
hasso52dc7ee2004-09-23 19:18:23 +0000977 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000978 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +0200979 vrf_id_t vrf_id = VRF_DEFAULT;
980
paul718e3742002-12-13 20:15:29 +0000981#ifdef HAVE_PROC_NET_DEV
982 /* If system has interface statistics via proc file system, update
983 statistics. */
984 ifstat_update_proc ();
985#endif /* HAVE_PROC_NET_DEV */
986#ifdef HAVE_NET_RT_IFLIST
987 ifstat_update_sysctl ();
988#endif /* HAVE_NET_RT_IFLIST */
989
Feng Lua2854772015-05-22 11:40:01 +0200990 if (argc > 0)
991 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +0000992
993 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +0200994 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +0000995 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000996
997 return CMD_SUCCESS;
998}
999
Feng Lua2854772015-05-22 11:40:01 +02001000ALIAS (show_interface,
1001 show_interface_vrf_cmd,
1002 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +00001003 SHOW_STR
1004 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +02001005 VRF_CMD_HELP_STR)
1006
1007/* Show all interfaces to vty. */
1008DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
1009 "show interface " VRF_ALL_CMD_STR,
1010 SHOW_STR
1011 "Interface status and configuration\n"
1012 VRF_ALL_CMD_HELP_STR)
1013{
1014 struct listnode *node;
1015 struct interface *ifp;
1016 vrf_iter_t iter;
1017
1018#ifdef HAVE_PROC_NET_DEV
1019 /* If system has interface statistics via proc file system, update
1020 statistics. */
1021 ifstat_update_proc ();
1022#endif /* HAVE_PROC_NET_DEV */
1023#ifdef HAVE_NET_RT_IFLIST
1024 ifstat_update_sysctl ();
1025#endif /* HAVE_NET_RT_IFLIST */
1026
1027 /* All interface print. */
1028 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1029 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1030 if_dump_vty (vty, ifp);
1031
1032 return CMD_SUCCESS;
1033}
1034
1035/* Show specified interface to vty. */
1036DEFUN (show_interface_name, show_interface_name_cmd,
1037 "show interface IFNAME",
1038 SHOW_STR
1039 "Interface status and configuration\n"
1040 "Inteface name\n")
1041{
1042 struct interface *ifp;
1043 vrf_id_t vrf_id = VRF_DEFAULT;
1044
1045#ifdef HAVE_PROC_NET_DEV
1046 /* If system has interface statistics via proc file system, update
1047 statistics. */
1048 ifstat_update_proc ();
1049#endif /* HAVE_PROC_NET_DEV */
1050#ifdef HAVE_NET_RT_IFLIST
1051 ifstat_update_sysctl ();
1052#endif /* HAVE_NET_RT_IFLIST */
1053
1054 if (argc > 1)
1055 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1056
1057 /* Specified interface print. */
1058 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1059 if (ifp == NULL)
1060 {
1061 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1062 VTY_NEWLINE);
1063 return CMD_WARNING;
1064 }
1065 if_dump_vty (vty, ifp);
1066
1067 return CMD_SUCCESS;
1068}
1069
1070ALIAS (show_interface_name,
1071 show_interface_name_vrf_cmd,
1072 "show interface IFNAME " VRF_CMD_STR,
1073 SHOW_STR
1074 "Interface status and configuration\n"
1075 "Inteface name\n"
1076 VRF_CMD_HELP_STR)
1077
1078/* Show specified interface to vty. */
1079DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1080 "show interface IFNAME " VRF_ALL_CMD_STR,
1081 SHOW_STR
1082 "Interface status and configuration\n"
1083 "Inteface name\n"
1084 VRF_ALL_CMD_HELP_STR)
1085{
1086 struct interface *ifp;
1087 vrf_iter_t iter;
1088 int found = 0;
1089
1090#ifdef HAVE_PROC_NET_DEV
1091 /* If system has interface statistics via proc file system, update
1092 statistics. */
1093 ifstat_update_proc ();
1094#endif /* HAVE_PROC_NET_DEV */
1095#ifdef HAVE_NET_RT_IFLIST
1096 ifstat_update_sysctl ();
1097#endif /* HAVE_NET_RT_IFLIST */
1098
1099 /* All interface print. */
1100 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1101 {
1102 /* Specified interface print. */
1103 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1104 if (ifp)
1105 {
1106 if_dump_vty (vty, ifp);
1107 found++;
1108 }
1109 }
1110
1111 if (!found)
1112 {
1113 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1114 return CMD_WARNING;
1115 }
1116
1117 return CMD_SUCCESS;
1118}
1119
1120static void
1121if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001122{
1123 struct listnode *node;
1124 struct interface *ifp;
1125
1126 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001127 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001128 {
1129 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001130
1131 len = vty_out (vty, "%s", ifp->name);
1132 vty_out (vty, "%*s", (16 - len), " ");
1133
1134 if (if_is_up(ifp))
1135 {
1136 vty_out (vty, "up ");
1137 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1138 {
1139 if (if_is_running(ifp))
1140 vty_out (vty, "up ");
1141 else
1142 vty_out (vty, "down ");
1143 }
1144 else
1145 {
1146 vty_out (vty, "unknown ");
1147 }
1148 }
1149 else
1150 {
1151 vty_out (vty, "down down ");
1152 }
1153
1154 if (ifp->desc)
1155 vty_out (vty, "%s", ifp->desc);
1156 vty_out (vty, "%s", VTY_NEWLINE);
1157 }
Feng Lua2854772015-05-22 11:40:01 +02001158}
1159
1160DEFUN (show_interface_desc,
1161 show_interface_desc_cmd,
1162 "show interface description",
1163 SHOW_STR
1164 "Interface status and configuration\n"
1165 "Interface description\n")
1166{
1167 vrf_id_t vrf_id = VRF_DEFAULT;
1168
1169 if (argc > 0)
1170 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1171
1172 if_show_description (vty, vrf_id);
1173
1174 return CMD_SUCCESS;
1175}
1176
1177ALIAS (show_interface_desc,
1178 show_interface_desc_vrf_cmd,
1179 "show interface description " VRF_CMD_STR,
1180 SHOW_STR
1181 "Interface status and configuration\n"
1182 "Interface description\n"
1183 VRF_CMD_HELP_STR)
1184
1185DEFUN (show_interface_desc_vrf_all,
1186 show_interface_desc_vrf_all_cmd,
1187 "show interface description " VRF_ALL_CMD_STR,
1188 SHOW_STR
1189 "Interface status and configuration\n"
1190 "Interface description\n"
1191 VRF_ALL_CMD_HELP_STR)
1192{
1193 vrf_iter_t iter;
1194
1195 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1196 if (!list_isempty (vrf_iter2iflist (iter)))
1197 {
1198 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1199 vrf_iter2id (iter),
1200 VTY_NEWLINE, VTY_NEWLINE);
1201 if_show_description (vty, vrf_iter2id (iter));
1202 }
1203
hassoed9bb6d2005-03-13 19:17:21 +00001204 return CMD_SUCCESS;
1205}
1206
paul718e3742002-12-13 20:15:29 +00001207DEFUN (multicast,
1208 multicast_cmd,
1209 "multicast",
1210 "Set multicast flag to interface\n")
1211{
1212 int ret;
1213 struct interface *ifp;
1214 struct zebra_if *if_data;
1215
1216 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001217 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001218 {
paul48b33aa2002-12-13 20:52:52 +00001219 ret = if_set_flags (ifp, IFF_MULTICAST);
1220 if (ret < 0)
1221 {
1222 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1223 return CMD_WARNING;
1224 }
1225 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001226 }
paul718e3742002-12-13 20:15:29 +00001227 if_data = ifp->info;
1228 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001229
paul718e3742002-12-13 20:15:29 +00001230 return CMD_SUCCESS;
1231}
1232
1233DEFUN (no_multicast,
1234 no_multicast_cmd,
1235 "no multicast",
1236 NO_STR
1237 "Unset multicast flag to interface\n")
1238{
1239 int ret;
1240 struct interface *ifp;
1241 struct zebra_if *if_data;
1242
1243 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001244 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001245 {
paul48b33aa2002-12-13 20:52:52 +00001246 ret = if_unset_flags (ifp, IFF_MULTICAST);
1247 if (ret < 0)
1248 {
1249 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1250 return CMD_WARNING;
1251 }
1252 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001253 }
paul718e3742002-12-13 20:15:29 +00001254 if_data = ifp->info;
1255 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1256
1257 return CMD_SUCCESS;
1258}
1259
paul2e3b2e42002-12-13 21:03:13 +00001260DEFUN (linkdetect,
1261 linkdetect_cmd,
1262 "link-detect",
1263 "Enable link detection on interface\n")
1264{
paul2e3b2e42002-12-13 21:03:13 +00001265 struct interface *ifp;
1266 int if_was_operative;
1267
1268 ifp = (struct interface *) vty->index;
1269 if_was_operative = if_is_operative(ifp);
1270 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1271
1272 /* When linkdetection is enabled, if might come down */
1273 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1274
1275 /* FIXME: Will defer status change forwarding if interface
1276 does not come down! */
1277
1278 return CMD_SUCCESS;
1279}
1280
1281
1282DEFUN (no_linkdetect,
1283 no_linkdetect_cmd,
1284 "no link-detect",
1285 NO_STR
1286 "Disable link detection on interface\n")
1287{
paul2e3b2e42002-12-13 21:03:13 +00001288 struct interface *ifp;
1289 int if_was_operative;
1290
1291 ifp = (struct interface *) vty->index;
1292 if_was_operative = if_is_operative(ifp);
1293 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1294
1295 /* Interface may come up after disabling link detection */
1296 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1297
1298 /* FIXME: see linkdetect_cmd */
1299
1300 return CMD_SUCCESS;
1301}
1302
paul718e3742002-12-13 20:15:29 +00001303DEFUN (shutdown_if,
1304 shutdown_if_cmd,
1305 "shutdown",
1306 "Shutdown the selected interface\n")
1307{
1308 int ret;
1309 struct interface *ifp;
1310 struct zebra_if *if_data;
1311
1312 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001313 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001314 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001315 ret = if_unset_flags (ifp, IFF_UP);
1316 if (ret < 0)
1317 {
1318 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1319 return CMD_WARNING;
1320 }
1321 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001322 }
paul718e3742002-12-13 20:15:29 +00001323 if_data = ifp->info;
1324 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1325
1326 return CMD_SUCCESS;
1327}
1328
1329DEFUN (no_shutdown_if,
1330 no_shutdown_if_cmd,
1331 "no shutdown",
1332 NO_STR
1333 "Shutdown the selected interface\n")
1334{
1335 int ret;
1336 struct interface *ifp;
1337 struct zebra_if *if_data;
1338
1339 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001340
1341 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001342 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001343 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1344 if (ret < 0)
1345 {
1346 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1347 return CMD_WARNING;
1348 }
1349 if_refresh (ifp);
1350
1351 /* Some addresses (in particular, IPv6 addresses on Linux) get
1352 * removed when the interface goes down. They need to be readded.
1353 */
1354 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001355 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001356
paul718e3742002-12-13 20:15:29 +00001357 if_data = ifp->info;
1358 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1359
1360 return CMD_SUCCESS;
1361}
1362
1363DEFUN (bandwidth_if,
1364 bandwidth_if_cmd,
1365 "bandwidth <1-10000000>",
1366 "Set bandwidth informational parameter\n"
1367 "Bandwidth in kilobits\n")
1368{
1369 struct interface *ifp;
1370 unsigned int bandwidth;
1371
1372 ifp = (struct interface *) vty->index;
1373 bandwidth = strtol(argv[0], NULL, 10);
1374
1375 /* bandwidth range is <1-10000000> */
1376 if (bandwidth < 1 || bandwidth > 10000000)
1377 {
1378 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1379 return CMD_WARNING;
1380 }
1381
1382 ifp->bandwidth = bandwidth;
1383
1384 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001385 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001386 zebra_interface_up_update (ifp);
1387
1388 return CMD_SUCCESS;
1389}
1390
1391DEFUN (no_bandwidth_if,
1392 no_bandwidth_if_cmd,
1393 "no bandwidth",
1394 NO_STR
1395 "Set bandwidth informational parameter\n")
1396{
1397 struct interface *ifp;
1398
1399 ifp = (struct interface *) vty->index;
1400
1401 ifp->bandwidth = 0;
1402
1403 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001404 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001405 zebra_interface_up_update (ifp);
1406
1407 return CMD_SUCCESS;
1408}
1409
1410ALIAS (no_bandwidth_if,
1411 no_bandwidth_if_val_cmd,
1412 "no bandwidth <1-10000000>",
1413 NO_STR
1414 "Set bandwidth informational parameter\n"
1415 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001416
paula1ac18c2005-06-28 17:17:12 +00001417static int
hasso39db97e2004-10-12 20:50:58 +00001418ip_address_install (struct vty *vty, struct interface *ifp,
1419 const char *addr_str, const char *peer_str,
1420 const char *label)
paul718e3742002-12-13 20:15:29 +00001421{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001422 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001423 struct prefix_ipv4 cp;
1424 struct connected *ifc;
1425 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001426 int ret;
1427
Christian Frankebfac8dc2013-01-24 14:04:50 +00001428 if_data = ifp->info;
1429
paul718e3742002-12-13 20:15:29 +00001430 ret = str2prefix_ipv4 (addr_str, &cp);
1431 if (ret <= 0)
1432 {
1433 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1434 return CMD_WARNING;
1435 }
1436
paulca162182005-09-12 16:58:52 +00001437 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001438 if (! ifc)
1439 {
1440 ifc = connected_new ();
1441 ifc->ifp = ifp;
1442
1443 /* Address. */
1444 p = prefix_ipv4_new ();
1445 *p = cp;
1446 ifc->address = (struct prefix *) p;
1447
1448 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001449 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001450 {
1451 p = prefix_ipv4_new ();
1452 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001453 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001454 ifc->destination = (struct prefix *) p;
1455 }
1456
paul718e3742002-12-13 20:15:29 +00001457 /* Label. */
1458 if (label)
paul0752ef02005-11-03 12:35:21 +00001459 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001460
1461 /* Add to linked list. */
1462 listnode_add (ifp->connected, ifc);
1463 }
1464
1465 /* This address is configured from zebra. */
1466 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1467 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1468
1469 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001470 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001471 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1472 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001473 {
1474 /* Some system need to up the interface to set IP address. */
1475 if (! if_is_up (ifp))
1476 {
1477 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1478 if_refresh (ifp);
1479 }
1480
1481 ret = if_set_prefix (ifp, ifc);
1482 if (ret < 0)
1483 {
1484 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001485 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001486 return CMD_WARNING;
1487 }
1488
Christian Frankef7f740f2013-01-24 14:04:48 +00001489 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001490 /* The address will be advertised to zebra clients when the notification
1491 * from the kernel has been received.
1492 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001493 }
1494
1495 return CMD_SUCCESS;
1496}
1497
paula1ac18c2005-06-28 17:17:12 +00001498static int
hasso39db97e2004-10-12 20:50:58 +00001499ip_address_uninstall (struct vty *vty, struct interface *ifp,
1500 const char *addr_str, const char *peer_str,
1501 const char *label)
paul718e3742002-12-13 20:15:29 +00001502{
1503 struct prefix_ipv4 cp;
1504 struct connected *ifc;
1505 int ret;
1506
1507 /* Convert to prefix structure. */
1508 ret = str2prefix_ipv4 (addr_str, &cp);
1509 if (ret <= 0)
1510 {
1511 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1512 return CMD_WARNING;
1513 }
1514
1515 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001516 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001517 if (! ifc)
1518 {
1519 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1520 return CMD_WARNING;
1521 }
1522
1523 /* This is not configured address. */
1524 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1525 return CMD_WARNING;
1526
Paul Jakma74ecdc92006-06-15 18:10:47 +00001527 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1528
paul718e3742002-12-13 20:15:29 +00001529 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001530 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001531 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1532 {
1533 listnode_delete (ifp->connected, ifc);
1534 connected_free (ifc);
1535 return CMD_WARNING;
1536 }
1537
1538 /* This is real route. */
1539 ret = if_unset_prefix (ifp, ifc);
1540 if (ret < 0)
1541 {
1542 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001543 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001544 return CMD_WARNING;
1545 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001546 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001547 /* we will receive a kernel notification about this route being removed.
1548 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001549 return CMD_SUCCESS;
1550}
1551
1552DEFUN (ip_address,
1553 ip_address_cmd,
1554 "ip address A.B.C.D/M",
1555 "Interface Internet Protocol config commands\n"
1556 "Set the IP address of an interface\n"
1557 "IP address (e.g. 10.0.0.1/8)\n")
1558{
hassoeef1fe12004-10-03 18:46:08 +00001559 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001560}
1561
1562DEFUN (no_ip_address,
1563 no_ip_address_cmd,
1564 "no ip address A.B.C.D/M",
1565 NO_STR
1566 "Interface Internet Protocol config commands\n"
1567 "Set the IP address of an interface\n"
1568 "IP Address (e.g. 10.0.0.1/8)")
1569{
hassoeef1fe12004-10-03 18:46:08 +00001570 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001571}
1572
1573#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001574DEFUN (ip_address_label,
1575 ip_address_label_cmd,
1576 "ip address A.B.C.D/M label LINE",
1577 "Interface Internet Protocol config commands\n"
1578 "Set the IP address of an interface\n"
1579 "IP address (e.g. 10.0.0.1/8)\n"
1580 "Label of this address\n"
1581 "Label\n")
1582{
hassoeef1fe12004-10-03 18:46:08 +00001583 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001584}
1585
1586DEFUN (no_ip_address_label,
1587 no_ip_address_label_cmd,
1588 "no ip address A.B.C.D/M label LINE",
1589 NO_STR
1590 "Interface Internet Protocol config commands\n"
1591 "Set the IP address of an interface\n"
1592 "IP address (e.g. 10.0.0.1/8)\n"
1593 "Label of this address\n"
1594 "Label\n")
1595{
hassoeef1fe12004-10-03 18:46:08 +00001596 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001597}
1598#endif /* HAVE_NETLINK */
1599
1600#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001601static int
hasso39db97e2004-10-12 20:50:58 +00001602ipv6_address_install (struct vty *vty, struct interface *ifp,
1603 const char *addr_str, const char *peer_str,
1604 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001605{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001606 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001607 struct prefix_ipv6 cp;
1608 struct connected *ifc;
1609 struct prefix_ipv6 *p;
1610 int ret;
1611
Christian Frankebfac8dc2013-01-24 14:04:50 +00001612 if_data = ifp->info;
1613
paul718e3742002-12-13 20:15:29 +00001614 ret = str2prefix_ipv6 (addr_str, &cp);
1615 if (ret <= 0)
1616 {
1617 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1618 return CMD_WARNING;
1619 }
1620
paulca162182005-09-12 16:58:52 +00001621 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001622 if (! ifc)
1623 {
1624 ifc = connected_new ();
1625 ifc->ifp = ifp;
1626
1627 /* Address. */
1628 p = prefix_ipv6_new ();
1629 *p = cp;
1630 ifc->address = (struct prefix *) p;
1631
1632 /* Secondary. */
1633 if (secondary)
1634 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1635
1636 /* Label. */
1637 if (label)
paul0752ef02005-11-03 12:35:21 +00001638 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001639
1640 /* Add to linked list. */
1641 listnode_add (ifp->connected, ifc);
1642 }
1643
1644 /* This address is configured from zebra. */
1645 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1646 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1647
1648 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001649 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001650 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1651 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001652 {
1653 /* Some system need to up the interface to set IP address. */
1654 if (! if_is_up (ifp))
1655 {
1656 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1657 if_refresh (ifp);
1658 }
1659
1660 ret = if_prefix_add_ipv6 (ifp, ifc);
1661
1662 if (ret < 0)
1663 {
1664 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001665 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001666 return CMD_WARNING;
1667 }
1668
Christian Frankef7f740f2013-01-24 14:04:48 +00001669 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001670 /* The address will be advertised to zebra clients when the notification
1671 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001672 }
1673
1674 return CMD_SUCCESS;
1675}
1676
paula1ac18c2005-06-28 17:17:12 +00001677static int
hasso39db97e2004-10-12 20:50:58 +00001678ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1679 const char *addr_str, const char *peer_str,
1680 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001681{
1682 struct prefix_ipv6 cp;
1683 struct connected *ifc;
1684 int ret;
1685
1686 /* Convert to prefix structure. */
1687 ret = str2prefix_ipv6 (addr_str, &cp);
1688 if (ret <= 0)
1689 {
1690 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1691 return CMD_WARNING;
1692 }
1693
1694 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001695 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001696 if (! ifc)
1697 {
1698 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1699 return CMD_WARNING;
1700 }
1701
1702 /* This is not configured address. */
1703 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1704 return CMD_WARNING;
1705
Christian Franke676e1a02013-01-24 14:04:45 +00001706 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1707
paul718e3742002-12-13 20:15:29 +00001708 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001709 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001710 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1711 {
1712 listnode_delete (ifp->connected, ifc);
1713 connected_free (ifc);
1714 return CMD_WARNING;
1715 }
1716
1717 /* This is real route. */
1718 ret = if_prefix_delete_ipv6 (ifp, ifc);
1719 if (ret < 0)
1720 {
1721 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001722 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001723 return CMD_WARNING;
1724 }
1725
Christian Frankef7f740f2013-01-24 14:04:48 +00001726 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001727 /* This information will be propagated to the zclients when the
1728 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001729 return CMD_SUCCESS;
1730}
1731
1732DEFUN (ipv6_address,
1733 ipv6_address_cmd,
1734 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001735 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001736 "Set the IP address of an interface\n"
1737 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1738{
1739 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1740}
1741
1742DEFUN (no_ipv6_address,
1743 no_ipv6_address_cmd,
1744 "no ipv6 address X:X::X:X/M",
1745 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001746 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001747 "Set the IP address of an interface\n"
1748 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1749{
1750 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1751}
1752#endif /* HAVE_IPV6 */
1753
paula1ac18c2005-06-28 17:17:12 +00001754static int
paul718e3742002-12-13 20:15:29 +00001755if_config_write (struct vty *vty)
1756{
hasso52dc7ee2004-09-23 19:18:23 +00001757 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001758 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02001759 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00001760
Feng Lu471ea392015-05-22 11:40:00 +02001761 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1762 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00001763 {
1764 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001765 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001766 struct connected *ifc;
1767 struct prefix *p;
1768
paul718e3742002-12-13 20:15:29 +00001769 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02001770
1771 if (ifp->vrf_id == VRF_DEFAULT)
1772 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1773 else
1774 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1775 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001776
Christian Frankebfac8dc2013-01-24 14:04:50 +00001777 if (if_data)
1778 {
1779 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1780 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1781 }
1782
paul718e3742002-12-13 20:15:29 +00001783 if (ifp->desc)
1784 vty_out (vty, " description %s%s", ifp->desc,
1785 VTY_NEWLINE);
1786
1787 /* Assign bandwidth here to avoid unnecessary interface flap
1788 while processing config script */
1789 if (ifp->bandwidth != 0)
1790 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1791
paul2e3b2e42002-12-13 21:03:13 +00001792 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1793 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001794 else
1795 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001796
paul1eb8ef22005-04-07 07:30:20 +00001797 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001798 {
paul718e3742002-12-13 20:15:29 +00001799 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1800 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001801 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001802 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001803 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001804 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001805 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001806
paul718e3742002-12-13 20:15:29 +00001807 if (ifc->label)
1808 vty_out (vty, " label %s", ifc->label);
1809
1810 vty_out (vty, "%s", VTY_NEWLINE);
1811 }
1812 }
1813
1814 if (if_data)
1815 {
paul718e3742002-12-13 20:15:29 +00001816 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1817 vty_out (vty, " %smulticast%s",
1818 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1819 VTY_NEWLINE);
1820 }
1821
Donald Sharp64257732015-11-20 08:33:30 -05001822#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +00001823 rtadv_config_write (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -05001824#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +00001825
hassoca776982004-06-12 14:33:05 +00001826#ifdef HAVE_IRDP
1827 irdp_config_write (vty, ifp);
1828#endif /* IRDP */
1829
paul718e3742002-12-13 20:15:29 +00001830 vty_out (vty, "!%s", VTY_NEWLINE);
1831 }
1832 return 0;
1833}
1834
1835/* Allocate and initialize interface vector. */
1836void
paula1ac18c2005-06-28 17:17:12 +00001837zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001838{
1839 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001840 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1841 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1842
1843 /* Install configuration write function. */
1844 install_node (&interface_node, if_config_write);
1845
1846 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001847 install_element (VIEW_NODE, &show_interface_vrf_cmd);
1848 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
1849 install_element (VIEW_NODE, &show_interface_name_cmd);
1850 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
1851 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001852 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001853 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00001854 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001855 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
paul718e3742002-12-13 20:15:29 +00001856 install_default (INTERFACE_NODE);
1857 install_element (INTERFACE_NODE, &interface_desc_cmd);
1858 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1859 install_element (INTERFACE_NODE, &multicast_cmd);
1860 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001861 install_element (INTERFACE_NODE, &linkdetect_cmd);
1862 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001863 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1864 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1865 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1866 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1867 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1868 install_element (INTERFACE_NODE, &ip_address_cmd);
1869 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1870#ifdef HAVE_IPV6
1871 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1872 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1873#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001874#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001875 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001876 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001877#endif /* HAVE_NETLINK */
1878}