Annotation of embedaddon/quagga/zebra/redistribute.c, revision 1.1.1.4
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"
1.1.1.4 ! misho 33: #include "vrf.h"
1.1 misho 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:
1.1.1.4 ! misho 71: int
1.1 misho 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
1.1.1.4 ! misho 89: zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
1.1 misho 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. */
1.1.1.4 ! misho 105: table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1.1 misho 106: if (table)
107: {
108: rn = route_node_lookup (table, (struct prefix *)&p);
109: if (rn)
110: {
1.1.1.3 misho 111: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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. */
1.1.1.4 ! misho 125: table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1.1 misho 126: if (table)
127: {
128: rn = route_node_lookup (table, (struct prefix *)&p6);
129: if (rn)
130: {
1.1.1.3 misho 131: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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
1.1.1.4 ! misho 143: zebra_redistribute (struct zserv *client, int type, vrf_id_t vrf_id)
1.1 misho 144: {
145: struct rib *newrib;
146: struct route_table *table;
147: struct route_node *rn;
148:
1.1.1.4 ! misho 149: table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1.1 misho 150: if (table)
151: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 misho 152: RNODE_FOREACH_RIB (rn, newrib)
1.1.1.4 ! misho 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:
1.1 misho 165: #ifdef HAVE_IPV6
1.1.1.4 ! misho 166: table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
1.1 misho 167: if (table)
168: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.3 misho 169: RNODE_FOREACH_RIB (rn, newrib)
1.1 misho 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: {
1.1.1.4 ! misho 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))
1.1 misho 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: {
1.1.1.4 ! misho 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))
1.1 misho 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
1.1.1.4 ! misho 227: zebra_redistribute_add (int command, struct zserv *client, int length,
! 228: vrf_id_t vrf_id)
1.1 misho 229: {
230: int type;
231:
232: type = stream_getc (client->ibuf);
233:
1.1.1.2 misho 234: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
235: return;
236:
1.1.1.4 ! misho 237: if (! vrf_bitmap_check (client->redist[type], vrf_id))
1.1 misho 238: {
1.1.1.4 ! misho 239: vrf_bitmap_set (client->redist[type], vrf_id);
! 240: zebra_redistribute (client, type, vrf_id);
1.1 misho 241: }
1.1.1.2 misho 242: }
1.1 misho 243:
244: void
1.1.1.4 ! misho 245: zebra_redistribute_delete (int command, struct zserv *client, int length,
! 246: vrf_id_t vrf_id)
1.1 misho 247: {
248: int type;
249:
250: type = stream_getc (client->ibuf);
251:
1.1.1.2 misho 252: if (type == 0 || type >= ZEBRA_ROUTE_MAX)
253: return;
254:
1.1.1.4 ! misho 255: vrf_bitmap_unset (client->redist[type], vrf_id);
1.1.1.2 misho 256: }
1.1 misho 257:
258: void
1.1.1.4 ! misho 259: zebra_redistribute_default_add (int command, struct zserv *client, int length,
! 260: vrf_id_t vrf_id)
1.1 misho 261: {
1.1.1.4 ! misho 262: vrf_bitmap_set (client->redist_default, vrf_id);
! 263: zebra_redistribute_default (client, vrf_id);
1.1 misho 264: }
265:
266: void
267: zebra_redistribute_default_delete (int command, struct zserv *client,
1.1.1.4 ! misho 268: int length, vrf_id_t vrf_id)
1.1 misho 269: {
1.1.1.4 ! misho 270: vrf_bitmap_unset (client->redist_default, vrf_id);
1.1 misho 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: {
1.1.1.4 ! misho 341: char buf[PREFIX_STRLEN];
1.1 misho 342:
343: p = ifc->address;
1.1.1.4 ! misho 344: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
! 345: prefix2str (p, buf, sizeof(buf)),
! 346: ifc->ifp->name);
1.1 misho 347: }
348:
1.1.1.4 ! misho 349: if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
! 350: zlog_warn("WARNING: advertising address to clients that is not yet usable.");
! 351:
1.1 misho 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: {
1.1.1.4 ! misho 370: char buf[PREFIX_STRLEN];
1.1 misho 371:
372: p = ifc->address;
1.1.1.4 ! misho 373: zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
! 374: prefix2str (p, buf, sizeof(buf)),
! 375: ifc->ifp->name);
1.1 misho 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>