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 #define ZEBRA_PTM_SUPPORT
43 /* master zebra server structure */
44 extern struct zebra_t zebrad
;
47 zebra_check_addr (struct prefix
*p
)
49 if (p
->family
== AF_INET
)
53 addr
= p
->u
.prefix4
.s_addr
;
56 if (IPV4_NET127 (addr
)
58 || IPV4_LINKLOCAL(addr
))
62 if (p
->family
== AF_INET6
)
64 if (IN6_IS_ADDR_LOOPBACK (&p
->u
.prefix6
))
66 if (IN6_IS_ADDR_LINKLOCAL(&p
->u
.prefix6
))
69 #endif /* HAVE_IPV6 */
74 is_default (struct prefix
*p
)
76 if (p
->family
== AF_INET
)
77 if (p
->u
.prefix4
.s_addr
== 0 && p
->prefixlen
== 0)
80 #if 0 /* IPv6 default separation is now pending until protocol daemon
82 if (p
->family
== AF_INET6
)
83 if (IN6_IS_ADDR_UNSPECIFIED (&p
->u
.prefix6
) && p
->prefixlen
== 0)
86 #endif /* HAVE_IPV6 */
91 zebra_redistribute_default (struct zserv
*client
)
94 struct route_table
*table
;
95 struct route_node
*rn
;
98 struct prefix_ipv6 p6
;
99 #endif /* HAVE_IPV6 */
102 /* Lookup default route. */
103 memset (&p
, 0, sizeof (struct prefix_ipv4
));
107 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
110 rn
= route_node_lookup (table
, (struct prefix
*)&p
);
113 RNODE_FOREACH_RIB (rn
, newrib
)
114 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
115 && newrib
->distance
!= DISTANCE_INFINITY
)
116 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, &rn
->p
, newrib
);
117 route_unlock_node (rn
);
122 /* Lookup default route. */
123 memset (&p6
, 0, sizeof (struct prefix_ipv6
));
124 p6
.family
= AF_INET6
;
127 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
130 rn
= route_node_lookup (table
, (struct prefix
*)&p6
);
133 RNODE_FOREACH_RIB (rn
, newrib
)
134 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
135 && newrib
->distance
!= DISTANCE_INFINITY
)
136 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, &rn
->p
, newrib
);
137 route_unlock_node (rn
);
140 #endif /* HAVE_IPV6 */
143 /* Redistribute routes. */
145 zebra_redistribute (struct zserv
*client
, int type
)
148 struct route_table
*table
;
149 struct route_node
*rn
;
151 table
= vrf_table (AFI_IP
, SAFI_UNICAST
, 0);
153 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
154 RNODE_FOREACH_RIB (rn
, newrib
)
155 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
156 && newrib
->type
== type
157 && newrib
->distance
!= DISTANCE_INFINITY
158 && zebra_check_addr (&rn
->p
))
160 client
->redist_v4_add_cnt
++;
161 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, &rn
->p
, newrib
);
165 table
= vrf_table (AFI_IP6
, SAFI_UNICAST
, 0);
167 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
168 RNODE_FOREACH_RIB (rn
, newrib
)
169 if (CHECK_FLAG (newrib
->flags
, ZEBRA_FLAG_SELECTED
)
170 && newrib
->type
== type
171 && newrib
->distance
!= DISTANCE_INFINITY
172 && zebra_check_addr (&rn
->p
))
174 client
->redist_v6_add_cnt
++;
175 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, &rn
->p
, newrib
);
177 #endif /* HAVE_IPV6 */
181 redistribute_add (struct prefix
*p
, struct rib
*rib
)
183 struct listnode
*node
, *nnode
;
184 struct zserv
*client
;
186 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
190 if (client
->redist_default
|| client
->redist
[rib
->type
])
192 if (p
->family
== AF_INET
)
194 client
->redist_v4_add_cnt
++;
195 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
198 if (p
->family
== AF_INET6
)
200 client
->redist_v6_add_cnt
++;
201 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
203 #endif /* HAVE_IPV6 */
206 else if (client
->redist
[rib
->type
])
208 if (p
->family
== AF_INET
)
210 client
->redist_v4_add_cnt
++;
211 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD
, client
, p
, rib
);
214 if (p
->family
== AF_INET6
)
216 client
->redist_v6_add_cnt
++;
217 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD
, client
, p
, rib
);
219 #endif /* HAVE_IPV6 */
225 redistribute_delete (struct prefix
*p
, struct rib
*rib
)
227 struct listnode
*node
, *nnode
;
228 struct zserv
*client
;
230 /* Add DISTANCE_INFINITY check. */
231 if (rib
->distance
== DISTANCE_INFINITY
)
234 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
238 if (client
->redist_default
|| client
->redist
[rib
->type
])
240 if (p
->family
== AF_INET
)
241 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE
, client
, p
,
244 if (p
->family
== AF_INET6
)
245 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
,
247 #endif /* HAVE_IPV6 */
250 else if (client
->redist
[rib
->type
])
252 if (p
->family
== AF_INET
)
253 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE
, client
, p
, rib
);
255 if (p
->family
== AF_INET6
)
256 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE
, client
, p
, rib
);
257 #endif /* HAVE_IPV6 */
263 zebra_redistribute_add (int command
, struct zserv
*client
, int length
)
267 type
= stream_getc (client
->ibuf
);
269 if (type
== 0 || type
>= ZEBRA_ROUTE_MAX
)
272 if (! client
->redist
[type
])
274 client
->redist
[type
] = 1;
275 zebra_redistribute (client
, type
);
280 zebra_redistribute_delete (int command
, struct zserv
*client
, int length
)
284 type
= stream_getc (client
->ibuf
);
286 if (type
== 0 || type
>= ZEBRA_ROUTE_MAX
)
289 client
->redist
[type
] = 0;
293 zebra_redistribute_default_add (int command
, struct zserv
*client
, int length
)
295 client
->redist_default
= 1;
296 zebra_redistribute_default (client
);
300 zebra_redistribute_default_delete (int command
, struct zserv
*client
,
303 client
->redist_default
= 0;;
306 /* Interface up information. */
308 zebra_interface_up_update (struct interface
*ifp
)
310 struct listnode
*node
, *nnode
;
311 struct zserv
*client
;
313 if (IS_ZEBRA_DEBUG_EVENT
)
314 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp
->name
);
316 if (ifp
->ptm_status
|| !ifp
->ptm_enable
) {
317 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
319 zsend_interface_update (ZEBRA_INTERFACE_UP
, client
, ifp
);
324 /* Interface down information. */
326 zebra_interface_down_update (struct interface
*ifp
)
328 struct listnode
*node
, *nnode
;
329 struct zserv
*client
;
331 if (IS_ZEBRA_DEBUG_EVENT
)
332 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp
->name
);
334 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
336 zsend_interface_update (ZEBRA_INTERFACE_DOWN
, client
, ifp
);
340 /* Interface information update. */
342 zebra_interface_add_update (struct interface
*ifp
)
344 struct listnode
*node
, *nnode
;
345 struct zserv
*client
;
347 if (IS_ZEBRA_DEBUG_EVENT
)
348 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp
->name
);
350 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
354 zsend_interface_add (client
, ifp
);
359 zebra_interface_delete_update (struct interface
*ifp
)
361 struct listnode
*node
, *nnode
;
362 struct zserv
*client
;
364 if (IS_ZEBRA_DEBUG_EVENT
)
365 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp
->name
);
367 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
371 zsend_interface_delete (client
, ifp
);
375 /* Interface address addition. */
377 zebra_interface_address_add_update (struct interface
*ifp
,
378 struct connected
*ifc
)
380 struct listnode
*node
, *nnode
;
381 struct zserv
*client
;
384 if (IS_ZEBRA_DEBUG_EVENT
)
386 char buf
[INET6_ADDRSTRLEN
];
389 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
390 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
391 p
->prefixlen
, ifc
->ifp
->name
);
394 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
395 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
397 router_id_add_address(ifc
);
399 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
400 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
402 client
->connected_rt_add_cnt
++;
403 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
, ifp
, ifc
);
407 /* Interface address deletion. */
409 zebra_interface_address_delete_update (struct interface
*ifp
,
410 struct connected
*ifc
)
412 struct listnode
*node
, *nnode
;
413 struct zserv
*client
;
416 if (IS_ZEBRA_DEBUG_EVENT
)
418 char buf
[INET6_ADDRSTRLEN
];
421 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
422 inet_ntop (p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
),
423 p
->prefixlen
, ifc
->ifp
->name
);
426 router_id_del_address(ifc
);
428 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
429 if (client
->ifinfo
&& CHECK_FLAG (ifc
->conf
, ZEBRA_IFC_REAL
))
431 client
->connected_rt_del_cnt
++;
432 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE
, client
, ifp
, ifc
);
437 zebra_interface_bfd_update (struct interface
*ifp
, struct prefix
*p
)
439 struct listnode
*node
, *nnode
;
440 struct zserv
*client
;
442 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
444 /* Supporting for OSPF and BGP */
445 if (client
->proto
!= ZEBRA_ROUTE_OSPF
&& client
->proto
!= ZEBRA_ROUTE_BGP
)
448 /* Notify to the protocol daemons. */
449 zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_DOWN
, client
, ifp
, p
);