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

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

gradually introduce async ports, initial phase

The initial phase is to reimplement the traditional async client connections as an untyped fallback port. This creates the possibility to introduce ports typed by interface type gradually in later changesets.

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