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