source: mainline/uspace/srv/net/inetsrv/sroute.c@ 02a09ed

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

add basic infrastructure for IPv6 (inactive)
make inet_addr_t a universal address type

  • 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#include "sroute.h"
45#include "inetsrv.h"
46#include "inet_link.h"
47
48static FIBRIL_MUTEX_INITIALIZE(sroute_list_lock);
49static LIST_INITIALIZE(sroute_list);
50static sysarg_t sroute_id = 0;
51
52inet_sroute_t *inet_sroute_new(void)
53{
54 inet_sroute_t *sroute = calloc(1, sizeof(inet_sroute_t));
55
56 if (sroute == NULL) {
57 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating static route object. "
58 "Out of memory.");
59 return NULL;
60 }
61
62 link_initialize(&sroute->sroute_list);
63 fibril_mutex_lock(&sroute_list_lock);
64 sroute->id = ++sroute_id;
65 fibril_mutex_unlock(&sroute_list_lock);
66
67 return sroute;
68}
69
70void inet_sroute_delete(inet_sroute_t *sroute)
71{
72 if (sroute->name != NULL)
73 free(sroute->name);
74 free(sroute);
75}
76
77void inet_sroute_add(inet_sroute_t *sroute)
78{
79 fibril_mutex_lock(&sroute_list_lock);
80 list_append(&sroute->sroute_list, &sroute_list);
81 fibril_mutex_unlock(&sroute_list_lock);
82}
83
84void inet_sroute_remove(inet_sroute_t *sroute)
85{
86 fibril_mutex_lock(&sroute_list_lock);
87 list_remove(&sroute->sroute_list);
88 fibril_mutex_unlock(&sroute_list_lock);
89}
90
91/** Find address object matching address @a addr.
92 *
93 * @param addr Address
94 */
95inet_sroute_t *inet_sroute_find(inet_addr_t *addr)
96{
97 uint16_t addr_af = inet_addr_get(addr, NULL, NULL);
98
99 inet_sroute_t *best = NULL;
100 uint8_t best_bits = 0;
101
102 fibril_mutex_lock(&sroute_list_lock);
103
104 list_foreach(sroute_list, link) {
105 inet_sroute_t *sroute = list_get_instance(link,
106 inet_sroute_t, sroute_list);
107
108 uint8_t dest_bits;
109 uint16_t dest_af = inet_naddr_get(&sroute->dest, NULL, NULL,
110 &dest_bits);
111
112 /* Skip comparison with different address family */
113 if (addr_af != dest_af)
114 continue;
115
116 /* Look for the most specific route */
117 if ((best != NULL) && (best_bits >= dest_bits))
118 continue;
119
120 if (inet_naddr_compare_mask(&sroute->dest, addr)) {
121 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: found candidate %p",
122 sroute);
123
124 best = sroute;
125 best_bits = dest_bits;
126 }
127 }
128
129 if (best == NULL)
130 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: Not found");
131
132 fibril_mutex_unlock(&sroute_list_lock);
133
134 return best;
135}
136
137/** Find static route with a specific name.
138 *
139 * @param name Address object name
140 * @return Address object
141 */
142inet_sroute_t *inet_sroute_find_by_name(const char *name)
143{
144 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name('%s')",
145 name);
146
147 fibril_mutex_lock(&sroute_list_lock);
148
149 list_foreach(sroute_list, link) {
150 inet_sroute_t *sroute = list_get_instance(link,
151 inet_sroute_t, sroute_list);
152
153 if (str_cmp(sroute->name, name) == 0) {
154 fibril_mutex_unlock(&sroute_list_lock);
155 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: found %p",
156 sroute);
157 return sroute;
158 }
159 }
160
161 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: Not found");
162 fibril_mutex_unlock(&sroute_list_lock);
163
164 return NULL;
165}
166
167/** Find static route with the given ID.
168 *
169 * @param id Address object ID
170 * @return Address object
171 */
172inet_sroute_t *inet_sroute_get_by_id(sysarg_t id)
173{
174 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
175
176 fibril_mutex_lock(&sroute_list_lock);
177
178 list_foreach(sroute_list, link) {
179 inet_sroute_t *sroute = list_get_instance(link,
180 inet_sroute_t, sroute_list);
181
182 if (sroute->id == id) {
183 fibril_mutex_unlock(&sroute_list_lock);
184 return sroute;
185 }
186 }
187
188 fibril_mutex_unlock(&sroute_list_lock);
189
190 return NULL;
191}
192
193/** Get IDs of all static routes. */
194int inet_sroute_get_id_list(sysarg_t **rid_list, size_t *rcount)
195{
196 sysarg_t *id_list;
197 size_t count, i;
198
199 fibril_mutex_lock(&sroute_list_lock);
200 count = list_count(&sroute_list);
201
202 id_list = calloc(count, sizeof(sysarg_t));
203 if (id_list == NULL) {
204 fibril_mutex_unlock(&sroute_list_lock);
205 return ENOMEM;
206 }
207
208 i = 0;
209 list_foreach(sroute_list, link) {
210 inet_sroute_t *sroute = list_get_instance(link,
211 inet_sroute_t, sroute_list);
212
213 id_list[i++] = sroute->id;
214 }
215
216 fibril_mutex_unlock(&sroute_list_lock);
217
218 *rid_list = id_list;
219 *rcount = count;
220
221 return EOK;
222}
223
224/** @}
225 */
Note: See TracBrowser for help on using the repository browser.