Annotation of embedaddon/quagga/zebra/redistribute.c, revision 1.1.1.1
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: {
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);
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: {
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);
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))
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);
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))
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 */
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:
248: switch (type)
249: {
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])
259: {
260: client->redist[type] = 1;
261: zebra_redistribute (client, type);
262: }
263: break;
264: default:
265: break;
266: }
267: }
268:
269: void
270: zebra_redistribute_delete (int command, struct zserv *client, int length)
271: {
272: int type;
273:
274: type = stream_getc (client->ibuf);
275:
276: switch (type)
277: {
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;
287: break;
288: default:
289: break;
290: }
291: }
292:
293: void
294: zebra_redistribute_default_add (int command, struct zserv *client, int length)
295: {
296: client->redist_default = 1;
297: zebra_redistribute_default (client);
298: }
299:
300: void
301: zebra_redistribute_default_delete (int command, struct zserv *client,
302: int length)
303: {
304: client->redist_default = 0;;
305: }
306:
307: /* Interface up information. */
308: void
309: zebra_interface_up_update (struct interface *ifp)
310: {
311: struct listnode *node, *nnode;
312: struct zserv *client;
313:
314: if (IS_ZEBRA_DEBUG_EVENT)
315: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
316:
317: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
318: zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
319: }
320:
321: /* Interface down information. */
322: void
323: zebra_interface_down_update (struct interface *ifp)
324: {
325: struct listnode *node, *nnode;
326: struct zserv *client;
327:
328: if (IS_ZEBRA_DEBUG_EVENT)
329: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
330:
331: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
332: zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
333: }
334:
335: /* Interface information update. */
336: void
337: zebra_interface_add_update (struct interface *ifp)
338: {
339: struct listnode *node, *nnode;
340: struct zserv *client;
341:
342: if (IS_ZEBRA_DEBUG_EVENT)
343: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
344:
345: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
346: if (client->ifinfo)
347: zsend_interface_add (client, ifp);
348: }
349:
350: void
351: zebra_interface_delete_update (struct interface *ifp)
352: {
353: struct listnode *node, *nnode;
354: struct zserv *client;
355:
356: if (IS_ZEBRA_DEBUG_EVENT)
357: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
358:
359: for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
360: if (client->ifinfo)
361: zsend_interface_delete (client, ifp);
362: }
363:
364: /* Interface address addition. */
365: void
366: zebra_interface_address_add_update (struct interface *ifp,
367: struct connected *ifc)
368: {
369: struct listnode *node, *nnode;
370: struct zserv *client;
371: struct prefix *p;
372:
373: if (IS_ZEBRA_DEBUG_EVENT)
374: {
375: char buf[INET6_ADDRSTRLEN];
376:
377: p = ifc->address;
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);
381: }
382:
383: router_id_add_address(ifc);
384:
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);
388: }
389:
390: /* Interface address deletion. */
391: void
392: zebra_interface_address_delete_update (struct interface *ifp,
393: struct connected *ifc)
394: {
395: struct listnode *node, *nnode;
396: struct zserv *client;
397: struct prefix *p;
398:
399: if (IS_ZEBRA_DEBUG_EVENT)
400: {
401: char buf[INET6_ADDRSTRLEN];
402:
403: p = ifc->address;
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);
407: }
408:
409: router_id_del_address(ifc);
410:
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);
414: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>