]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
zebra: Fix Startup with > 1k interfaces
[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 /* VRF information update. */
460 void
461 zebra_vrf_add_update (struct zebra_vrf *zvrf)
462 {
463 struct listnode *node, *nnode;
464 struct zserv *client;
465
466 if (IS_ZEBRA_DEBUG_EVENT)
467 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name);
468
469 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
470 zsend_vrf_add (client, zvrf);
471 }
472
473 void
474 zebra_vrf_delete_update (struct zebra_vrf *zvrf)
475 {
476 struct listnode *node, *nnode;
477 struct zserv *client;
478
479 if (IS_ZEBRA_DEBUG_EVENT)
480 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name);
481
482 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
483 zsend_vrf_delete (client, zvrf);
484 }
485
486 void
487 zebra_vrf_update_all (struct zserv *client)
488 {
489 struct vrf *vrf;
490 vrf_iter_t iter;
491
492 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
493 {
494 if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id)
495 zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
496 }
497 }
498
499
500 /* Interface address addition. */
501 void
502 zebra_interface_address_add_update (struct interface *ifp,
503 struct connected *ifc)
504 {
505 struct listnode *node, *nnode;
506 struct zserv *client;
507 struct prefix *p;
508
509 if (IS_ZEBRA_DEBUG_EVENT)
510 {
511 char buf[INET6_ADDRSTRLEN];
512
513 p = ifc->address;
514 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
515 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
516 p->prefixlen, ifc->ifp->name);
517 }
518
519 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
520 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
521
522 router_id_add_address(ifc);
523
524 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
525 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
526 {
527 client->connected_rt_add_cnt++;
528 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
529 }
530 }
531
532 /* Interface address deletion. */
533 void
534 zebra_interface_address_delete_update (struct interface *ifp,
535 struct connected *ifc)
536 {
537 struct listnode *node, *nnode;
538 struct zserv *client;
539 struct prefix *p;
540
541 if (IS_ZEBRA_DEBUG_EVENT)
542 {
543 char buf[INET6_ADDRSTRLEN];
544
545 p = ifc->address;
546 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
547 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
548 p->prefixlen, ifc->ifp->name);
549 }
550
551 router_id_del_address(ifc);
552
553 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
554 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
555 {
556 client->connected_rt_del_cnt++;
557 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
558 }
559 }
560
561 /* Interface VRF change. May need to delete from clients not interested in
562 * the new VRF. Note that this function is invoked *prior* to the VRF change.
563 */
564 void
565 zebra_interface_vrf_update_del (struct interface *ifp, vrf_id_t new_vrf_id)
566 {
567 struct listnode *node, *nnode;
568 struct zserv *client;
569
570 if (IS_ZEBRA_DEBUG_EVENT)
571 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
572 ifp->name, ifp->vrf_id, new_vrf_id);
573
574 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
575 {
576 /* Skip clients not interested in both VRFs. */
577 if (!vrf_bitmap_check (client->ifinfo, ifp->vrf_id) &&
578 !vrf_bitmap_check (client->ifinfo, new_vrf_id))
579 continue;
580
581 if (!vrf_bitmap_check (client->ifinfo, new_vrf_id))
582 {
583 /* Need to delete if the client is not interested in the new VRF. */
584 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
585 client->ifdel_cnt++;
586 zsend_interface_delete (client, ifp);
587 }
588 else if (vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
589 {
590 /* Client is interested in both VRFs, inform about the change. */
591 zsend_interface_vrf_update (client, ifp, new_vrf_id);
592 }
593 }
594 }
595
596 /* Interface VRF change. This function is invoked *post* VRF change and sends an
597 * add to clients who are interested in the new VRF but not in the old VRF.
598 */
599 void
600 zebra_interface_vrf_update_add (struct interface *ifp, vrf_id_t old_vrf_id)
601 {
602 struct listnode *node, *nnode;
603 struct zserv *client;
604
605 if (IS_ZEBRA_DEBUG_EVENT)
606 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
607 ifp->name, old_vrf_id, ifp->vrf_id);
608
609 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
610 {
611 /* Skip clients interested in both VRFs - they would've got an Update. */
612 if (vrf_bitmap_check (client->ifinfo, ifp->vrf_id) &&
613 vrf_bitmap_check (client->ifinfo, old_vrf_id))
614 continue;
615
616 /* Skip clients not interested in the new VRF - they would've
617 * got a Delete.
618 */
619 if (!vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
620 continue;
621
622 /* Need to add if the client is interested in the new VRF. */
623 client->ifadd_cnt++;
624 zsend_interface_add (client, ifp);
625 zsend_interface_addresses (client, ifp);
626 }
627 }
628
629 int
630 zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
631 {
632 struct rib *newrib;
633 struct prefix_ipv4 p4;
634 struct nexthop *nhop;
635 struct in_addr *gate;
636
637 if (rn->p.family == AF_INET)
638 {
639 p4.family = AF_INET;
640 p4.prefixlen = rn->p.prefixlen;
641 p4.prefix = rn->p.u.prefix4;
642
643 if (rib->nexthop_num == 1)
644 {
645 nhop = rib->nexthop;
646 if (nhop->type == NEXTHOP_TYPE_IFINDEX)
647 gate = NULL;
648 else
649 gate = &nhop->gate.ipv4;
650
651 rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
652 gate, &nhop->src.ipv4,
653 nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
654 rib->metric,
655 zebra_import_table_distance[AFI_IP][rib->table],
656 SAFI_UNICAST);
657 }
658 else if (rib->nexthop_num > 1)
659 {
660 newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
661 newrib->type = ZEBRA_ROUTE_TABLE;
662 newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
663 newrib->flags = rib->flags;
664 newrib->metric = rib->metric;
665 newrib->table = zebrad.rtm_table_default;
666 newrib->nexthop_num = 0;
667 newrib->uptime = time(NULL);
668 newrib->instance = rib->table;
669
670 /* Assuming these routes are never recursive */
671 for (nhop = rib->nexthop; nhop; nhop = nhop->next)
672 rib_copy_nexthops(newrib, nhop);
673
674 rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
675 }
676 }
677 /* DD: Add IPv6 code */
678 return 0;
679 }
680
681 int
682 zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
683 {
684 struct prefix_ipv4 p4;
685
686 if (rn->p.family == AF_INET)
687 {
688 p4.family = AF_INET;
689 p4.prefixlen = rn->p.prefixlen;
690 p4.prefix = rn->p.u.prefix4;
691
692 rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
693 0, rib->vrf_id, zebrad.rtm_table_default, SAFI_UNICAST);
694 }
695 /* DD: Add IPv6 code */
696
697 return 0;
698 }
699
700 /* Assuming no one calls this with the main routing table */
701 int
702 zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
703 {
704 struct route_table *table;
705 struct rib *rib;
706 struct route_node *rn;
707
708 if (!is_zebra_valid_kernel_table(table_id) ||
709 ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default)))
710 return (-1);
711
712 if (afi >= AFI_MAX)
713 return (-1);
714
715 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
716 if (table == NULL)
717 {
718 return 0;
719 }
720 else if (IS_ZEBRA_DEBUG_RIB)
721 {
722 zlog_debug ("%s routes from table %d",
723 add ? "Importing" : "Unimporting", table_id);
724 }
725
726 if (add)
727 {
728 SET_FLAG(zebra_import_table_used[table_id], afi);
729 zebra_import_table_distance[afi][table_id] = distance;
730 }
731 else
732 {
733 UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
734 zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
735 }
736
737 for (rn = route_top(table); rn; rn = route_next(rn))
738 {
739 /* For each entry in the non-default routing table,
740 * add the entry in the main table
741 */
742 if (!rn->info)
743 continue;
744
745 RNODE_FOREACH_RIB (rn, rib)
746 {
747 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
748 continue;
749 break;
750 }
751
752 if (!rib)
753 continue;
754
755 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
756 ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
757 {
758 if (add)
759 zebra_add_import_table_entry (rn, rib);
760 else
761 zebra_del_import_table_entry (rn, rib);
762 }
763 }
764 return 0;
765 }
766
767 int
768 zebra_import_table_config (struct vty *vty)
769 {
770 int i;
771 afi_t afi;
772 int write = 0;
773 char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
774
775 for (afi = AFI_IP; afi < AFI_MAX; afi++)
776 {
777 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
778 {
779 if (is_zebra_import_table_enabled(afi, i))
780 {
781 if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
782 {
783 vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
784 i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
785 }
786 else
787 {
788 vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
789 VTY_NEWLINE);
790 }
791 write = 1;
792 }
793 }
794 }
795
796 return write;
797 }