Annotation of embedaddon/quagga/zebra/redistribute.c, revision 1.1.1.3
1.1 misho 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:
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"
39:
40: /* master zebra server structure */
41: extern struct zebra_t zebrad;
42:
43: int
44: zebra_check_addr (struct prefix *p)
45: {
46: if (p->family == AF_INET)
47: {
48: u_int32_t addr;
49:
50: addr = p->u.prefix4.s_addr;
51: addr = ntohl (addr);
52:
53: if (IPV4_NET127 (addr)
54: || IN_CLASSD (addr)
55: || IPV4_LINKLOCAL(addr))
56: return 0;
57: }
58: #ifdef HAVE_IPV6
59: if (p->family == AF_INET6)
60: {
61: if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
62: return 0;
63: if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
64: return 0;
65: }
66: #endif /* HAVE_IPV6 */
67: return 1;
68: }
69:
70: static int
71: is_default (struct prefix *p)
72: {
73: if (p->family == AF_INET)
74: if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
75: return 1;
76: #ifdef HAVE_IPV6
77: #if 0 /* IPv6 default separation is now pending until protocol daemon
78: can handle that. */
79: if (p->family == AF_INET6)
80: if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
81: return 1;
82: #endif /* 0 */
83: #endif /* HAVE_IPV6 */
84: return 0;
85: }
86:
87: static void
88: zebra_redistribute_default (struct zserv *client)
89: {
90: struct prefix_ipv4 p;
91: struct route_table *table;
92: struct route_node *rn;
93: struct rib *newrib;
94: #ifdef HAVE_IPV6
95: struct prefix_ipv6 p6;
96: #endif /* HAVE_IPV6 */
97:
98:
99: /* Lookup default route. */
100: memset (&p, 0, sizeof (struct prefix_ipv4));
101: p.family = AF_INET;
102:
103: /* Lookup table. */
104: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
105: if (table)
106: {
107: rn = route_node_lookup (table, (struct prefix *)&p);
108: if (rn)
109: {
1.1.1.3 ! misho 110: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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);
115: }
116: }
117:
118: #ifdef HAVE_IPV6
119: /* Lookup default route. */
120: memset (&p6, 0, sizeof (struct prefix_ipv6));
121: p6.family = AF_INET6;
122:
123: /* Lookup table. */
124: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
125: if (table)
126: {
127: rn = route_node_lookup (table, (struct prefix *)&p6);
128: if (rn)
129: {
1.1.1.3 ! misho 130: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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);
135: }
136: }
137: #endif /* HAVE_IPV6 */
138: }
139:
140: /* Redistribute routes. */
141: static void
142: zebra_redistribute (struct zserv *client, int type)
143: {
144: struct rib *newrib;
145: struct route_table *table;
146: struct route_node *rn;
147:
148: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
149: if (table)
150: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 151: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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);
157:
158: #ifdef HAVE_IPV6
159: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
160: if (table)
161: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 ! misho 162: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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 */
169: }
170:
171: void
172: redistribute_add (struct prefix *p, struct rib *rib)
173: {
174: struct listnode *node, *nnode;
175: struct zserv *client;
176:
177: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
178: {
179: if (is_default (p))
180: {
181: if (client->redist_default || client->redist[rib->type])
182: {
183: if (p->family == AF_INET)
184: zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
185: #ifdef HAVE_IPV6
186: if (p->family == AF_INET6)
187: zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
188: #endif /* HAVE_IPV6 */
189: }
190: }
191: else if (client->redist[rib->type])
192: {
193: if (p->family == AF_INET)
194: zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
195: #ifdef HAVE_IPV6
196: if (p->family == AF_INET6)
197: zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
198: #endif /* HAVE_IPV6 */
199: }
200: }
201: }
202:
203: void
204: redistribute_delete (struct prefix *p, struct rib *rib)
205: {
206: struct listnode *node, *nnode;
207: struct zserv *client;
208:
209: /* Add DISTANCE_INFINITY check. */
210: if (rib->distance == DISTANCE_INFINITY)
211: return;
212:
213: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
214: {
215: if (is_default (p))
216: {
217: if (client->redist_default || client->redist[rib->type])
218: {
219: if (p->family == AF_INET)
220: zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
221: rib);
222: #ifdef HAVE_IPV6
223: if (p->family == AF_INET6)
224: zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
225: rib);
226: #endif /* HAVE_IPV6 */
227: }
228: }
229: else if (client->redist[rib->type])
230: {
231: if (p->family == AF_INET)
232: zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
233: #ifdef HAVE_IPV6
234: if (p->family == AF_INET6)
235: zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
236: #endif /* HAVE_IPV6 */
237: }
238: }
239: }
240:
241: void
242: zebra_redistribute_add (int command, struct zserv *client, int length)
243: {
244: int type;
245:
246: type = stream_getc (client->ibuf);
247:
1.1.1.2 misho 248: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
249: return;
250:
251: if (! client->redist[type])
1.1 misho 252: {
1.1.1.2 misho 253: client->redist[type] = 1;
254: zebra_redistribute (client, type);
1.1 misho 255: }
1.1.1.2 misho 256: }
1.1 misho 257:
258: void
259: zebra_redistribute_delete (int command, struct zserv *client, int length)
260: {
261: int type;
262:
263: type = stream_getc (client->ibuf);
264:
1.1.1.2 misho 265: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
266: return;
267:
268: client->redist[type] = 0;
269: }
1.1 misho 270:
271: void
272: zebra_redistribute_default_add (int command, struct zserv *client, int length)
273: {
274: client->redist_default = 1;
275: zebra_redistribute_default (client);
276: }
277:
278: void
279: zebra_redistribute_default_delete (int command, struct zserv *client,
280: int length)
281: {
282: client->redist_default = 0;;
283: }
284:
285: /* Interface up information. */
286: void
287: zebra_interface_up_update (struct interface *ifp)
288: {
289: struct listnode *node, *nnode;
290: struct zserv *client;
291:
292: if (IS_ZEBRA_DEBUG_EVENT)
293: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
294:
295: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
296: zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
297: }
298:
299: /* Interface down information. */
300: void
301: zebra_interface_down_update (struct interface *ifp)
302: {
303: struct listnode *node, *nnode;
304: struct zserv *client;
305:
306: if (IS_ZEBRA_DEBUG_EVENT)
307: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
308:
309: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
310: zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
311: }
312:
313: /* Interface information update. */
314: void
315: zebra_interface_add_update (struct interface *ifp)
316: {
317: struct listnode *node, *nnode;
318: struct zserv *client;
319:
320: if (IS_ZEBRA_DEBUG_EVENT)
321: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
322:
323: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
324: if (client->ifinfo)
325: zsend_interface_add (client, ifp);
326: }
327:
328: void
329: zebra_interface_delete_update (struct interface *ifp)
330: {
331: struct listnode *node, *nnode;
332: struct zserv *client;
333:
334: if (IS_ZEBRA_DEBUG_EVENT)
335: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
336:
337: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
338: if (client->ifinfo)
339: zsend_interface_delete (client, ifp);
340: }
341:
342: /* Interface address addition. */
343: void
344: zebra_interface_address_add_update (struct interface *ifp,
345: struct connected *ifc)
346: {
347: struct listnode *node, *nnode;
348: struct zserv *client;
349: struct prefix *p;
350:
351: if (IS_ZEBRA_DEBUG_EVENT)
352: {
353: char buf[INET6_ADDRSTRLEN];
354:
355: p = ifc->address;
356: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
357: inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
358: p->prefixlen, ifc->ifp->name);
359: }
360:
361: router_id_add_address(ifc);
362:
363: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
364: if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
365: zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
366: }
367:
368: /* Interface address deletion. */
369: void
370: zebra_interface_address_delete_update (struct interface *ifp,
371: struct connected *ifc)
372: {
373: struct listnode *node, *nnode;
374: struct zserv *client;
375: struct prefix *p;
376:
377: if (IS_ZEBRA_DEBUG_EVENT)
378: {
379: char buf[INET6_ADDRSTRLEN];
380:
381: p = ifc->address;
382: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
383: inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
384: p->prefixlen, ifc->ifp->name);
385: }
386:
387: router_id_del_address(ifc);
388:
389: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
390: if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
391: zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
392: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>