]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
zebra: zebra-warnings.patch
[mirror_frr.git] / zebra / redistribute.c
CommitLineData
718e3744 1/* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "vector.h"
25#include "vty.h"
26#include "command.h"
27#include "prefix.h"
28#include "table.h"
29#include "stream.h"
30#include "zclient.h"
31#include "linklist.h"
32#include "log.h"
33
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36#include "zebra/redistribute.h"
37#include "zebra/debug.h"
18a6dce6 38#include "zebra/router-id.h"
718e3744 39
244c1cdc
DS
40#define ZEBRA_PTM_SUPPORT
41
42
b21b19c5 43/* master zebra server structure */
44extern struct zebra_t zebrad;
45
7a4bb9c5
DS
46/* array holding redistribute info about table redistribution */
47/* bit AFI is set if that AFI is redistributing routes from this table */
48static u_char zebra_import_table_used[ZEBRA_KERNEL_TABLE_MAX];
49static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
50
51int
52is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
53{
54 if (is_zebra_valid_kernel_table(table_id))
55 {
56 if (CHECK_FLAG(zebra_import_table_used[table_id], (u_char)afi))
57 return 1;
58 else
59 return 0;
60 }
61
62 return 0;
63}
64
6dc686a2 65int
718e3744 66zebra_check_addr (struct prefix *p)
67{
68 if (p->family == AF_INET)
69 {
70 u_int32_t addr;
71
72 addr = p->u.prefix4.s_addr;
73 addr = ntohl (addr);
74
6dc686a2
PJ
75 if (IPV4_NET127 (addr)
76 || IN_CLASSD (addr)
77 || IPV4_LINKLOCAL(addr))
718e3744 78 return 0;
79 }
80#ifdef HAVE_IPV6
81 if (p->family == AF_INET6)
82 {
83 if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
84 return 0;
85 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
86 return 0;
87 }
88#endif /* HAVE_IPV6 */
89 return 1;
90}
91
27da3988 92static int
718e3744 93is_default (struct prefix *p)
94{
95 if (p->family == AF_INET)
96 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
97 return 1;
98#ifdef HAVE_IPV6
99#if 0 /* IPv6 default separation is now pending until protocol daemon
100 can handle that. */
101 if (p->family == AF_INET6)
102 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
103 return 1;
104#endif /* 0 */
105#endif /* HAVE_IPV6 */
106 return 0;
107}
108
27da3988 109static void
718e3744 110zebra_redistribute_default (struct zserv *client)
111{
112 struct prefix_ipv4 p;
113 struct route_table *table;
114 struct route_node *rn;
115 struct rib *newrib;
116#ifdef HAVE_IPV6
117 struct prefix_ipv6 p6;
118#endif /* HAVE_IPV6 */
119
120
121 /* Lookup default route. */
122 memset (&p, 0, sizeof (struct prefix_ipv4));
123 p.family = AF_INET;
124
125 /* Lookup table. */
126 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
127 if (table)
128 {
129 rn = route_node_lookup (table, (struct prefix *)&p);
130 if (rn)
131 {
9fd92e3c 132 RNODE_FOREACH_RIB (rn, newrib)
718e3744 133 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
134 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 135 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
718e3744 136 route_unlock_node (rn);
137 }
138 }
139
140#ifdef HAVE_IPV6
141 /* Lookup default route. */
142 memset (&p6, 0, sizeof (struct prefix_ipv6));
143 p6.family = AF_INET6;
144
145 /* Lookup table. */
146 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
147 if (table)
148 {
149 rn = route_node_lookup (table, (struct prefix *)&p6);
150 if (rn)
151 {
9fd92e3c 152 RNODE_FOREACH_RIB (rn, newrib)
718e3744 153 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
154 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 155 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
718e3744 156 route_unlock_node (rn);
157 }
158 }
159#endif /* HAVE_IPV6 */
160}
161
162/* Redistribute routes. */
27da3988 163static void
7c8ff89e 164zebra_redistribute (struct zserv *client, int type, u_short instance)
718e3744 165{
166 struct rib *newrib;
167 struct route_table *table;
168 struct route_node *rn;
169
170 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
171 if (table)
172 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 173 RNODE_FOREACH_RIB (rn, newrib)
718e3744 174 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
7c8ff89e
DS
175 && newrib->type == type
176 && newrib->instance == instance
718e3744 177 && newrib->distance != DISTANCE_INFINITY
178 && zebra_check_addr (&rn->p))
04b02fda
DS
179 {
180 client->redist_v4_add_cnt++;
181 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
182 }
718e3744 183
184#ifdef HAVE_IPV6
185 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
186 if (table)
187 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 188 RNODE_FOREACH_RIB (rn, newrib)
718e3744 189 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
7c8ff89e
DS
190 && newrib->type == type
191 && newrib->instance == instance
718e3744 192 && newrib->distance != DISTANCE_INFINITY
193 && zebra_check_addr (&rn->p))
04b02fda
DS
194 {
195 client->redist_v6_add_cnt++;
196 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
197 }
718e3744 198#endif /* HAVE_IPV6 */
199}
200
718e3744 201void
202redistribute_add (struct prefix *p, struct rib *rib)
203{
1eb8ef25 204 struct listnode *node, *nnode;
718e3744 205 struct zserv *client;
206
1eb8ef25 207 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
208 {
209 if (is_default (p))
210 {
8bb0831e
DS
211 if ((p->family == AF_INET) &&
212 (client->redist_default ||
213 redist_check_instance(&client->redist[AFI_IP][rib->type],
214 rib->instance)))
215 {
216 client->redist_v4_add_cnt++;
217 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
218 }
718e3744 219#ifdef HAVE_IPV6
8bb0831e
DS
220 if ((p->family == AF_INET6) &&
221 (client->redist_default ||
222 redist_check_instance(&client->redist[AFI_IP6][rib->type],
223 rib->instance)))
224 {
225 client->redist_v6_add_cnt++;
226 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
227 }
718e3744 228#endif /* HAVE_IPV6 */
1eb8ef25 229 }
8bb0831e 230 else
1eb8ef25 231 {
8bb0831e
DS
232 if ((p->family == AF_INET) &&
233 redist_check_instance(&client->redist[AFI_IP][rib->type],
234 rib->instance))
04b02fda
DS
235 {
236 client->redist_v4_add_cnt++;
8bb0831e
DS
237 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
238 }
718e3744 239#ifdef HAVE_IPV6
8bb0831e
DS
240 if ((p->family == AF_INET6) &&
241 redist_check_instance(&client->redist[AFI_IP6][rib->type],
242 rib->instance))
243 {
244 client->redist_v6_add_cnt++;
245 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
246 }
718e3744 247#endif /* HAVE_IPV6 */
1eb8ef25 248 }
249 }
718e3744 250}
251
252void
253redistribute_delete (struct prefix *p, struct rib *rib)
254{
1eb8ef25 255 struct listnode *node, *nnode;
718e3744 256 struct zserv *client;
257
258 /* Add DISTANCE_INFINITY check. */
259 if (rib->distance == DISTANCE_INFINITY)
260 return;
261
1eb8ef25 262 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
263 {
264 if (is_default (p))
265 {
8bb0831e
DS
266 if ((p->family == AF_INET) &&
267 (client->redist_default ||
268 redist_check_instance(&client->redist[AFI_IP][rib->type],
269 rib->instance)))
270 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
1eb8ef25 271 rib);
718e3744 272#ifdef HAVE_IPV6
8bb0831e
DS
273 if ((p->family == AF_INET6) &&
274 (client->redist_default ||
275 redist_check_instance(&client->redist[AFI_IP6][rib->type],
276 rib->instance)))
277 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
1eb8ef25 278 rib);
279#endif /* HAVE_IPV6 */
1eb8ef25 280 }
8bb0831e
DS
281 else
282 {
283 if ((p->family == AF_INET) &&
284 redist_check_instance(&client->redist[AFI_IP][rib->type],
285 rib->instance))
286 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
287 rib);
718e3744 288#ifdef HAVE_IPV6
8bb0831e
DS
289 if ((p->family == AF_INET6) &&
290 redist_check_instance(&client->redist[AFI_IP6][rib->type],
291 rib->instance))
292 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
293 rib);
1eb8ef25 294#endif /* HAVE_IPV6 */
295 }
296 }
718e3744 297}
298
299void
300zebra_redistribute_add (int command, struct zserv *client, int length)
301{
8bb0831e 302 afi_t afi;
718e3744 303 int type;
7c8ff89e 304 u_short instance;
718e3744 305
8bb0831e 306 afi = stream_getc (client->ibuf);
718e3744 307 type = stream_getc (client->ibuf);
7c8ff89e 308 instance = stream_getw (client->ibuf);
718e3744 309
ebf08631
DL
310 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
311 return;
312
8bb0831e 313 if (!redist_check_instance(&client->redist[afi][type], instance))
718e3744 314 {
8bb0831e 315 redist_add_instance(&client->redist[afi][type], instance);
7c8ff89e 316 zebra_redistribute (client, type, instance);
718e3744 317 }
ebf08631 318}
718e3744 319
320void
321zebra_redistribute_delete (int command, struct zserv *client, int length)
322{
8bb0831e 323 afi_t afi;
718e3744 324 int type;
7c8ff89e 325 u_short instance;
718e3744 326
8bb0831e 327 afi = stream_getc (client->ibuf);
718e3744 328 type = stream_getc (client->ibuf);
7c8ff89e 329 instance = stream_getw (client->ibuf);
718e3744 330
ebf08631
DL
331 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
332 return;
333
8bb0831e 334 if (redist_check_instance(&client->redist[afi][type], instance))
7c8ff89e 335 {
8bb0831e 336 redist_del_instance(&client->redist[afi][type], instance);
7c8ff89e
DS
337 //Pending: why no reaction here?
338 }
ebf08631 339}
718e3744 340
341void
342zebra_redistribute_default_add (int command, struct zserv *client, int length)
343{
344 client->redist_default = 1;
345 zebra_redistribute_default (client);
346}
347
348void
349zebra_redistribute_default_delete (int command, struct zserv *client,
350 int length)
351{
352 client->redist_default = 0;;
353}
354
355/* Interface up information. */
356void
357zebra_interface_up_update (struct interface *ifp)
358{
1eb8ef25 359 struct listnode *node, *nnode;
718e3744 360 struct zserv *client;
361
362 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 363 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
718e3744 364
244c1cdc
DS
365 if (ifp->ptm_status || !ifp->ptm_enable) {
366 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
04b02fda
DS
367 {
368 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
369 }
244c1cdc 370 }
718e3744 371}
372
373/* Interface down information. */
374void
375zebra_interface_down_update (struct interface *ifp)
376{
1eb8ef25 377 struct listnode *node, *nnode;
718e3744 378 struct zserv *client;
379
380 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 381 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
718e3744 382
1eb8ef25 383 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
04b02fda
DS
384 {
385 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
386 }
718e3744 387}
388
389/* Interface information update. */
390void
391zebra_interface_add_update (struct interface *ifp)
392{
1eb8ef25 393 struct listnode *node, *nnode;
718e3744 394 struct zserv *client;
395
396 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 397 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
718e3744 398
1eb8ef25 399 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
400 if (client->ifinfo)
04b02fda
DS
401 {
402 client->ifadd_cnt++;
403 zsend_interface_add (client, ifp);
404 }
718e3744 405}
406
407void
408zebra_interface_delete_update (struct interface *ifp)
409{
1eb8ef25 410 struct listnode *node, *nnode;
718e3744 411 struct zserv *client;
412
413 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 414 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
718e3744 415
1eb8ef25 416 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
417 if (client->ifinfo)
04b02fda
DS
418 {
419 client->ifdel_cnt++;
420 zsend_interface_delete (client, ifp);
421 }
718e3744 422}
423
424/* Interface address addition. */
425void
426zebra_interface_address_add_update (struct interface *ifp,
427 struct connected *ifc)
428{
1eb8ef25 429 struct listnode *node, *nnode;
718e3744 430 struct zserv *client;
431 struct prefix *p;
718e3744 432
433 if (IS_ZEBRA_DEBUG_EVENT)
434 {
81cce018
SH
435 char buf[INET6_ADDRSTRLEN];
436
718e3744 437 p = ifc->address;
b6178002 438 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
81cce018 439 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
b6178002 440 p->prefixlen, ifc->ifp->name);
718e3744 441 }
442
c7df92de
CF
443 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
444 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
445
18a6dce6 446 router_id_add_address(ifc);
447
1eb8ef25 448 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
449 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
04b02fda
DS
450 {
451 client->connected_rt_add_cnt++;
452 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
453 }
718e3744 454}
455
456/* Interface address deletion. */
457void
458zebra_interface_address_delete_update (struct interface *ifp,
459 struct connected *ifc)
460{
1eb8ef25 461 struct listnode *node, *nnode;
718e3744 462 struct zserv *client;
463 struct prefix *p;
718e3744 464
465 if (IS_ZEBRA_DEBUG_EVENT)
466 {
81cce018
SH
467 char buf[INET6_ADDRSTRLEN];
468
718e3744 469 p = ifc->address;
b6178002 470 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
81cce018 471 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
718e3744 472 p->prefixlen, ifc->ifp->name);
473 }
474
18a6dce6 475 router_id_del_address(ifc);
476
1eb8ef25 477 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
478 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
04b02fda
DS
479 {
480 client->connected_rt_del_cnt++;
481 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
482 }
718e3744 483}
d5a5c8f0
DS
484
485void
486zebra_interface_bfd_update (struct interface *ifp, struct prefix *p)
487{
488 struct listnode *node, *nnode;
489 struct zserv *client;
490
491 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
492 {
493 /* Supporting for OSPF and BGP */
494 if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP)
495 continue;
496
497 /* Notify to the protocol daemons. */
498 zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_DOWN, client, ifp, p);
499 }
500}
7a4bb9c5
DS
501
502int
503zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
504{
505 struct rib *newrib;
506 struct prefix_ipv4 p4;
507 struct nexthop *nhop;
508 struct in_addr *gate;
509
510 if (rn->p.family == AF_INET)
511 {
512 p4.family = AF_INET;
513 p4.prefixlen = rn->p.prefixlen;
514 p4.prefix = rn->p.u.prefix4;
515
516 if (rib->nexthop_num == 1)
517 {
518 nhop = rib->nexthop;
519 if ((nhop->type == NEXTHOP_TYPE_IFINDEX) ||
520 (nhop->type == NEXTHOP_TYPE_IFNAME))
521 gate = NULL;
522 else
523 gate = &nhop->gate.ipv4;
524
525 rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
526 gate, &nhop->src.ipv4,
527 nhop->ifindex, zebrad.rtm_table_default,
528 rib->metric,
529 zebra_import_table_distance[AFI_IP][rib->table],
530 SAFI_UNICAST);
531 }
532 else if (rib->nexthop_num > 1)
533 {
534 newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
535 newrib->type = ZEBRA_ROUTE_TABLE;
536 newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
537 newrib->flags = rib->flags;
538 newrib->metric = rib->metric;
539 newrib->table = zebrad.rtm_table_default;
540 newrib->nexthop_num = 0;
541 newrib->uptime = time(NULL);
542 newrib->instance = rib->table;
543
544 /* Assuming these routes are never recursive */
545 for (nhop = rib->nexthop; nhop; nhop = nhop->next)
546 copy_nexthops(newrib, nhop);
547
548 rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
549 }
550 }
551 /* DD: Add IPv6 code */
552 return 0;
553}
554
555int
556zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
557{
558 struct prefix_ipv4 p4;
559
560 if (rn->p.family == AF_INET)
561 {
562 p4.family = AF_INET;
563 p4.prefixlen = rn->p.prefixlen;
564 p4.prefix = rn->p.u.prefix4;
565
566 rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
567 0, zebrad.rtm_table_default, SAFI_UNICAST);
568 }
569 /* DD: Add IPv6 code */
570
571 return 0;
572}
573
574/* Assuming no one calls this with the main routing table */
575int
576zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
577{
578 struct route_table *table;
579 struct rib *rib;
580 struct route_node *rn;
581
582 if (!is_zebra_valid_kernel_table(table_id) ||
583 ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default)))
584 return (-1);
585
586 if (afi >= AFI_MAX)
587 return (-1);
588
589 table = vrf_other_route_table(afi, table_id, 0);
590 if (table == NULL)
591 {
592 return 0;
593 }
594 else if (IS_ZEBRA_DEBUG_RIB)
595 {
596 zlog_debug ("%s routes from table %d",
597 add ? "Importing" : "Unimporting", table_id);
598 }
599
600 if (add)
601 {
602 SET_FLAG(zebra_import_table_used[table_id], afi);
603 zebra_import_table_distance[afi][table_id] = distance;
604 }
605 else
606 {
607 UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
608 zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
609 }
610
611 for (rn = route_top(table); rn; rn = route_next(rn))
612 {
613 /* For each entry in the non-default routing table,
614 * add the entry in the main table
615 */
616 if (!rn->info)
617 continue;
618
619 RNODE_FOREACH_RIB (rn, rib)
620 {
621 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
622 continue;
623 break;
624 }
625
626 if (!rib)
627 continue;
628
4e3afb14
DS
629 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
630 ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
7a4bb9c5
DS
631 {
632 if (add)
633 zebra_add_import_table_entry (rn, rib);
634 else
635 zebra_del_import_table_entry (rn, rib);
636 }
637 }
638 return 0;
639}
640
641int
642zebra_import_table_config (struct vty *vty)
643{
644 int i;
645 afi_t afi;
646 int write = 0;
647 char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
648
649 for (afi = AFI_IP; afi < AFI_MAX; afi++)
650 {
651 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
652 {
653 if (is_zebra_import_table_enabled(afi, i))
654 {
655 if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
656 {
657 vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
658 i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
659 }
660 else
661 {
662 vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
663 VTY_NEWLINE);
664 }
665 write = 1;
666 }
667 }
668 }
669
670 return write;
671}