source: mainline/uspace/srv/net/loopip/loopip.c@ c77cfd8

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c77cfd8 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: 6.6 KB
RevLine 
[606c369]1/*
[b4edc96]2 * Copyright (c) 2021 Jiri Svoboda
[606c369]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 loopip
30 * @{
31 */
32/**
33 * @file
34 * @brief Loopback IP link provider
35 */
36
37#include <adt/prodcons.h>
38#include <async.h>
39#include <errno.h>
[c1694b6b]40#include <str_error.h>
[606c369]41#include <inet/iplink_srv.h>
[02a09ed]42#include <inet/addr.h>
[b4edc96]43#include <inet/eth_addr.h>
[606c369]44#include <io/log.h>
45#include <loc.h>
46#include <stdio.h>
47#include <stdlib.h>
[1d6dd2a]48#include <str.h>
[1c635d6]49#include <task.h>
[606c369]50
[257feec]51#define NAME "loopip"
[606c369]52
[b7fd2a0]53static errno_t loopip_open(iplink_srv_t *srv);
54static errno_t loopip_close(iplink_srv_t *srv);
55static errno_t loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu);
56static errno_t loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu);
57static errno_t loopip_get_mtu(iplink_srv_t *srv, size_t *mtu);
[b4edc96]58static errno_t loopip_get_mac48(iplink_srv_t *srv, eth_addr_t *mac);
[b7fd2a0]59static errno_t loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr);
60static errno_t loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr);
[606c369]61
[984a9ba]62static void loopip_client_conn(ipc_call_t *icall, void *arg);
[606c369]63
64static iplink_ops_t loopip_iplink_ops = {
65 .open = loopip_open,
66 .close = loopip_close,
67 .send = loopip_send,
[a17356fd]68 .send6 = loopip_send6,
[606c369]69 .get_mtu = loopip_get_mtu,
[a17356fd]70 .get_mac48 = loopip_get_mac48,
[606c369]71 .addr_add = loopip_addr_add,
72 .addr_remove = loopip_addr_remove
73};
74
75static iplink_srv_t loopip_iplink;
76static prodcons_t loopip_rcv_queue;
77
78typedef struct {
79 link_t link;
[a35b458]80
[417a2ba1]81 /* XXX Version should be part of SDU */
82 ip_ver_t ver;
[02a09ed]83 iplink_recv_sdu_t sdu;
[606c369]84} rqueue_entry_t;
85
[b7fd2a0]86static errno_t loopip_recv_fibril(void *arg)
[606c369]87{
88 while (true) {
[a1a101d]89 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_recv_fibril(): Wait for one item");
[606c369]90 link_t *link = prodcons_consume(&loopip_rcv_queue);
[02a09ed]91 rqueue_entry_t *rqe =
92 list_get_instance(link, rqueue_entry_t, link);
[a35b458]93
[417a2ba1]94 (void) iplink_ev_recv(&loopip_iplink, &rqe->sdu, rqe->ver);
[a35b458]95
[02a09ed]96 free(rqe->sdu.data);
97 free(rqe);
[606c369]98 }
[a35b458]99
[606c369]100 return 0;
101}
102
[b7fd2a0]103static errno_t loopip_init(void)
[606c369]104{
[b688fd8]105 async_set_fallback_port_handler(loopip_client_conn, NULL);
[a35b458]106
[b7fd2a0]107 errno_t rc = loc_server_register(NAME);
[606c369]108 if (rc != EOK) {
[a1a101d]109 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
[606c369]110 return rc;
111 }
[a35b458]112
[606c369]113 iplink_srv_init(&loopip_iplink);
114 loopip_iplink.ops = &loopip_iplink_ops;
115 loopip_iplink.arg = NULL;
[a35b458]116
[606c369]117 prodcons_initialize(&loopip_rcv_queue);
[a35b458]118
[02a09ed]119 const char *svc_name = "net/loopback";
120 service_id_t sid;
[606c369]121 rc = loc_service_register(svc_name, &sid);
122 if (rc != EOK) {
[02a09ed]123 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service %s.",
124 svc_name);
[606c369]125 return rc;
126 }
[a35b458]127
[02a09ed]128 category_id_t iplink_cat;
[606c369]129 rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
130 if (rc != EOK) {
[a1a101d]131 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
[606c369]132 return rc;
133 }
[a35b458]134
[606c369]135 rc = loc_service_add_to_cat(sid, iplink_cat);
136 if (rc != EOK) {
[02a09ed]137 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding %s to category.",
138 svc_name);
[606c369]139 return rc;
140 }
[a35b458]141
[606c369]142 fid_t fid = fibril_create(loopip_recv_fibril, NULL);
143 if (fid == 0)
144 return ENOMEM;
[a35b458]145
[606c369]146 fibril_add_ready(fid);
[a35b458]147
[606c369]148 return EOK;
149}
150
[984a9ba]151static void loopip_client_conn(ipc_call_t *icall, void *arg)
[606c369]152{
[a1a101d]153 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_client_conn()");
[984a9ba]154 iplink_conn(icall, &loopip_iplink);
[606c369]155}
156
[b7fd2a0]157static errno_t loopip_open(iplink_srv_t *srv)
[606c369]158{
[a1a101d]159 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_open()");
[606c369]160 return EOK;
161}
162
[b7fd2a0]163static errno_t loopip_close(iplink_srv_t *srv)
[606c369]164{
[a1a101d]165 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_close()");
[606c369]166 return EOK;
167}
168
[b7fd2a0]169static errno_t loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu)
[606c369]170{
[a1a101d]171 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()");
[a35b458]172
[a17356fd]173 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t));
174 if (rqe == NULL)
175 return ENOMEM;
[a35b458]176
[a17356fd]177 /*
178 * Clone SDU
179 */
[417a2ba1]180 rqe->ver = ip_v4;
[a17356fd]181 rqe->sdu.data = malloc(sdu->size);
182 if (rqe->sdu.data == NULL) {
183 free(rqe);
184 return ENOMEM;
185 }
[a35b458]186
[a17356fd]187 memcpy(rqe->sdu.data, sdu->data, sdu->size);
188 rqe->sdu.size = sdu->size;
[a35b458]189
[a17356fd]190 /*
191 * Insert to receive queue
192 */
193 prodcons_produce(&loopip_rcv_queue, &rqe->link);
[a35b458]194
[a17356fd]195 return EOK;
196}
197
[b7fd2a0]198static errno_t loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu)
[a17356fd]199{
200 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip6_send()");
[a35b458]201
[02a09ed]202 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t));
[606c369]203 if (rqe == NULL)
204 return ENOMEM;
[a35b458]205
[606c369]206 /*
207 * Clone SDU
208 */
[417a2ba1]209 rqe->ver = ip_v6;
[606c369]210 rqe->sdu.data = malloc(sdu->size);
211 if (rqe->sdu.data == NULL) {
212 free(rqe);
213 return ENOMEM;
214 }
[a35b458]215
[606c369]216 memcpy(rqe->sdu.data, sdu->data, sdu->size);
217 rqe->sdu.size = sdu->size;
[a35b458]218
[606c369]219 /*
220 * Insert to receive queue
221 */
222 prodcons_produce(&loopip_rcv_queue, &rqe->link);
[a35b458]223
[606c369]224 return EOK;
225}
226
[b7fd2a0]227static errno_t loopip_get_mtu(iplink_srv_t *srv, size_t *mtu)
[606c369]228{
[a1a101d]229 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mtu()");
[606c369]230 *mtu = 1500;
231 return EOK;
232}
233
[b4edc96]234static errno_t loopip_get_mac48(iplink_srv_t *src, eth_addr_t *mac)
[a17356fd]235{
236 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mac48()");
237 return ENOTSUP;
238}
239
[b7fd2a0]240static errno_t loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr)
[606c369]241{
242 return EOK;
243}
244
[b7fd2a0]245static errno_t loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr)
[606c369]246{
247 return EOK;
248}
249
250int main(int argc, char *argv[])
251{
[02a09ed]252 printf("%s: HelenOS loopback IP link provider\n", NAME);
[a35b458]253
[b7fd2a0]254 errno_t rc = log_init(NAME);
[02a09ed]255 if (rc != EOK) {
[c1694b6b]256 printf("%s: Failed to initialize logging: %s.\n", NAME, str_error(rc));
[02a09ed]257 return rc;
[606c369]258 }
[a35b458]259
[606c369]260 rc = loopip_init();
[c1694b6b]261 if (rc != EOK) {
262 printf("%s: Failed to initialize loopip: %s.\n", NAME, str_error(rc));
[02a09ed]263 return rc;
[c1694b6b]264 }
[a35b458]265
[02a09ed]266 printf("%s: Accepting connections.\n", NAME);
[606c369]267 task_retval(0);
268 async_manager();
[a35b458]269
[606c369]270 /* Not reached */
271 return 0;
272}
273
274/** @}
275 */
Note: See TracBrowser for help on using the repository browser.