1: /*
2: * RIPng routes function.
3: * Copyright (C) 1998 Kunihiro Ishiguro
4: *
5: * This file is part of GNU Zebra.
6: *
7: * GNU Zebra is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2, or (at your option) any
10: * later version.
11: *
12: * GNU Zebra is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with GNU Zebra; see the file COPYING. If not, write to the Free
19: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20: * 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "prefix.h"
26: #include "table.h"
27: #include "memory.h"
28: #include "if.h"
29: #include "vty.h"
30:
31: #include "ripngd/ripngd.h"
32: #include "ripngd/ripng_route.h"
33:
34: static struct ripng_aggregate *
35: ripng_aggregate_new ()
36: {
37: struct ripng_aggregate *new;
38:
39: new = XCALLOC (MTYPE_RIPNG_AGGREGATE, sizeof (struct ripng_aggregate));
40: return new;
41: }
42:
43: void
44: ripng_aggregate_free (struct ripng_aggregate *aggregate)
45: {
46: XFREE (MTYPE_RIPNG_AGGREGATE, aggregate);
47: }
48:
49: /* Aggregate count increment check. */
50: void
51: ripng_aggregate_increment (struct route_node *child, struct ripng_info *rinfo)
52: {
53: struct route_node *np;
54: struct ripng_aggregate *aggregate;
55:
56: for (np = child; np; np = np->parent)
57: if ((aggregate = np->aggregate) != NULL)
58: {
59: aggregate->count++;
60: rinfo->suppress++;
61: }
62: }
63:
64: /* Aggregate count decrement check. */
65: void
66: ripng_aggregate_decrement (struct route_node *child, struct ripng_info *rinfo)
67: {
68: struct route_node *np;
69: struct ripng_aggregate *aggregate;
70:
71: for (np = child; np; np = np->parent)
72: if ((aggregate = np->aggregate) != NULL)
73: {
74: aggregate->count--;
75: rinfo->suppress--;
76: }
77: }
78:
79: /* Aggregate count decrement check for a list. */
80: void
81: ripng_aggregate_decrement_list (struct route_node *child, struct list *list)
82: {
83: struct route_node *np;
84: struct ripng_aggregate *aggregate;
85: struct ripng_info *rinfo = NULL;
86: struct listnode *node = NULL;
87:
88: for (np = child; np; np = np->parent)
89: if ((aggregate = np->aggregate) != NULL)
90: aggregate->count -= listcount (list);
91:
92: for (ALL_LIST_ELEMENTS_RO (list, node, rinfo))
93: rinfo->suppress--;
94: }
95:
96: /* RIPng routes treatment. */
97: int
98: ripng_aggregate_add (struct prefix *p)
99: {
100: struct route_node *top;
101: struct route_node *rp;
102: struct ripng_info *rinfo;
103: struct ripng_aggregate *aggregate;
104: struct ripng_aggregate *sub;
105: struct list *list = NULL;
106: struct listnode *node = NULL;
107:
108: /* Get top node for aggregation. */
109: top = route_node_get (ripng->table, p);
110:
111: /* Allocate new aggregate. */
112: aggregate = ripng_aggregate_new ();
113: aggregate->metric = 1;
114:
115: top->aggregate = aggregate;
116:
117: /* Suppress routes match to the aggregate. */
118: for (rp = route_lock_node (top); rp; rp = route_next_until (rp, top))
119: {
120: /* Suppress normal route. */
121: if ((list = rp->info) != NULL)
122: for (ALL_LIST_ELEMENTS_RO (list, node, rinfo))
123: {
124: aggregate->count++;
125: rinfo->suppress++;
126: }
127: /* Suppress aggregate route. This may not need. */
128: if (rp != top && (sub = rp->aggregate) != NULL)
129: {
130: aggregate->count++;
131: sub->suppress++;
132: }
133: }
134:
135: return 0;
136: }
137:
138: /* Delete RIPng static route. */
139: int
140: ripng_aggregate_delete (struct prefix *p)
141: {
142: struct route_node *top;
143: struct route_node *rp;
144: struct ripng_info *rinfo;
145: struct ripng_aggregate *aggregate;
146: struct ripng_aggregate *sub;
147: struct list *list = NULL;
148: struct listnode *node = NULL;
149:
150: /* Get top node for aggregation. */
151: top = route_node_get (ripng->table, p);
152:
153: /* Allocate new aggregate. */
154: aggregate = top->aggregate;
155:
156: /* Suppress routes match to the aggregate. */
157: for (rp = route_lock_node (top); rp; rp = route_next_until (rp, top))
158: {
159: /* Suppress normal route. */
160: if ((list = rp->info) != NULL)
161: for (ALL_LIST_ELEMENTS_RO (list, node, rinfo))
162: {
163: aggregate->count--;
164: rinfo->suppress--;
165: }
166:
167: if (rp != top && (sub = rp->aggregate) != NULL)
168: {
169: aggregate->count--;
170: sub->suppress--;
171: }
172: }
173:
174: top->aggregate = NULL;
175: ripng_aggregate_free (aggregate);
176:
177: route_unlock_node (top);
178: route_unlock_node (top);
179:
180: return 0;
181: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>