]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
Merge pull request #9080 from ton31337/fix/reason_bgpd
[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 {
d9083050
IR
340 if (!vrf_bitmap_check(client->redist[afi][type],
341 zvrf_id(zvrf))) {
342 if (IS_ZEBRA_DEBUG_EVENT)
343 zlog_debug(
344 "%s: setting vrf %s(%u) redist bitmap",
345 __func__, VRF_LOGNAME(zvrf->vrf),
346 zvrf_id(zvrf));
347 vrf_bitmap_set(client->redist[afi][type],
348 zvrf_id(zvrf));
349 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
350 }
4e1cadf0 351 }
ec93aa12
DS
352
353stream_failure:
354 return;
ebf08631 355}
718e3744 356
89f4e507 357void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
718e3744 358{
ec93aa12
DS
359 afi_t afi = 0;
360 int type = 0;
d7c0a89a 361 unsigned short instance;
d62a17ae 362
1002497a
QY
363 STREAM_GETC(msg, afi);
364 STREAM_GETC(msg, type);
365 STREAM_GETW(msg, instance);
d62a17ae 366
67da9573
EDP
367 if (IS_ZEBRA_DEBUG_EVENT)
368 zlog_debug(
369 "%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d",
370 __func__, zebra_route_string(client->proto), afi,
371 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
372 zvrf_id(zvrf), instance);
373
374
e1fa928d 375 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 376 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 377 "%s: Specified afi %d does not exist", __func__, afi);
d62a17ae 378 return;
ec93aa12
DS
379 }
380
381 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe 382 zlog_debug("%s: Specified Route Type %d does not exist",
15569c58 383 __func__, type);
ec93aa12
DS
384 return;
385 }
d62a17ae 386
387 /*
388 * NOTE: no need to withdraw the previously advertised routes. The
389 * clients
390 * themselves should keep track of the received routes from zebra and
391 * withdraw them when necessary.
392 */
393 if (instance)
394 redist_del_instance(&client->mi_redist[afi][type], instance);
395 else
396 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
ec93aa12
DS
397
398stream_failure:
399 return;
ebf08631 400}
718e3744 401
89f4e507 402void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
718e3744 403{
49db7a7b
RW
404 afi_t afi = 0;
405
406 STREAM_GETC(msg, afi);
407
408 if (afi == 0 || afi >= AFI_MAX) {
409 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 410 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
411 return;
412 }
413
414 vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
d62a17ae 415 zebra_redistribute_default(client, zvrf_id(zvrf));
49db7a7b
RW
416
417stream_failure:
418 return;
d62a17ae 419}
718e3744 420
89f4e507 421void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
718e3744 422{
49db7a7b
RW
423 afi_t afi = 0;
424
425 STREAM_GETC(msg, afi);
426
427 if (afi == 0 || afi >= AFI_MAX) {
428 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 429 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
430 return;
431 }
432
433 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
434
435stream_failure:
436 return;
d62a17ae 437}
718e3744 438
439/* Interface up information. */
d62a17ae 440void zebra_interface_up_update(struct interface *ifp)
718e3744 441{
d62a17ae 442 struct listnode *node, *nnode;
443 struct zserv *client;
444
445 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 446 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
a36898e7 447 ifp->name, ifp->vrf_id);
d62a17ae 448
449 if (ifp->ptm_status || !ifp->ptm_enable) {
161e9ab7 450 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
a8a20c4e 451 client)) {
17da84a4
KS
452 /* Do not send unsolicited messages to synchronous
453 * clients.
454 */
455 if (client->synchronous)
456 continue;
457
a8a20c4e
DS
458 zsend_interface_update(ZEBRA_INTERFACE_UP,
459 client, ifp);
460 zsend_interface_link_params(client, ifp);
461 }
16f1b9ee 462 }
718e3744 463}
464
465/* Interface down information. */
d62a17ae 466void zebra_interface_down_update(struct interface *ifp)
718e3744 467{
d62a17ae 468 struct listnode *node, *nnode;
469 struct zserv *client;
718e3744 470
d62a17ae 471 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 472 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
a36898e7 473 ifp->name, ifp->vrf_id);
718e3744 474
161e9ab7 475 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
476 /* Do not send unsolicited messages to synchronous clients. */
477 if (client->synchronous)
478 continue;
479
d62a17ae 480 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
481 }
718e3744 482}
483
484/* Interface information update. */
d62a17ae 485void zebra_interface_add_update(struct interface *ifp)
718e3744 486{
d62a17ae 487 struct listnode *node, *nnode;
488 struct zserv *client;
489
490 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 491 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
a36898e7 492 ifp->vrf_id);
d62a17ae 493
a8a20c4e 494 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
495 /* Do not send unsolicited messages to synchronous clients. */
496 if (client->synchronous)
497 continue;
498
a8a20c4e
DS
499 client->ifadd_cnt++;
500 zsend_interface_add(client, ifp);
501 zsend_interface_link_params(client, ifp);
502 }
718e3744 503}
504
d62a17ae 505void zebra_interface_delete_update(struct interface *ifp)
718e3744 506{
d62a17ae 507 struct listnode *node, *nnode;
508 struct zserv *client;
718e3744 509
d62a17ae 510 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 511 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
a36898e7 512 ifp->name, ifp->vrf_id);
718e3744 513
161e9ab7 514 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
515 /* Do not send unsolicited messages to synchronous clients. */
516 if (client->synchronous)
517 continue;
518
d62a17ae 519 client->ifdel_cnt++;
520 zsend_interface_delete(client, ifp);
521 }
718e3744 522}
523
524/* Interface address addition. */
d62a17ae 525void zebra_interface_address_add_update(struct interface *ifp,
526 struct connected *ifc)
718e3744 527{
d62a17ae 528 struct listnode *node, *nnode;
529 struct zserv *client;
530 struct prefix *p;
531
532 if (IS_ZEBRA_DEBUG_EVENT) {
d62a17ae 533 p = ifc->address;
2dbe669b
DA
534 zlog_debug(
535 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s(%u)",
536 p, ifp->name, ifp->vrf_id);
d62a17ae 537 }
538
539 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
9df414fe 540 flog_warn(
e914ccbe 541 EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
ad6f7449 542 "advertising address to clients that is not yet usable.");
d62a17ae 543
1a98c087
MK
544 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
545
d62a17ae 546 router_id_add_address(ifc);
547
17da84a4
KS
548 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
549 /* Do not send unsolicited messages to synchronous clients. */
550 if (client->synchronous)
551 continue;
552
d62a17ae 553 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
554 client->connected_rt_add_cnt++;
555 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
556 client, ifp, ifc);
557 }
17da84a4 558 }
718e3744 559}
560
561/* Interface address deletion. */
d62a17ae 562void zebra_interface_address_delete_update(struct interface *ifp,
563 struct connected *ifc)
718e3744 564{
d62a17ae 565 struct listnode *node, *nnode;
566 struct zserv *client;
567 struct prefix *p;
568
569 if (IS_ZEBRA_DEBUG_EVENT) {
d62a17ae 570 p = ifc->address;
2dbe669b
DA
571 zlog_debug(
572 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s(%u)",
573 p, ifp->name, ifp->vrf_id);
d62a17ae 574 }
575
1a98c087
MK
576 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
577
d62a17ae 578 router_id_del_address(ifc);
579
17da84a4
KS
580 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
581 /* Do not send unsolicited messages to synchronous clients. */
582 if (client->synchronous)
583 continue;
584
d62a17ae 585 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
586 client->connected_rt_del_cnt++;
587 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
588 client, ifp, ifc);
589 }
17da84a4 590 }
718e3744 591}
d5a5c8f0 592
c8e264b6 593/* Interface VRF change. May need to delete from clients not interested in
594 * the new VRF. Note that this function is invoked *prior* to the VRF change.
595 */
d62a17ae 596void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
c8e264b6 597{
d62a17ae 598 struct listnode *node, *nnode;
599 struct zserv *client;
600
601 if (IS_ZEBRA_DEBUG_EVENT)
602 zlog_debug(
603 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
a36898e7 604 ifp->name, ifp->vrf_id, new_vrf_id);
d62a17ae 605
161e9ab7 606 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
607 /* Do not send unsolicited messages to synchronous clients. */
608 if (client->synchronous)
609 continue;
610
d62a17ae 611 /* Need to delete if the client is not interested in the new
612 * VRF. */
613 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
614 client->ifdel_cnt++;
615 zsend_interface_delete(client, ifp);
616 zsend_interface_vrf_update(client, ifp, new_vrf_id);
617 }
c8e264b6 618}
619
620/* Interface VRF change. This function is invoked *post* VRF change and sends an
621 * add to clients who are interested in the new VRF but not in the old VRF.
622 */
d62a17ae 623void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
c8e264b6 624{
d62a17ae 625 struct listnode *node, *nnode;
626 struct zserv *client;
627
628 if (IS_ZEBRA_DEBUG_EVENT)
629 zlog_debug(
630 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
a36898e7 631 ifp->name, old_vrf_id, ifp->vrf_id);
d62a17ae 632
161e9ab7 633 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
634 /* Do not send unsolicited messages to synchronous clients. */
635 if (client->synchronous)
636 continue;
637
d62a17ae 638 /* Need to add if the client is interested in the new VRF. */
639 client->ifadd_cnt++;
640 zsend_interface_add(client, ifp);
641 zsend_interface_addresses(client, ifp);
642 }
c8e264b6 643}
644
fe257ae7
DS
645int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
646 struct route_entry *re, const char *rmap_name)
7a4bb9c5 647{
d62a17ae 648 struct route_entry *newre;
649 struct route_entry *same;
650 struct prefix p;
0eb97b86 651 struct nexthop_group *ng;
b68885f9 652 route_map_result_t ret = RMAP_PERMITMATCH;
f8c175f3 653 afi_t afi;
d62a17ae 654
f8c175f3 655 afi = family2afi(rn->p.family);
d62a17ae 656 if (rmap_name)
657 ret = zebra_import_table_route_map_check(
0eb97b86 658 afi, re->type, re->instance, &rn->p,
c415d895 659 re->nhe->nhg.nexthop,
fe257ae7 660 zvrf->vrf->vrf_id, re->tag, rmap_name);
d62a17ae 661
b68885f9 662 if (ret != RMAP_PERMITMATCH) {
85c615ac 663 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 664 zebra_del_import_table_entry(zvrf, rn, re);
20796bc3
DS
665 return 0;
666 }
d62a17ae 667
f8c175f3 668 prefix_copy(&p, &rn->p);
d62a17ae 669
a2addae8
RW
670 RNODE_FOREACH_RE (rn, same) {
671 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
f8c175f3 672 continue;
20796bc3 673
996c9314 674 if (same->type == re->type && same->instance == re->instance
f8c175f3
DS
675 && same->table == re->table
676 && same->type != ZEBRA_ROUTE_CONNECT)
677 break;
678 }
20796bc3 679
e71c84ca
DS
680 if (same) {
681 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 682 zebra_del_import_table_entry(zvrf, rn, same);
e71c84ca 683 }
f8c175f3 684
996c9314 685 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
5c4b6e57
DS
686 newre->type = ZEBRA_ROUTE_TABLE;
687 newre->distance = zebra_import_table_distance[afi][re->table];
688 newre->flags = re->flags;
689 newre->metric = re->metric;
690 newre->mtu = re->mtu;
317c6a10 691 newre->table = zvrf->table_id;
98572489 692 newre->uptime = monotime(NULL);
5c4b6e57 693 newre->instance = re->table;
5c4b6e57 694
0eb97b86 695 ng = nexthop_group_new();
c415d895 696 copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL);
0eb97b86
MS
697
698 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng);
5c4b6e57 699
d62a17ae 700 return 0;
7a4bb9c5
DS
701}
702
fe257ae7
DS
703int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
704 struct route_entry *re)
7a4bb9c5 705{
d62a17ae 706 struct prefix p;
f8c175f3 707 afi_t afi;
7a4bb9c5 708
f8c175f3
DS
709 afi = family2afi(rn->p.family);
710 prefix_copy(&p, &rn->p);
7a4bb9c5 711
fe257ae7 712 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
c415d895 713 re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
0eb97b86 714 re->nhe_id, zvrf->table_id, re->metric, re->distance,
3ceae22b 715 false);
7a4bb9c5 716
d62a17ae 717 return 0;
7a4bb9c5
DS
718}
719
720/* Assuming no one calls this with the main routing table */
fe257ae7
DS
721int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
722 uint32_t distance, const char *rmap_name, int add)
7a4bb9c5 723{
d62a17ae 724 struct route_table *table;
725 struct route_entry *re;
726 struct route_node *rn;
fe257ae7 727 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
d62a17ae 728
729 if (!is_zebra_valid_kernel_table(table_id)
c447ad08 730 || (table_id == RT_TABLE_MAIN))
95f7965d 731 return -1;
d62a17ae 732
733 if (afi >= AFI_MAX)
95f7965d 734 return -1;
d62a17ae 735
c7c0b007
SW
736 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id,
737 table_id);
d62a17ae 738 if (table == NULL) {
739 return 0;
740 } else if (IS_ZEBRA_DEBUG_RIB) {
741 zlog_debug("%s routes from table %d",
742 add ? "Importing" : "Unimporting", table_id);
7a4bb9c5
DS
743 }
744
d62a17ae 745 if (add) {
746 if (rmap_name)
747 zebra_add_import_table_route_map(afi, rmap_name,
748 table_id);
749 else {
750 rmap_name =
751 zebra_get_import_table_route_map(afi, table_id);
3660beec 752 if (rmap_name) {
d62a17ae 753 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
754 rmap_name = NULL;
755 }
d62a17ae 756 }
7a4bb9c5 757
d62a17ae 758 zebra_import_table_used[afi][table_id] = 1;
759 zebra_import_table_distance[afi][table_id] = distance;
760 } else {
761 zebra_import_table_used[afi][table_id] = 0;
762 zebra_import_table_distance[afi][table_id] =
763 ZEBRA_TABLE_DISTANCE_DEFAULT;
764
765 rmap_name = zebra_get_import_table_route_map(afi, table_id);
3660beec 766 if (rmap_name) {
d62a17ae 767 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
768 rmap_name = NULL;
769 }
7a4bb9c5 770 }
7a4bb9c5 771
d62a17ae 772 for (rn = route_top(table); rn; rn = route_next(rn)) {
773 /* For each entry in the non-default routing table,
774 * add the entry in the main table
775 */
776 if (!rn->info)
777 continue;
778
a2addae8 779 RNODE_FOREACH_RE (rn, re) {
d62a17ae 780 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
781 continue;
782 break;
7a4bb9c5 783 }
8902474b 784
d62a17ae 785 if (!re)
786 continue;
8902474b 787
d62a17ae 788 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
789 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
790 if (add)
fe257ae7
DS
791 zebra_add_import_table_entry(zvrf, rn, re,
792 rmap_name);
d62a17ae 793 else
fe257ae7 794 zebra_del_import_table_entry(zvrf, rn, re);
d62a17ae 795 }
796 }
797 return 0;
798}
799
fe257ae7 800int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id)
d62a17ae 801{
802 int i;
803 afi_t afi;
804 int write = 0;
805 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
806 const char *rmap_name;
807
808 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
809 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
fe257ae7 810 if (!is_zebra_import_table_enabled(afi, vrf_id, i))
20796bc3 811 continue;
d62a17ae 812
20796bc3
DS
813 if (zebra_import_table_distance[afi][i]
814 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
996c9314 815 vty_out(vty, "%s import-table %d distance %d",
20796bc3
DS
816 afi_str[afi], i,
817 zebra_import_table_distance[afi][i]);
818 } else {
996c9314
LB
819 vty_out(vty, "%s import-table %d", afi_str[afi],
820 i);
d62a17ae 821 }
20796bc3
DS
822
823 rmap_name = zebra_get_import_table_route_map(afi, i);
824 if (rmap_name)
996c9314 825 vty_out(vty, " route-map %s", rmap_name);
20796bc3
DS
826
827 vty_out(vty, "\n");
828 write = 1;
d62a17ae 829 }
7a4bb9c5 830 }
7a4bb9c5 831
d62a17ae 832 return write;
7a4bb9c5 833}
8902474b 834
fe257ae7
DS
835static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf,
836 afi_t afi, int table_id,
837 const char *rmap)
8902474b 838{
d62a17ae 839 struct route_table *table;
840 struct route_entry *re;
841 struct route_node *rn;
842 const char *rmap_name;
843
fe257ae7
DS
844 rmap_name = zebra_get_import_table_route_map(afi, table_id);
845 if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
846 return;
d62a17ae 847
c7c0b007
SW
848 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST,
849 zvrf->vrf->vrf_id, table_id);
fe257ae7
DS
850 if (!table) {
851 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
852 zlog_debug("%s: Table id=%d not found", __func__,
853 table_id);
854 return;
855 }
856
857 for (rn = route_top(table); rn; rn = route_next(rn)) {
858 /*
859 * For each entry in the non-default routing table,
860 * add the entry in the main table
861 */
862 if (!rn->info)
863 continue;
864
865 RNODE_FOREACH_RE (rn, re) {
866 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
d5b8c216 867 continue;
fe257ae7
DS
868 break;
869 }
870
871 if (!re)
872 continue;
873
874 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
875 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
876 zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
877 }
878
879 return;
880}
881
882static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf,
883 const char *rmap)
884{
885 afi_t afi;
886 int i;
887
888 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
889 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
890 if (!is_zebra_import_table_enabled(
891 afi, zvrf->vrf->vrf_id, i))
2c7ef20d 892 continue;
2c7ef20d 893
fe257ae7
DS
894 zebra_import_table_rm_update_vrf_afi(zvrf, afi, i,
895 rmap);
d62a17ae 896 }
8902474b 897 }
fe257ae7 898}
8902474b 899
fe257ae7
DS
900void zebra_import_table_rm_update(const char *rmap)
901{
902 struct vrf *vrf;
903 struct zebra_vrf *zvrf;
904
905 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
906 zvrf = vrf->info;
907
908 if (!zvrf)
909 continue;
910
911 zebra_import_table_rm_update_vrf(zvrf, rmap);
912 }
8902474b 913}
16f1b9ee
OD
914
915/* Interface parameters update */
d62a17ae 916void zebra_interface_parameters_update(struct interface *ifp)
16f1b9ee 917{
d62a17ae 918 struct listnode *node, *nnode;
919 struct zserv *client;
16f1b9ee 920
d62a17ae 921 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 922 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
a36898e7 923 ifp->name, ifp->vrf_id);
16f1b9ee 924
17da84a4
KS
925 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
926 /* Do not send unsolicited messages to synchronous clients. */
927 if (client->synchronous)
928 continue;
929
a8a20c4e 930 zsend_interface_link_params(client, ifp);
17da84a4 931 }
16f1b9ee 932}