source: mainline/uspace/srv/net/inetsrv/sroute.c@ 96cbd18

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 96cbd18 was a2e3ee6, checked in by Martin Decky <martin@…>, 12 years ago

use new network address infrastructure (towards IPv6 support)

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <bitops.h>
38#include <errno.h>
39#include <fibril_synch.h>
40#include <io/log.h>
41#include <ipc/loc.h>
42#include <stdlib.h>
43#include <str.h>
44
45#include "sroute.h"
46#include "inetsrv.h"
47#include "inet_link.h"
48#include "inet_util.h"
49
50static FIBRIL_MUTEX_INITIALIZE(sroute_list_lock);
51static LIST_INITIALIZE(sroute_list);
52static sysarg_t sroute_id = 0;
53
54inet_sroute_t *inet_sroute_new(void)
55{
56 inet_sroute_t *sroute = calloc(1, sizeof(inet_sroute_t));
57
58 if (sroute == NULL) {
59 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating static route object. "
60 "Out of memory.");
61 return NULL;
62 }
63
64 link_initialize(&sroute->sroute_list);
65 fibril_mutex_lock(&sroute_list_lock);
66 sroute->id = ++sroute_id;
67 fibril_mutex_unlock(&sroute_list_lock);
68
69 return sroute;
70}
71
72void inet_sroute_delete(inet_sroute_t *sroute)
73{
74 if (sroute->name != NULL)
75 free(sroute->name);
76 free(sroute);
77}
78
79void inet_sroute_add(inet_sroute_t *sroute)
80{
81 fibril_mutex_lock(&sroute_list_lock);
82 list_append(&sroute->sroute_list, &sroute_list);
83 fibril_mutex_unlock(&sroute_list_lock);
84}
85
86void inet_sroute_remove(inet_sroute_t *sroute)
87{
88 fibril_mutex_lock(&sroute_list_lock);
89 list_remove(&sroute->sroute_list);
90 fibril_mutex_unlock(&sroute_list_lock);
91}
92
93/** Find address object matching address @a addr.
94 *
95 * @param addr Address
96 */
97inet_sroute_t *inet_sroute_find(inet_addr_t *addr)
98{
99 uint32_t addr_addr;
100 int rc = inet_addr_pack(addr, &addr_addr);
101 if (rc != EOK)
102 return NULL;
103
104 inet_sroute_t *best = NULL;
105 uint8_t best_bits = 0;
106
107 fibril_mutex_lock(&sroute_list_lock);
108
109 list_foreach(sroute_list, link) {
110 inet_sroute_t *sroute = list_get_instance(link,
111 inet_sroute_t, sroute_list);
112
113 uint32_t dest_addr;
114 uint8_t dest_bits;
115 rc = inet_naddr_pack(&sroute->dest, &dest_addr, &dest_bits);
116 if (rc != EOK)
117 continue;
118
119 /* Look for the most specific route */
120 if ((best != NULL) && (best_bits >= dest_bits))
121 continue;
122
123 uint32_t mask = inet_netmask(dest_bits);
124 if ((dest_addr & mask) == (addr_addr & mask)) {
125 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: found candidate %p",
126 sroute);
127
128 best = sroute;
129 best_bits = dest_bits;
130 }
131 }
132
133 if (best == NULL)
134 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: Not found");
135
136 fibril_mutex_unlock(&sroute_list_lock);
137
138 return best;
139}
140
141/** Find static route with a specific name.
142 *
143 * @param name Address object name
144 * @return Address object
145 */
146inet_sroute_t *inet_sroute_find_by_name(const char *name)
147{
148 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name('%s')",
149 name);
150
151 fibril_mutex_lock(&sroute_list_lock);
152
153 list_foreach(sroute_list, link) {
154 inet_sroute_t *sroute = list_get_instance(link,
155 inet_sroute_t, sroute_list);
156
157 if (str_cmp(sroute->name, name) == 0) {
158 fibril_mutex_unlock(&sroute_list_lock);
159 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: found %p",
160 sroute);
161 return sroute;
162 }
163 }
164
165 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: Not found");
166 fibril_mutex_unlock(&sroute_list_lock);
167
168 return NULL;
169}
170
171/** Find static route with the given ID.
172 *
173 * @param id Address object ID
174 * @return Address object
175 */
176inet_sroute_t *inet_sroute_get_by_id(sysarg_t id)
177{
178 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
179
180 fibril_mutex_lock(&sroute_list_lock);
181
182 list_foreach(sroute_list, link) {
183 inet_sroute_t *sroute = list_get_instance(link,
184 inet_sroute_t, sroute_list);
185
186 if (sroute->id == id) {
187 fibril_mutex_unlock(&sroute_list_lock);
188 return sroute;
189 }
190 }
191
192 fibril_mutex_unlock(&sroute_list_lock);
193
194 return NULL;
195}
196
197/** Get IDs of all static routes. */
198int inet_sroute_get_id_list(sysarg_t **rid_list, size_t *rcount)
199{
200 sysarg_t *id_list;
201 size_t count, i;
202
203 fibril_mutex_lock(&sroute_list_lock);
204 count = list_count(&sroute_list);
205
206 id_list = calloc(count, sizeof(sysarg_t));
207 if (id_list == NULL) {
208 fibril_mutex_unlock(&sroute_list_lock);
209 return ENOMEM;
210 }
211
212 i = 0;
213 list_foreach(sroute_list, link) {
214 inet_sroute_t *sroute = list_get_instance(link,
215 inet_sroute_t, sroute_list);
216
217 id_list[i++] = sroute->id;
218 }
219
220 fibril_mutex_unlock(&sroute_list_lock);
221
222 *rid_list = id_list;
223 *rcount = count;
224
225 return EOK;
226}
227
228/** @}
229 */
Note: See TracBrowser for help on using the repository browser.