]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
Merge pull request #8581 from qlyoung/bgp-fix-last-reset-buffer-size
[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"
161e9ab7 36#include "zebra/zebra_router.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"
1a98c087 44#include "zebra/zebra_vxlan.h"
364fed6b 45#include "zebra/zebra_errors.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
fe257ae7 54int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, 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++) {
29a35332
DS
77
78 if (!vrf_bitmap_check(client->redist_default[afi], vrf_id))
79 continue;
80
d62a17ae 81 /* Lookup table. */
82 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
83 if (!table)
84 continue;
85
86 /* Lookup default route. */
87 memset(&p, 0, sizeof(p));
88 p.family = afi2family(afi);
89 rn = route_node_lookup(table, &p);
90 if (!rn)
91 continue;
92
a2addae8 93 RNODE_FOREACH_RE (rn, newre) {
c3d0d6e8 94 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
407c87a6 95 zsend_redistribute_route(
a2addae8
RW
96 ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
97 &rn->p, NULL, newre);
407c87a6 98 }
d62a17ae 99
100 route_unlock_node(rn);
101 }
718e3744 102}
103
104/* Redistribute routes. */
d7c0a89a
QY
105static void zebra_redistribute(struct zserv *client, int type,
106 unsigned short instance, vrf_id_t vrf_id,
107 int afi)
718e3744 108{
d62a17ae 109 struct route_entry *newre;
110 struct route_table *table;
111 struct route_node *rn;
112
113 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
114 if (!table)
115 return;
116
f0c4b8e1 117 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 118 RNODE_FOREACH_RE (rn, newre) {
86391e56 119 const struct prefix *dst_p, *src_p;
3e178809 120
d62a17ae 121 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
122
14a4d9d0 123 if (IS_ZEBRA_DEBUG_RIB)
d62a17ae 124 zlog_debug(
2dbe669b 125 "%s: client %s %pFX(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
d62a17ae 126 __func__,
1b6e575b 127 zebra_route_string(client->proto),
2dbe669b
DA
128 dst_p, vrf_id,
129 CHECK_FLAG(newre->flags,
130 ZEBRA_FLAG_SELECTED),
d62a17ae 131 newre->type, newre->distance,
3e178809 132 newre->metric, zebra_check_addr(dst_p));
d62a17ae 133
134 if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
135 continue;
136 if ((type != ZEBRA_ROUTE_ALL
137 && (newre->type != type
138 || newre->instance != instance)))
139 continue;
d62a17ae 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
14fe366e
S
148/*
149 * Function to check if prefix is candidate for
150 * redistribute.
151 */
152static bool zebra_redistribute_check(const struct route_entry *re,
153 struct zserv *client,
154 const struct prefix *p, int afi)
155{
156 /* Process only if there is valid re */
157 if (!re)
158 return false;
159
160 /* If default route and redistributed */
161 if (is_default_prefix(p)
162 && vrf_bitmap_check(client->redist_default[afi], re->vrf_id))
163 return true;
164
165 /* If redistribute in enabled for zebra route all */
166 if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id))
167 return true;
168
169 /*
170 * If multi-instance then check for route
171 * redistribution for given instance.
172 */
173 if (re->instance
174 && redist_check_instance(&client->mi_redist[afi][re->type],
175 re->instance))
176 return true;
177
178 /* If redistribution is enabled for give route type. */
179 if (vrf_bitmap_check(client->redist[afi][re->type], re->vrf_id))
180 return true;
181
182 return false;
183}
184
c41fc67b 185/* Either advertise a route for redistribution to registered clients or */
186/* withdraw redistribution if add cannot be done for client */
86391e56 187void redistribute_update(const struct prefix *p, const struct prefix *src_p,
40f321c0
MS
188 const struct route_entry *re,
189 const struct route_entry *prev_re)
718e3744 190{
d62a17ae 191 struct listnode *node, *nnode;
192 struct zserv *client;
d62a17ae 193 int afi;
d62a17ae 194
2dbe669b 195 if (IS_ZEBRA_DEBUG_RIB)
d62a17ae 196 zlog_debug(
2dbe669b
DA
197 "(%u:%u):%pFX: Redist update re %p (%s), old %p (%s)",
198 re->vrf_id, re->table, p, re,
199 zebra_route_string(re->type), prev_re,
2da33d6b 200 prev_re ? zebra_route_string(prev_re->type) : "None");
d62a17ae 201
202 afi = family2afi(p->family);
203 if (!afi) {
e914ccbe 204 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
1d5453d6 205 "%s: Unknown AFI/SAFI prefix received", __func__);
d62a17ae 206 return;
c41fc67b 207 }
79becec8 208 if (!zebra_check_addr(p)) {
209 if (IS_ZEBRA_DEBUG_RIB)
2dbe669b 210 zlog_debug("Redist update filter prefix %pFX", p);
79becec8 211 return;
212 }
213
d62a17ae 214
161e9ab7 215 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
14fe366e 216 if (zebra_redistribute_check(re, client, p, afi)) {
14a4d9d0 217 if (IS_ZEBRA_DEBUG_RIB) {
3e178809 218 zlog_debug(
2dbe669b 219 "%s: client %s %pFX(%u:%u), type=%d, distance=%d, metric=%d",
c2c02b76 220 __func__,
2dbe669b 221 zebra_route_string(client->proto), p,
c2c02b76
DS
222 re->vrf_id, re->table, re->type,
223 re->distance, re->metric);
3e178809 224 }
74489921
RW
225 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
226 client, p, src_p, re);
14fe366e 227 } else if (zebra_redistribute_check(prev_re, client, p, afi))
74489921
RW
228 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
229 client, p, src_p, prev_re);
c41fc67b 230 }
718e3744 231}
232
40f321c0
MS
233/*
234 * During a route delete, where 'new_re' is NULL, redist a delete to all
235 * clients registered for the type of 'old_re'.
236 * During a route update, redist a delete to any clients who will not see
237 * an update when the new route is installed. There are cases when a client
238 * may have seen a redist for 'old_re', but will not see
239 * the redist for 'new_re'.
240 */
86391e56 241void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
40f321c0
MS
242 const struct route_entry *old_re,
243 const struct route_entry *new_re)
718e3744 244{
d62a17ae 245 struct listnode *node, *nnode;
246 struct zserv *client;
d62a17ae 247 int afi;
40f321c0
MS
248 vrf_id_t vrfid;
249
250 if (old_re)
251 vrfid = old_re->vrf_id;
252 else if (new_re)
253 vrfid = new_re->vrf_id;
254 else
255 return;
d62a17ae 256
257 if (IS_ZEBRA_DEBUG_RIB) {
2dbe669b
DA
258 zlog_debug("%u:%pFX: Redist del: re %p (%s), new re %p (%s)",
259 vrfid, p, old_re,
260 old_re ? zebra_route_string(old_re->type) : "None",
261 new_re,
262 new_re ? zebra_route_string(new_re->type) : "None");
d62a17ae 263 }
264
d62a17ae 265 afi = family2afi(p->family);
266 if (!afi) {
e914ccbe 267 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
1d5453d6 268 "%s: Unknown AFI/SAFI prefix received",
40f321c0 269 __func__);
d62a17ae 270 return;
271 }
272
40f321c0 273 /* Skip invalid (e.g. linklocal) prefix */
79becec8 274 if (!zebra_check_addr(p)) {
40f321c0
MS
275 if (IS_ZEBRA_DEBUG_RIB) {
276 zlog_debug(
2dbe669b
DA
277 "%u:%pFX: Redist del old: skipping invalid prefix",
278 vrfid, p);
40f321c0 279 }
79becec8 280 return;
281 }
282
161e9ab7 283 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
284 /* Do not send unsolicited messages to synchronous clients. */
285 if (client->synchronous)
286 continue;
14fe366e
S
287 /*
288 * Skip this client if it will receive an update for the
289 * 'new' re
290 */
291 if (zebra_redistribute_check(new_re, client, p, afi))
292 continue;
40f321c0
MS
293
294 /* Send a delete for the 'old' re to any subscribed client. */
14fe366e 295 if (zebra_redistribute_check(old_re, client, p, afi))
74489921 296 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
40f321c0 297 client, p, src_p, old_re);
1eb8ef25 298 }
718e3744 299}
300
14fe366e 301
89f4e507 302void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
718e3744 303{
ec93aa12
DS
304 afi_t afi = 0;
305 int type = 0;
d7c0a89a 306 unsigned short instance;
d62a17ae 307
1002497a
QY
308 STREAM_GETC(msg, afi);
309 STREAM_GETC(msg, type);
310 STREAM_GETW(msg, instance);
d62a17ae 311
1b6e575b
PZ
312 if (IS_ZEBRA_DEBUG_EVENT)
313 zlog_debug(
c479e756 314 "%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d",
1b6e575b 315 __func__, zebra_route_string(client->proto), afi,
c479e756
DS
316 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
317 zvrf_id(zvrf), instance);
1b6e575b 318
e1fa928d 319 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 320 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 321 "%s: Specified afi %d does not exist", __func__, afi);
d62a17ae 322 return;
ec93aa12
DS
323 }
324
325 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe 326 zlog_debug("%s: Specified Route Type %d does not exist",
15569c58 327 __func__, type);
ec93aa12
DS
328 return;
329 }
d62a17ae 330
331 if (instance) {
332 if (!redist_check_instance(&client->mi_redist[afi][type],
333 instance)) {
334 redist_add_instance(&client->mi_redist[afi][type],
335 instance);
336 zebra_redistribute(client, type, instance,
337 zvrf_id(zvrf), afi);
338 }
339 } else {
6b2433c6
AR
340 if (IS_ZEBRA_DEBUG_EVENT)
341 zlog_debug("%s: setting vrf %s(%u) redist bitmap",
342 __func__, VRF_LOGNAME(zvrf->vrf),
343 zvrf_id(zvrf));
344 vrf_bitmap_set(client->redist[afi][type], zvrf_id(zvrf));
345 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
4e1cadf0 346 }
ec93aa12
DS
347
348stream_failure:
349 return;
ebf08631 350}
718e3744 351
89f4e507 352void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
718e3744 353{
ec93aa12
DS
354 afi_t afi = 0;
355 int type = 0;
d7c0a89a 356 unsigned short instance;
d62a17ae 357
1002497a
QY
358 STREAM_GETC(msg, afi);
359 STREAM_GETC(msg, type);
360 STREAM_GETW(msg, instance);
d62a17ae 361
67da9573
EDP
362 if (IS_ZEBRA_DEBUG_EVENT)
363 zlog_debug(
364 "%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d",
365 __func__, zebra_route_string(client->proto), afi,
366 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
367 zvrf_id(zvrf), instance);
368
369
e1fa928d 370 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 371 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 372 "%s: Specified afi %d does not exist", __func__, afi);
d62a17ae 373 return;
ec93aa12
DS
374 }
375
376 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe 377 zlog_debug("%s: Specified Route Type %d does not exist",
15569c58 378 __func__, type);
ec93aa12
DS
379 return;
380 }
d62a17ae 381
382 /*
383 * NOTE: no need to withdraw the previously advertised routes. The
384 * clients
385 * themselves should keep track of the received routes from zebra and
386 * withdraw them when necessary.
387 */
388 if (instance)
389 redist_del_instance(&client->mi_redist[afi][type], instance);
390 else
391 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
ec93aa12
DS
392
393stream_failure:
394 return;
ebf08631 395}
718e3744 396
89f4e507 397void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
718e3744 398{
49db7a7b
RW
399 afi_t afi = 0;
400
401 STREAM_GETC(msg, afi);
402
403 if (afi == 0 || afi >= AFI_MAX) {
404 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 405 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
406 return;
407 }
408
409 vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
d62a17ae 410 zebra_redistribute_default(client, zvrf_id(zvrf));
49db7a7b
RW
411
412stream_failure:
413 return;
d62a17ae 414}
718e3744 415
89f4e507 416void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
718e3744 417{
49db7a7b
RW
418 afi_t afi = 0;
419
420 STREAM_GETC(msg, afi);
421
422 if (afi == 0 || afi >= AFI_MAX) {
423 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 424 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
425 return;
426 }
427
428 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
429
430stream_failure:
431 return;
d62a17ae 432}
718e3744 433
434/* Interface up information. */
d62a17ae 435void zebra_interface_up_update(struct interface *ifp)
718e3744 436{
d62a17ae 437 struct listnode *node, *nnode;
438 struct zserv *client;
439
440 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 441 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
a36898e7 442 ifp->name, ifp->vrf_id);
d62a17ae 443
444 if (ifp->ptm_status || !ifp->ptm_enable) {
161e9ab7 445 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
a8a20c4e 446 client)) {
17da84a4
KS
447 /* Do not send unsolicited messages to synchronous
448 * clients.
449 */
450 if (client->synchronous)
451 continue;
452
a8a20c4e
DS
453 zsend_interface_update(ZEBRA_INTERFACE_UP,
454 client, ifp);
455 zsend_interface_link_params(client, ifp);
456 }
16f1b9ee 457 }
718e3744 458}
459
460/* Interface down information. */
d62a17ae 461void zebra_interface_down_update(struct interface *ifp)
718e3744 462{
d62a17ae 463 struct listnode *node, *nnode;
464 struct zserv *client;
718e3744 465
d62a17ae 466 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 467 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
a36898e7 468 ifp->name, ifp->vrf_id);
718e3744 469
161e9ab7 470 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
471 /* Do not send unsolicited messages to synchronous clients. */
472 if (client->synchronous)
473 continue;
474
d62a17ae 475 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
476 }
718e3744 477}
478
479/* Interface information update. */
d62a17ae 480void zebra_interface_add_update(struct interface *ifp)
718e3744 481{
d62a17ae 482 struct listnode *node, *nnode;
483 struct zserv *client;
484
485 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 486 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
a36898e7 487 ifp->vrf_id);
d62a17ae 488
a8a20c4e 489 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
490 /* Do not send unsolicited messages to synchronous clients. */
491 if (client->synchronous)
492 continue;
493
a8a20c4e
DS
494 client->ifadd_cnt++;
495 zsend_interface_add(client, ifp);
496 zsend_interface_link_params(client, ifp);
497 }
718e3744 498}
499
d62a17ae 500void zebra_interface_delete_update(struct interface *ifp)
718e3744 501{
d62a17ae 502 struct listnode *node, *nnode;
503 struct zserv *client;
718e3744 504
d62a17ae 505 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 506 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
a36898e7 507 ifp->name, ifp->vrf_id);
718e3744 508
161e9ab7 509 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
510 /* Do not send unsolicited messages to synchronous clients. */
511 if (client->synchronous)
512 continue;
513
d62a17ae 514 client->ifdel_cnt++;
515 zsend_interface_delete(client, ifp);
516 }
718e3744 517}
518
519/* Interface address addition. */
d62a17ae 520void zebra_interface_address_add_update(struct interface *ifp,
521 struct connected *ifc)
718e3744 522{
d62a17ae 523 struct listnode *node, *nnode;
524 struct zserv *client;
525 struct prefix *p;
526
527 if (IS_ZEBRA_DEBUG_EVENT) {
d62a17ae 528 p = ifc->address;
2dbe669b
DA
529 zlog_debug(
530 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s(%u)",
531 p, ifp->name, ifp->vrf_id);
d62a17ae 532 }
533
534 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
9df414fe 535 flog_warn(
e914ccbe 536 EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
ad6f7449 537 "advertising address to clients that is not yet usable.");
d62a17ae 538
1a98c087
MK
539 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
540
d62a17ae 541 router_id_add_address(ifc);
542
17da84a4
KS
543 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
544 /* Do not send unsolicited messages to synchronous clients. */
545 if (client->synchronous)
546 continue;
547
d62a17ae 548 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
549 client->connected_rt_add_cnt++;
550 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
551 client, ifp, ifc);
552 }
17da84a4 553 }
718e3744 554}
555
556/* Interface address deletion. */
d62a17ae 557void zebra_interface_address_delete_update(struct interface *ifp,
558 struct connected *ifc)
718e3744 559{
d62a17ae 560 struct listnode *node, *nnode;
561 struct zserv *client;
562 struct prefix *p;
563
564 if (IS_ZEBRA_DEBUG_EVENT) {
d62a17ae 565 p = ifc->address;
2dbe669b
DA
566 zlog_debug(
567 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s(%u)",
568 p, ifp->name, ifp->vrf_id);
d62a17ae 569 }
570
1a98c087
MK
571 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
572
d62a17ae 573 router_id_del_address(ifc);
574
17da84a4
KS
575 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
576 /* Do not send unsolicited messages to synchronous clients. */
577 if (client->synchronous)
578 continue;
579
d62a17ae 580 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
581 client->connected_rt_del_cnt++;
582 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
583 client, ifp, ifc);
584 }
17da84a4 585 }
718e3744 586}
d5a5c8f0 587
c8e264b6 588/* Interface VRF change. May need to delete from clients not interested in
589 * the new VRF. Note that this function is invoked *prior* to the VRF change.
590 */
d62a17ae 591void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
c8e264b6 592{
d62a17ae 593 struct listnode *node, *nnode;
594 struct zserv *client;
595
596 if (IS_ZEBRA_DEBUG_EVENT)
597 zlog_debug(
598 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
a36898e7 599 ifp->name, ifp->vrf_id, new_vrf_id);
d62a17ae 600
161e9ab7 601 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
602 /* Do not send unsolicited messages to synchronous clients. */
603 if (client->synchronous)
604 continue;
605
d62a17ae 606 /* Need to delete if the client is not interested in the new
607 * VRF. */
608 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
609 client->ifdel_cnt++;
610 zsend_interface_delete(client, ifp);
611 zsend_interface_vrf_update(client, ifp, new_vrf_id);
612 }
c8e264b6 613}
614
615/* Interface VRF change. This function is invoked *post* VRF change and sends an
616 * add to clients who are interested in the new VRF but not in the old VRF.
617 */
d62a17ae 618void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
c8e264b6 619{
d62a17ae 620 struct listnode *node, *nnode;
621 struct zserv *client;
622
623 if (IS_ZEBRA_DEBUG_EVENT)
624 zlog_debug(
625 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
a36898e7 626 ifp->name, old_vrf_id, ifp->vrf_id);
d62a17ae 627
161e9ab7 628 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
629 /* Do not send unsolicited messages to synchronous clients. */
630 if (client->synchronous)
631 continue;
632
d62a17ae 633 /* Need to add if the client is interested in the new VRF. */
634 client->ifadd_cnt++;
635 zsend_interface_add(client, ifp);
636 zsend_interface_addresses(client, ifp);
637 }
c8e264b6 638}
639
fe257ae7
DS
640int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
641 struct route_entry *re, const char *rmap_name)
7a4bb9c5 642{
d62a17ae 643 struct route_entry *newre;
644 struct route_entry *same;
645 struct prefix p;
0eb97b86 646 struct nexthop_group *ng;
b68885f9 647 route_map_result_t ret = RMAP_PERMITMATCH;
f8c175f3 648 afi_t afi;
d62a17ae 649
f8c175f3 650 afi = family2afi(rn->p.family);
d62a17ae 651 if (rmap_name)
652 ret = zebra_import_table_route_map_check(
0eb97b86 653 afi, re->type, re->instance, &rn->p,
c415d895 654 re->nhe->nhg.nexthop,
fe257ae7 655 zvrf->vrf->vrf_id, re->tag, rmap_name);
d62a17ae 656
b68885f9 657 if (ret != RMAP_PERMITMATCH) {
85c615ac 658 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 659 zebra_del_import_table_entry(zvrf, rn, re);
20796bc3
DS
660 return 0;
661 }
d62a17ae 662
f8c175f3 663 prefix_copy(&p, &rn->p);
d62a17ae 664
a2addae8
RW
665 RNODE_FOREACH_RE (rn, same) {
666 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
f8c175f3 667 continue;
20796bc3 668
996c9314 669 if (same->type == re->type && same->instance == re->instance
f8c175f3
DS
670 && same->table == re->table
671 && same->type != ZEBRA_ROUTE_CONNECT)
672 break;
673 }
20796bc3 674
e71c84ca
DS
675 if (same) {
676 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 677 zebra_del_import_table_entry(zvrf, rn, same);
e71c84ca 678 }
f8c175f3 679
996c9314 680 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
5c4b6e57
DS
681 newre->type = ZEBRA_ROUTE_TABLE;
682 newre->distance = zebra_import_table_distance[afi][re->table];
683 newre->flags = re->flags;
684 newre->metric = re->metric;
685 newre->mtu = re->mtu;
317c6a10 686 newre->table = zvrf->table_id;
98572489 687 newre->uptime = monotime(NULL);
5c4b6e57 688 newre->instance = re->table;
5c4b6e57 689
0eb97b86 690 ng = nexthop_group_new();
c415d895 691 copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL);
0eb97b86
MS
692
693 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng);
5c4b6e57 694
d62a17ae 695 return 0;
7a4bb9c5
DS
696}
697
fe257ae7
DS
698int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
699 struct route_entry *re)
7a4bb9c5 700{
d62a17ae 701 struct prefix p;
f8c175f3 702 afi_t afi;
7a4bb9c5 703
f8c175f3
DS
704 afi = family2afi(rn->p.family);
705 prefix_copy(&p, &rn->p);
7a4bb9c5 706
fe257ae7 707 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
c415d895 708 re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
0eb97b86 709 re->nhe_id, zvrf->table_id, re->metric, re->distance,
3ceae22b 710 false);
7a4bb9c5 711
d62a17ae 712 return 0;
7a4bb9c5
DS
713}
714
715/* Assuming no one calls this with the main routing table */
fe257ae7
DS
716int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
717 uint32_t distance, const char *rmap_name, int add)
7a4bb9c5 718{
d62a17ae 719 struct route_table *table;
720 struct route_entry *re;
721 struct route_node *rn;
fe257ae7 722 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
d62a17ae 723
724 if (!is_zebra_valid_kernel_table(table_id)
c447ad08 725 || (table_id == RT_TABLE_MAIN))
95f7965d 726 return -1;
d62a17ae 727
728 if (afi >= AFI_MAX)
95f7965d 729 return -1;
d62a17ae 730
c7c0b007
SW
731 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id,
732 table_id);
d62a17ae 733 if (table == NULL) {
734 return 0;
735 } else if (IS_ZEBRA_DEBUG_RIB) {
736 zlog_debug("%s routes from table %d",
737 add ? "Importing" : "Unimporting", table_id);
7a4bb9c5
DS
738 }
739
d62a17ae 740 if (add) {
741 if (rmap_name)
742 zebra_add_import_table_route_map(afi, rmap_name,
743 table_id);
744 else {
745 rmap_name =
746 zebra_get_import_table_route_map(afi, table_id);
3660beec 747 if (rmap_name) {
d62a17ae 748 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
749 rmap_name = NULL;
750 }
d62a17ae 751 }
7a4bb9c5 752
d62a17ae 753 zebra_import_table_used[afi][table_id] = 1;
754 zebra_import_table_distance[afi][table_id] = distance;
755 } else {
756 zebra_import_table_used[afi][table_id] = 0;
757 zebra_import_table_distance[afi][table_id] =
758 ZEBRA_TABLE_DISTANCE_DEFAULT;
759
760 rmap_name = zebra_get_import_table_route_map(afi, table_id);
3660beec 761 if (rmap_name) {
d62a17ae 762 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
763 rmap_name = NULL;
764 }
7a4bb9c5 765 }
7a4bb9c5 766
d62a17ae 767 for (rn = route_top(table); rn; rn = route_next(rn)) {
768 /* For each entry in the non-default routing table,
769 * add the entry in the main table
770 */
771 if (!rn->info)
772 continue;
773
a2addae8 774 RNODE_FOREACH_RE (rn, re) {
d62a17ae 775 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
776 continue;
777 break;
7a4bb9c5 778 }
8902474b 779
d62a17ae 780 if (!re)
781 continue;
8902474b 782
d62a17ae 783 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
784 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
785 if (add)
fe257ae7
DS
786 zebra_add_import_table_entry(zvrf, rn, re,
787 rmap_name);
d62a17ae 788 else
fe257ae7 789 zebra_del_import_table_entry(zvrf, rn, re);
d62a17ae 790 }
791 }
792 return 0;
793}
794
fe257ae7 795int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id)
d62a17ae 796{
797 int i;
798 afi_t afi;
799 int write = 0;
800 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
801 const char *rmap_name;
802
803 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
804 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
fe257ae7 805 if (!is_zebra_import_table_enabled(afi, vrf_id, i))
20796bc3 806 continue;
d62a17ae 807
20796bc3
DS
808 if (zebra_import_table_distance[afi][i]
809 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
996c9314 810 vty_out(vty, "%s import-table %d distance %d",
20796bc3
DS
811 afi_str[afi], i,
812 zebra_import_table_distance[afi][i]);
813 } else {
996c9314
LB
814 vty_out(vty, "%s import-table %d", afi_str[afi],
815 i);
d62a17ae 816 }
20796bc3
DS
817
818 rmap_name = zebra_get_import_table_route_map(afi, i);
819 if (rmap_name)
996c9314 820 vty_out(vty, " route-map %s", rmap_name);
20796bc3
DS
821
822 vty_out(vty, "\n");
823 write = 1;
d62a17ae 824 }
7a4bb9c5 825 }
7a4bb9c5 826
d62a17ae 827 return write;
7a4bb9c5 828}
8902474b 829
fe257ae7
DS
830static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf,
831 afi_t afi, int table_id,
832 const char *rmap)
8902474b 833{
d62a17ae 834 struct route_table *table;
835 struct route_entry *re;
836 struct route_node *rn;
837 const char *rmap_name;
838
fe257ae7
DS
839 rmap_name = zebra_get_import_table_route_map(afi, table_id);
840 if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
841 return;
d62a17ae 842
c7c0b007
SW
843 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST,
844 zvrf->vrf->vrf_id, table_id);
fe257ae7
DS
845 if (!table) {
846 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
847 zlog_debug("%s: Table id=%d not found", __func__,
848 table_id);
849 return;
850 }
851
852 for (rn = route_top(table); rn; rn = route_next(rn)) {
853 /*
854 * For each entry in the non-default routing table,
855 * add the entry in the main table
856 */
857 if (!rn->info)
858 continue;
859
860 RNODE_FOREACH_RE (rn, re) {
861 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
d5b8c216 862 continue;
fe257ae7
DS
863 break;
864 }
865
866 if (!re)
867 continue;
868
869 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
870 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
871 zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
872 }
873
874 return;
875}
876
877static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf,
878 const char *rmap)
879{
880 afi_t afi;
881 int i;
882
883 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
884 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
885 if (!is_zebra_import_table_enabled(
886 afi, zvrf->vrf->vrf_id, i))
2c7ef20d 887 continue;
2c7ef20d 888
fe257ae7
DS
889 zebra_import_table_rm_update_vrf_afi(zvrf, afi, i,
890 rmap);
d62a17ae 891 }
8902474b 892 }
fe257ae7 893}
8902474b 894
fe257ae7
DS
895void zebra_import_table_rm_update(const char *rmap)
896{
897 struct vrf *vrf;
898 struct zebra_vrf *zvrf;
899
900 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
901 zvrf = vrf->info;
902
903 if (!zvrf)
904 continue;
905
906 zebra_import_table_rm_update_vrf(zvrf, rmap);
907 }
8902474b 908}
16f1b9ee
OD
909
910/* Interface parameters update */
d62a17ae 911void zebra_interface_parameters_update(struct interface *ifp)
16f1b9ee 912{
d62a17ae 913 struct listnode *node, *nnode;
914 struct zserv *client;
16f1b9ee 915
d62a17ae 916 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 917 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
a36898e7 918 ifp->name, ifp->vrf_id);
16f1b9ee 919
17da84a4
KS
920 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
921 /* Do not send unsolicited messages to synchronous clients. */
922 if (client->synchronous)
923 continue;
924
a8a20c4e 925 zsend_interface_link_params(client, ifp);
17da84a4 926 }
16f1b9ee 927}