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