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