]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
f55b04ee0db88b6ae26738d98f78875a8cd7197d
[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
34 #include "zebra/rib.h"
35 #include "zebra/zserv.h"
36 #include "zebra/redistribute.h"
37 #include "zebra/debug.h"
38 #include "zebra/router-id.h"
39
40 #define ZEBRA_PTM_SUPPORT
41
42
43 /* master zebra server structure */
44 extern struct zebra_t zebrad;
45
46 /* array holding redistribute info about table redistribution */
47 /* bit AFI is set if that AFI is redistributing routes from this table */
48 static u_char zebra_import_table_used[ZEBRA_KERNEL_TABLE_MAX];
49 static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
50
51 int
52 is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
53 {
54 if (is_zebra_valid_kernel_table(table_id))
55 {
56 if (CHECK_FLAG(zebra_import_table_used[table_id], (u_char)afi))
57 return 1;
58 else
59 return 0;
60 }
61
62 return 0;
63 }
64
65 static int
66 is_default (struct prefix *p)
67 {
68 if (p->family == AF_INET)
69 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
70 return 1;
71 #ifdef HAVE_IPV6
72 #if 0 /* IPv6 default separation is now pending until protocol daemon
73 can handle that. */
74 if (p->family == AF_INET6)
75 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
76 return 1;
77 #endif /* 0 */
78 #endif /* HAVE_IPV6 */
79 return 0;
80 }
81
82 static void
83 zebra_redistribute_default (struct zserv *client)
84 {
85 struct prefix_ipv4 p;
86 struct route_table *table;
87 struct route_node *rn;
88 struct rib *newrib;
89 #ifdef HAVE_IPV6
90 struct prefix_ipv6 p6;
91 #endif /* HAVE_IPV6 */
92
93
94 /* Lookup default route. */
95 memset (&p, 0, sizeof (struct prefix_ipv4));
96 p.family = AF_INET;
97
98 /* Lookup table. */
99 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
100 if (table)
101 {
102 rn = route_node_lookup (table, (struct prefix *)&p);
103 if (rn)
104 {
105 RNODE_FOREACH_RIB (rn, newrib)
106 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
107 && newrib->distance != DISTANCE_INFINITY)
108 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client, &rn->p, newrib);
109 route_unlock_node (rn);
110 }
111 }
112
113 #ifdef HAVE_IPV6
114 /* Lookup default route. */
115 memset (&p6, 0, sizeof (struct prefix_ipv6));
116 p6.family = AF_INET6;
117
118 /* Lookup table. */
119 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
120 if (table)
121 {
122 rn = route_node_lookup (table, (struct prefix *)&p6);
123 if (rn)
124 {
125 RNODE_FOREACH_RIB (rn, newrib)
126 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
127 && newrib->distance != DISTANCE_INFINITY)
128 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client, &rn->p, newrib);
129 route_unlock_node (rn);
130 }
131 }
132 #endif /* HAVE_IPV6 */
133 }
134
135 /* Redistribute routes. */
136 static void
137 zebra_redistribute (struct zserv *client, int type, u_short instance)
138 {
139 struct rib *newrib;
140 struct route_table *table;
141 struct route_node *rn;
142
143 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
144 if (table)
145 for (rn = route_top (table); rn; rn = route_next (rn))
146 RNODE_FOREACH_RIB (rn, newrib)
147 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
148 && newrib->type == type
149 && newrib->instance == instance
150 && newrib->distance != DISTANCE_INFINITY
151 && zebra_check_addr (&rn->p))
152 {
153 client->redist_v4_add_cnt++;
154 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client, &rn->p, newrib);
155 }
156
157 #ifdef HAVE_IPV6
158 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
159 if (table)
160 for (rn = route_top (table); rn; rn = route_next (rn))
161 RNODE_FOREACH_RIB (rn, newrib)
162 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
163 && newrib->type == type
164 && newrib->instance == instance
165 && newrib->distance != DISTANCE_INFINITY
166 && zebra_check_addr (&rn->p))
167 {
168 client->redist_v6_add_cnt++;
169 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client, &rn->p, newrib);
170 }
171 #endif /* HAVE_IPV6 */
172 }
173
174 void
175 redistribute_add (struct prefix *p, struct rib *rib)
176 {
177 struct listnode *node, *nnode;
178 struct zserv *client;
179
180 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
181 {
182 if (is_default (p))
183 {
184 if ((p->family == AF_INET) &&
185 (client->redist_default ||
186 redist_check_instance(&client->redist[AFI_IP][rib->type],
187 rib->instance)))
188 {
189 client->redist_v4_add_cnt++;
190 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client,
191 p, rib);
192 }
193 #ifdef HAVE_IPV6
194 if ((p->family == AF_INET6) &&
195 (client->redist_default ||
196 redist_check_instance(&client->redist[AFI_IP6][rib->type],
197 rib->instance)))
198 {
199 client->redist_v6_add_cnt++;
200 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client,
201 p, rib);
202 }
203 #endif /* HAVE_IPV6 */
204 }
205 else
206 {
207 if ((p->family == AF_INET) &&
208 redist_check_instance(&client->redist[AFI_IP][rib->type],
209 rib->instance))
210 {
211 client->redist_v4_add_cnt++;
212 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client,
213 p, rib);
214 }
215 #ifdef HAVE_IPV6
216 if ((p->family == AF_INET6) &&
217 redist_check_instance(&client->redist[AFI_IP6][rib->type],
218 rib->instance))
219 {
220 client->redist_v6_add_cnt++;
221 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client,
222 p, rib);
223 }
224 #endif /* HAVE_IPV6 */
225 }
226 }
227 }
228
229 void
230 redistribute_delete (struct prefix *p, struct rib *rib)
231 {
232 struct listnode *node, *nnode;
233 struct zserv *client;
234
235 /* Add DISTANCE_INFINITY check. */
236 if (rib->distance == DISTANCE_INFINITY)
237 return;
238
239 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
240 {
241 if (is_default (p))
242 {
243 if ((p->family == AF_INET) &&
244 (client->redist_default ||
245 redist_check_instance(&client->redist[AFI_IP][rib->type],
246 rib->instance)))
247 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_DEL, client, p,
248 rib);
249 #ifdef HAVE_IPV6
250 if ((p->family == AF_INET6) &&
251 (client->redist_default ||
252 redist_check_instance(&client->redist[AFI_IP6][rib->type],
253 rib->instance)))
254 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_DEL, client, p,
255 rib);
256 #endif /* HAVE_IPV6 */
257 }
258 else
259 {
260 if ((p->family == AF_INET) &&
261 redist_check_instance(&client->redist[AFI_IP][rib->type],
262 rib->instance))
263 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_DEL, client, p,
264 rib);
265 #ifdef HAVE_IPV6
266 if ((p->family == AF_INET6) &&
267 redist_check_instance(&client->redist[AFI_IP6][rib->type],
268 rib->instance))
269 zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_DEL, client, p,
270 rib);
271 #endif /* HAVE_IPV6 */
272 }
273 }
274 }
275
276 void
277 zebra_redistribute_add (int command, struct zserv *client, int length)
278 {
279 afi_t afi;
280 int type;
281 u_short instance;
282
283 afi = stream_getc (client->ibuf);
284 type = stream_getc (client->ibuf);
285 instance = stream_getw (client->ibuf);
286
287 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
288 return;
289
290 if (!redist_check_instance(&client->redist[afi][type], instance))
291 {
292 redist_add_instance(&client->redist[afi][type], instance);
293 zebra_redistribute (client, type, instance);
294 }
295 }
296
297 void
298 zebra_redistribute_delete (int command, struct zserv *client, int length)
299 {
300 afi_t afi;
301 int type;
302 u_short instance;
303
304 afi = stream_getc (client->ibuf);
305 type = stream_getc (client->ibuf);
306 instance = stream_getw (client->ibuf);
307
308 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
309 return;
310
311 if (redist_check_instance(&client->redist[afi][type], instance))
312 {
313 redist_del_instance(&client->redist[afi][type], instance);
314 //Pending: why no reaction here?
315 }
316 }
317
318 void
319 zebra_redistribute_default_add (int command, struct zserv *client, int length)
320 {
321 client->redist_default = 1;
322 zebra_redistribute_default (client);
323 }
324
325 void
326 zebra_redistribute_default_delete (int command, struct zserv *client,
327 int length)
328 {
329 client->redist_default = 0;;
330 }
331
332 /* Interface up information. */
333 void
334 zebra_interface_up_update (struct interface *ifp)
335 {
336 struct listnode *node, *nnode;
337 struct zserv *client;
338
339 if (IS_ZEBRA_DEBUG_EVENT)
340 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
341
342 if (ifp->ptm_status || !ifp->ptm_enable) {
343 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
344 {
345 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
346 }
347 }
348 }
349
350 /* Interface down information. */
351 void
352 zebra_interface_down_update (struct interface *ifp)
353 {
354 struct listnode *node, *nnode;
355 struct zserv *client;
356
357 if (IS_ZEBRA_DEBUG_EVENT)
358 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
359
360 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
361 {
362 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
363 }
364 }
365
366 /* Interface information update. */
367 void
368 zebra_interface_add_update (struct interface *ifp)
369 {
370 struct listnode *node, *nnode;
371 struct zserv *client;
372
373 if (IS_ZEBRA_DEBUG_EVENT)
374 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
375
376 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
377 if (client->ifinfo)
378 {
379 client->ifadd_cnt++;
380 zsend_interface_add (client, ifp);
381 }
382 }
383
384 void
385 zebra_interface_delete_update (struct interface *ifp)
386 {
387 struct listnode *node, *nnode;
388 struct zserv *client;
389
390 if (IS_ZEBRA_DEBUG_EVENT)
391 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
392
393 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
394 if (client->ifinfo)
395 {
396 client->ifdel_cnt++;
397 zsend_interface_delete (client, ifp);
398 }
399 }
400
401 /* Interface address addition. */
402 void
403 zebra_interface_address_add_update (struct interface *ifp,
404 struct connected *ifc)
405 {
406 struct listnode *node, *nnode;
407 struct zserv *client;
408 struct prefix *p;
409
410 if (IS_ZEBRA_DEBUG_EVENT)
411 {
412 char buf[INET6_ADDRSTRLEN];
413
414 p = ifc->address;
415 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
416 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
417 p->prefixlen, ifc->ifp->name);
418 }
419
420 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
421 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
422
423 router_id_add_address(ifc);
424
425 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
426 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
427 {
428 client->connected_rt_add_cnt++;
429 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
430 }
431 }
432
433 /* Interface address deletion. */
434 void
435 zebra_interface_address_delete_update (struct interface *ifp,
436 struct connected *ifc)
437 {
438 struct listnode *node, *nnode;
439 struct zserv *client;
440 struct prefix *p;
441
442 if (IS_ZEBRA_DEBUG_EVENT)
443 {
444 char buf[INET6_ADDRSTRLEN];
445
446 p = ifc->address;
447 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
448 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
449 p->prefixlen, ifc->ifp->name);
450 }
451
452 router_id_del_address(ifc);
453
454 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
455 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
456 {
457 client->connected_rt_del_cnt++;
458 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
459 }
460 }
461
462 int
463 zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
464 {
465 struct rib *newrib;
466 struct prefix_ipv4 p4;
467 struct nexthop *nhop;
468 struct in_addr *gate;
469
470 if (rn->p.family == AF_INET)
471 {
472 p4.family = AF_INET;
473 p4.prefixlen = rn->p.prefixlen;
474 p4.prefix = rn->p.u.prefix4;
475
476 if (rib->nexthop_num == 1)
477 {
478 nhop = rib->nexthop;
479 if ((nhop->type == NEXTHOP_TYPE_IFINDEX) ||
480 (nhop->type == NEXTHOP_TYPE_IFNAME))
481 gate = NULL;
482 else
483 gate = &nhop->gate.ipv4;
484
485 rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
486 gate, &nhop->src.ipv4,
487 nhop->ifindex, zebrad.rtm_table_default,
488 rib->metric,
489 zebra_import_table_distance[AFI_IP][rib->table],
490 SAFI_UNICAST);
491 }
492 else if (rib->nexthop_num > 1)
493 {
494 newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
495 newrib->type = ZEBRA_ROUTE_TABLE;
496 newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
497 newrib->flags = rib->flags;
498 newrib->metric = rib->metric;
499 newrib->table = zebrad.rtm_table_default;
500 newrib->nexthop_num = 0;
501 newrib->uptime = time(NULL);
502 newrib->instance = rib->table;
503
504 /* Assuming these routes are never recursive */
505 for (nhop = rib->nexthop; nhop; nhop = nhop->next)
506 copy_nexthops(newrib, nhop);
507
508 rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
509 }
510 }
511 /* DD: Add IPv6 code */
512 return 0;
513 }
514
515 int
516 zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
517 {
518 struct prefix_ipv4 p4;
519
520 if (rn->p.family == AF_INET)
521 {
522 p4.family = AF_INET;
523 p4.prefixlen = rn->p.prefixlen;
524 p4.prefix = rn->p.u.prefix4;
525
526 rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
527 0, zebrad.rtm_table_default, SAFI_UNICAST);
528 }
529 /* DD: Add IPv6 code */
530
531 return 0;
532 }
533
534 /* Assuming no one calls this with the main routing table */
535 int
536 zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
537 {
538 struct route_table *table;
539 struct rib *rib;
540 struct route_node *rn;
541
542 if (!is_zebra_valid_kernel_table(table_id) ||
543 ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default)))
544 return (-1);
545
546 if (afi >= AFI_MAX)
547 return (-1);
548
549 table = vrf_other_route_table(afi, table_id, 0);
550 if (table == NULL)
551 {
552 return 0;
553 }
554 else if (IS_ZEBRA_DEBUG_RIB)
555 {
556 zlog_debug ("%s routes from table %d",
557 add ? "Importing" : "Unimporting", table_id);
558 }
559
560 if (add)
561 {
562 SET_FLAG(zebra_import_table_used[table_id], afi);
563 zebra_import_table_distance[afi][table_id] = distance;
564 }
565 else
566 {
567 UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
568 zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
569 }
570
571 for (rn = route_top(table); rn; rn = route_next(rn))
572 {
573 /* For each entry in the non-default routing table,
574 * add the entry in the main table
575 */
576 if (!rn->info)
577 continue;
578
579 RNODE_FOREACH_RIB (rn, rib)
580 {
581 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
582 continue;
583 break;
584 }
585
586 if (!rib)
587 continue;
588
589 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
590 ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
591 {
592 if (add)
593 zebra_add_import_table_entry (rn, rib);
594 else
595 zebra_del_import_table_entry (rn, rib);
596 }
597 }
598 return 0;
599 }
600
601 int
602 zebra_import_table_config (struct vty *vty)
603 {
604 int i;
605 afi_t afi;
606 int write = 0;
607 char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
608
609 for (afi = AFI_IP; afi < AFI_MAX; afi++)
610 {
611 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
612 {
613 if (is_zebra_import_table_enabled(afi, i))
614 {
615 if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
616 {
617 vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
618 i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
619 }
620 else
621 {
622 vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
623 VTY_NEWLINE);
624 }
625 write = 1;
626 }
627 }
628 }
629
630 return write;
631 }