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"
38 #include "zebra/router-id.h"
40 /* master zebra server structure */
41 extern struct zebra_t zebrad
;
44 zebra_check_addr (struct prefix
*p
)
46 if (p
->family
== AF_INET
)
50 addr
= p
->u
.prefix4
.s_addr
;
53 if (IPV4_NET127 (addr
) || IN_CLASSD (addr
))
57 if (p
->family
== AF_INET6
)
59 if (IN6_IS_ADDR_LOOPBACK (&p
->u
.prefix6
))
61 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
64 #endif /* HAVE_IPV6 */
69 is_default (struct prefix
*p
)
71 if (p
->family
== AF_INET
)
72 if (p
->u
.prefix4
.s_addr
== 0 && p
->prefixlen
== 0)
75 #if 0 /* IPv6 default separation is now pending until protocol daemon
77 if (p
->family
== AF_INET6
)
78 if (IN6_IS_ADDR_UNSPECIFIED (&p
->u
.prefix6
) && p
->prefixlen
== 0)
81 #endif /* HAVE_IPV6 */
86 zebra_redistribute_default (struct zserv
*client
)
89 struct route_table
*table
;
90 struct route_node
*rn
;
93 struct prefix_ipv6 p6
;
94 #endif /* HAVE_IPV6 */
97 /* Lookup default route. */
98 memset (&p
, 0, sizeof (struct prefix_ipv4
));
102 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
105 rn
= route_node_lookup (table
, (struct prefix
*)&p
);
108 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
109 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
110 && newrib
->distance
!= DISTANCE_INFINITY
)
111 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, &rn
->p
, newrib
);
112 route_unlock_node (rn
);
117 /* Lookup default route. */
118 memset (&p6
, 0, sizeof (struct prefix_ipv6
));
119 p6
.family
= AF_INET6
;
122 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
125 rn
= route_node_lookup (table
, (struct prefix
*)&p6
);
128 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
129 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
130 && newrib
->distance
!= DISTANCE_INFINITY
)
131 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, &rn
->p
, newrib
);
132 route_unlock_node (rn
);
135 #endif /* HAVE_IPV6 */
138 /* Redistribute routes. */
140 zebra_redistribute (struct zserv
*client
, int type
)
143 struct route_table
*table
;
144 struct route_node
*rn
;
146 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
148 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
149 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
150 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
151 && newrib
->type
== type
152 && newrib
->distance
!= DISTANCE_INFINITY
153 && zebra_check_addr (&rn
->p
))
154 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, &rn
->p
, newrib
);
157 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
159 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
160 for (newrib
= rn
->info
; newrib
; newrib
= newrib
->next
)
161 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
162 && newrib
->type
== type
163 && newrib
->distance
!= DISTANCE_INFINITY
164 && zebra_check_addr (&rn
->p
))
165 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, &rn
->p
, newrib
);
166 #endif /* HAVE_IPV6 */
170 redistribute_add (struct prefix
*p
, struct rib
*rib
)
172 struct listnode
*node
;
173 struct zserv
*client
;
175 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
176 if ((client
= getdata (node
)) != NULL
)
180 if (client
->redist_default
|| client
->redist
[rib
->type
])
182 if (p
->family
== AF_INET
)
183 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
185 if (p
->family
== AF_INET6
)
186 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
187 #endif /* HAVE_IPV6 */
190 else if (client
->redist
[rib
->type
])
192 if (p
->family
== AF_INET
)
193 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
195 if (p
->family
== AF_INET6
)
196 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
197 #endif /* HAVE_IPV6 */
203 redistribute_delete (struct prefix
*p
, struct rib
*rib
)
205 struct listnode
*node
;
206 struct zserv
*client
;
208 /* Add DISTANCE_INFINITY check. */
209 if (rib
->distance
== DISTANCE_INFINITY
)
212 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
213 if ((client
= getdata (node
)) != NULL
)
217 if (client
->redist_default
|| client
->redist
[rib
->type
])
219 if (p
->family
== AF_INET
)
220 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE
, client
, p
, rib
);
222 if (p
->family
== AF_INET6
)
223 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
, rib
);
224 #endif /* HAVE_IPV6 */
227 else if (client
->redist
[rib
->type
])
229 if (p
->family
== AF_INET
)
230 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE
, client
, p
, rib
);
232 if (p
->family
== AF_INET6
)
233 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
, rib
);
234 #endif /* HAVE_IPV6 */
240 zebra_redistribute_add (int command
, struct zserv
*client
, int length
)
244 type
= stream_getc (client
->ibuf
);
248 case ZEBRA_ROUTE_KERNEL
:
249 case ZEBRA_ROUTE_CONNECT
:
250 case ZEBRA_ROUTE_STATIC
:
251 case ZEBRA_ROUTE_RIP
:
252 case ZEBRA_ROUTE_RIPNG
:
253 case ZEBRA_ROUTE_OSPF
:
254 case ZEBRA_ROUTE_OSPF6
:
255 case ZEBRA_ROUTE_BGP
:
256 if (! client
->redist
[type
])
258 client
->redist
[type
] = 1;
259 zebra_redistribute (client
, type
);
268 zebra_redistribute_delete (int command
, struct zserv
*client
, int length
)
272 type
= stream_getc (client
->ibuf
);
276 case ZEBRA_ROUTE_KERNEL
:
277 case ZEBRA_ROUTE_CONNECT
:
278 case ZEBRA_ROUTE_STATIC
:
279 case ZEBRA_ROUTE_RIP
:
280 case ZEBRA_ROUTE_RIPNG
:
281 case ZEBRA_ROUTE_OSPF
:
282 case ZEBRA_ROUTE_OSPF6
:
283 case ZEBRA_ROUTE_BGP
:
284 client
->redist
[type
] = 0;
292 zebra_redistribute_default_add (int command
, struct zserv
*client
, int length
)
294 client
->redist_default
= 1;
295 zebra_redistribute_default (client
);
299 zebra_redistribute_default_delete (int command
, struct zserv
*client
,
302 client
->redist_default
= 0;;
305 /* Interface up information. */
307 zebra_interface_up_update (struct interface
*ifp
)
309 struct listnode
*node
;
310 struct zserv
*client
;
312 if (IS_ZEBRA_DEBUG_EVENT
)
313 zlog_info ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp
->name
);
315 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
316 if ((client
= getdata (node
)) != NULL
)
317 zsend_interface_update (ZEBRA_INTERFACE_UP
, client
, ifp
);
320 /* Interface down information. */
322 zebra_interface_down_update (struct interface
*ifp
)
324 struct listnode
*node
;
325 struct zserv
*client
;
327 if (IS_ZEBRA_DEBUG_EVENT
)
328 zlog_info ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp
->name
);
330 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
331 if ((client
= getdata (node
)) != NULL
)
332 zsend_interface_update (ZEBRA_INTERFACE_DOWN
, client
, ifp
);
335 /* Interface information update. */
337 zebra_interface_add_update (struct interface
*ifp
)
339 struct listnode
*node
;
340 struct zserv
*client
;
342 if (IS_ZEBRA_DEBUG_EVENT
)
343 zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp
->name
);
345 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
346 if ((client
= getdata (node
)) != NULL
)
348 zsend_interface_add (client
, ifp
);
352 * This function is only called when support for
353 * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
354 * is available. It is not called on Solaris.
356 #if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
358 zebra_interface_delete_update (struct interface
*ifp
)
360 struct listnode
*node
;
361 struct zserv
*client
;
363 if (IS_ZEBRA_DEBUG_EVENT
)
364 zlog_info ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp
->name
);
366 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
367 if ((client
= getdata (node
)) != NULL
)
369 zsend_interface_delete (client
, ifp
);
371 #endif /* defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK) */
373 /* Interface address addition. */
375 zebra_interface_address_add_update (struct interface
*ifp
,
376 struct connected
*ifc
)
378 struct listnode
*node
;
379 struct zserv
*client
;
383 if (IS_ZEBRA_DEBUG_EVENT
)
386 zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
387 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
388 p
->prefixlen
, ifc
->ifp
->name
);
391 router_id_add_address(ifc
);
393 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
394 if ((client
= getdata (node
)) != NULL
)
395 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
396 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
, ifp
, ifc
);
399 /* Interface address deletion. */
401 zebra_interface_address_delete_update (struct interface
*ifp
,
402 struct connected
*ifc
)
404 struct listnode
*node
;
405 struct zserv
*client
;
409 if (IS_ZEBRA_DEBUG_EVENT
)
412 zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
413 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
414 p
->prefixlen
, ifc
->ifp
->name
);
417 router_id_del_address(ifc
);
419 for (node
= listhead (zebrad
.client_list
); node
; nextnode (node
))
420 if ((client
= getdata (node
)) != NULL
)
421 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
422 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE
, client
, ifp
, ifc
);