source: mainline/uspace/srv/net/inetsrv/ntrans.c@ ca48672

Last change on this file since ca48672 was b4edc96, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Rename and move addr48_t to eth_addr_t

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * Copyright (c) 2013 Antonin Steinhauser
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup inet
31 * @{
32 */
33/**
34 * @file
35 * @brief
36 */
37
38#include <adt/list.h>
39#include <errno.h>
40#include <fibril_synch.h>
41#include <inet/eth_addr.h>
42#include <inet/iplink_srv.h>
43#include <stdlib.h>
44#include "ntrans.h"
45
46/** Address translation list (of inet_ntrans_t) */
47static FIBRIL_MUTEX_INITIALIZE(ntrans_list_lock);
48static LIST_INITIALIZE(ntrans_list);
49static FIBRIL_CONDVAR_INITIALIZE(ntrans_cv);
50
51/** Look for address in translation table
52 *
53 * @param ip_addr IPv6 address
54 *
55 * @return inet_ntrans_t with the address on success
56 * @return NULL if nothing found
57 */
58static inet_ntrans_t *ntrans_find(addr128_t ip_addr)
59{
60 list_foreach(ntrans_list, ntrans_list, inet_ntrans_t, ntrans) {
61 if (addr128_compare(ntrans->ip_addr, ip_addr))
62 return ntrans;
63 }
64
65 return NULL;
66}
67
68/** Add entry to translation table
69 *
70 * @param ip_addr IPv6 address of the new entry
71 * @param mac_addr MAC address of the new entry
72 *
73 * @return EOK on success
74 * @return ENOMEM if not enough memory
75 *
76 */
77errno_t ntrans_add(addr128_t ip_addr, eth_addr_t *mac_addr)
78{
79 inet_ntrans_t *ntrans;
80 inet_ntrans_t *prev;
81
82 ntrans = calloc(1, sizeof(inet_ntrans_t));
83 if (ntrans == NULL)
84 return ENOMEM;
85
86 addr128(ip_addr, ntrans->ip_addr);
87 ntrans->mac_addr = *mac_addr;
88
89 fibril_mutex_lock(&ntrans_list_lock);
90 prev = ntrans_find(ip_addr);
91 if (prev != NULL) {
92 list_remove(&prev->ntrans_list);
93 free(prev);
94 }
95
96 list_append(&ntrans->ntrans_list, &ntrans_list);
97 fibril_mutex_unlock(&ntrans_list_lock);
98 fibril_condvar_broadcast(&ntrans_cv);
99
100 return EOK;
101}
102
103/** Remove entry from translation table
104 *
105 * @param ip_addr IPv6 address of the entry to be removed
106 *
107 * @return EOK on success
108 * @return ENOENT when no such address found
109 *
110 */
111errno_t ntrans_remove(addr128_t ip_addr)
112{
113 inet_ntrans_t *ntrans;
114
115 fibril_mutex_lock(&ntrans_list_lock);
116 ntrans = ntrans_find(ip_addr);
117 if (ntrans == NULL) {
118 fibril_mutex_unlock(&ntrans_list_lock);
119 return ENOENT;
120 }
121
122 list_remove(&ntrans->ntrans_list);
123 fibril_mutex_unlock(&ntrans_list_lock);
124 free(ntrans);
125
126 return EOK;
127}
128
129/** Translate IPv6 address to MAC address using the translation table
130 *
131 * @param ip_addr IPv6 address to be translated
132 * @param mac_addr MAC address to be assigned
133 *
134 * @return EOK on success
135 * @return ENOENT when no such address found
136 *
137 */
138errno_t ntrans_lookup(addr128_t ip_addr, eth_addr_t *mac_addr)
139{
140 fibril_mutex_lock(&ntrans_list_lock);
141 inet_ntrans_t *ntrans = ntrans_find(ip_addr);
142 if (ntrans == NULL) {
143 fibril_mutex_unlock(&ntrans_list_lock);
144 return ENOENT;
145 }
146
147 fibril_mutex_unlock(&ntrans_list_lock);
148 *mac_addr = ntrans->mac_addr;
149 return EOK;
150}
151
152/** Wait on translation table CV for some time
153 *
154 * @param timeout Timeout in microseconds
155 *
156 * @return EOK if woken up by another fibril
157 * @return ETIMEOUT if timed out
158 *
159 */
160errno_t ntrans_wait_timeout(usec_t timeout)
161{
162 fibril_mutex_lock(&ntrans_list_lock);
163 errno_t rc = fibril_condvar_wait_timeout(&ntrans_cv, &ntrans_list_lock,
164 timeout);
165 fibril_mutex_unlock(&ntrans_list_lock);
166
167 return rc;
168}
169
170/** @}
171 */
Note: See TracBrowser for help on using the repository browser.