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
)
55 || IPV4_LINKLOCAL(addr
))
59 if (p
->family
== AF_INET6
)
61 if (IN6_IS_ADDR_LOOPBACK (&p
->u
.prefix6
))
63 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
66 #endif /* HAVE_IPV6 */
71 is_default (struct prefix
*p
)
73 if (p
->family
== AF_INET
)
74 if (p
->u
.prefix4
.s_addr
== 0 && p
->prefixlen
== 0)
77 #if 0 /* IPv6 default separation is now pending until protocol daemon
79 if (p
->family
== AF_INET6
)
80 if (IN6_IS_ADDR_UNSPECIFIED (&p
->u
.prefix6
) && p
->prefixlen
== 0)
83 #endif /* HAVE_IPV6 */
88 zebra_redistribute_default (struct zserv
*client
)
91 struct route_table
*table
;
92 struct route_node
*rn
;
95 struct prefix_ipv6 p6
;
96 #endif /* HAVE_IPV6 */
99 /* Lookup default route. */
100 memset (&p
, 0, sizeof (struct prefix_ipv4
));
104 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
107 rn
= route_node_lookup (table
, (struct prefix
*)&p
);
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
);
119 /* Lookup default route. */
120 memset (&p6
, 0, sizeof (struct prefix_ipv6
));
121 p6
.family
= AF_INET6
;
124 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
127 rn
= route_node_lookup (table
, (struct prefix
*)&p6
);
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
);
137 #endif /* HAVE_IPV6 */
140 /* Redistribute routes. */
142 zebra_redistribute (struct zserv
*client
, int type
)
145 struct route_table
*table
;
146 struct route_node
*rn
;
148 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
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
);
159 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
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 */
172 redistribute_add (struct prefix
*p
, struct rib
*rib
)
174 struct listnode
*node
, *nnode
;
175 struct zserv
*client
;
177 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
181 if (client
->redist_default
|| client
->redist
[rib
->type
])
183 if (p
->family
== AF_INET
)
184 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
186 if (p
->family
== AF_INET6
)
187 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
188 #endif /* HAVE_IPV6 */
191 else if (client
->redist
[rib
->type
])
193 if (p
->family
== AF_INET
)
194 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
196 if (p
->family
== AF_INET6
)
197 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
198 #endif /* HAVE_IPV6 */
204 redistribute_delete (struct prefix
*p
, struct rib
*rib
)
206 struct listnode
*node
, *nnode
;
207 struct zserv
*client
;
209 /* Add DISTANCE_INFINITY check. */
210 if (rib
->distance
== DISTANCE_INFINITY
)
213 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
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
,
223 if (p
->family
== AF_INET6
)
224 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
,
226 #endif /* HAVE_IPV6 */
229 else if (client
->redist
[rib
->type
])
231 if (p
->family
== AF_INET
)
232 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE
, client
, p
, rib
);
234 if (p
->family
== AF_INET6
)
235 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
, rib
);
236 #endif /* HAVE_IPV6 */
242 zebra_redistribute_add (int command
, struct zserv
*client
, int length
)
246 type
= stream_getc (client
->ibuf
);
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
])
260 client
->redist
[type
] = 1;
261 zebra_redistribute (client
, type
);
270 zebra_redistribute_delete (int command
, struct zserv
*client
, int length
)
274 type
= stream_getc (client
->ibuf
);
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;
294 zebra_redistribute_default_add (int command
, struct zserv
*client
, int length
)
296 client
->redist_default
= 1;
297 zebra_redistribute_default (client
);
301 zebra_redistribute_default_delete (int command
, struct zserv
*client
,
304 client
->redist_default
= 0;;
307 /* Interface up information. */
309 zebra_interface_up_update (struct interface
*ifp
)
311 struct listnode
*node
, *nnode
;
312 struct zserv
*client
;
314 if (IS_ZEBRA_DEBUG_EVENT
)
315 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp
->name
);
317 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
318 zsend_interface_update (ZEBRA_INTERFACE_UP
, client
, ifp
);
321 /* Interface down information. */
323 zebra_interface_down_update (struct interface
*ifp
)
325 struct listnode
*node
, *nnode
;
326 struct zserv
*client
;
328 if (IS_ZEBRA_DEBUG_EVENT
)
329 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp
->name
);
331 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
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
, *nnode
;
340 struct zserv
*client
;
342 if (IS_ZEBRA_DEBUG_EVENT
)
343 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp
->name
);
345 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
347 zsend_interface_add (client
, ifp
);
351 zebra_interface_delete_update (struct interface
*ifp
)
353 struct listnode
*node
, *nnode
;
354 struct zserv
*client
;
356 if (IS_ZEBRA_DEBUG_EVENT
)
357 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp
->name
);
359 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
361 zsend_interface_delete (client
, ifp
);
364 /* Interface address addition. */
366 zebra_interface_address_add_update (struct interface
*ifp
,
367 struct connected
*ifc
)
369 struct listnode
*node
, *nnode
;
370 struct zserv
*client
;
373 if (IS_ZEBRA_DEBUG_EVENT
)
375 char buf
[INET6_ADDRSTRLEN
];
378 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
379 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
380 p
->prefixlen
, ifc
->ifp
->name
);
383 router_id_add_address(ifc
);
385 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
386 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
387 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
, ifp
, ifc
);
390 /* Interface address deletion. */
392 zebra_interface_address_delete_update (struct interface
*ifp
,
393 struct connected
*ifc
)
395 struct listnode
*node
, *nnode
;
396 struct zserv
*client
;
399 if (IS_ZEBRA_DEBUG_EVENT
)
401 char buf
[INET6_ADDRSTRLEN
];
404 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
405 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
406 p
->prefixlen
, ifc
->ifp
->name
);
409 router_id_del_address(ifc
);
411 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
412 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
413 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE
, client
, ifp
, ifc
);