]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
*: change interface structure, from vrf_id to vrf
[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
d7c0a89a 55int is_zebra_import_table_enabled(afi_t afi, 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
122 if (IS_ZEBRA_DEBUG_EVENT)
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,
d62a17ae 152 struct route_entry *re, struct route_entry *prev_re)
718e3744 153{
d62a17ae 154 struct listnode *node, *nnode;
155 struct zserv *client;
156 int send_redistribute;
157 int afi;
3e178809 158 char buf[PREFIX_STRLEN];
d62a17ae 159
160 if (IS_ZEBRA_DEBUG_RIB) {
d62a17ae 161 zlog_debug(
2da33d6b 162 "%u:%s: Redist update re %p (%s), old %p (%s)",
3e178809 163 re->vrf_id, prefix2str(p, buf, sizeof(buf)),
2da33d6b
DS
164 re, zebra_route_string(re->type), prev_re,
165 prev_re ? zebra_route_string(prev_re->type) : "None");
d62a17ae 166 }
167
168 afi = family2afi(p->family);
169 if (!afi) {
e914ccbe 170 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
9df414fe 171 "%s: Unknown AFI/SAFI prefix received\n",
d62a17ae 172 __FUNCTION__);
173 return;
c41fc67b 174 }
d62a17ae 175
161e9ab7 176 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
d62a17ae 177 send_redistribute = 0;
178
f229873a 179 if (is_default_prefix(p)
49db7a7b
RW
180 && vrf_bitmap_check(client->redist_default[afi],
181 re->vrf_id))
d62a17ae 182 send_redistribute = 1;
183 else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
184 re->vrf_id))
185 send_redistribute = 1;
186 else if (re->instance
187 && redist_check_instance(
188 &client->mi_redist[afi][re->type],
189 re->instance))
190 send_redistribute = 1;
191 else if (vrf_bitmap_check(client->redist[afi][re->type],
192 re->vrf_id))
193 send_redistribute = 1;
194
195 if (send_redistribute) {
3e178809
DS
196 if (IS_ZEBRA_DEBUG_EVENT) {
197 zlog_debug(
38bbad1b 198 "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
3e178809
DS
199 __func__,
200 zebra_route_string(client->proto),
201 prefix2str(p, buf, sizeof(buf)),
202 re->vrf_id, re->type,
203 re->distance, re->metric);
204 }
74489921
RW
205 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
206 client, p, src_p, re);
d62a17ae 207 } else if (prev_re
208 && ((re->instance
209 && redist_check_instance(
210 &client->mi_redist[afi]
211 [prev_re->type],
212 re->instance))
213 || vrf_bitmap_check(
214 client->redist[afi][prev_re->type],
215 re->vrf_id))) {
74489921
RW
216 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
217 client, p, src_p, prev_re);
d62a17ae 218 }
c41fc67b 219 }
718e3744 220}
221
86391e56 222void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
d62a17ae 223 struct route_entry *re)
718e3744 224{
d62a17ae 225 struct listnode *node, *nnode;
226 struct zserv *client;
227 char buf[INET6_ADDRSTRLEN];
228 int afi;
229
230 if (IS_ZEBRA_DEBUG_RIB) {
231 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
2da33d6b
DS
232 zlog_debug("%u:%s/%d: Redist delete re %p (%s)",
233 re->vrf_id, buf, p->prefixlen, re,
234 zebra_route_string(re->type));
d62a17ae 235 }
236
237 /* Add DISTANCE_INFINITY check. */
238 if (re->distance == DISTANCE_INFINITY)
239 return;
240
241 afi = family2afi(p->family);
242 if (!afi) {
e914ccbe 243 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
9df414fe 244 "%s: Unknown AFI/SAFI prefix received\n",
d62a17ae 245 __FUNCTION__);
246 return;
247 }
248
161e9ab7 249 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
f229873a 250 if ((is_default_prefix(p)
49db7a7b
RW
251 && vrf_bitmap_check(client->redist_default[afi],
252 re->vrf_id))
d62a17ae 253 || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
254 re->vrf_id)
255 || (re->instance
256 && redist_check_instance(
257 &client->mi_redist[afi][re->type],
258 re->instance))
259 || vrf_bitmap_check(client->redist[afi][re->type],
260 re->vrf_id)) {
74489921
RW
261 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
262 client, p, src_p, re);
d62a17ae 263 }
1eb8ef25 264 }
718e3744 265}
266
89f4e507 267void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
718e3744 268{
ec93aa12
DS
269 afi_t afi = 0;
270 int type = 0;
d7c0a89a 271 unsigned short instance;
d62a17ae 272
1002497a
QY
273 STREAM_GETC(msg, afi);
274 STREAM_GETC(msg, type);
275 STREAM_GETW(msg, instance);
d62a17ae 276
1b6e575b
PZ
277 if (IS_ZEBRA_DEBUG_EVENT)
278 zlog_debug(
38bbad1b 279 "%s: client proto %s afi=%d, wants %s, vrf %u, instance=%d",
1b6e575b
PZ
280 __func__, zebra_route_string(client->proto), afi,
281 zebra_route_string(type), zvrf_id(zvrf), instance);
282
e1fa928d 283 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 284 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
9df414fe 285 "%s: Specified afi %d does not exist",
ec93aa12 286 __PRETTY_FUNCTION__, afi);
d62a17ae 287 return;
ec93aa12
DS
288 }
289
290 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe
QY
291 zlog_debug("%s: Specified Route Type %d does not exist",
292 __PRETTY_FUNCTION__, type);
ec93aa12
DS
293 return;
294 }
d62a17ae 295
296 if (instance) {
297 if (!redist_check_instance(&client->mi_redist[afi][type],
298 instance)) {
299 redist_add_instance(&client->mi_redist[afi][type],
300 instance);
301 zebra_redistribute(client, type, instance,
302 zvrf_id(zvrf), afi);
303 }
304 } else {
305 if (!vrf_bitmap_check(client->redist[afi][type],
306 zvrf_id(zvrf))) {
1b6e575b 307 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 308 zlog_debug("%s: setting vrf %u redist bitmap",
1b6e575b 309 __func__, zvrf_id(zvrf));
d62a17ae 310 vrf_bitmap_set(client->redist[afi][type],
311 zvrf_id(zvrf));
312 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
313 }
4e1cadf0 314 }
ec93aa12
DS
315
316stream_failure:
317 return;
ebf08631 318}
718e3744 319
89f4e507 320void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
718e3744 321{
ec93aa12
DS
322 afi_t afi = 0;
323 int type = 0;
d7c0a89a 324 unsigned short instance;
d62a17ae 325
1002497a
QY
326 STREAM_GETC(msg, afi);
327 STREAM_GETC(msg, type);
328 STREAM_GETW(msg, instance);
d62a17ae 329
e1fa928d 330 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 331 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
9df414fe 332 "%s: Specified afi %d does not exist",
ec93aa12 333 __PRETTY_FUNCTION__, afi);
d62a17ae 334 return;
ec93aa12
DS
335 }
336
337 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe
QY
338 zlog_debug("%s: Specified Route Type %d does not exist",
339 __PRETTY_FUNCTION__, type);
ec93aa12
DS
340 return;
341 }
d62a17ae 342
343 /*
344 * NOTE: no need to withdraw the previously advertised routes. The
345 * clients
346 * themselves should keep track of the received routes from zebra and
347 * withdraw them when necessary.
348 */
349 if (instance)
350 redist_del_instance(&client->mi_redist[afi][type], instance);
351 else
352 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
ec93aa12
DS
353
354stream_failure:
355 return;
ebf08631 356}
718e3744 357
89f4e507 358void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
718e3744 359{
49db7a7b
RW
360 afi_t afi = 0;
361
362 STREAM_GETC(msg, afi);
363
364 if (afi == 0 || afi >= AFI_MAX) {
365 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
366 "%s: Specified afi %u does not exist",
367 __PRETTY_FUNCTION__, afi);
368 return;
369 }
370
371 vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
d62a17ae 372 zebra_redistribute_default(client, zvrf_id(zvrf));
49db7a7b
RW
373
374stream_failure:
375 return;
d62a17ae 376}
718e3744 377
89f4e507 378void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
718e3744 379{
49db7a7b
RW
380 afi_t afi = 0;
381
382 STREAM_GETC(msg, afi);
383
384 if (afi == 0 || afi >= AFI_MAX) {
385 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
386 "%s: Specified afi %u does not exist",
387 __PRETTY_FUNCTION__, afi);
388 return;
389 }
390
391 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
392
393stream_failure:
394 return;
d62a17ae 395}
718e3744 396
397/* Interface up information. */
d62a17ae 398void zebra_interface_up_update(struct interface *ifp)
718e3744 399{
d62a17ae 400 struct listnode *node, *nnode;
401 struct zserv *client;
402
403 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 404 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
a41c4e1b 405 ifp->name, vrf_to_id(ifp->vrf));
d62a17ae 406
407 if (ifp->ptm_status || !ifp->ptm_enable) {
161e9ab7 408 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
a8a20c4e
DS
409 client)) {
410 zsend_interface_update(ZEBRA_INTERFACE_UP,
411 client, ifp);
412 zsend_interface_link_params(client, ifp);
413 }
16f1b9ee 414 }
718e3744 415}
416
417/* Interface down information. */
d62a17ae 418void zebra_interface_down_update(struct interface *ifp)
718e3744 419{
d62a17ae 420 struct listnode *node, *nnode;
421 struct zserv *client;
718e3744 422
d62a17ae 423 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 424 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
a41c4e1b 425 ifp->name, vrf_to_id(ifp->vrf));
718e3744 426
161e9ab7 427 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
d62a17ae 428 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
429 }
718e3744 430}
431
432/* Interface information update. */
d62a17ae 433void zebra_interface_add_update(struct interface *ifp)
718e3744 434{
d62a17ae 435 struct listnode *node, *nnode;
436 struct zserv *client;
437
438 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 439 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
a41c4e1b 440 vrf_to_id(ifp->vrf));
d62a17ae 441
a8a20c4e
DS
442 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
443 client->ifadd_cnt++;
444 zsend_interface_add(client, ifp);
445 zsend_interface_link_params(client, ifp);
446 }
718e3744 447}
448
d62a17ae 449void zebra_interface_delete_update(struct interface *ifp)
718e3744 450{
d62a17ae 451 struct listnode *node, *nnode;
452 struct zserv *client;
718e3744 453
d62a17ae 454 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 455 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
a41c4e1b 456 ifp->name, vrf_to_id(ifp->vrf));
718e3744 457
161e9ab7 458 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
d62a17ae 459 client->ifdel_cnt++;
460 zsend_interface_delete(client, ifp);
461 }
718e3744 462}
463
464/* Interface address addition. */
d62a17ae 465void zebra_interface_address_add_update(struct interface *ifp,
466 struct connected *ifc)
718e3744 467{
d62a17ae 468 struct listnode *node, *nnode;
469 struct zserv *client;
470 struct prefix *p;
471
472 if (IS_ZEBRA_DEBUG_EVENT) {
473 char buf[PREFIX_STRLEN];
474
475 p = ifc->address;
38bbad1b
DS
476 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
477 prefix2str(p, buf, sizeof(buf)), ifp->name,
a41c4e1b 478 vrf_to_id(ifp->vrf));
d62a17ae 479 }
480
481 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
9df414fe 482 flog_warn(
e914ccbe 483 EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
d62a17ae 484 "WARNING: advertising address to clients that is not yet usable.");
485
1a98c087
MK
486 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
487
d62a17ae 488 router_id_add_address(ifc);
489
161e9ab7 490 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
d62a17ae 491 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
492 client->connected_rt_add_cnt++;
493 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
494 client, ifp, ifc);
495 }
718e3744 496}
497
498/* Interface address deletion. */
d62a17ae 499void zebra_interface_address_delete_update(struct interface *ifp,
500 struct connected *ifc)
718e3744 501{
d62a17ae 502 struct listnode *node, *nnode;
503 struct zserv *client;
504 struct prefix *p;
505
506 if (IS_ZEBRA_DEBUG_EVENT) {
507 char buf[PREFIX_STRLEN];
508
509 p = ifc->address;
38bbad1b
DS
510 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
511 prefix2str(p, buf, sizeof(buf)),
a41c4e1b 512 ifp->name, vrf_to_id(ifp->vrf));
d62a17ae 513 }
514
1a98c087
MK
515 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
516
d62a17ae 517 router_id_del_address(ifc);
518
161e9ab7 519 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
d62a17ae 520 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
521 client->connected_rt_del_cnt++;
522 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
523 client, ifp, ifc);
524 }
718e3744 525}
d5a5c8f0 526
c8e264b6 527/* Interface VRF change. May need to delete from clients not interested in
528 * the new VRF. Note that this function is invoked *prior* to the VRF change.
529 */
d62a17ae 530void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
c8e264b6 531{
d62a17ae 532 struct listnode *node, *nnode;
533 struct zserv *client;
534
535 if (IS_ZEBRA_DEBUG_EVENT)
536 zlog_debug(
537 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
a41c4e1b 538 ifp->name, vrf_to_id(ifp->vrf), new_vrf_id);
d62a17ae 539
161e9ab7 540 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
d62a17ae 541 /* Need to delete if the client is not interested in the new
542 * VRF. */
543 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
544 client->ifdel_cnt++;
545 zsend_interface_delete(client, ifp);
546 zsend_interface_vrf_update(client, ifp, new_vrf_id);
547 }
c8e264b6 548}
549
550/* Interface VRF change. This function is invoked *post* VRF change and sends an
551 * add to clients who are interested in the new VRF but not in the old VRF.
552 */
d62a17ae 553void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
c8e264b6 554{
d62a17ae 555 struct listnode *node, *nnode;
556 struct zserv *client;
557
558 if (IS_ZEBRA_DEBUG_EVENT)
559 zlog_debug(
560 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
a41c4e1b 561 ifp->name, old_vrf_id, vrf_to_id(ifp->vrf));
d62a17ae 562
161e9ab7 563 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
d62a17ae 564 /* Need to add if the client is interested in the new VRF. */
565 client->ifadd_cnt++;
566 zsend_interface_add(client, ifp);
567 zsend_interface_addresses(client, ifp);
568 }
c8e264b6 569}
570
d62a17ae 571int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
572 const char *rmap_name)
7a4bb9c5 573{
d62a17ae 574 struct route_entry *newre;
575 struct route_entry *same;
576 struct prefix p;
2789041a 577 route_map_result_t ret = RMAP_MATCH;
f8c175f3 578 afi_t afi;
d62a17ae 579
f8c175f3 580 afi = family2afi(rn->p.family);
d62a17ae 581 if (rmap_name)
582 ret = zebra_import_table_route_map_check(
633a66a5
DS
583 afi, re->type, re->instance, &rn->p, re->ng.nexthop,
584 re->vrf_id, re->tag, rmap_name);
d62a17ae 585
2789041a 586 if (ret != RMAP_MATCH) {
85c615ac 587 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
20796bc3
DS
588 zebra_del_import_table_entry(rn, re);
589 return 0;
590 }
d62a17ae 591
f8c175f3 592 prefix_copy(&p, &rn->p);
d62a17ae 593
a2addae8
RW
594 RNODE_FOREACH_RE (rn, same) {
595 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
f8c175f3 596 continue;
20796bc3 597
996c9314 598 if (same->type == re->type && same->instance == re->instance
f8c175f3
DS
599 && same->table == re->table
600 && same->type != ZEBRA_ROUTE_CONNECT)
601 break;
602 }
20796bc3 603
e71c84ca
DS
604 if (same) {
605 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
f8c175f3 606 zebra_del_import_table_entry(rn, same);
e71c84ca 607 }
f8c175f3 608
996c9314 609 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
5c4b6e57
DS
610 newre->type = ZEBRA_ROUTE_TABLE;
611 newre->distance = zebra_import_table_distance[afi][re->table];
612 newre->flags = re->flags;
613 newre->metric = re->metric;
614 newre->mtu = re->mtu;
c447ad08 615 newre->table = 0;
5c4b6e57 616 newre->nexthop_num = 0;
98572489 617 newre->uptime = monotime(NULL);
5c4b6e57 618 newre->instance = re->table;
7ee30f28 619 route_entry_copy_nexthops(newre, re->ng.nexthop);
5c4b6e57
DS
620
621 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
622
d62a17ae 623 return 0;
7a4bb9c5
DS
624}
625
d62a17ae 626int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
7a4bb9c5 627{
d62a17ae 628 struct prefix p;
f8c175f3 629 afi_t afi;
7a4bb9c5 630
f8c175f3
DS
631 afi = family2afi(rn->p.family);
632 prefix_copy(&p, &rn->p);
7a4bb9c5 633
996c9314 634 rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
c447ad08
DS
635 re->flags, &p, NULL, re->ng.nexthop, 0, re->metric,
636 re->distance, false);
7a4bb9c5 637
d62a17ae 638 return 0;
7a4bb9c5
DS
639}
640
641/* Assuming no one calls this with the main routing table */
d7c0a89a 642int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance,
d62a17ae 643 const char *rmap_name, int add)
7a4bb9c5 644{
d62a17ae 645 struct route_table *table;
646 struct route_entry *re;
647 struct route_node *rn;
648
649 if (!is_zebra_valid_kernel_table(table_id)
c447ad08 650 || (table_id == RT_TABLE_MAIN))
d62a17ae 651 return (-1);
652
653 if (afi >= AFI_MAX)
654 return (-1);
655
8ab39b7f
DS
656 table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
657 table_id, VRF_DEFAULT);
d62a17ae 658 if (table == NULL) {
659 return 0;
660 } else if (IS_ZEBRA_DEBUG_RIB) {
661 zlog_debug("%s routes from table %d",
662 add ? "Importing" : "Unimporting", table_id);
7a4bb9c5
DS
663 }
664
d62a17ae 665 if (add) {
666 if (rmap_name)
667 zebra_add_import_table_route_map(afi, rmap_name,
668 table_id);
669 else {
670 rmap_name =
671 zebra_get_import_table_route_map(afi, table_id);
3660beec 672 if (rmap_name) {
d62a17ae 673 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
674 rmap_name = NULL;
675 }
d62a17ae 676 }
7a4bb9c5 677
d62a17ae 678 zebra_import_table_used[afi][table_id] = 1;
679 zebra_import_table_distance[afi][table_id] = distance;
680 } else {
681 zebra_import_table_used[afi][table_id] = 0;
682 zebra_import_table_distance[afi][table_id] =
683 ZEBRA_TABLE_DISTANCE_DEFAULT;
684
685 rmap_name = zebra_get_import_table_route_map(afi, table_id);
3660beec 686 if (rmap_name) {
d62a17ae 687 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
688 rmap_name = NULL;
689 }
7a4bb9c5 690 }
7a4bb9c5 691
d62a17ae 692 for (rn = route_top(table); rn; rn = route_next(rn)) {
693 /* For each entry in the non-default routing table,
694 * add the entry in the main table
695 */
696 if (!rn->info)
697 continue;
698
a2addae8 699 RNODE_FOREACH_RE (rn, re) {
d62a17ae 700 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
701 continue;
702 break;
7a4bb9c5 703 }
8902474b 704
d62a17ae 705 if (!re)
706 continue;
8902474b 707
d62a17ae 708 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
709 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
710 if (add)
711 zebra_add_import_table_entry(rn, re, rmap_name);
712 else
713 zebra_del_import_table_entry(rn, re);
714 }
715 }
716 return 0;
717}
718
719int zebra_import_table_config(struct vty *vty)
720{
721 int i;
722 afi_t afi;
723 int write = 0;
724 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
725 const char *rmap_name;
726
727 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
728 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
20796bc3
DS
729 if (!is_zebra_import_table_enabled(afi, i))
730 continue;
d62a17ae 731
20796bc3
DS
732 if (zebra_import_table_distance[afi][i]
733 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
996c9314 734 vty_out(vty, "%s import-table %d distance %d",
20796bc3
DS
735 afi_str[afi], i,
736 zebra_import_table_distance[afi][i]);
737 } else {
996c9314
LB
738 vty_out(vty, "%s import-table %d", afi_str[afi],
739 i);
d62a17ae 740 }
20796bc3
DS
741
742 rmap_name = zebra_get_import_table_route_map(afi, i);
743 if (rmap_name)
996c9314 744 vty_out(vty, " route-map %s", rmap_name);
20796bc3
DS
745
746 vty_out(vty, "\n");
747 write = 1;
d62a17ae 748 }
7a4bb9c5 749 }
7a4bb9c5 750
d62a17ae 751 return write;
7a4bb9c5 752}
8902474b 753
d5b8c216 754void zebra_import_table_rm_update(const char *rmap)
8902474b 755{
d62a17ae 756 afi_t afi;
757 int i;
758 struct route_table *table;
759 struct route_entry *re;
760 struct route_node *rn;
761 const char *rmap_name;
762
763 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
764 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
20796bc3
DS
765 if (!is_zebra_import_table_enabled(afi, i))
766 continue;
d62a17ae 767
20796bc3 768 rmap_name = zebra_get_import_table_route_map(afi, i);
d5b8c216 769 if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
770 continue;
8ab39b7f
DS
771 table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
772 i, VRF_DEFAULT);
2c7ef20d
SW
773 if (!table) {
774 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
775 zlog_debug("%s: Table id=%d not found",
776 __func__, i);
777 continue;
778 }
779
996c9314 780 for (rn = route_top(table); rn; rn = route_next(rn)) {
20796bc3
DS
781 /* For each entry in the non-default
782 * routing table,
783 * add the entry in the main table
784 */
785 if (!rn->info)
786 continue;
d62a17ae 787
a2addae8
RW
788 RNODE_FOREACH_RE (rn, re) {
789 if (CHECK_FLAG(re->status,
790 ROUTE_ENTRY_REMOVED))
d62a17ae 791 continue;
20796bc3 792 break;
d62a17ae 793 }
20796bc3
DS
794
795 if (!re)
796 continue;
797
798 if (((afi == AFI_IP)
799 && (rn->p.family == AF_INET))
800 || ((afi == AFI_IP6)
801 && (rn->p.family == AF_INET6)))
996c9314
LB
802 zebra_add_import_table_entry(rn, re,
803 rmap_name);
d62a17ae 804 }
805 }
8902474b 806 }
8902474b 807
d62a17ae 808 return;
8902474b 809}
16f1b9ee
OD
810
811/* Interface parameters update */
d62a17ae 812void zebra_interface_parameters_update(struct interface *ifp)
16f1b9ee 813{
d62a17ae 814 struct listnode *node, *nnode;
815 struct zserv *client;
16f1b9ee 816
d62a17ae 817 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 818 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
a41c4e1b 819 ifp->name, vrf_to_id(ifp->vrf));
16f1b9ee 820
161e9ab7 821 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
a8a20c4e 822 zsend_interface_link_params(client, ifp);
16f1b9ee 823}