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