]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - zebra/redistribute.c
New upstream release and new maintainer
[quagga-debian.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/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 zebra_check_addr (struct prefix *p)
46 {
47   if (p->family == AF_INET)
48     {
49       u_int32_t addr;
50
51       addr = p->u.prefix4.s_addr;
52       addr = ntohl (addr);
53
54       if (IPV4_NET127 (addr)
55           || IN_CLASSD (addr)
56           || IPV4_LINKLOCAL(addr))
57         return 0;
58     }
59 #ifdef HAVE_IPV6
60   if (p->family == AF_INET6)
61     {
62       if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
63         return 0;
64       if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
65         return 0;
66     }
67 #endif /* HAVE_IPV6 */
68   return 1;
69 }
70
71 int
72 is_default (struct prefix *p)
73 {
74   if (p->family == AF_INET)
75     if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
76       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   return 0;
86 }
87
88 static void
89 zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
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   memset (&p, 0, sizeof (struct prefix_ipv4));
102   p.family = AF_INET;
103
104   /* Lookup table.  */
105   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
106   if (table)
107     {
108       rn = route_node_lookup (table, (struct prefix *)&p);
109       if (rn)
110         {
111           RNODE_FOREACH_RIB (rn, newrib)
112             if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
113                 && newrib->distance != DISTANCE_INFINITY)
114               zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
115           route_unlock_node (rn);
116         }
117     }
118
119 #ifdef HAVE_IPV6
120   /* Lookup default route. */
121   memset (&p6, 0, sizeof (struct prefix_ipv6));
122   p6.family = AF_INET6;
123
124   /* Lookup table.  */
125   table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
126   if (table)
127     {
128       rn = route_node_lookup (table, (struct prefix *)&p6);
129       if (rn)
130         {
131           RNODE_FOREACH_RIB (rn, newrib)
132             if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
133                 && newrib->distance != DISTANCE_INFINITY)
134               zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
135           route_unlock_node (rn);
136         }
137     }
138 #endif /* HAVE_IPV6 */
139 }
140
141 /* Redistribute routes. */
142 static void
143 zebra_redistribute (struct zserv *client, int type, vrf_id_t vrf_id)
144 {
145   struct rib *newrib;
146   struct route_table *table;
147   struct route_node *rn;
148
149   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
150   if (table)
151     for (rn = route_top (table); rn; rn = route_next (rn))
152       RNODE_FOREACH_RIB (rn, newrib)
153         {
154           if (IS_ZEBRA_DEBUG_EVENT)
155             zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, zebra_check_addr=%d",
156                        __func__, CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
157                        newrib->type, newrib->distance, zebra_check_addr (&rn->p));
158           if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
159               && newrib->type == type
160               && newrib->distance != DISTANCE_INFINITY
161               && zebra_check_addr (&rn->p))
162             {
163               client->redist_v4_add_cnt++;
164               zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
165             }
166         }
167
168 #ifdef HAVE_IPV6
169   table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
170   if (table)
171     for (rn = route_top (table); rn; rn = route_next (rn))
172       RNODE_FOREACH_RIB (rn, newrib)
173         if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
174             && newrib->type == type 
175             && newrib->distance != DISTANCE_INFINITY
176             && zebra_check_addr (&rn->p))
177           {
178             client->redist_v6_add_cnt++;
179             zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
180           }
181 #endif /* HAVE_IPV6 */
182 }
183
184 void
185 redistribute_add (struct prefix *p, struct rib *rib, struct rib *rib_old)
186 {
187   struct listnode *node, *nnode;
188   struct zserv *client;
189   
190   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
191     {
192       if ((is_default (p) &&
193            vrf_bitmap_check (client->redist_default, rib->vrf_id))
194           || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
195         {
196           if (p->family == AF_INET)
197             {
198               client->redist_v4_add_cnt++;
199               zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
200             }
201           if (p->family == AF_INET6)
202             {
203               client->redist_v6_add_cnt++;
204               zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
205             }
206         }
207       else if (rib_old && vrf_bitmap_check (client->redist[rib_old->type], 
208                                             rib_old->vrf_id))
209         {
210           /* redistribute_add has implicit withdraw semantics, so there
211            * may be an old route already redistributed that is being updated.
212            *
213            * However, if the new route is of a type that is /not/ redistributed
214            * to the client, then we must ensure the old route is explicitly
215            * withdrawn.
216            */
217           if (p->family == AF_INET)
218             zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib_old);
219           if (p->family == AF_INET6)
220             zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib_old);
221         }
222     }
223 }
224
225 void
226 redistribute_delete (struct prefix *p, struct rib *rib)
227 {
228   struct listnode *node, *nnode;
229   struct zserv *client;
230
231   /* Add DISTANCE_INFINITY check. */
232   if (rib->distance == DISTANCE_INFINITY)
233     return;
234
235   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
236     {
237       if ((is_default (p) &&
238            vrf_bitmap_check (client->redist_default, rib->vrf_id))
239           || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
240         {
241           if (p->family == AF_INET)
242             zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
243 #ifdef HAVE_IPV6
244           if (p->family == AF_INET6)
245             zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
246 #endif /* HAVE_IPV6 */
247         }
248     }
249 }
250
251 void
252 zebra_redistribute_add (int command, struct zserv *client, int length,
253     vrf_id_t vrf_id)
254 {
255   int type;
256
257   type = stream_getc (client->ibuf);
258
259   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
260     return;
261
262   if (! vrf_bitmap_check (client->redist[type], vrf_id))
263     {
264       vrf_bitmap_set (client->redist[type], vrf_id);
265       zebra_redistribute (client, type, vrf_id);
266     }
267 }
268
269 void
270 zebra_redistribute_delete (int command, struct zserv *client, int length,
271     vrf_id_t vrf_id)
272 {
273   int type;
274
275   type = stream_getc (client->ibuf);
276
277   if (type == 0 || type >= ZEBRA_ROUTE_MAX)
278     return;
279
280   vrf_bitmap_unset (client->redist[type], vrf_id);
281 }
282
283 void
284 zebra_redistribute_default_add (int command, struct zserv *client, int length,
285     vrf_id_t vrf_id)
286 {
287   vrf_bitmap_set (client->redist_default, vrf_id);
288   zebra_redistribute_default (client, vrf_id);
289 }     
290
291 void
292 zebra_redistribute_default_delete (int command, struct zserv *client,
293     int length, vrf_id_t vrf_id)
294 {
295   vrf_bitmap_unset (client->redist_default, vrf_id);
296 }     
297
298 /* Interface up information. */
299 void
300 zebra_interface_up_update (struct interface *ifp)
301 {
302   struct listnode *node, *nnode;
303   struct zserv *client;
304
305   if (IS_ZEBRA_DEBUG_EVENT)
306     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
307
308   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
309     if (client->ifinfo)
310       {
311         zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
312         zsend_interface_link_params (client, ifp);
313       }
314 }
315
316 /* Interface down information. */
317 void
318 zebra_interface_down_update (struct interface *ifp)
319 {
320   struct listnode *node, *nnode;
321   struct zserv *client;
322
323   if (IS_ZEBRA_DEBUG_EVENT)
324     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
325
326   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
327     {
328       zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
329     }
330 }
331
332 /* Interface information update. */
333 void
334 zebra_interface_add_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_ADD %s", ifp->name);
341     
342   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
343     if (client->ifinfo)
344       {
345         client->ifadd_cnt++;
346         zsend_interface_add (client, ifp);
347         zsend_interface_link_params (client, ifp);
348       }
349 }
350
351 void
352 zebra_interface_delete_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_DELETE %s", ifp->name);
359
360   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
361     if (client->ifinfo)
362       {
363         client->ifdel_cnt++;
364         zsend_interface_delete (client, ifp);
365       }
366 }
367
368 /* Interface address addition. */
369 void
370 zebra_interface_address_add_update (struct interface *ifp,
371                                     struct connected *ifc)
372 {
373   struct listnode *node, *nnode;
374   struct zserv *client;
375   struct prefix *p;
376
377   if (IS_ZEBRA_DEBUG_EVENT)
378     {
379       char buf[PREFIX_STRLEN];
380
381       p = ifc->address;
382       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
383                   prefix2str (p, buf, sizeof(buf)),
384                   ifc->ifp->name);
385     }
386
387   if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
388     zlog_warn("WARNING: advertising address to clients that is not yet usable.");
389
390   router_id_add_address(ifc);
391
392   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
393     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
394       {
395         client->connected_rt_add_cnt++;
396         zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
397       }
398 }
399
400 /* Interface address deletion. */
401 void
402 zebra_interface_address_delete_update (struct interface *ifp,
403                                        struct connected *ifc)
404 {
405   struct listnode *node, *nnode;
406   struct zserv *client;
407   struct prefix *p;
408
409   if (IS_ZEBRA_DEBUG_EVENT)
410     {
411       char buf[PREFIX_STRLEN];
412
413       p = ifc->address;
414       zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
415                   prefix2str (p, buf, sizeof(buf)),
416                   ifc->ifp->name);
417     }
418
419   router_id_del_address(ifc);
420
421   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
422     if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
423       {
424         client->connected_rt_del_cnt++;
425         zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
426       }
427 }
428
429 /* Interface parameters update */
430 void
431 zebra_interface_parameters_update (struct interface *ifp)
432 {
433   struct listnode *node, *nnode;
434   struct zserv *client;
435
436   if (IS_ZEBRA_DEBUG_EVENT)
437     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s", ifp->name);
438
439   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
440     if (client->ifinfo)
441       zsend_interface_link_params (client, ifp);
442 }