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