1 /* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
34 #include "zebra/rib.h"
35 #include "zebra/zserv.h"
36 #include "zebra/redistribute.h"
37 #include "zebra/debug.h"
40 zebra_check_addr (struct prefix
*p
)
42 if (p
->family
== AF_INET
)
46 addr
= p
->u
.prefix4
.s_addr
;
49 if (IPV4_NET127 (addr
) || IN_CLASSD (addr
))
53 if (p
->family
== AF_INET6
)
55 if (IN6_IS_ADDR_LOOPBACK (&p
->u
.prefix6
))
57 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
60 #endif /* HAVE_IPV6 */
65 is_default (struct prefix
*p
)
67 if (p
->family
== AF_INET
)
68 if (p
->u
.prefix4
.s_addr
== 0 && p
->prefixlen
== 0)
71 #if 0 /* IPv6 default separation is now pending until protocol daemon
73 if (p
->family
== AF_INET6
)
74 if (IN6_IS_ADDR_UNSPECIFIED (&p
->u
.prefix6
) && p
->prefixlen
== 0)
77 #endif /* HAVE_IPV6 */
82 zebra_redistribute_default (struct zserv
*client
)
85 struct route_table
*table
;
86 struct route_node
*rn
;
89 struct prefix_ipv6 p6
;
90 #endif /* HAVE_IPV6 */
93 /* Lookup default route. */
94 memset (&p
, 0, sizeof (struct prefix_ipv4
));
98 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
101 rn
= route_node_lookup (table
, (struct prefix
*)&p
);
104 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
105 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
106 && newrib
->distance
!= DISTANCE_INFINITY
)
107 zsend_ipv4_add_multipath (client
, &rn
->p
, newrib
);
108 route_unlock_node (rn
);
113 /* Lookup default route. */
114 memset (&p6
, 0, sizeof (struct prefix_ipv6
));
115 p6
.family
= AF_INET6
;
118 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
121 rn
= route_node_lookup (table
, (struct prefix
*)&p6
);
124 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
125 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
126 && newrib
->distance
!= DISTANCE_INFINITY
)
127 zsend_ipv6_add_multipath (client
, &rn
->p
, newrib
);
128 route_unlock_node (rn
);
131 #endif /* HAVE_IPV6 */
134 /* Redistribute routes. */
136 zebra_redistribute (struct zserv
*client
, int type
)
139 struct route_table
*table
;
140 struct route_node
*rn
;
142 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
144 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
145 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
146 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
147 && newrib
->type
== type
148 && newrib
->distance
!= DISTANCE_INFINITY
149 && zebra_check_addr (&rn
->p
))
150 zsend_ipv4_add_multipath (client
, &rn
->p
, newrib
);
153 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
155 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
156 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
157 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
158 && newrib
->type
== type
159 && newrib
->distance
!= DISTANCE_INFINITY
160 && zebra_check_addr (&rn
->p
))
161 zsend_ipv6_add_multipath (client
, &rn
->p
, newrib
);
162 #endif /* HAVE_IPV6 */
165 extern list client_list
;
168 redistribute_add (struct prefix
*p
, struct rib
*rib
)
171 struct zserv
*client
;
173 for (node
= listhead (client_list
); node
; nextnode (node
))
174 if ((client
= getdata (node
)) != NULL
)
178 if (client
->redist_default
|| client
->redist
[rib
->type
])
180 if (p
->family
== AF_INET
)
181 zsend_ipv4_add_multipath (client
, p
, rib
);
183 if (p
->family
== AF_INET6
)
184 zsend_ipv6_add_multipath (client
, p
, rib
);
185 #endif /* HAVE_IPV6 */
188 else if (client
->redist
[rib
->type
])
190 if (p
->family
== AF_INET
)
191 zsend_ipv4_add_multipath (client
, p
, rib
);
193 if (p
->family
== AF_INET6
)
194 zsend_ipv6_add_multipath (client
, p
, rib
);
195 #endif /* HAVE_IPV6 */
201 redistribute_delete (struct prefix
*p
, struct rib
*rib
)
204 struct zserv
*client
;
206 /* Add DISTANCE_INFINITY check. */
207 if (rib
->distance
== DISTANCE_INFINITY
)
210 for (node
= listhead (client_list
); node
; nextnode (node
))
211 if ((client
= getdata (node
)) != NULL
)
215 if (client
->redist_default
|| client
->redist
[rib
->type
])
217 if (p
->family
== AF_INET
)
218 zsend_ipv4_delete_multipath (client
, p
, rib
);
220 if (p
->family
== AF_INET6
)
221 zsend_ipv6_delete_multipath (client
, p
, rib
);
222 #endif /* HAVE_IPV6 */
225 else if (client
->redist
[rib
->type
])
227 if (p
->family
== AF_INET
)
228 zsend_ipv4_delete_multipath (client
, p
, rib
);
230 if (p
->family
== AF_INET6
)
231 zsend_ipv6_delete_multipath (client
, p
, rib
);
232 #endif /* HAVE_IPV6 */
238 zebra_redistribute_add (int command
, struct zserv
*client
, int length
)
242 type
= stream_getc (client
->ibuf
);
246 case ZEBRA_ROUTE_KERNEL
:
247 case ZEBRA_ROUTE_CONNECT
:
248 case ZEBRA_ROUTE_STATIC
:
249 case ZEBRA_ROUTE_RIP
:
250 case ZEBRA_ROUTE_RIPNG
:
251 case ZEBRA_ROUTE_OSPF
:
252 case ZEBRA_ROUTE_OSPF6
:
253 case ZEBRA_ROUTE_BGP
:
254 if (! client
->redist
[type
])
256 client
->redist
[type
] = 1;
257 zebra_redistribute (client
, type
);
266 zebra_redistribute_delete (int command
, struct zserv
*client
, int length
)
270 type
= stream_getc (client
->ibuf
);
274 case ZEBRA_ROUTE_KERNEL
:
275 case ZEBRA_ROUTE_CONNECT
:
276 case ZEBRA_ROUTE_STATIC
:
277 case ZEBRA_ROUTE_RIP
:
278 case ZEBRA_ROUTE_RIPNG
:
279 case ZEBRA_ROUTE_OSPF
:
280 case ZEBRA_ROUTE_OSPF6
:
281 case ZEBRA_ROUTE_BGP
:
282 client
->redist
[type
] = 0;
290 zebra_redistribute_default_add (int command
, struct zserv
*client
, int length
)
292 client
->redist_default
= 1;
293 zebra_redistribute_default (client
);
297 zebra_redistribute_default_delete (int command
, struct zserv
*client
,
300 client
->redist_default
= 0;;
303 /* Interface up information. */
305 zebra_interface_up_update (struct interface
*ifp
)
308 struct zserv
*client
;
310 if (IS_ZEBRA_DEBUG_EVENT
)
311 zlog_info ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp
->name
);
313 for (node
= listhead (client_list
); node
; nextnode (node
))
314 if ((client
= getdata (node
)) != NULL
)
315 zsend_interface_up (client
, ifp
);
318 /* Interface down information. */
320 zebra_interface_down_update (struct interface
*ifp
)
323 struct zserv
*client
;
325 if (IS_ZEBRA_DEBUG_EVENT
)
326 zlog_info ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp
->name
);
328 for (node
= listhead (client_list
); node
; nextnode (node
))
329 if ((client
= getdata (node
)) != NULL
)
330 zsend_interface_down (client
, ifp
);
333 /* Interface information update. */
335 zebra_interface_add_update (struct interface
*ifp
)
338 struct zserv
*client
;
340 if (IS_ZEBRA_DEBUG_EVENT
)
341 zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp
->name
);
343 for (node
= listhead (client_list
); node
; nextnode (node
))
344 if ((client
= getdata (node
)) != NULL
)
346 zsend_interface_add (client
, ifp
);
350 zebra_interface_delete_update (struct interface
*ifp
)
353 struct zserv
*client
;
355 if (IS_ZEBRA_DEBUG_EVENT
)
356 zlog_info ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp
->name
);
358 for (node
= listhead (client_list
); node
; nextnode (node
))
359 if ((client
= getdata (node
)) != NULL
)
361 zsend_interface_delete (client
, ifp
);
364 /* Interface address addition. */
366 zebra_interface_address_add_update (struct interface
*ifp
,
367 struct connected
*ifc
)
370 struct zserv
*client
;
374 if (IS_ZEBRA_DEBUG_EVENT
)
377 zlog_info ("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
);
382 for (node
= listhead (client_list
); node
; nextnode (node
))
383 if ((client
= getdata (node
)) != NULL
)
384 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
385 zsend_interface_address_add (client
, ifp
, ifc
);
388 /* Interface address deletion. */
390 zebra_interface_address_delete_update (struct interface
*ifp
,
391 struct connected
*ifc
)
394 struct zserv
*client
;
398 if (IS_ZEBRA_DEBUG_EVENT
)
401 zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
402 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
403 p
->prefixlen
, ifc
->ifp
->name
);
406 for (node
= listhead (client_list
); node
; nextnode (node
))
407 if ((client
= getdata (node
)) != NULL
)
408 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
409 zsend_interface_address_delete (client
, ifp
, ifc
);