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