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