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