source: mainline/uspace/srv/net/inetsrv/inetcfg.c@ 9aa51406

Last change on this file since 9aa51406 was 1bbc6dc, checked in by Jiri Svoboda <jiri@…>, 9 months ago

Network configuration persistence.

nconfsrv is folded into inetsrv
DHCP is disabled when a static address is configured on a link

  • Property mode set to 100644
File size: 21.2 KB
RevLine 
[0e25780]1/*
[1bbc6dc]2 * Copyright (c) 2024 Jiri Svoboda
[0e25780]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 inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <async.h>
38#include <errno.h>
39#include <macros.h>
40#include <io/log.h>
41#include <ipc/inet.h>
42#include <loc.h>
43#include <stdlib.h>
[0e94b979]44#include <str.h>
[8d2dd7f2]45#include <stddef.h>
[b8b1adb1]46#include <types/inetcfg.h>
[0e25780]47
[45aa22c]48#include "addrobj.h"
[b4ec1ea]49#include "inetsrv.h"
[45aa22c]50#include "inet_link.h"
[0e25780]51#include "inetcfg.h"
[8bf672d]52#include "sroute.h"
[0e25780]53
[b7fd2a0]54static errno_t inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
[291c792]55 sysarg_t link_id, sysarg_t *addr_id)
[0e25780]56{
[45aa22c]57 inet_link_t *ilink;
58 inet_addrobj_t *addr;
[a2e3ee6]59 inet_addr_t iaddr;
[b7fd2a0]60 errno_t rc;
[45aa22c]61
62 ilink = inet_link_get_by_id(link_id);
63 if (ilink == NULL) {
[a1a101d]64 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
[45aa22c]65 (unsigned long) link_id);
66 return ENOENT;
67 }
68
69 addr = inet_addrobj_new();
[8bf672d]70 if (addr == NULL) {
71 *addr_id = 0;
72 return ENOMEM;
73 }
74
[45aa22c]75 addr->naddr = *naddr;
76 addr->ilink = ilink;
[291c792]77 addr->name = str_dup(name);
[bf9e6fc]78 rc = inet_addrobj_add(addr);
79 if (rc != EOK) {
[a1a101d]80 log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
[bf9e6fc]81 inet_addrobj_delete(addr);
82 return rc;
83 }
[45aa22c]84
[a2e3ee6]85 inet_naddr_addr(&addr->naddr, &iaddr);
[45aa22c]86 rc = iplink_addr_add(ilink->iplink, &iaddr);
87 if (rc != EOK) {
[a1a101d]88 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
[45aa22c]89 inet_addrobj_remove(addr);
90 inet_addrobj_delete(addr);
91 return rc;
92 }
93
[1bbc6dc]94 rc = inet_cfg_sync(cfg);
95 if (rc != EOK) {
96 log_msg(LOG_DEFAULT, LVL_ERROR, "Error saving configuration.");
97 return rc;
98 }
99
[45aa22c]100 return EOK;
[0e25780]101}
102
[b7fd2a0]103static errno_t inetcfg_addr_delete(sysarg_t addr_id)
[0e25780]104{
[fa101c4]105 inet_addrobj_t *addr;
[1bbc6dc]106 inet_link_cfg_info_t info;
107 unsigned acnt;
108 inet_link_t *ilink;
109 errno_t rc;
110
111 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete()");
[fa101c4]112
113 addr = inet_addrobj_get_by_id(addr_id);
114 if (addr == NULL)
115 return ENOENT;
116
[1bbc6dc]117 info.svc_id = addr->ilink->svc_id;
118 info.svc_name = str_dup(addr->ilink->svc_name);
119 if (info.svc_name == NULL)
120 return ENOMEM;
121
[fa101c4]122 inet_addrobj_remove(addr);
123 inet_addrobj_delete(addr);
124
[1bbc6dc]125 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete(): sync");
126
127 rc = inet_cfg_sync(cfg);
128 if (rc != EOK) {
129 log_msg(LOG_DEFAULT, LVL_ERROR, "Error saving configuration.");
130 free(info.svc_name);
131 return rc;
132 }
133
134 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete(): get link by ID");
135
136 ilink = inet_link_get_by_id(info.svc_id);
137 if (ilink == NULL) {
138 log_msg(LOG_DEFAULT, LVL_ERROR, "Error finding link.");
139 return ENOENT;
140 }
141
142 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete(): check addrobj count");
143
144 /* If there are no configured addresses left, autoconfigure link */
145 acnt = inet_addrobj_cnt_by_link(ilink);
146 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete(): acnt=%u", acnt);
147 if (acnt == 0)
148 inet_link_autoconf_link(&info);
149
150 log_msg(LOG_DEFAULT, LVL_NOTE, "inetcfg_addr_delete(): DONE");
[fa101c4]151 return EOK;
[0e25780]152}
153
[b7fd2a0]154static errno_t inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
[0e25780]155{
[0e94b979]156 inet_addrobj_t *addr;
157
158 addr = inet_addrobj_get_by_id(addr_id);
159 if (addr == NULL)
160 return ENOENT;
161
162 ainfo->naddr = addr->naddr;
163 ainfo->ilink = addr->ilink->svc_id;
164 ainfo->name = str_dup(addr->name);
165
166 return EOK;
[0e25780]167}
168
[b7fd2a0]169static errno_t inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
[fa101c4]170{
171 inet_link_t *ilink;
172 inet_addrobj_t *addr;
173
174 ilink = inet_link_get_by_id(link_id);
175 if (ilink == NULL) {
[a1a101d]176 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
[fa101c4]177 return ENOENT;
178 }
179
180 addr = inet_addrobj_find_by_name(name, ilink);
181 if (addr == NULL) {
[a1a101d]182 log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
[fa101c4]183 return ENOENT;
184 }
185
186 *addr_id = addr->id;
187 return EOK;
188}
189
[b7fd2a0]190static errno_t inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
[0e25780]191{
[0e94b979]192 return inet_addrobj_get_id_list(addrs, count);
[0e25780]193}
194
[b7fd2a0]195static errno_t inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
[0e25780]196{
[b8b1adb1]197 return inet_link_get_id_list(addrs, count);
[0e25780]198}
199
[b7fd2a0]200static errno_t inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
[8bf672d]201{
202 return inet_sroute_get_id_list(sroutes, count);
203}
204
[b7fd2a0]205static errno_t inetcfg_link_add(sysarg_t link_id)
[7af0cc5]206{
207 return inet_link_open(link_id);
208}
209
[b7fd2a0]210static errno_t inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
[0e25780]211{
[0e94b979]212 inet_link_t *ilink;
213
214 ilink = inet_link_get_by_id(link_id);
215 if (ilink == NULL) {
216 return ENOENT;
217 }
218
219 linfo->name = str_dup(ilink->svc_name);
[347768d]220 linfo->def_mtu = ilink->def_mtu;
[b8b1adb1]221 if (ilink->mac_valid) {
[d5ed54b]222 linfo->mac_addr = ilink->mac;
[b8b1adb1]223 } else {
[f05edcb]224 memset(&linfo->mac_addr, 0, sizeof(linfo->mac_addr));
[b8b1adb1]225 }
226
[0e94b979]227 return EOK;
[0e25780]228}
229
[b7fd2a0]230static errno_t inetcfg_link_remove(sysarg_t link_id)
[7af0cc5]231{
232 return ENOTSUP;
233}
234
[b7fd2a0]235static errno_t inetcfg_sroute_create(char *name, inet_naddr_t *dest,
[8bf672d]236 inet_addr_t *router, sysarg_t *sroute_id)
237{
[1bbc6dc]238 errno_t rc;
[8bf672d]239 inet_sroute_t *sroute;
240
241 sroute = inet_sroute_new();
242 if (sroute == NULL) {
243 *sroute_id = 0;
244 return ENOMEM;
245 }
246
247 sroute->dest = *dest;
248 sroute->router = *router;
249 sroute->name = str_dup(name);
250 inet_sroute_add(sroute);
251
252 *sroute_id = sroute->id;
[1bbc6dc]253
254 rc = inet_cfg_sync(cfg);
255 if (rc != EOK) {
256 log_msg(LOG_DEFAULT, LVL_ERROR, "Error saving configuration.");
257 return rc;
258 }
259
[8bf672d]260 return EOK;
261}
262
[b7fd2a0]263static errno_t inetcfg_sroute_delete(sysarg_t sroute_id)
[8bf672d]264{
[1bbc6dc]265 errno_t rc;
[8bf672d]266 inet_sroute_t *sroute;
267
268 sroute = inet_sroute_get_by_id(sroute_id);
269 if (sroute == NULL)
270 return ENOENT;
271
272 inet_sroute_remove(sroute);
273 inet_sroute_delete(sroute);
274
[1bbc6dc]275 rc = inet_cfg_sync(cfg);
276 if (rc != EOK) {
277 log_msg(LOG_DEFAULT, LVL_ERROR, "Error saving configuration.");
278 return rc;
279 }
280
[8bf672d]281 return EOK;
282}
283
[b7fd2a0]284static errno_t inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
[8bf672d]285{
286 inet_sroute_t *sroute;
287
288 sroute = inet_sroute_get_by_id(sroute_id);
289 if (sroute == NULL)
290 return ENOENT;
291
292 srinfo->dest = sroute->dest;
293 srinfo->router = sroute->router;
294 srinfo->name = str_dup(sroute->name);
295
296 return EOK;
297}
298
[b7fd2a0]299static errno_t inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
[8bf672d]300{
301 inet_sroute_t *sroute;
302
303 sroute = inet_sroute_find_by_name(name);
304 if (sroute == NULL) {
[a1a101d]305 log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
[8bf672d]306 return ENOENT;
307 }
308
309 *sroute_id = sroute->id;
310 return EOK;
311}
312
[984a9ba]313static void inetcfg_addr_create_static_srv(ipc_call_t *icall)
[0e25780]314{
[a1a101d]315 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
[a35b458]316
[fafb8e5]317 sysarg_t link_id = ipc_get_arg1(icall);
[a35b458]318
[984a9ba]319 ipc_call_t call;
[02a09ed]320 size_t size;
[984a9ba]321 if (!async_data_write_receive(&call, &size)) {
322 async_answer_0(&call, EINVAL);
323 async_answer_0(icall, EINVAL);
[02a09ed]324 return;
325 }
[a35b458]326
[02a09ed]327 if (size != sizeof(inet_naddr_t)) {
[984a9ba]328 async_answer_0(&call, EINVAL);
329 async_answer_0(icall, EINVAL);
[02a09ed]330 return;
331 }
[a35b458]332
[02a09ed]333 inet_naddr_t naddr;
[984a9ba]334 errno_t rc = async_data_write_finalize(&call, &naddr, size);
[02a09ed]335 if (rc != EOK) {
[984a9ba]336 async_answer_0(&call, rc);
337 async_answer_0(icall, rc);
[02a09ed]338 return;
339 }
[a35b458]340
[02a09ed]341 char *name;
[291c792]342 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
343 0, NULL);
344 if (rc != EOK) {
[984a9ba]345 async_answer_0(icall, rc);
[291c792]346 return;
347 }
[a35b458]348
[02a09ed]349 sysarg_t addr_id = 0;
[291c792]350 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
351 free(name);
[984a9ba]352 async_answer_1(icall, rc, addr_id);
[0e25780]353}
354
[984a9ba]355static void inetcfg_addr_delete_srv(ipc_call_t *call)
[0e25780]356{
357 sysarg_t addr_id;
[b7fd2a0]358 errno_t rc;
[0e25780]359
[a1a101d]360 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
[0e25780]361
[fafb8e5]362 addr_id = ipc_get_arg1(call);
[0e25780]363
364 rc = inetcfg_addr_delete(addr_id);
[984a9ba]365 async_answer_0(call, rc);
[0e25780]366}
367
[984a9ba]368static void inetcfg_addr_get_srv(ipc_call_t *icall)
[0e25780]369{
[a1a101d]370 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
[a35b458]371
[fafb8e5]372 sysarg_t addr_id = ipc_get_arg1(icall);
[a35b458]373
[a2e3ee6]374 inet_addr_info_t ainfo;
[a35b458]375
[a2e3ee6]376 inet_naddr_any(&ainfo.naddr);
[0e94b979]377 ainfo.ilink = 0;
378 ainfo.name = NULL;
[a35b458]379
[b7fd2a0]380 errno_t rc = inetcfg_addr_get(addr_id, &ainfo);
[02a09ed]381 if (rc != EOK) {
[984a9ba]382 async_answer_0(icall, rc);
[02a09ed]383 return;
384 }
[a35b458]385
[984a9ba]386 ipc_call_t call;
[02a09ed]387 size_t size;
[984a9ba]388 if (!async_data_read_receive(&call, &size)) {
389 async_answer_0(&call, EREFUSED);
390 async_answer_0(icall, EREFUSED);
[0e94b979]391 return;
392 }
[a35b458]393
[02a09ed]394 if (size != sizeof(inet_naddr_t)) {
[984a9ba]395 async_answer_0(&call, EINVAL);
396 async_answer_0(icall, EINVAL);
[0e94b979]397 return;
398 }
[a35b458]399
[984a9ba]400 rc = async_data_read_finalize(&call, &ainfo.naddr, size);
[a2e3ee6]401 if (rc != EOK) {
[984a9ba]402 async_answer_0(&call, rc);
403 async_answer_0(icall, rc);
[02a09ed]404 return;
405 }
[a35b458]406
[984a9ba]407 if (!async_data_read_receive(&call, &size)) {
408 async_answer_0(&call, EREFUSED);
409 async_answer_0(icall, EREFUSED);
[a2e3ee6]410 return;
411 }
[a35b458]412
[984a9ba]413 rc = async_data_read_finalize(&call, ainfo.name,
[02a09ed]414 min(size, str_size(ainfo.name)));
[0e94b979]415 free(ainfo.name);
[a35b458]416
[02a09ed]417 if (rc != EOK) {
[984a9ba]418 async_answer_0(&call, rc);
419 async_answer_0(icall, rc);
[02a09ed]420 return;
421 }
[a35b458]422
[984a9ba]423 async_answer_1(icall, rc, ainfo.ilink);
[0e25780]424}
425
[984a9ba]426static void inetcfg_addr_get_id_srv(ipc_call_t *call)
[fa101c4]427{
428 char *name;
429 sysarg_t link_id;
430 sysarg_t addr_id;
[b7fd2a0]431 errno_t rc;
[fa101c4]432
[a1a101d]433 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
[fa101c4]434
[fafb8e5]435 link_id = ipc_get_arg1(call);
[fa101c4]436
437 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
438 0, NULL);
439 if (rc != EOK) {
[984a9ba]440 async_answer_0(call, rc);
[fa101c4]441 return;
442 }
443
444 addr_id = 0;
445 rc = inetcfg_addr_get_id(name, link_id, &addr_id);
446 free(name);
[984a9ba]447 async_answer_1(call, rc, addr_id);
[fa101c4]448}
449
[984a9ba]450static void inetcfg_get_addr_list_srv(ipc_call_t *call)
[0e25780]451{
[984a9ba]452 ipc_call_t rcall;
[0e94b979]453 size_t count;
[0e25780]454 size_t max_size;
455 size_t act_size;
456 size_t size;
457 sysarg_t *id_buf;
[b7fd2a0]458 errno_t rc;
[0e25780]459
[a1a101d]460 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
[0e25780]461
[984a9ba]462 if (!async_data_read_receive(&rcall, &max_size)) {
463 async_answer_0(&rcall, EREFUSED);
464 async_answer_0(call, EREFUSED);
[0e25780]465 return;
466 }
467
[0e94b979]468 rc = inetcfg_get_addr_list(&id_buf, &count);
[0e25780]469 if (rc != EOK) {
[984a9ba]470 async_answer_0(&rcall, rc);
471 async_answer_0(call, rc);
[0e25780]472 return;
473 }
474
[0e94b979]475 act_size = count * sizeof(sysarg_t);
[0e25780]476 size = min(act_size, max_size);
477
[984a9ba]478 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
[0e25780]479 free(id_buf);
480
[984a9ba]481 async_answer_1(call, retval, act_size);
[0e25780]482}
483
[984a9ba]484static void inetcfg_get_link_list_srv(ipc_call_t *call)
[8bf672d]485{
[984a9ba]486 ipc_call_t rcall;
[b8b1adb1]487 size_t count;
[8bf672d]488 size_t max_size;
489 size_t act_size;
490 size_t size;
491 sysarg_t *id_buf;
[b7fd2a0]492 errno_t rc;
[8bf672d]493
[b8b1adb1]494 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
[8bf672d]495
[984a9ba]496 if (!async_data_read_receive(&rcall, &max_size)) {
497 async_answer_0(&rcall, EREFUSED);
498 async_answer_0(call, EREFUSED);
[8bf672d]499 return;
500 }
501
[b8b1adb1]502 rc = inetcfg_get_link_list(&id_buf, &count);
[8bf672d]503 if (rc != EOK) {
[984a9ba]504 async_answer_0(&rcall, rc);
505 async_answer_0(call, rc);
[8bf672d]506 return;
507 }
508
[b8b1adb1]509 act_size = count * sizeof(sysarg_t);
[8bf672d]510 size = min(act_size, max_size);
511
[984a9ba]512 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
[8bf672d]513 free(id_buf);
514
[984a9ba]515 async_answer_1(call, retval, act_size);
[8bf672d]516}
517
[984a9ba]518static void inetcfg_get_sroute_list_srv(ipc_call_t *call)
[8bf672d]519{
[984a9ba]520 ipc_call_t rcall;
[8bf672d]521 size_t count;
522 size_t max_size;
523 size_t act_size;
524 size_t size;
525 sysarg_t *id_buf;
[b7fd2a0]526 errno_t rc;
[8bf672d]527
[a1a101d]528 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
[8bf672d]529
[984a9ba]530 if (!async_data_read_receive(&rcall, &max_size)) {
531 async_answer_0(&rcall, EREFUSED);
532 async_answer_0(call, EREFUSED);
[8bf672d]533 return;
534 }
535
536 rc = inetcfg_get_sroute_list(&id_buf, &count);
537 if (rc != EOK) {
[984a9ba]538 async_answer_0(&rcall, rc);
539 async_answer_0(call, rc);
[8bf672d]540 return;
541 }
542
543 act_size = count * sizeof(sysarg_t);
544 size = min(act_size, max_size);
545
[984a9ba]546 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
[8bf672d]547 free(id_buf);
548
[984a9ba]549 async_answer_1(call, retval, act_size);
[8bf672d]550}
551
[984a9ba]552static void inetcfg_link_add_srv(ipc_call_t *call)
[7af0cc5]553{
554 sysarg_t link_id;
[b7fd2a0]555 errno_t rc;
[7af0cc5]556
557 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
558
[fafb8e5]559 link_id = ipc_get_arg1(call);
[7af0cc5]560
561 rc = inetcfg_link_add(link_id);
[984a9ba]562 async_answer_0(call, rc);
[7af0cc5]563}
564
[984a9ba]565static void inetcfg_link_get_srv(ipc_call_t *call)
[0e25780]566{
[984a9ba]567 ipc_call_t name;
568 ipc_call_t laddr;
[b8b1adb1]569 size_t name_max_size;
570 size_t laddr_max_size;
[0e94b979]571
[0e25780]572 sysarg_t link_id;
573 inet_link_info_t linfo;
[b7fd2a0]574 errno_t rc;
[0e25780]575
[fafb8e5]576 link_id = ipc_get_arg1(call);
[a1a101d]577 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
[0e25780]578
[0e94b979]579 linfo.name = NULL;
580
[984a9ba]581 if (!async_data_read_receive(&name, &name_max_size)) {
582 async_answer_0(&name, EREFUSED);
583 async_answer_0(call, EREFUSED);
[b8b1adb1]584 return;
585 }
586
[984a9ba]587 if (!async_data_read_receive(&laddr, &laddr_max_size)) {
588 async_answer_0(&laddr, EREFUSED);
589 async_answer_0(&name, EREFUSED);
590 async_answer_0(call, EREFUSED);
[0e94b979]591 return;
592 }
593
[0e25780]594 rc = inetcfg_link_get(link_id, &linfo);
[0e94b979]595 if (rc != EOK) {
[984a9ba]596 async_answer_0(&laddr, rc);
597 async_answer_0(&name, rc);
598 async_answer_0(call, rc);
[0e94b979]599 return;
600 }
601
[984a9ba]602 errno_t retval = async_data_read_finalize(&name, linfo.name,
[b8b1adb1]603 min(name_max_size, str_size(linfo.name)));
604 if (retval != EOK) {
605 free(linfo.name);
[984a9ba]606 async_answer_0(&laddr, retval);
607 async_answer_0(call, retval);
[b8b1adb1]608 return;
609 }
610
[984a9ba]611 retval = async_data_read_finalize(&laddr, &linfo.mac_addr,
[b8b1adb1]612 min(laddr_max_size, sizeof(linfo.mac_addr)));
613
[0e94b979]614 free(linfo.name);
615
[984a9ba]616 async_answer_1(call, retval, linfo.def_mtu);
[0e25780]617}
618
[984a9ba]619static void inetcfg_link_remove_srv(ipc_call_t *call)
[7af0cc5]620{
621 sysarg_t link_id;
[b7fd2a0]622 errno_t rc;
[7af0cc5]623
624 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
625
[fafb8e5]626 link_id = ipc_get_arg1(call);
[7af0cc5]627
628 rc = inetcfg_link_remove(link_id);
[984a9ba]629 async_answer_0(call, rc);
[7af0cc5]630}
631
[984a9ba]632static void inetcfg_sroute_create_srv(ipc_call_t *icall)
[8bf672d]633{
[a1a101d]634 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
[02a09ed]635
[984a9ba]636 ipc_call_t call;
[02a09ed]637 size_t size;
[984a9ba]638 if (!async_data_write_receive(&call, &size)) {
639 async_answer_0(&call, EINVAL);
640 async_answer_0(icall, EINVAL);
[02a09ed]641 return;
642 }
[a35b458]643
[02a09ed]644 if (size != sizeof(inet_naddr_t)) {
[984a9ba]645 async_answer_0(&call, EINVAL);
646 async_answer_0(icall, EINVAL);
[02a09ed]647 return;
648 }
[a35b458]649
[02a09ed]650 inet_naddr_t dest;
[984a9ba]651 errno_t rc = async_data_write_finalize(&call, &dest, size);
[8bf672d]652 if (rc != EOK) {
[984a9ba]653 async_answer_0(&call, rc);
654 async_answer_0(icall, rc);
[02a09ed]655 return;
656 }
[a35b458]657
[984a9ba]658 if (!async_data_write_receive(&call, &size)) {
659 async_answer_0(&call, EINVAL);
660 async_answer_0(icall, EINVAL);
[02a09ed]661 return;
662 }
[a35b458]663
[02a09ed]664 if (size != sizeof(inet_addr_t)) {
[984a9ba]665 async_answer_0(&call, EINVAL);
666 async_answer_0(icall, EINVAL);
[8bf672d]667 return;
668 }
[a35b458]669
[a2e3ee6]670 inet_addr_t router;
[984a9ba]671 rc = async_data_write_finalize(&call, &router, size);
[02a09ed]672 if (rc != EOK) {
[984a9ba]673 async_answer_0(&call, rc);
674 async_answer_0(icall, rc);
[02a09ed]675 return;
676 }
[a35b458]677
[02a09ed]678 char *name;
679 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
680 0, NULL);
681 if (rc != EOK) {
[984a9ba]682 async_answer_0(icall, rc);
[02a09ed]683 return;
684 }
[a35b458]685
[a2e3ee6]686 sysarg_t sroute_id = 0;
[8bf672d]687 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
688 free(name);
[984a9ba]689 async_answer_1(icall, rc, sroute_id);
[8bf672d]690}
691
[984a9ba]692static void inetcfg_sroute_delete_srv(ipc_call_t *call)
[8bf672d]693{
694 sysarg_t sroute_id;
[b7fd2a0]695 errno_t rc;
[8bf672d]696
[a1a101d]697 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
[8bf672d]698
[fafb8e5]699 sroute_id = ipc_get_arg1(call);
[8bf672d]700
701 rc = inetcfg_sroute_delete(sroute_id);
[984a9ba]702 async_answer_0(call, rc);
[8bf672d]703}
704
[984a9ba]705static void inetcfg_sroute_get_srv(ipc_call_t *icall)
[0e25780]706{
[a1a101d]707 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
[a35b458]708
[fafb8e5]709 sysarg_t sroute_id = ipc_get_arg1(icall);
[a35b458]710
[a2e3ee6]711 inet_sroute_info_t srinfo;
[a35b458]712
[a2e3ee6]713 inet_naddr_any(&srinfo.dest);
714 inet_addr_any(&srinfo.router);
[8bf672d]715 srinfo.name = NULL;
[a35b458]716
[b7fd2a0]717 errno_t rc = inetcfg_sroute_get(sroute_id, &srinfo);
[02a09ed]718 if (rc != EOK) {
[984a9ba]719 async_answer_0(icall, rc);
[02a09ed]720 return;
721 }
[a35b458]722
[984a9ba]723 ipc_call_t call;
[02a09ed]724 size_t size;
[984a9ba]725 if (!async_data_read_receive(&call, &size)) {
726 async_answer_0(&call, EREFUSED);
727 async_answer_0(icall, EREFUSED);
[0e25780]728 return;
729 }
[a35b458]730
[02a09ed]731 if (size != sizeof(inet_naddr_t)) {
[984a9ba]732 async_answer_0(&call, EINVAL);
733 async_answer_0(icall, EINVAL);
[0e25780]734 return;
735 }
[a35b458]736
[984a9ba]737 rc = async_data_read_finalize(&call, &srinfo.dest, size);
[a2e3ee6]738 if (rc != EOK) {
[984a9ba]739 async_answer_0(&call, rc);
740 async_answer_0(icall, rc);
[02a09ed]741 return;
742 }
[a35b458]743
[984a9ba]744 if (!async_data_read_receive(&call, &size)) {
745 async_answer_0(&call, EREFUSED);
746 async_answer_0(icall, EREFUSED);
[02a09ed]747 return;
748 }
[a35b458]749
[02a09ed]750 if (size != sizeof(inet_addr_t)) {
[984a9ba]751 async_answer_0(&call, EINVAL);
752 async_answer_0(icall, EINVAL);
[a2e3ee6]753 return;
754 }
[a35b458]755
[984a9ba]756 rc = async_data_read_finalize(&call, &srinfo.router, size);
[a2e3ee6]757 if (rc != EOK) {
[984a9ba]758 async_answer_0(&call, rc);
759 async_answer_0(icall, rc);
[02a09ed]760 return;
761 }
[a35b458]762
[984a9ba]763 if (!async_data_read_receive(&call, &size)) {
764 async_answer_0(&call, EREFUSED);
765 async_answer_0(icall, EREFUSED);
[a2e3ee6]766 return;
767 }
[a35b458]768
[984a9ba]769 rc = async_data_read_finalize(&call, srinfo.name,
[02a09ed]770 min(size, str_size(srinfo.name)));
[8bf672d]771 free(srinfo.name);
[a35b458]772
[984a9ba]773 async_answer_0(icall, rc);
[8bf672d]774}
[0e25780]775
[984a9ba]776static void inetcfg_sroute_get_id_srv(ipc_call_t *call)
[8bf672d]777{
778 char *name;
779 sysarg_t sroute_id;
[b7fd2a0]780 errno_t rc;
[8bf672d]781
[a1a101d]782 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
[8bf672d]783
784 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
785 0, NULL);
786 if (rc != EOK) {
[984a9ba]787 async_answer_0(call, rc);
[8bf672d]788 return;
789 }
790
791 sroute_id = 0;
792 rc = inetcfg_sroute_get_id(name, &sroute_id);
793 free(name);
[984a9ba]794 async_answer_1(call, rc, sroute_id);
[0e25780]795}
796
[984a9ba]797void inet_cfg_conn(ipc_call_t *icall, void *arg)
[0e25780]798{
[a1a101d]799 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
[0e25780]800
801 /* Accept the connection */
[beb83c1]802 async_accept_0(icall);
[0e25780]803
804 while (true) {
805 ipc_call_t call;
[984a9ba]806 async_get_call(&call);
[fafb8e5]807 sysarg_t method = ipc_get_imethod(&call);
[0e25780]808
[bd88bee]809 log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
[0e25780]810 if (!method) {
811 /* The other side has hung up */
[984a9ba]812 async_answer_0(&call, EOK);
[0e25780]813 return;
814 }
815
816 switch (method) {
817 case INETCFG_ADDR_CREATE_STATIC:
[984a9ba]818 inetcfg_addr_create_static_srv(&call);
[0e25780]819 break;
820 case INETCFG_ADDR_DELETE:
[984a9ba]821 inetcfg_addr_delete_srv(&call);
[0e25780]822 break;
823 case INETCFG_ADDR_GET:
[984a9ba]824 inetcfg_addr_get_srv(&call);
[0e25780]825 break;
[fa101c4]826 case INETCFG_ADDR_GET_ID:
[984a9ba]827 inetcfg_addr_get_id_srv(&call);
[fa101c4]828 break;
[0e25780]829 case INETCFG_GET_ADDR_LIST:
[984a9ba]830 inetcfg_get_addr_list_srv(&call);
[0e25780]831 break;
832 case INETCFG_GET_LINK_LIST:
[984a9ba]833 inetcfg_get_link_list_srv(&call);
[0e25780]834 break;
[8bf672d]835 case INETCFG_GET_SROUTE_LIST:
[984a9ba]836 inetcfg_get_sroute_list_srv(&call);
[8bf672d]837 break;
[7af0cc5]838 case INETCFG_LINK_ADD:
[984a9ba]839 inetcfg_link_add_srv(&call);
[7af0cc5]840 break;
[0e25780]841 case INETCFG_LINK_GET:
[984a9ba]842 inetcfg_link_get_srv(&call);
[0e25780]843 break;
[7af0cc5]844 case INETCFG_LINK_REMOVE:
[984a9ba]845 inetcfg_link_remove_srv(&call);
[7af0cc5]846 break;
[8bf672d]847 case INETCFG_SROUTE_CREATE:
[984a9ba]848 inetcfg_sroute_create_srv(&call);
[8bf672d]849 break;
850 case INETCFG_SROUTE_DELETE:
[984a9ba]851 inetcfg_sroute_delete_srv(&call);
[8bf672d]852 break;
853 case INETCFG_SROUTE_GET:
[984a9ba]854 inetcfg_sroute_get_srv(&call);
[8bf672d]855 break;
856 case INETCFG_SROUTE_GET_ID:
[984a9ba]857 inetcfg_sroute_get_id_srv(&call);
[8bf672d]858 break;
[0e25780]859 default:
[984a9ba]860 async_answer_0(&call, EINVAL);
[0e25780]861 }
862 }
863}
864
[1bbc6dc]865static errno_t inet_cfg_load(const char *cfg_path)
866{
867 sif_doc_t *doc = NULL;
868 sif_node_t *rnode;
869 sif_node_t *naddrs;
870 sif_node_t *nroutes;
871 const char *ntype;
872 errno_t rc;
873
874 rc = sif_load(cfg_path, &doc);
875 if (rc != EOK)
876 goto error;
877
878 rnode = sif_get_root(doc);
879 naddrs = sif_node_first_child(rnode);
880 ntype = sif_node_get_type(naddrs);
881 if (str_cmp(ntype, "addresses") != 0) {
882 rc = EIO;
883 goto error;
884 }
885
886 rc = inet_addrobjs_load(naddrs);
887 if (rc != EOK)
888 goto error;
889
890 nroutes = sif_node_next_child(naddrs);
891 ntype = sif_node_get_type(nroutes);
892 if (str_cmp(ntype, "static-routes") != 0) {
893 rc = EIO;
894 goto error;
895 }
896
897 rc = inet_sroutes_load(nroutes);
898 if (rc != EOK)
899 goto error;
900
901 sif_delete(doc);
902 return EOK;
903error:
904 if (doc != NULL)
905 sif_delete(doc);
906 return rc;
907
908}
909
910static errno_t inet_cfg_save(const char *cfg_path)
911{
912 sif_doc_t *doc = NULL;
913 sif_node_t *rnode;
914 sif_node_t *nsroutes;
915 sif_node_t *naddrobjs;
916 errno_t rc;
917
918 log_msg(LOG_DEFAULT, LVL_NOTE, "inet_cfg_save(%s)", cfg_path);
919
920 rc = sif_new(&doc);
921 if (rc != EOK)
922 goto error;
923
924 rnode = sif_get_root(doc);
925
926 /* Address objects */
927
928 rc = sif_node_append_child(rnode, "addresses", &naddrobjs);
929 if (rc != EOK)
930 goto error;
931
932 rc = inet_addrobjs_save(naddrobjs);
933 if (rc != EOK)
934 goto error;
935
936 /* Static routes */
937
938 rc = sif_node_append_child(rnode, "static-routes", &nsroutes);
939 if (rc != EOK)
940 goto error;
941
942 rc = inet_sroutes_save(nsroutes);
943 if (rc != EOK)
944 goto error;
945
946 /* Save */
947
948 rc = sif_save(doc, cfg_path);
949 if (rc != EOK)
950 goto error;
951
952 sif_delete(doc);
953 return EOK;
954error:
955 if (doc != NULL)
956 sif_delete(doc);
957 return rc;
958}
959
960/** Open internet server configuration.
961 *
962 * @param cfg_path Configuration file path
963 * @param rcfg Place to store pointer to configuration object
964 * @return EOK on success or an error code
965 */
966errno_t inet_cfg_open(const char *cfg_path, inet_cfg_t **rcfg)
967{
968 inet_cfg_t *cfg;
969 errno_t rc;
970
971 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_open(%s)", cfg_path);
972
973 rc = inet_cfg_load(cfg_path);
974 if (rc != EOK) {
975 log_msg(LOG_DEFAULT, LVL_WARN, "inet_cfg_open(%s) :"
976 "could not load configuration.", cfg_path);
977 }
978
979 cfg = calloc(1, sizeof(inet_cfg_t));
980 if (cfg == NULL)
981 return ENOMEM;
982
983 cfg->cfg_path = str_dup(cfg_path);
984 if (cfg->cfg_path == NULL) {
985 free(cfg);
986 return ENOMEM;
987 }
988
989 *rcfg = cfg;
990 return EOK;
991}
992
993errno_t inet_cfg_sync(inet_cfg_t *cfg)
994{
995 log_msg(LOG_DEFAULT, LVL_NOTE, "inet_cfg_sync(cfg=%p)", cfg);
996 return inet_cfg_save(cfg->cfg_path);
997}
998
999void inet_cfg_close(inet_cfg_t *cfg)
1000{
1001 free(cfg);
1002}
1003
[0e25780]1004/** @}
1005 */
Note: See TracBrowser for help on using the repository browser.