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