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

Last change on this file since c81d4f1 was 46577995, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

After this commit, HelenOS is free of code that mixes error codes with non-error
values on the assumption that error codes are negative.

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