]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
This patch adds support for a new BFD session down message from zebra to
[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 int
47 zebra_check_addr (struct prefix *p)
48 {
49 if (p->family == AF_INET)
50 {
51 u_int32_t addr;
52
53 addr = p->u.prefix4.s_addr;
54 addr = ntohl (addr);
55
56 if (IPV4_NET127 (addr)
57 || IN_CLASSD (addr)
58 || IPV4_LINKLOCAL(addr))
59 return 0;
60 }
61 #ifdef HAVE_IPV6
62 if (p->family == AF_INET6)
63 {
64 if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
65 return 0;
66 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
67 return 0;
68 }
69 #endif /* HAVE_IPV6 */
70 return 1;
71 }
72
73 static int
74 is_default (struct prefix *p)
75 {
76 if (p->family == AF_INET)
77 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
78 return 1;
79 #ifdef HAVE_IPV6
80 #if 0 /* IPv6 default separation is now pending until protocol daemon
81 can handle that. */
82 if (p->family == AF_INET6)
83 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
84 return 1;
85 #endif /* 0 */
86 #endif /* HAVE_IPV6 */
87 return 0;
88 }
89
90 static void
91 zebra_redistribute_default (struct zserv *client)
92 {
93 struct prefix_ipv4 p;
94 struct route_table *table;
95 struct route_node *rn;
96 struct rib *newrib;
97 #ifdef HAVE_IPV6
98 struct prefix_ipv6 p6;
99 #endif /* HAVE_IPV6 */
100
101
102 /* Lookup default route. */
103 memset (&p, 0, sizeof (struct prefix_ipv4));
104 p.family = AF_INET;
105
106 /* Lookup table. */
107 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
108 if (table)
109 {
110 rn = route_node_lookup (table, (struct prefix *)&p);
111 if (rn)
112 {
113 RNODE_FOREACH_RIB (rn, newrib)
114 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
115 && newrib->distance != DISTANCE_INFINITY)
116 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
117 route_unlock_node (rn);
118 }
119 }
120
121 #ifdef HAVE_IPV6
122 /* Lookup default route. */
123 memset (&p6, 0, sizeof (struct prefix_ipv6));
124 p6.family = AF_INET6;
125
126 /* Lookup table. */
127 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
128 if (table)
129 {
130 rn = route_node_lookup (table, (struct prefix *)&p6);
131 if (rn)
132 {
133 RNODE_FOREACH_RIB (rn, newrib)
134 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
135 && newrib->distance != DISTANCE_INFINITY)
136 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
137 route_unlock_node (rn);
138 }
139 }
140 #endif /* HAVE_IPV6 */
141 }
142
143 /* Redistribute routes. */
144 static void
145 zebra_redistribute (struct zserv *client, int type)
146 {
147 struct rib *newrib;
148 struct route_table *table;
149 struct route_node *rn;
150
151 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
152 if (table)
153 for (rn = route_top (table); rn; rn = route_next (rn))
154 RNODE_FOREACH_RIB (rn, newrib)
155 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
156 && newrib->type == type
157 && newrib->distance != DISTANCE_INFINITY
158 && zebra_check_addr (&rn->p))
159 {
160 client->redist_v4_add_cnt++;
161 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
162 }
163
164 #ifdef HAVE_IPV6
165 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
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->distance != DISTANCE_INFINITY
172 && zebra_check_addr (&rn->p))
173 {
174 client->redist_v6_add_cnt++;
175 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
176 }
177 #endif /* HAVE_IPV6 */
178 }
179
180 void
181 redistribute_add (struct prefix *p, struct rib *rib)
182 {
183 struct listnode *node, *nnode;
184 struct zserv *client;
185
186 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
187 {
188 if (is_default (p))
189 {
190 if (client->redist_default || client->redist[rib->type])
191 {
192 if (p->family == AF_INET)
193 {
194 client->redist_v4_add_cnt++;
195 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
196 }
197 #ifdef HAVE_IPV6
198 if (p->family == AF_INET6)
199 {
200 client->redist_v6_add_cnt++;
201 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
202 }
203 #endif /* HAVE_IPV6 */
204 }
205 }
206 else if (client->redist[rib->type])
207 {
208 if (p->family == AF_INET)
209 {
210 client->redist_v4_add_cnt++;
211 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
212 }
213 #ifdef HAVE_IPV6
214 if (p->family == AF_INET6)
215 {
216 client->redist_v6_add_cnt++;
217 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
218 }
219 #endif /* HAVE_IPV6 */
220 }
221 }
222 }
223
224 void
225 redistribute_delete (struct prefix *p, struct rib *rib)
226 {
227 struct listnode *node, *nnode;
228 struct zserv *client;
229
230 /* Add DISTANCE_INFINITY check. */
231 if (rib->distance == DISTANCE_INFINITY)
232 return;
233
234 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
235 {
236 if (is_default (p))
237 {
238 if (client->redist_default || client->redist[rib->type])
239 {
240 if (p->family == AF_INET)
241 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
242 rib);
243 #ifdef HAVE_IPV6
244 if (p->family == AF_INET6)
245 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
246 rib);
247 #endif /* HAVE_IPV6 */
248 }
249 }
250 else if (client->redist[rib->type])
251 {
252 if (p->family == AF_INET)
253 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
254 #ifdef HAVE_IPV6
255 if (p->family == AF_INET6)
256 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
257 #endif /* HAVE_IPV6 */
258 }
259 }
260 }
261
262 void
263 zebra_redistribute_add (int command, struct zserv *client, int length)
264 {
265 int type;
266
267 type = stream_getc (client->ibuf);
268
269 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
270 return;
271
272 if (! client->redist[type])
273 {
274 client->redist[type] = 1;
275 zebra_redistribute (client, type);
276 }
277 }
278
279 void
280 zebra_redistribute_delete (int command, struct zserv *client, int length)
281 {
282 int type;
283
284 type = stream_getc (client->ibuf);
285
286 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
287 return;
288
289 client->redist[type] = 0;
290 }
291
292 void
293 zebra_redistribute_default_add (int command, struct zserv *client, int length)
294 {
295 client->redist_default = 1;
296 zebra_redistribute_default (client);
297 }
298
299 void
300 zebra_redistribute_default_delete (int command, struct zserv *client,
301 int length)
302 {
303 client->redist_default = 0;;
304 }
305
306 /* Interface up information. */
307 void
308 zebra_interface_up_update (struct interface *ifp)
309 {
310 struct listnode *node, *nnode;
311 struct zserv *client;
312
313 if (IS_ZEBRA_DEBUG_EVENT)
314 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
315
316 if (ifp->ptm_status || !ifp->ptm_enable) {
317 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
318 {
319 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
320 }
321 }
322 }
323
324 /* Interface down information. */
325 void
326 zebra_interface_down_update (struct interface *ifp)
327 {
328 struct listnode *node, *nnode;
329 struct zserv *client;
330
331 if (IS_ZEBRA_DEBUG_EVENT)
332 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
333
334 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
335 {
336 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
337 }
338 }
339
340 /* Interface information update. */
341 void
342 zebra_interface_add_update (struct interface *ifp)
343 {
344 struct listnode *node, *nnode;
345 struct zserv *client;
346
347 if (IS_ZEBRA_DEBUG_EVENT)
348 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
349
350 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
351 if (client->ifinfo)
352 {
353 client->ifadd_cnt++;
354 zsend_interface_add (client, ifp);
355 }
356 }
357
358 void
359 zebra_interface_delete_update (struct interface *ifp)
360 {
361 struct listnode *node, *nnode;
362 struct zserv *client;
363
364 if (IS_ZEBRA_DEBUG_EVENT)
365 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
366
367 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
368 if (client->ifinfo)
369 {
370 client->ifdel_cnt++;
371 zsend_interface_delete (client, ifp);
372 }
373 }
374
375 /* Interface address addition. */
376 void
377 zebra_interface_address_add_update (struct interface *ifp,
378 struct connected *ifc)
379 {
380 struct listnode *node, *nnode;
381 struct zserv *client;
382 struct prefix *p;
383
384 if (IS_ZEBRA_DEBUG_EVENT)
385 {
386 char buf[INET6_ADDRSTRLEN];
387
388 p = ifc->address;
389 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
390 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
391 p->prefixlen, ifc->ifp->name);
392 }
393
394 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
395 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
396
397 router_id_add_address(ifc);
398
399 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
400 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
401 {
402 client->connected_rt_add_cnt++;
403 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
404 }
405 }
406
407 /* Interface address deletion. */
408 void
409 zebra_interface_address_delete_update (struct interface *ifp,
410 struct connected *ifc)
411 {
412 struct listnode *node, *nnode;
413 struct zserv *client;
414 struct prefix *p;
415
416 if (IS_ZEBRA_DEBUG_EVENT)
417 {
418 char buf[INET6_ADDRSTRLEN];
419
420 p = ifc->address;
421 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
422 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
423 p->prefixlen, ifc->ifp->name);
424 }
425
426 router_id_del_address(ifc);
427
428 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
429 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
430 {
431 client->connected_rt_del_cnt++;
432 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
433 }
434 }
435
436 void
437 zebra_interface_bfd_update (struct interface *ifp, struct prefix *p)
438 {
439 struct listnode *node, *nnode;
440 struct zserv *client;
441
442 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
443 {
444 /* Supporting for OSPF and BGP */
445 if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP)
446 continue;
447
448 /* Notify to the protocol daemons. */
449 zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_DOWN, client, ifp, p);
450 }
451 }