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