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: zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
163: }
164:
165: #ifdef HAVE_IPV6
166: table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
167: if (table)
168: for (rn = route_top (table); rn; rn = route_next (rn))
169: RNODE_FOREACH_RIB (rn, newrib)
170: if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
171: && newrib->type == type
172: && newrib->distance != DISTANCE_INFINITY
173: && zebra_check_addr (&rn->p))
174: zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
175: #endif /* HAVE_IPV6 */
176: }
177:
178: void
179: redistribute_add (struct prefix *p, struct rib *rib)
180: {
181: struct listnode *node, *nnode;
182: struct zserv *client;
183:
184: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
185: {
186: if ((is_default (p) &&
187: vrf_bitmap_check (client->redist_default, rib->vrf_id))
188: || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
189: {
190: if (p->family == AF_INET)
191: zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
192: #ifdef HAVE_IPV6
193: if (p->family == AF_INET6)
194: zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
195: #endif /* HAVE_IPV6 */
196: }
197: }
198: }
199:
200: void
201: redistribute_delete (struct prefix *p, struct rib *rib)
202: {
203: struct listnode *node, *nnode;
204: struct zserv *client;
205:
206: /* Add DISTANCE_INFINITY check. */
207: if (rib->distance == DISTANCE_INFINITY)
208: return;
209:
210: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
211: {
212: if ((is_default (p) &&
213: vrf_bitmap_check (client->redist_default, rib->vrf_id))
214: || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
215: {
216: if (p->family == AF_INET)
217: zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
218: #ifdef HAVE_IPV6
219: if (p->family == AF_INET6)
220: zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
221: #endif /* HAVE_IPV6 */
222: }
223: }
224: }
225:
226: void
227: zebra_redistribute_add (int command, struct zserv *client, int length,
228: vrf_id_t vrf_id)
229: {
230: int type;
231:
232: type = stream_getc (client->ibuf);
233:
234: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
235: return;
236:
237: if (! vrf_bitmap_check (client->redist[type], vrf_id))
238: {
239: vrf_bitmap_set (client->redist[type], vrf_id);
240: zebra_redistribute (client, type, vrf_id);
241: }
242: }
243:
244: void
245: zebra_redistribute_delete (int command, struct zserv *client, int length,
246: vrf_id_t vrf_id)
247: {
248: int type;
249:
250: type = stream_getc (client->ibuf);
251:
252: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
253: return;
254:
255: vrf_bitmap_unset (client->redist[type], vrf_id);
256: }
257:
258: void
259: zebra_redistribute_default_add (int command, struct zserv *client, int length,
260: vrf_id_t vrf_id)
261: {
262: vrf_bitmap_set (client->redist_default, vrf_id);
263: zebra_redistribute_default (client, vrf_id);
264: }
265:
266: void
267: zebra_redistribute_default_delete (int command, struct zserv *client,
268: int length, vrf_id_t vrf_id)
269: {
270: vrf_bitmap_unset (client->redist_default, vrf_id);
271: }
272:
273: /* Interface up information. */
274: void
275: zebra_interface_up_update (struct interface *ifp)
276: {
277: struct listnode *node, *nnode;
278: struct zserv *client;
279:
280: if (IS_ZEBRA_DEBUG_EVENT)
281: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
282:
283: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
284: zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
285: }
286:
287: /* Interface down information. */
288: void
289: zebra_interface_down_update (struct interface *ifp)
290: {
291: struct listnode *node, *nnode;
292: struct zserv *client;
293:
294: if (IS_ZEBRA_DEBUG_EVENT)
295: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
296:
297: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
298: zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
299: }
300:
301: /* Interface information update. */
302: void
303: zebra_interface_add_update (struct interface *ifp)
304: {
305: struct listnode *node, *nnode;
306: struct zserv *client;
307:
308: if (IS_ZEBRA_DEBUG_EVENT)
309: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
310:
311: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
312: if (client->ifinfo)
313: zsend_interface_add (client, ifp);
314: }
315:
316: void
317: zebra_interface_delete_update (struct interface *ifp)
318: {
319: struct listnode *node, *nnode;
320: struct zserv *client;
321:
322: if (IS_ZEBRA_DEBUG_EVENT)
323: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
324:
325: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
326: if (client->ifinfo)
327: zsend_interface_delete (client, ifp);
328: }
329:
330: /* Interface address addition. */
331: void
332: zebra_interface_address_add_update (struct interface *ifp,
333: struct connected *ifc)
334: {
335: struct listnode *node, *nnode;
336: struct zserv *client;
337: struct prefix *p;
338:
339: if (IS_ZEBRA_DEBUG_EVENT)
340: {
341: char buf[PREFIX_STRLEN];
342:
343: p = ifc->address;
344: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
345: prefix2str (p, buf, sizeof(buf)),
346: ifc->ifp->name);
347: }
348:
349: if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
350: zlog_warn("WARNING: advertising address to clients that is not yet usable.");
351:
352: router_id_add_address(ifc);
353:
354: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
355: if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
356: zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
357: }
358:
359: /* Interface address deletion. */
360: void
361: zebra_interface_address_delete_update (struct interface *ifp,
362: struct connected *ifc)
363: {
364: struct listnode *node, *nnode;
365: struct zserv *client;
366: struct prefix *p;
367:
368: if (IS_ZEBRA_DEBUG_EVENT)
369: {
370: char buf[PREFIX_STRLEN];
371:
372: p = ifc->address;
373: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
374: prefix2str (p, buf, sizeof(buf)),
375: ifc->ifp->name);
376: }
377:
378: router_id_del_address(ifc);
379:
380: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
381: if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
382: zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
383: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>