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