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