Merge branch 'release-0.6.5'
[olsrd.git] / src / gateway_list.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
4  * IPv4 performance optimization (c) 2006, sven-ola(gmx.de)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #ifdef __linux__
43
44 #include "gateway_list.h"
45
46 #include "gateway.h"
47 #include "common/list.h"
48
49 #include <stdint.h>
50 #include <stdbool.h>
51 #include <assert.h>
52
53 /*
54  * Exported functions
55  */
56
57 /**
58  * Initialization
59  *
60  * @param list a pointer to the list
61  * @param count the maximum number of entries to be kept in the list. Must be
62  * larger than zero
63  */
64 void olsr_gw_list_init(struct gw_list * list, uint8_t count) {
65         assert(list);
66         assert(count > 0);
67
68         list_head_init(&list->head);
69         list->count_max = count;
70         list->count = 0;
71 }
72
73 /**
74  * Cleanup
75  *
76  * @param list a pointer to the list
77  */
78 void olsr_gw_list_cleanup(struct gw_list * list __attribute__((unused))) {
79         /* nothing to do */
80 }
81
82 /**
83  * Find an entry on the list
84  *
85  * @param list a pointer to the list
86  * @param entry a pointer to the entry to find
87  * @return a pointer to the entry, or NULL when not found
88  */
89 struct gw_container_entry * olsr_gw_list_find(struct gw_list * list, struct gateway_entry * entry) {
90         struct gw_container_entry * gw;
91
92         assert(list);
93         assert(entry);
94
95         OLSR_FOR_ALL_GWS(&list->head, gw) {
96                 if (gw && gw->gw && (gw->gw == entry)) {
97                         return gw;
98                 }
99         }
100         OLSR_FOR_ALL_GWS_END(gw);
101
102         return NULL;
103 }
104
105 /**
106  * Add an entry to the list.
107  *
108  * The list is ordered on costs with the lowest costs (best) first and the
109  * highest costs (worst) last. In case of equal costs, the entry is added
110  * _before_ the one(s) that is(are) already in the list.
111  *
112  * @param list a pointer to the list
113  * @param entry a pointer to the entry
114  * @return a pointer to the added entry
115  */
116 struct gw_container_entry * olsr_gw_list_add(struct gw_list * list, struct gw_container_entry * entry) {
117         struct gw_container_entry * gw;
118
119         assert(list);
120         assert(entry);
121         assert(!olsr_gw_list_full(list));
122
123         list_node_init(&entry->list_node);
124
125         OLSR_FOR_ALL_GWS(&list->head, gw) {
126                 if (gw && (entry->path_cost <= gw->path_cost)) {
127                         /* add before the iterated list entry: the gateway to insert has lower
128                          * costs or has equal costs but is newer (since we insert it) */
129                         list_add_before(&gw->list_node, &entry->list_node);
130                         list->count++;
131                         return entry;
132                 }
133         }
134         OLSR_FOR_ALL_GWS_END(gw);
135
136         /* add at the end */
137         list_add_after(list->head.prev, &entry->list_node);
138         list->count++;
139         return entry;
140 }
141
142 /**
143  * Update an entry on the list.
144  *
145  * @param list a pointer to the list
146  * @param entry a pointer to the entry
147  * @param path_cost the costs of the entry
148  * @return a pointer to the updated entry
149  */
150 struct gw_container_entry * olsr_gw_list_update(struct gw_list * list, struct gw_container_entry * entry,
151                 uint64_t path_cost) {
152         assert(list);
153         assert(entry);
154         assert(!olsr_gw_list_empty(list));
155
156         if (entry->path_cost == path_cost) {
157                 return entry;
158         }
159
160         /* don't touch gw */
161         /* don't touch tunnel */
162         entry->path_cost = path_cost;
163         /* don't touch list_node */
164
165         list_remove(&entry->list_node);
166         list->count--;
167         return olsr_gw_list_add(list, entry);
168 }
169
170 /**
171  * Remove a gateway from the list (but do not free it's memory)
172  *
173  * @param list a pointer to the list
174  * @param entry a pointer to the gateway
175  * @return a pointer to the removed entry
176  */
177 struct gw_container_entry * olsr_gw_list_remove(struct gw_list * list, struct gw_container_entry * entry) {
178         assert(list);
179         assert(entry);
180         assert(!olsr_gw_list_empty(list));
181
182         list_remove(&entry->list_node);
183         list->count--;
184         return entry;
185 }
186
187 #endif /* __linux__ */