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