source: mainline/uspace/lib/inet/src/iplink.c@ 95658c9

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 95658c9 was edeee9f, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Fix header guards and doxy groups of stuff moved out of libc

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[f834f90d]1/*
[f05edcb]2 * Copyright (c) 2021 Jiri Svoboda
[f834f90d]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
[edeee9f]29/** @addtogroup libinet
[f834f90d]30 * @{
31 */
32/**
33 * @file
34 * @brief IP link client stub
35 */
36
37#include <async.h>
38#include <assert.h>
39#include <errno.h>
[a2e3ee6]40#include <inet/addr.h>
[b4edc96]41#include <inet/eth_addr.h>
42#include <inet/iplink.h>
[f834f90d]43#include <ipc/iplink.h>
44#include <ipc/services.h>
45#include <loc.h>
46#include <stdlib.h>
47
[984a9ba]48static void iplink_cb_conn(ipc_call_t *icall, void *arg);
[f834f90d]49
[b7fd2a0]50errno_t iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops, void *arg,
[f834f90d]51 iplink_t **riplink)
52{
[77ad86c]53 iplink_t *iplink = calloc(1, sizeof(iplink_t));
[f834f90d]54 if (iplink == NULL)
55 return ENOMEM;
[a35b458]56
[f834f90d]57 iplink->sess = sess;
58 iplink->ev_ops = ev_ops;
[8d48c7e]59 iplink->arg = arg;
[a35b458]60
[f834f90d]61 async_exch_t *exch = async_exchange_begin(sess);
[f9b2cb4c]62
63 port_id_t port;
[b7fd2a0]64 errno_t rc = async_create_callback_port(exch, INTERFACE_IPLINK_CB, 0, 0,
[f9b2cb4c]65 iplink_cb_conn, iplink, &port);
[a35b458]66
[f834f90d]67 async_exchange_end(exch);
[a35b458]68
[f834f90d]69 if (rc != EOK)
70 goto error;
[a35b458]71
[f834f90d]72 *riplink = iplink;
73 return EOK;
[a35b458]74
[f834f90d]75error:
76 if (iplink != NULL)
77 free(iplink);
[a35b458]78
[f834f90d]79 return rc;
80}
81
82void iplink_close(iplink_t *iplink)
83{
84 /* XXX Synchronize with iplink_cb_conn */
85 free(iplink);
86}
87
[b7fd2a0]88errno_t iplink_send(iplink_t *iplink, iplink_sdu_t *sdu)
[f834f90d]89{
90 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]91
[f834f90d]92 ipc_call_t answer;
[a17356fd]93 aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->src,
94 (sysarg_t) sdu->dest, &answer);
[a35b458]95
[b7fd2a0]96 errno_t rc = async_data_write_start(exch, sdu->data, sdu->size);
[a35b458]97
[a17356fd]98 async_exchange_end(exch);
[a35b458]99
[02a09ed]100 if (rc != EOK) {
101 async_forget(req);
102 return rc;
103 }
[a35b458]104
[b7fd2a0]105 errno_t retval;
[a17356fd]106 async_wait_for(req, &retval);
[a35b458]107
[25a179e]108 return retval;
[a17356fd]109}
110
[b7fd2a0]111errno_t iplink_send6(iplink_t *iplink, iplink_sdu6_t *sdu)
[a17356fd]112{
113 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]114
[a17356fd]115 ipc_call_t answer;
116 aid_t req = async_send_0(exch, IPLINK_SEND6, &answer);
[a35b458]117
[b4edc96]118 errno_t rc = async_data_write_start(exch, &sdu->dest, sizeof(eth_addr_t));
[02a09ed]119 if (rc != EOK) {
120 async_exchange_end(exch);
121 async_forget(req);
122 return rc;
123 }
[a35b458]124
[02a09ed]125 rc = async_data_write_start(exch, sdu->data, sdu->size);
[a35b458]126
[f834f90d]127 async_exchange_end(exch);
[a35b458]128
[f834f90d]129 if (rc != EOK) {
[50b581d]130 async_forget(req);
[f834f90d]131 return rc;
132 }
[a35b458]133
[b7fd2a0]134 errno_t retval;
[f834f90d]135 async_wait_for(req, &retval);
[a35b458]136
[25a179e]137 return retval;
[f834f90d]138}
139
[b7fd2a0]140errno_t iplink_get_mtu(iplink_t *iplink, size_t *rmtu)
[f834f90d]141{
142 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]143
[a17356fd]144 sysarg_t mtu;
[b7fd2a0]145 errno_t rc = async_req_0_1(exch, IPLINK_GET_MTU, &mtu);
[a35b458]146
[f834f90d]147 async_exchange_end(exch);
[a35b458]148
[f834f90d]149 if (rc != EOK)
150 return rc;
[a35b458]151
[f834f90d]152 *rmtu = mtu;
153 return EOK;
154}
155
[b4edc96]156errno_t iplink_get_mac48(iplink_t *iplink, eth_addr_t *mac)
[a17356fd]157{
158 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]159
[a17356fd]160 ipc_call_t answer;
161 aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
[a35b458]162
[b4edc96]163 errno_t rc = async_data_read_start(exch, mac, sizeof(eth_addr_t));
[a35b458]164
[a17356fd]165 loc_exchange_end(exch);
[a35b458]166
[a17356fd]167 if (rc != EOK) {
168 async_forget(req);
169 return rc;
170 }
[a35b458]171
[b7fd2a0]172 errno_t retval;
[a17356fd]173 async_wait_for(req, &retval);
[a35b458]174
[25a179e]175 return retval;
[a17356fd]176}
177
[b4edc96]178errno_t iplink_set_mac48(iplink_t *iplink, eth_addr_t *mac)
[c3b25985]179{
180 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]181
[c3b25985]182 ipc_call_t answer;
183 aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
[a35b458]184
[b4edc96]185 errno_t rc = async_data_read_start(exch, mac, sizeof(eth_addr_t));
[a35b458]186
[c3b25985]187 loc_exchange_end(exch);
[a35b458]188
[c3b25985]189 if (rc != EOK) {
190 async_forget(req);
191 return rc;
192 }
[a35b458]193
[b7fd2a0]194 errno_t retval;
[c3b25985]195 async_wait_for(req, &retval);
[a35b458]196
[25a179e]197 return retval;
[c3b25985]198}
199
[b7fd2a0]200errno_t iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
[962f03b]201{
202 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]203
[02a09ed]204 ipc_call_t answer;
205 aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
[a35b458]206
[b7fd2a0]207 errno_t rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
[962f03b]208 async_exchange_end(exch);
[a35b458]209
[02a09ed]210 if (rc != EOK) {
211 async_forget(req);
212 return rc;
213 }
[a35b458]214
[b7fd2a0]215 errno_t retval;
[02a09ed]216 async_wait_for(req, &retval);
[a35b458]217
[25a179e]218 return retval;
[962f03b]219}
220
[b7fd2a0]221errno_t iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
[962f03b]222{
223 async_exch_t *exch = async_exchange_begin(iplink->sess);
[a35b458]224
[02a09ed]225 ipc_call_t answer;
226 aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
[a35b458]227
[b7fd2a0]228 errno_t rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
[962f03b]229 async_exchange_end(exch);
[a35b458]230
[02a09ed]231 if (rc != EOK) {
232 async_forget(req);
233 return rc;
234 }
[a35b458]235
[b7fd2a0]236 errno_t retval;
[02a09ed]237 async_wait_for(req, &retval);
[a35b458]238
[25a179e]239 return retval;
[962f03b]240}
241
[8d48c7e]242void *iplink_get_userptr(iplink_t *iplink)
243{
244 return iplink->arg;
245}
246
[984a9ba]247static void iplink_ev_recv(iplink_t *iplink, ipc_call_t *icall)
[f834f90d]248{
[02a09ed]249 iplink_recv_sdu_t sdu;
[a35b458]250
[fafb8e5]251 ip_ver_t ver = ipc_get_arg1(icall);
[a35b458]252
[b7fd2a0]253 errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
[02a09ed]254 &sdu.size);
[f834f90d]255 if (rc != EOK) {
[984a9ba]256 async_answer_0(icall, rc);
[f834f90d]257 return;
258 }
[a35b458]259
[417a2ba1]260 rc = iplink->ev_ops->recv(iplink, &sdu, ver);
[ffa8912]261 free(sdu.data);
[984a9ba]262 async_answer_0(icall, rc);
[f834f90d]263}
264
[984a9ba]265static void iplink_ev_change_addr(iplink_t *iplink, ipc_call_t *icall)
[c3b25985]266{
[b4edc96]267 eth_addr_t *addr;
[c3b25985]268 size_t size;
[a35b458]269
[984a9ba]270 errno_t rc = async_data_write_accept((void **) &addr, false,
[b4edc96]271 sizeof(eth_addr_t), sizeof(eth_addr_t), 0, &size);
[c3b25985]272 if (rc != EOK) {
[984a9ba]273 async_answer_0(icall, rc);
[c3b25985]274 return;
275 }
276
[f05edcb]277 rc = iplink->ev_ops->change_addr(iplink, addr);
[c3b25985]278 free(addr);
[984a9ba]279 async_answer_0(icall, EOK);
[c3b25985]280}
281
[984a9ba]282static void iplink_cb_conn(ipc_call_t *icall, void *arg)
[f834f90d]283{
[b5cf742a]284 iplink_t *iplink = (iplink_t *) arg;
[a35b458]285
[f834f90d]286 while (true) {
287 ipc_call_t call;
[984a9ba]288 async_get_call(&call);
[a35b458]289
[fafb8e5]290 if (!ipc_get_imethod(&call)) {
[889cdb1]291 async_answer_0(&call, EOK);
[f834f90d]292 return;
293 }
[a35b458]294
[fafb8e5]295 switch (ipc_get_imethod(&call)) {
[f834f90d]296 case IPLINK_EV_RECV:
[984a9ba]297 iplink_ev_recv(iplink, &call);
[f834f90d]298 break;
[c3b25985]299 case IPLINK_EV_CHANGE_ADDR:
[984a9ba]300 iplink_ev_change_addr(iplink, &call);
[dc12262]301 break;
[f834f90d]302 default:
[984a9ba]303 async_answer_0(&call, ENOTSUP);
[f834f90d]304 }
305 }
306}
307
308/** @}
309 */
Note: See TracBrowser for help on using the repository browser.