]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
Merge pull request #998 from mkanjari/dev-master
[mirror_frr.git] / zebra / redistribute.c
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 *
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
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"
32 #include "vrf.h"
33 #include "srcdest_table.h"
34
35 #include "zebra/rib.h"
36 #include "zebra/zserv.h"
37 #include "zebra/zebra_ns.h"
38 #include "zebra/zebra_vrf.h"
39 #include "zebra/zebra_routemap.h"
40 #include "zebra/redistribute.h"
41 #include "zebra/debug.h"
42 #include "zebra/router-id.h"
43 #include "zebra/zebra_memory.h"
44 #include "zebra/zebra_vxlan.h"
45
46 #define ZEBRA_PTM_SUPPORT
47
48 /* array holding redistribute info about table redistribution */
49 /* bit AFI is set if that AFI is redistributing routes from this table */
50 static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
51 static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
52
53 int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
54 {
55 if (is_zebra_valid_kernel_table(table_id))
56 return zebra_import_table_used[afi][table_id];
57 return 0;
58 }
59
60 int is_default(struct prefix *p)
61 {
62 if (p->family == AF_INET)
63 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
64 return 1;
65 #if 0 /* IPv6 default separation is now pending until protocol daemon \
66 can handle that. */
67 if (p->family == AF_INET6)
68 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
69 return 1;
70 #endif /* 0 */
71 return 0;
72 }
73
74 static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
75 {
76 int afi;
77 struct prefix p;
78 struct route_table *table;
79 struct route_node *rn;
80 struct route_entry *newre;
81
82 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
83 /* Lookup table. */
84 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
85 if (!table)
86 continue;
87
88 /* Lookup default route. */
89 memset(&p, 0, sizeof(p));
90 p.family = afi2family(afi);
91 rn = route_node_lookup(table, &p);
92 if (!rn)
93 continue;
94
95 RNODE_FOREACH_RE(rn, newre)
96 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
97 && newre->distance != DISTANCE_INFINITY)
98 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
99 client, &rn->p, NULL, newre);
100
101 route_unlock_node(rn);
102 }
103 }
104
105 /* Redistribute routes. */
106 static void zebra_redistribute(struct zserv *client, int type, u_short instance,
107 vrf_id_t vrf_id, int afi)
108 {
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
117 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
118 RNODE_FOREACH_RE(rn, newre)
119 {
120 struct prefix *dst_p, *src_p;
121 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
122
123 if (IS_ZEBRA_DEBUG_EVENT)
124 zlog_debug(
125 "%s: checking: selected=%d, type=%d, distance=%d, "
126 "zebra_check_addr=%d",
127 __func__,
128 CHECK_FLAG(newre->flags,
129 ZEBRA_FLAG_SELECTED),
130 newre->type, newre->distance,
131 zebra_check_addr(dst_p));
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
144 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
145 client, dst_p, src_p, newre);
146 }
147 }
148
149 /* Either advertise a route for redistribution to registered clients or */
150 /* withdraw redistribution if add cannot be done for client */
151 void redistribute_update(struct prefix *p, struct prefix *src_p,
152 struct route_entry *re, struct route_entry *prev_re)
153 {
154 struct listnode *node, *nnode;
155 struct zserv *client;
156 int send_redistribute;
157 int afi;
158 char buf[INET6_ADDRSTRLEN];
159
160 if (IS_ZEBRA_DEBUG_RIB) {
161 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
162 zlog_debug(
163 "%u:%s/%d: Redist update re %p (type %d), old %p (type %d)",
164 re->vrf_id, buf, p->prefixlen, re, re->type, prev_re,
165 prev_re ? prev_re->type : -1);
166 }
167
168 afi = family2afi(p->family);
169 if (!afi) {
170 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
171 __FUNCTION__);
172 return;
173 }
174
175 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
176 send_redistribute = 0;
177
178 if (is_default(p)
179 && vrf_bitmap_check(client->redist_default, re->vrf_id))
180 send_redistribute = 1;
181 else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
182 re->vrf_id))
183 send_redistribute = 1;
184 else if (re->instance
185 && redist_check_instance(
186 &client->mi_redist[afi][re->type],
187 re->instance))
188 send_redistribute = 1;
189 else if (vrf_bitmap_check(client->redist[afi][re->type],
190 re->vrf_id))
191 send_redistribute = 1;
192
193 if (send_redistribute) {
194 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
195 client, p, src_p, re);
196 } else if (prev_re
197 && ((re->instance
198 && redist_check_instance(
199 &client->mi_redist[afi]
200 [prev_re->type],
201 re->instance))
202 || vrf_bitmap_check(
203 client->redist[afi][prev_re->type],
204 re->vrf_id))) {
205 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
206 client, p, src_p, prev_re);
207 }
208 }
209 }
210
211 void redistribute_delete(struct prefix *p, struct prefix *src_p,
212 struct route_entry *re)
213 {
214 struct listnode *node, *nnode;
215 struct zserv *client;
216 char buf[INET6_ADDRSTRLEN];
217 int afi;
218
219 if (IS_ZEBRA_DEBUG_RIB) {
220 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
221 zlog_debug("%u:%s/%d: Redist delete re %p (type %d)",
222 re->vrf_id, buf, p->prefixlen, re, re->type);
223 }
224
225 /* Add DISTANCE_INFINITY check. */
226 if (re->distance == DISTANCE_INFINITY)
227 return;
228
229 afi = family2afi(p->family);
230 if (!afi) {
231 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
232 __FUNCTION__);
233 return;
234 }
235
236 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
237 if ((is_default(p)
238 && vrf_bitmap_check(client->redist_default, re->vrf_id))
239 || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
240 re->vrf_id)
241 || (re->instance
242 && redist_check_instance(
243 &client->mi_redist[afi][re->type],
244 re->instance))
245 || vrf_bitmap_check(client->redist[afi][re->type],
246 re->vrf_id)) {
247 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
248 client, p, src_p, re);
249 }
250 }
251 }
252
253 void zebra_redistribute_add(int command, struct zserv *client, int length,
254 struct zebra_vrf *zvrf)
255 {
256 afi_t afi;
257 int type;
258 u_short instance;
259
260 afi = stream_getc(client->ibuf);
261 type = stream_getc(client->ibuf);
262 instance = stream_getw(client->ibuf);
263
264 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
265 return;
266
267 if (instance) {
268 if (!redist_check_instance(&client->mi_redist[afi][type],
269 instance)) {
270 redist_add_instance(&client->mi_redist[afi][type],
271 instance);
272 zebra_redistribute(client, type, instance,
273 zvrf_id(zvrf), afi);
274 }
275 } else {
276 if (!vrf_bitmap_check(client->redist[afi][type],
277 zvrf_id(zvrf))) {
278 vrf_bitmap_set(client->redist[afi][type],
279 zvrf_id(zvrf));
280 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
281 }
282 }
283 }
284
285 void zebra_redistribute_delete(int command, struct zserv *client, int length,
286 struct zebra_vrf *zvrf)
287 {
288 afi_t afi;
289 int type;
290 u_short instance;
291
292 afi = stream_getc(client->ibuf);
293 type = stream_getc(client->ibuf);
294 instance = stream_getw(client->ibuf);
295
296 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
297 return;
298
299 /*
300 * NOTE: no need to withdraw the previously advertised routes. The
301 * clients
302 * themselves should keep track of the received routes from zebra and
303 * withdraw them when necessary.
304 */
305 if (instance)
306 redist_del_instance(&client->mi_redist[afi][type], instance);
307 else
308 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
309 }
310
311 void zebra_redistribute_default_add(int command, struct zserv *client,
312 int length, struct zebra_vrf *zvrf)
313 {
314 vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
315 zebra_redistribute_default(client, zvrf_id(zvrf));
316 }
317
318 void zebra_redistribute_default_delete(int command, struct zserv *client,
319 int length, struct zebra_vrf *zvrf)
320 {
321 vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
322 }
323
324 /* Interface up information. */
325 void zebra_interface_up_update(struct interface *ifp)
326 {
327 struct listnode *node, *nnode;
328 struct zserv *client;
329
330 if (IS_ZEBRA_DEBUG_EVENT)
331 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
332
333 if (ifp->ptm_status || !ifp->ptm_enable) {
334 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
335 if (client->ifinfo) {
336 zsend_interface_update(ZEBRA_INTERFACE_UP,
337 client, ifp);
338 zsend_interface_link_params(client, ifp);
339 }
340 }
341 }
342
343 /* Interface down information. */
344 void zebra_interface_down_update(struct interface *ifp)
345 {
346 struct listnode *node, *nnode;
347 struct zserv *client;
348
349 if (IS_ZEBRA_DEBUG_EVENT)
350 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
351
352 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
353 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
354 }
355 }
356
357 /* Interface information update. */
358 void zebra_interface_add_update(struct interface *ifp)
359 {
360 struct listnode *node, *nnode;
361 struct zserv *client;
362
363 if (IS_ZEBRA_DEBUG_EVENT)
364 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name,
365 ifp->vrf_id);
366
367 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
368 if (client->ifinfo) {
369 client->ifadd_cnt++;
370 zsend_interface_add(client, ifp);
371 zsend_interface_link_params(client, ifp);
372 }
373 }
374
375 void zebra_interface_delete_update(struct interface *ifp)
376 {
377 struct listnode *node, *nnode;
378 struct zserv *client;
379
380 if (IS_ZEBRA_DEBUG_EVENT)
381 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
382
383 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
384 client->ifdel_cnt++;
385 zsend_interface_delete(client, ifp);
386 }
387 }
388
389 /* Interface address addition. */
390 void zebra_interface_address_add_update(struct interface *ifp,
391 struct connected *ifc)
392 {
393 struct listnode *node, *nnode;
394 struct zserv *client;
395 struct prefix *p;
396
397 if (IS_ZEBRA_DEBUG_EVENT) {
398 char buf[PREFIX_STRLEN];
399
400 p = ifc->address;
401 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
402 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
403 }
404
405 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
406 zlog_warn(
407 "WARNING: advertising address to clients that is not yet usable.");
408
409 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
410
411 router_id_add_address(ifc);
412
413 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
414 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
415 client->connected_rt_add_cnt++;
416 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
417 client, ifp, ifc);
418 }
419 }
420
421 /* Interface address deletion. */
422 void zebra_interface_address_delete_update(struct interface *ifp,
423 struct connected *ifc)
424 {
425 struct listnode *node, *nnode;
426 struct zserv *client;
427 struct prefix *p;
428
429 if (IS_ZEBRA_DEBUG_EVENT) {
430 char buf[PREFIX_STRLEN];
431
432 p = ifc->address;
433 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
434 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
435 }
436
437 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
438
439 router_id_del_address(ifc);
440
441 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
442 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
443 client->connected_rt_del_cnt++;
444 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
445 client, ifp, ifc);
446 }
447 }
448
449 /* Interface VRF change. May need to delete from clients not interested in
450 * the new VRF. Note that this function is invoked *prior* to the VRF change.
451 */
452 void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
453 {
454 struct listnode *node, *nnode;
455 struct zserv *client;
456
457 if (IS_ZEBRA_DEBUG_EVENT)
458 zlog_debug(
459 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
460 ifp->name, ifp->vrf_id, new_vrf_id);
461
462 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
463 /* Need to delete if the client is not interested in the new
464 * VRF. */
465 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
466 client->ifdel_cnt++;
467 zsend_interface_delete(client, ifp);
468 zsend_interface_vrf_update(client, ifp, new_vrf_id);
469 }
470 }
471
472 /* Interface VRF change. This function is invoked *post* VRF change and sends an
473 * add to clients who are interested in the new VRF but not in the old VRF.
474 */
475 void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
476 {
477 struct listnode *node, *nnode;
478 struct zserv *client;
479
480 if (IS_ZEBRA_DEBUG_EVENT)
481 zlog_debug(
482 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
483 ifp->name, old_vrf_id, ifp->vrf_id);
484
485 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
486 /* Need to add if the client is interested in the new VRF. */
487 client->ifadd_cnt++;
488 zsend_interface_add(client, ifp);
489 zsend_interface_addresses(client, ifp);
490 }
491 }
492
493 int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
494 const char *rmap_name)
495 {
496 struct route_entry *newre;
497 struct route_entry *same;
498 struct prefix p;
499 route_map_result_t ret = RMAP_MATCH;
500
501 if (rmap_name)
502 ret = zebra_import_table_route_map_check(
503 AFI_IP, re->type, &rn->p, re->nexthop, re->vrf_id,
504 re->tag, rmap_name);
505
506 if (ret == RMAP_MATCH) {
507 if (rn->p.family == AF_INET) {
508 p.family = AF_INET;
509 p.prefixlen = rn->p.prefixlen;
510 p.u.prefix4 = rn->p.u.prefix4;
511
512 RNODE_FOREACH_RE(rn, same)
513 {
514 if (CHECK_FLAG(same->status,
515 ROUTE_ENTRY_REMOVED))
516 continue;
517
518 if (same->type == re->type
519 && same->instance == re->instance
520 && same->table == re->table
521 && same->type != ZEBRA_ROUTE_CONNECT)
522 break;
523 }
524
525 if (same)
526 zebra_del_import_table_entry(rn, same);
527
528
529 if (re->nexthop_num == 1) {
530 rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id,
531 ZEBRA_ROUTE_TABLE, re->table, 0, &p,
532 NULL, re->nexthop,
533 zebrad.rtm_table_default,
534 re->metric, re->mtu,
535 zebra_import_table_distance[AFI_IP]
536 [re->table]);
537 } else if (re->nexthop_num > 1) {
538 newre = XCALLOC(MTYPE_RE,
539 sizeof(struct route_entry));
540 newre->type = ZEBRA_ROUTE_TABLE;
541 newre->distance =
542 zebra_import_table_distance[AFI_IP]
543 [re->table];
544 newre->flags = re->flags;
545 newre->metric = re->metric;
546 newre->mtu = re->mtu;
547 newre->table = zebrad.rtm_table_default;
548 newre->nexthop_num = 0;
549 newre->uptime = time(NULL);
550 newre->instance = re->table;
551 route_entry_copy_nexthops(newre, re->nexthop);
552
553 rib_add_multipath(AFI_IP, SAFI_UNICAST, &p,
554 NULL, newre);
555 }
556 }
557 } else {
558 zebra_del_import_table_entry(rn, re);
559 }
560 /* DD: Add IPv6 code */
561 return 0;
562 }
563
564 int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
565 {
566 struct prefix p;
567
568 if (rn->p.family == AF_INET) {
569 p.family = AF_INET;
570 p.prefixlen = rn->p.prefixlen;
571 p.u.prefix4 = rn->p.u.prefix4;
572
573 rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
574 re->table, re->flags, &p, NULL, NULL,
575 zebrad.rtm_table_default, re->metric);
576 }
577 /* DD: Add IPv6 code */
578
579 return 0;
580 }
581
582 /* Assuming no one calls this with the main routing table */
583 int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance,
584 const char *rmap_name, int add)
585 {
586 struct route_table *table;
587 struct route_entry *re;
588 struct route_node *rn;
589
590 if (!is_zebra_valid_kernel_table(table_id)
591 || ((table_id == RT_TABLE_MAIN)
592 || (table_id == zebrad.rtm_table_default)))
593 return (-1);
594
595 if (afi >= AFI_MAX)
596 return (-1);
597
598 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
599 if (table == NULL) {
600 return 0;
601 } else if (IS_ZEBRA_DEBUG_RIB) {
602 zlog_debug("%s routes from table %d",
603 add ? "Importing" : "Unimporting", table_id);
604 }
605
606 if (add) {
607 if (rmap_name)
608 zebra_add_import_table_route_map(afi, rmap_name,
609 table_id);
610 else {
611 rmap_name =
612 zebra_get_import_table_route_map(afi, table_id);
613 if (rmap_name)
614 zebra_del_import_table_route_map(afi, table_id);
615 }
616
617 zebra_import_table_used[afi][table_id] = 1;
618 zebra_import_table_distance[afi][table_id] = distance;
619 } else {
620 zebra_import_table_used[afi][table_id] = 0;
621 zebra_import_table_distance[afi][table_id] =
622 ZEBRA_TABLE_DISTANCE_DEFAULT;
623
624 rmap_name = zebra_get_import_table_route_map(afi, table_id);
625 if (rmap_name)
626 zebra_del_import_table_route_map(afi, table_id);
627 }
628
629 for (rn = route_top(table); rn; rn = route_next(rn)) {
630 /* For each entry in the non-default routing table,
631 * add the entry in the main table
632 */
633 if (!rn->info)
634 continue;
635
636 RNODE_FOREACH_RE(rn, re)
637 {
638 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
639 continue;
640 break;
641 }
642
643 if (!re)
644 continue;
645
646 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
647 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
648 if (add)
649 zebra_add_import_table_entry(rn, re, rmap_name);
650 else
651 zebra_del_import_table_entry(rn, re);
652 }
653 }
654 return 0;
655 }
656
657 int zebra_import_table_config(struct vty *vty)
658 {
659 int i;
660 afi_t afi;
661 int write = 0;
662 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
663 const char *rmap_name;
664
665 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
666 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
667 if (is_zebra_import_table_enabled(afi, i)) {
668 if (zebra_import_table_distance[afi][i]
669 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
670 vty_out(vty,
671 "%s import-table %d distance %d",
672 afi_str[afi], i,
673 zebra_import_table_distance[afi]
674 [i]);
675 } else {
676 vty_out(vty, "%s import-table %d",
677 afi_str[afi], i);
678 }
679
680 rmap_name = zebra_get_import_table_route_map(
681 afi, i);
682 if (rmap_name)
683 vty_out(vty, " route-map %s",
684 rmap_name);
685
686 vty_out(vty, "\n");
687 write = 1;
688 }
689 }
690 }
691
692 return write;
693 }
694
695 void zebra_import_table_rm_update()
696 {
697 afi_t afi;
698 int i;
699 struct route_table *table;
700 struct route_entry *re;
701 struct route_node *rn;
702 const char *rmap_name;
703
704 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
705 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
706 if (is_zebra_import_table_enabled(afi, i)) {
707 rmap_name = zebra_get_import_table_route_map(
708 afi, i);
709 if (!rmap_name)
710 return;
711
712 table = zebra_vrf_other_route_table(
713 afi, i, VRF_DEFAULT);
714 for (rn = route_top(table); rn;
715 rn = route_next(rn)) {
716 /* For each entry in the non-default
717 * routing table,
718 * add the entry in the main table
719 */
720 if (!rn->info)
721 continue;
722
723 RNODE_FOREACH_RE(rn, re)
724 {
725 if (CHECK_FLAG(
726 re->status,
727 ROUTE_ENTRY_REMOVED))
728 continue;
729 break;
730 }
731
732 if (!re)
733 continue;
734
735 if (((afi == AFI_IP)
736 && (rn->p.family == AF_INET))
737 || ((afi == AFI_IP6)
738 && (rn->p.family == AF_INET6)))
739 zebra_add_import_table_entry(
740 rn, re, rmap_name);
741 }
742 }
743 }
744 }
745
746 return;
747 }
748
749 /* Interface parameters update */
750 void zebra_interface_parameters_update(struct interface *ifp)
751 {
752 struct listnode *node, *nnode;
753 struct zserv *client;
754
755 if (IS_ZEBRA_DEBUG_EVENT)
756 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s",
757 ifp->name);
758
759 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
760 if (client->ifinfo)
761 zsend_interface_link_params(client, ifp);
762 }