Import Debian changes 1.2.2-1
[quagga-debian.git] / ripngd / ripng_route.c
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 }