source: mainline/uspace/srv/net/inetsrv/inetcfg.c

Last change on this file 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
Line 
1/*
2 * Copyright (c) 2024 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 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>
44#include <str.h>
45#include <stddef.h>
46#include <types/inetcfg.h>
47
48#include "addrobj.h"
49#include "inetsrv.h"
50#include "inet_link.h"
51#include "inetcfg.h"
52#include "sroute.h"
53
54static errno_t inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
55 sysarg_t link_id, sysarg_t *addr_id)
56{
57 inet_link_t *ilink;
58 inet_addrobj_t *addr;
59 inet_addr_t iaddr;
60 errno_t rc;
61
62 ilink = inet_link_get_by_id(link_id);
63 if (ilink == NULL) {
64 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
65 (unsigned long) link_id);
66 return ENOENT;
67 }
68
69 addr = inet_addrobj_new();
70 if (addr == NULL) {
71 *addr_id = 0;
72 return ENOMEM;
73 }
74
75 addr->naddr = *naddr;
76 addr->ilink = ilink;
77 addr->name = str_dup(name);
78 rc = inet_addrobj_add(addr);
79 if (rc != EOK) {
80 log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
81 inet_addrobj_delete(addr);
82 return rc;
83 }
84
85 inet_naddr_addr(&addr->naddr, &iaddr);
86 rc = iplink_addr_add(ilink->iplink, &iaddr);
87 if (rc != EOK) {
88 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
89 inet_addrobj_remove(addr);
90 inet_addrobj_delete(addr);
91 return rc;
92 }
93
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
100 return EOK;
101}
102
103static errno_t inetcfg_addr_delete(sysarg_t addr_id)
104{
105 inet_addrobj_t *addr;
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()");
112
113 addr = inet_addrobj_get_by_id(addr_id);
114 if (addr == NULL)
115 return ENOENT;
116
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
122 inet_addrobj_remove(addr);
123 inet_addrobj_delete(addr);
124
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");
151 return EOK;
152}
153
154static errno_t inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
155{
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;
167}
168
169static errno_t inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
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) {
176 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
177 return ENOENT;
178 }
179
180 addr = inet_addrobj_find_by_name(name, ilink);
181 if (addr == NULL) {
182 log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
183 return ENOENT;
184 }
185
186 *addr_id = addr->id;
187 return EOK;
188}
189
190static errno_t inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
191{
192 return inet_addrobj_get_id_list(addrs, count);
193}
194
195static errno_t inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
196{
197 return inet_link_get_id_list(addrs, count);
198}
199
200static errno_t inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
201{
202 return inet_sroute_get_id_list(sroutes, count);
203}
204
205static errno_t inetcfg_link_add(sysarg_t link_id)
206{
207 return inet_link_open(link_id);
208}
209
210static errno_t inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
211{
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);
220 linfo->def_mtu = ilink->def_mtu;
221 if (ilink->mac_valid) {
222 linfo->mac_addr = ilink->mac;
223 } else {
224 memset(&linfo->mac_addr, 0, sizeof(linfo->mac_addr));
225 }
226
227 return EOK;
228}
229
230static errno_t inetcfg_link_remove(sysarg_t link_id)
231{
232 return ENOTSUP;
233}
234
235static errno_t inetcfg_sroute_create(char *name, inet_naddr_t *dest,
236 inet_addr_t *router, sysarg_t *sroute_id)
237{
238 errno_t rc;
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;
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
260 return EOK;
261}
262
263static errno_t inetcfg_sroute_delete(sysarg_t sroute_id)
264{
265 errno_t rc;
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
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
281 return EOK;
282}
283
284static errno_t inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
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
299static errno_t inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
300{
301 inet_sroute_t *sroute;
302
303 sroute = inet_sroute_find_by_name(name);
304 if (sroute == NULL) {
305 log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
306 return ENOENT;
307 }
308
309 *sroute_id = sroute->id;
310 return EOK;
311}
312
313static void inetcfg_addr_create_static_srv(ipc_call_t *icall)
314{
315 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
316
317 sysarg_t link_id = ipc_get_arg1(icall);
318
319 ipc_call_t call;
320 size_t size;
321 if (!async_data_write_receive(&call, &size)) {
322 async_answer_0(&call, EINVAL);
323 async_answer_0(icall, EINVAL);
324 return;
325 }
326
327 if (size != sizeof(inet_naddr_t)) {
328 async_answer_0(&call, EINVAL);
329 async_answer_0(icall, EINVAL);
330 return;
331 }
332
333 inet_naddr_t naddr;
334 errno_t rc = async_data_write_finalize(&call, &naddr, size);
335 if (rc != EOK) {
336 async_answer_0(&call, rc);
337 async_answer_0(icall, rc);
338 return;
339 }
340
341 char *name;
342 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
343 0, NULL);
344 if (rc != EOK) {
345 async_answer_0(icall, rc);
346 return;
347 }
348
349 sysarg_t addr_id = 0;
350 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
351 free(name);
352 async_answer_1(icall, rc, addr_id);
353}
354
355static void inetcfg_addr_delete_srv(ipc_call_t *call)
356{
357 sysarg_t addr_id;
358 errno_t rc;
359
360 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
361
362 addr_id = ipc_get_arg1(call);
363
364 rc = inetcfg_addr_delete(addr_id);
365 async_answer_0(call, rc);
366}
367
368static void inetcfg_addr_get_srv(ipc_call_t *icall)
369{
370 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
371
372 sysarg_t addr_id = ipc_get_arg1(icall);
373
374 inet_addr_info_t ainfo;
375
376 inet_naddr_any(&ainfo.naddr);
377 ainfo.ilink = 0;
378 ainfo.name = NULL;
379
380 errno_t rc = inetcfg_addr_get(addr_id, &ainfo);
381 if (rc != EOK) {
382 async_answer_0(icall, rc);
383 return;
384 }
385
386 ipc_call_t call;
387 size_t size;
388 if (!async_data_read_receive(&call, &size)) {
389 async_answer_0(&call, EREFUSED);
390 async_answer_0(icall, EREFUSED);
391 return;
392 }
393
394 if (size != sizeof(inet_naddr_t)) {
395 async_answer_0(&call, EINVAL);
396 async_answer_0(icall, EINVAL);
397 return;
398 }
399
400 rc = async_data_read_finalize(&call, &ainfo.naddr, size);
401 if (rc != EOK) {
402 async_answer_0(&call, rc);
403 async_answer_0(icall, rc);
404 return;
405 }
406
407 if (!async_data_read_receive(&call, &size)) {
408 async_answer_0(&call, EREFUSED);
409 async_answer_0(icall, EREFUSED);
410 return;
411 }
412
413 rc = async_data_read_finalize(&call, ainfo.name,
414 min(size, str_size(ainfo.name)));
415 free(ainfo.name);
416
417 if (rc != EOK) {
418 async_answer_0(&call, rc);
419 async_answer_0(icall, rc);
420 return;
421 }
422
423 async_answer_1(icall, rc, ainfo.ilink);
424}
425
426static void inetcfg_addr_get_id_srv(ipc_call_t *call)
427{
428 char *name;
429 sysarg_t link_id;
430 sysarg_t addr_id;
431 errno_t rc;
432
433 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
434
435 link_id = ipc_get_arg1(call);
436
437 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
438 0, NULL);
439 if (rc != EOK) {
440 async_answer_0(call, rc);
441 return;
442 }
443
444 addr_id = 0;
445 rc = inetcfg_addr_get_id(name, link_id, &addr_id);
446 free(name);
447 async_answer_1(call, rc, addr_id);
448}
449
450static void inetcfg_get_addr_list_srv(ipc_call_t *call)
451{
452 ipc_call_t rcall;
453 size_t count;
454 size_t max_size;
455 size_t act_size;
456 size_t size;
457 sysarg_t *id_buf;
458 errno_t rc;
459
460 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
461
462 if (!async_data_read_receive(&rcall, &max_size)) {
463 async_answer_0(&rcall, EREFUSED);
464 async_answer_0(call, EREFUSED);
465 return;
466 }
467
468 rc = inetcfg_get_addr_list(&id_buf, &count);
469 if (rc != EOK) {
470 async_answer_0(&rcall, rc);
471 async_answer_0(call, rc);
472 return;
473 }
474
475 act_size = count * sizeof(sysarg_t);
476 size = min(act_size, max_size);
477
478 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
479 free(id_buf);
480
481 async_answer_1(call, retval, act_size);
482}
483
484static void inetcfg_get_link_list_srv(ipc_call_t *call)
485{
486 ipc_call_t rcall;
487 size_t count;
488 size_t max_size;
489 size_t act_size;
490 size_t size;
491 sysarg_t *id_buf;
492 errno_t rc;
493
494 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
495
496 if (!async_data_read_receive(&rcall, &max_size)) {
497 async_answer_0(&rcall, EREFUSED);
498 async_answer_0(call, EREFUSED);
499 return;
500 }
501
502 rc = inetcfg_get_link_list(&id_buf, &count);
503 if (rc != EOK) {
504 async_answer_0(&rcall, rc);
505 async_answer_0(call, rc);
506 return;
507 }
508
509 act_size = count * sizeof(sysarg_t);
510 size = min(act_size, max_size);
511
512 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
513 free(id_buf);
514
515 async_answer_1(call, retval, act_size);
516}
517
518static void inetcfg_get_sroute_list_srv(ipc_call_t *call)
519{
520 ipc_call_t rcall;
521 size_t count;
522 size_t max_size;
523 size_t act_size;
524 size_t size;
525 sysarg_t *id_buf;
526 errno_t rc;
527
528 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
529
530 if (!async_data_read_receive(&rcall, &max_size)) {
531 async_answer_0(&rcall, EREFUSED);
532 async_answer_0(call, EREFUSED);
533 return;
534 }
535
536 rc = inetcfg_get_sroute_list(&id_buf, &count);
537 if (rc != EOK) {
538 async_answer_0(&rcall, rc);
539 async_answer_0(call, rc);
540 return;
541 }
542
543 act_size = count * sizeof(sysarg_t);
544 size = min(act_size, max_size);
545
546 errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
547 free(id_buf);
548
549 async_answer_1(call, retval, act_size);
550}
551
552static void inetcfg_link_add_srv(ipc_call_t *call)
553{
554 sysarg_t link_id;
555 errno_t rc;
556
557 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
558
559 link_id = ipc_get_arg1(call);
560
561 rc = inetcfg_link_add(link_id);
562 async_answer_0(call, rc);
563}
564
565static void inetcfg_link_get_srv(ipc_call_t *call)
566{
567 ipc_call_t name;
568 ipc_call_t laddr;
569 size_t name_max_size;
570 size_t laddr_max_size;
571
572 sysarg_t link_id;
573 inet_link_info_t linfo;
574 errno_t rc;
575
576 link_id = ipc_get_arg1(call);
577 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
578
579 linfo.name = NULL;
580
581 if (!async_data_read_receive(&name, &name_max_size)) {
582 async_answer_0(&name, EREFUSED);
583 async_answer_0(call, EREFUSED);
584 return;
585 }
586
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);
591 return;
592 }
593
594 rc = inetcfg_link_get(link_id, &linfo);
595 if (rc != EOK) {
596 async_answer_0(&laddr, rc);
597 async_answer_0(&name, rc);
598 async_answer_0(call, rc);
599 return;
600 }
601
602 errno_t retval = async_data_read_finalize(&name, linfo.name,
603 min(name_max_size, str_size(linfo.name)));
604 if (retval != EOK) {
605 free(linfo.name);
606 async_answer_0(&laddr, retval);
607 async_answer_0(call, retval);
608 return;
609 }
610
611 retval = async_data_read_finalize(&laddr, &linfo.mac_addr,
612 min(laddr_max_size, sizeof(linfo.mac_addr)));
613
614 free(linfo.name);
615
616 async_answer_1(call, retval, linfo.def_mtu);
617}
618
619static void inetcfg_link_remove_srv(ipc_call_t *call)
620{
621 sysarg_t link_id;
622 errno_t rc;
623
624 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
625
626 link_id = ipc_get_arg1(call);
627
628 rc = inetcfg_link_remove(link_id);
629 async_answer_0(call, rc);
630}
631
632static void inetcfg_sroute_create_srv(ipc_call_t *icall)
633{
634 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
635
636 ipc_call_t call;
637 size_t size;
638 if (!async_data_write_receive(&call, &size)) {
639 async_answer_0(&call, EINVAL);
640 async_answer_0(icall, EINVAL);
641 return;
642 }
643
644 if (size != sizeof(inet_naddr_t)) {
645 async_answer_0(&call, EINVAL);
646 async_answer_0(icall, EINVAL);
647 return;
648 }
649
650 inet_naddr_t dest;
651 errno_t rc = async_data_write_finalize(&call, &dest, size);
652 if (rc != EOK) {
653 async_answer_0(&call, rc);
654 async_answer_0(icall, rc);
655 return;
656 }
657
658 if (!async_data_write_receive(&call, &size)) {
659 async_answer_0(&call, EINVAL);
660 async_answer_0(icall, EINVAL);
661 return;
662 }
663
664 if (size != sizeof(inet_addr_t)) {
665 async_answer_0(&call, EINVAL);
666 async_answer_0(icall, EINVAL);
667 return;
668 }
669
670 inet_addr_t router;
671 rc = async_data_write_finalize(&call, &router, size);
672 if (rc != EOK) {
673 async_answer_0(&call, rc);
674 async_answer_0(icall, rc);
675 return;
676 }
677
678 char *name;
679 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
680 0, NULL);
681 if (rc != EOK) {
682 async_answer_0(icall, rc);
683 return;
684 }
685
686 sysarg_t sroute_id = 0;
687 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
688 free(name);
689 async_answer_1(icall, rc, sroute_id);
690}
691
692static void inetcfg_sroute_delete_srv(ipc_call_t *call)
693{
694 sysarg_t sroute_id;
695 errno_t rc;
696
697 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
698
699 sroute_id = ipc_get_arg1(call);
700
701 rc = inetcfg_sroute_delete(sroute_id);
702 async_answer_0(call, rc);
703}
704
705static void inetcfg_sroute_get_srv(ipc_call_t *icall)
706{
707 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
708
709 sysarg_t sroute_id = ipc_get_arg1(icall);
710
711 inet_sroute_info_t srinfo;
712
713 inet_naddr_any(&srinfo.dest);
714 inet_addr_any(&srinfo.router);
715 srinfo.name = NULL;
716
717 errno_t rc = inetcfg_sroute_get(sroute_id, &srinfo);
718 if (rc != EOK) {
719 async_answer_0(icall, rc);
720 return;
721 }
722
723 ipc_call_t call;
724 size_t size;
725 if (!async_data_read_receive(&call, &size)) {
726 async_answer_0(&call, EREFUSED);
727 async_answer_0(icall, EREFUSED);
728 return;
729 }
730
731 if (size != sizeof(inet_naddr_t)) {
732 async_answer_0(&call, EINVAL);
733 async_answer_0(icall, EINVAL);
734 return;
735 }
736
737 rc = async_data_read_finalize(&call, &srinfo.dest, size);
738 if (rc != EOK) {
739 async_answer_0(&call, rc);
740 async_answer_0(icall, rc);
741 return;
742 }
743
744 if (!async_data_read_receive(&call, &size)) {
745 async_answer_0(&call, EREFUSED);
746 async_answer_0(icall, EREFUSED);
747 return;
748 }
749
750 if (size != sizeof(inet_addr_t)) {
751 async_answer_0(&call, EINVAL);
752 async_answer_0(icall, EINVAL);
753 return;
754 }
755
756 rc = async_data_read_finalize(&call, &srinfo.router, size);
757 if (rc != EOK) {
758 async_answer_0(&call, rc);
759 async_answer_0(icall, rc);
760 return;
761 }
762
763 if (!async_data_read_receive(&call, &size)) {
764 async_answer_0(&call, EREFUSED);
765 async_answer_0(icall, EREFUSED);
766 return;
767 }
768
769 rc = async_data_read_finalize(&call, srinfo.name,
770 min(size, str_size(srinfo.name)));
771 free(srinfo.name);
772
773 async_answer_0(icall, rc);
774}
775
776static void inetcfg_sroute_get_id_srv(ipc_call_t *call)
777{
778 char *name;
779 sysarg_t sroute_id;
780 errno_t rc;
781
782 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
783
784 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
785 0, NULL);
786 if (rc != EOK) {
787 async_answer_0(call, rc);
788 return;
789 }
790
791 sroute_id = 0;
792 rc = inetcfg_sroute_get_id(name, &sroute_id);
793 free(name);
794 async_answer_1(call, rc, sroute_id);
795}
796
797void inet_cfg_conn(ipc_call_t *icall, void *arg)
798{
799 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
800
801 /* Accept the connection */
802 async_accept_0(icall);
803
804 while (true) {
805 ipc_call_t call;
806 async_get_call(&call);
807 sysarg_t method = ipc_get_imethod(&call);
808
809 log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
810 if (!method) {
811 /* The other side has hung up */
812 async_answer_0(&call, EOK);
813 return;
814 }
815
816 switch (method) {
817 case INETCFG_ADDR_CREATE_STATIC:
818 inetcfg_addr_create_static_srv(&call);
819 break;
820 case INETCFG_ADDR_DELETE:
821 inetcfg_addr_delete_srv(&call);
822 break;
823 case INETCFG_ADDR_GET:
824 inetcfg_addr_get_srv(&call);
825 break;
826 case INETCFG_ADDR_GET_ID:
827 inetcfg_addr_get_id_srv(&call);
828 break;
829 case INETCFG_GET_ADDR_LIST:
830 inetcfg_get_addr_list_srv(&call);
831 break;
832 case INETCFG_GET_LINK_LIST:
833 inetcfg_get_link_list_srv(&call);
834 break;
835 case INETCFG_GET_SROUTE_LIST:
836 inetcfg_get_sroute_list_srv(&call);
837 break;
838 case INETCFG_LINK_ADD:
839 inetcfg_link_add_srv(&call);
840 break;
841 case INETCFG_LINK_GET:
842 inetcfg_link_get_srv(&call);
843 break;
844 case INETCFG_LINK_REMOVE:
845 inetcfg_link_remove_srv(&call);
846 break;
847 case INETCFG_SROUTE_CREATE:
848 inetcfg_sroute_create_srv(&call);
849 break;
850 case INETCFG_SROUTE_DELETE:
851 inetcfg_sroute_delete_srv(&call);
852 break;
853 case INETCFG_SROUTE_GET:
854 inetcfg_sroute_get_srv(&call);
855 break;
856 case INETCFG_SROUTE_GET_ID:
857 inetcfg_sroute_get_id_srv(&call);
858 break;
859 default:
860 async_answer_0(&call, EINVAL);
861 }
862 }
863}
864
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
1004/** @}
1005 */
Note: See TracBrowser for help on using the repository browser.