Changeset 1bbc6dc in mainline


Ignore:
Timestamp:
2024-09-17T06:44:46Z (5 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
9aa51406
Parents:
096c0786
git-author:
Jiri Svoboda <jiri@…> (2024-09-16 18:44:38)
git-committer:
Jiri Svoboda <jiri@…> (2024-09-17 06:44:46)
Message:

Network configuration persistence.

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

Location:
uspace
Files:
5 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/init/init.c

    r096c0786 r1bbc6dc  
    509509        srv_start("/srv/net/loopip");
    510510        srv_start("/srv/net/ethip");
     511        srv_start("/srv/net/dhcp");
    511512        srv_start("/srv/net/inetsrv");
    512513        srv_start("/srv/net/tcp");
    513514        srv_start("/srv/net/udp");
    514515        srv_start("/srv/net/dnsrsrv");
    515         srv_start("/srv/net/dhcp");
    516         srv_start("/srv/net/nconfsrv");
    517516
    518517        srv_start("/srv/clipboard");
  • uspace/srv/meson.build

    r096c0786 r1bbc6dc  
    6161        'net/inetsrv',
    6262        'net/loopip',
    63         'net/nconfsrv',
    6463        'net/slip',
    6564        'net/tcp',
  • uspace/srv/net/dhcp/dhcp.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    7171static list_t dhcp_links;
    7272
     73bool inetcfg_inited = false;
     74
    7375static void dhcpsrv_discover_timeout(void *);
    7476static void dhcpsrv_request_timeout(void *);
     
    468470        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id);
    469471
     472        if (!inetcfg_inited) {
     473                rc = inetcfg_init();
     474                if (rc != EOK) {
     475                        log_msg(LOG_DEFAULT, LVL_ERROR, "Error contacting "
     476                            "inet configuration service.\n");
     477                        return EIO;
     478                }
     479
     480                inetcfg_inited = true;
     481        }
     482
    470483        if (dhcpsrv_link_find(link_id) != NULL) {
    471484                log_msg(LOG_DEFAULT, LVL_NOTE, "Link %zu already added",
  • uspace/srv/net/dhcp/main.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#include <str_error.h>
    3939#include <io/log.h>
    40 #include <inet/inetcfg.h>
    4140#include <ipc/dhcp.h>
    4241#include <ipc/services.h>
     
    6059
    6160        dhcpsrv_links_init();
    62 
    63         rc = inetcfg_init();
    64         if (rc != EOK) {
    65                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error contacting inet configuration service.\n");
    66                 return EIO;
    67         }
    6861
    6962        async_set_fallback_port_handler(dhcp_client_conn, NULL);
  • uspace/srv/net/doc/doxygroups.h

    r096c0786 r1bbc6dc  
    2020/**    @addtogroup slip slip
    2121 *     @brief SLIP service
    22  *     @ingroup net
    23  */
    24 
    25 /**    @addtogroup nconfsrv nconfsrv
    26  *     @brief Network configuration service
    2722 *     @ingroup net
    2823 */
  • uspace/srv/net/inetsrv/addrobj.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <io/log.h>
    4242#include <ipc/loc.h>
     43#include <sif.h>
     44#include <stdio.h>
    4345#include <stdlib.h>
    4446#include <str.h>
     
    211213}
    212214
     215/** Count number of non-temporary address objects configured for link.
     216 *
     217 * @param ilink Inet link
     218 * @return Number of address objects configured for this link
     219 */
     220unsigned inet_addrobj_cnt_by_link(inet_link_t *ilink)
     221{
     222        unsigned cnt;
     223
     224        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_cnt_by_link()");
     225
     226        fibril_mutex_lock(&addr_list_lock);
     227
     228        cnt = 0;
     229        list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
     230                if (naddr->ilink == ilink && naddr->temp == false)
     231                        ++cnt;
     232        }
     233
     234        fibril_mutex_unlock(&addr_list_lock);
     235        return cnt;
     236}
     237
    213238/** Send datagram from address object */
    214239errno_t inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
     
    282307}
    283308
     309/** Load address object from SIF node.
     310 *
     311 * @param anode SIF node to load address object from
     312 * @return EOK on success or an error code
     313 */
     314static errno_t inet_addrobj_load(sif_node_t *anode)
     315{
     316        errno_t rc;
     317        const char *sid;
     318        const char *snaddr;
     319        const char *slink;
     320        const char *name;
     321        char *endptr;
     322        int id;
     323        inet_naddr_t naddr;
     324        inet_addrobj_t *addr;
     325        inet_link_t *link;
     326
     327        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_load()");
     328
     329        sid = sif_node_get_attr(anode, "id");
     330        if (sid == NULL)
     331                return EIO;
     332
     333        snaddr = sif_node_get_attr(anode, "naddr");
     334        if (snaddr == NULL)
     335                return EIO;
     336
     337        slink = sif_node_get_attr(anode, "link");
     338        if (slink == NULL)
     339                return EIO;
     340
     341        name = sif_node_get_attr(anode, "name");
     342        if (name == NULL)
     343                return EIO;
     344
     345        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_addrobj_load(): id='%s' "
     346            "naddr='%s' link='%s' name='%s'", sid, snaddr, slink, name);
     347
     348        id = strtoul(sid, &endptr, 10);
     349        if (*endptr != '\0')
     350                return EIO;
     351
     352        rc = inet_naddr_parse(snaddr, &naddr, NULL);
     353        if (rc != EOK)
     354                return EIO;
     355
     356        link = inet_link_get_by_svc_name(slink);
     357        if (link == NULL) {
     358                log_msg(LOG_DEFAULT, LVL_ERROR, "Link '%s' not found",
     359                    slink);
     360                return EIO;
     361        }
     362
     363        addr = inet_addrobj_new();
     364        if (addr == NULL)
     365                return ENOMEM;
     366
     367        addr->id = id;
     368        addr->naddr = naddr;
     369        addr->ilink = link;
     370        addr->name = str_dup(name);
     371
     372        if (addr->name == NULL) {
     373                inet_addrobj_delete(addr);
     374                return ENOMEM;
     375        }
     376
     377        inet_addrobj_add(addr);
     378        return EOK;
     379}
     380
     381/** Load address objects from SIF node.
     382 *
     383 * @param naddrs SIF node to load address objects from
     384 * @return EOK on success or an error code
     385 */
     386errno_t inet_addrobjs_load(sif_node_t *naddrs)
     387{
     388        sif_node_t *naddr;
     389        const char *ntype;
     390        errno_t rc;
     391
     392        naddr = sif_node_first_child(naddrs);
     393        while (naddr != NULL) {
     394                ntype = sif_node_get_type(naddr);
     395                if (str_cmp(ntype, "address") != 0) {
     396                        rc = EIO;
     397                        goto error;
     398                }
     399
     400                rc = inet_addrobj_load(naddr);
     401                if (rc != EOK)
     402                        goto error;
     403
     404                naddr = sif_node_next_child(naddr);
     405        }
     406
     407        return EOK;
     408error:
     409        return rc;
     410
     411}
     412
     413/** Save address object to SIF node.
     414 *
     415 * @param addr Address object
     416 * @param naddr SIF node to save addres to
     417 * @return EOK on success or an error code
     418 */
     419static errno_t inet_addrobj_save(inet_addrobj_t *addr, sif_node_t *naddr)
     420{
     421        char *str = NULL;
     422        errno_t rc;
     423        int rv;
     424
     425        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_save(%p, %p)",
     426            addr, naddr);
     427
     428        /* id */
     429
     430        rv = asprintf(&str, "%lu", addr->id);
     431        if (rv < 0) {
     432                str = NULL;
     433                rc = ENOMEM;
     434                goto error;
     435        }
     436
     437        rc = sif_node_set_attr(naddr, "id", str);
     438        if (rc != EOK)
     439                goto error;
     440
     441        free(str);
     442        str = NULL;
     443
     444        /* dest */
     445
     446        rc = inet_naddr_format(&addr->naddr, &str);
     447        if (rc != EOK)
     448                goto error;
     449
     450        rc = sif_node_set_attr(naddr, "naddr", str);
     451        if (rc != EOK)
     452                goto error;
     453
     454        free(str);
     455        str = NULL;
     456
     457        /* link */
     458
     459        rc = sif_node_set_attr(naddr, "link", addr->ilink->svc_name);
     460        if (rc != EOK)
     461                goto error;
     462
     463        /* name */
     464
     465        rc = sif_node_set_attr(naddr, "name", addr->name);
     466        if (rc != EOK)
     467                goto error;
     468
     469        free(str);
     470
     471        return rc;
     472error:
     473        if (str != NULL)
     474                free(str);
     475        return rc;
     476}
     477
     478/** Save address objects to SIF node.
     479 *
     480 * @param cnode SIF node to save address objects to
     481 * @return EOK on success or an error code
     482 */
     483errno_t inet_addrobjs_save(sif_node_t *cnode)
     484{
     485        sif_node_t *naddr;
     486        errno_t rc;
     487
     488        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobjs_save()");
     489
     490        fibril_mutex_lock(&addr_list_lock);
     491
     492        list_foreach(addr_list, addr_list, inet_addrobj_t, addr) {
     493                if (addr->temp == false) {
     494                        rc = sif_node_append_child(cnode, "address", &naddr);
     495                        if (rc != EOK)
     496                                goto error;
     497
     498                        rc = inet_addrobj_save(addr, naddr);
     499                        if (rc != EOK)
     500                                goto error;
     501                }
     502        }
     503
     504        fibril_mutex_unlock(&addr_list_lock);
     505        return EOK;
     506error:
     507        fibril_mutex_unlock(&addr_list_lock);
     508        return rc;
     509}
     510
    284511/** @}
    285512 */
  • uspace/srv/net/inetsrv/addrobj.h

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#define INET_ADDROBJ_H_
    3939
     40#include <sif.h>
    4041#include <stddef.h>
    4142#include <stdint.h>
     
    5657extern inet_addrobj_t *inet_addrobj_find_by_name(const char *, inet_link_t *);
    5758extern inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t);
     59extern unsigned inet_addrobj_cnt_by_link(inet_link_t *);
    5860extern errno_t inet_addrobj_send_dgram(inet_addrobj_t *, inet_addr_t *,
    5961    inet_dgram_t *, uint8_t, uint8_t, int);
    6062extern errno_t inet_addrobj_get_id_list(sysarg_t **, size_t *);
     63extern errno_t inet_addrobjs_load(sif_node_t *);
     64extern errno_t inet_addrobjs_save(sif_node_t *);
    6165
    6266#endif
  • uspace/srv/net/inetsrv/inet_link.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3737#include <errno.h>
    3838#include <fibril_synch.h>
     39#include <inet/dhcp.h>
    3940#include <inet/eth_addr.h>
    4041#include <inet/iplink.h>
     
    164165}
    165166
    166 errno_t inet_link_open(service_id_t sid)
     167/** Open new IP link while inet_links_lock is held.
     168 *
     169 * @param sid IP link service ID
     170 * @return EOK on success or an error code
     171 */
     172static errno_t inet_link_open_locked(service_id_t sid)
    167173{
    168174        inet_link_t *ilink;
     
    170176        errno_t rc;
    171177
    172         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_link_open()");
     178        assert(fibril_mutex_is_locked(&inet_links_lock));
     179
     180        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_link_open_locked()");
    173181        ilink = inet_link_new();
    174182        if (ilink == NULL)
     
    213221        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    214222
    215         fibril_mutex_lock(&inet_links_lock);
    216 
    217223        if (inet_link_get_by_id_locked(sid) != NULL) {
    218                 fibril_mutex_unlock(&inet_links_lock);
    219224                log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu already open",
    220225                    sid);
     
    224229
    225230        list_append(&ilink->link_list, &inet_links);
    226         fibril_mutex_unlock(&inet_links_lock);
    227231
    228232        inet_addrobj_t *addr = NULL;
     
    239243                addr->ilink = ilink;
    240244                addr->name = str_dup("v4a");
     245                addr->temp = true;
    241246
    242247                rc = inet_addrobj_add(addr);
     
    275280                addr6->ilink = ilink;
    276281                addr6->name = str_dup("v6a");
     282                addr6->temp = true;
    277283
    278284                rc = inet_addrobj_add(addr6);
     
    303309}
    304310
     311/** Open new IP link..
     312 *
     313 * @param sid IP link service ID
     314 * @return EOK on success or an error code
     315 */
     316errno_t inet_link_open(service_id_t sid)
     317{
     318        errno_t rc;
     319
     320        fibril_mutex_lock(&inet_links_lock);
     321        rc = inet_link_open_locked(sid);
     322        fibril_mutex_unlock(&inet_links_lock);
     323
     324        return rc;
     325}
     326
    305327/** Send IPv4 datagram over Internet link
    306328 *
     
    476498}
    477499
     500/** Find link by service name while inet_links_lock is held.
     501 *
     502 * @param svc_name Service name
     503 * @return Link or @c NULL if not found
     504 */
     505static inet_link_t *inet_link_get_by_svc_name_locked(const char *svc_name)
     506{
     507        assert(fibril_mutex_is_locked(&inet_links_lock));
     508
     509        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     510                if (str_cmp(ilink->svc_name, svc_name) == 0)
     511                        return ilink;
     512        }
     513
     514        return NULL;
     515}
     516
     517/** Find link by service name.
     518 *
     519 * @param svc_name Service name
     520 * @return Link or @c NULL if not found
     521 */
     522inet_link_t *inet_link_get_by_svc_name(const char *svc_name)
     523{
     524        inet_link_t *ilink;
     525
     526        fibril_mutex_lock(&inet_links_lock);
     527        ilink = inet_link_get_by_svc_name_locked(svc_name);
     528        fibril_mutex_unlock(&inet_links_lock);
     529
     530        return ilink;
     531}
     532
    478533/** Get IDs of all links. */
    479534errno_t inet_link_get_id_list(sysarg_t **rid_list, size_t *rcount)
     
    504559}
    505560
     561/** Check for new IP links.
     562 *
     563 * @return EOK on success or an error code
     564 */
     565static errno_t inet_link_check_new(void)
     566{
     567        bool already_known;
     568        category_id_t iplink_cat;
     569        service_id_t *svcs;
     570        inet_link_cfg_info_t info;
     571        size_t count, i;
     572        errno_t rc;
     573
     574        fibril_mutex_lock(&inet_links_lock);
     575
     576        rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
     577        if (rc != EOK) {
     578                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category "
     579                    "'iplink'.");
     580                fibril_mutex_unlock(&inet_links_lock);
     581                return ENOENT;
     582        }
     583
     584        rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
     585        if (rc != EOK) {
     586                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting list of IP "
     587                    "links.");
     588                fibril_mutex_unlock(&inet_links_lock);
     589                return EIO;
     590        }
     591
     592        for (i = 0; i < count; i++) {
     593                already_known = false;
     594
     595                list_foreach(inet_links, link_list, inet_link_t, ilink) {
     596                        if (ilink->svc_id == svcs[i]) {
     597                                already_known = true;
     598                                break;
     599                        }
     600                }
     601
     602                if (!already_known) {
     603                        log_msg(LOG_DEFAULT, LVL_NOTE, "Found IP link '%lu'",
     604                            (unsigned long) svcs[i]);
     605                        rc = inet_link_open_locked(svcs[i]);
     606                        if (rc != EOK) {
     607                                log_msg(LOG_DEFAULT, LVL_ERROR, "Could not "
     608                                    "add IP link.");
     609                        }
     610                } else {
     611                        /* Clear so it won't be autoconfigured below */
     612                        svcs[i] = 0;
     613                }
     614        }
     615
     616        fibril_mutex_unlock(&inet_links_lock);
     617
     618        /*
     619         * Auto-configure new links. Note that newly discovered links
     620         * cannot have any configured address objects, because we only
     621         * retain configuration for present links.
     622         */
     623        for (i = 0; i < count; i++) {
     624                if (svcs[i] != 0) {
     625                        info.svc_id = svcs[i];
     626                        rc = loc_service_get_name(info.svc_id, &info.svc_name);
     627                        if (rc != EOK) {
     628                                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed "
     629                                    "getting service name.");
     630                                return rc;
     631                        }
     632
     633                        inet_link_autoconf_link(&info);
     634                        free(info.svc_name);
     635                        info.svc_name = NULL;
     636                }
     637        }
     638
     639        return EOK;
     640}
     641
     642/** IP link category change callback.
     643 *
     644 * @param arg Not used
     645 */
     646static void inet_link_cat_change_cb(void *arg)
     647{
     648        (void) inet_link_check_new();
     649}
     650
     651/** Start IP link discovery.
     652 *
     653 * @return EOK on success or an error code
     654 */
     655errno_t inet_link_discovery_start(void)
     656{
     657        errno_t rc;
     658
     659        rc = loc_register_cat_change_cb(inet_link_cat_change_cb, NULL);
     660        if (rc != EOK) {
     661                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering callback "
     662                    "for IP link discovery: %s.", str_error(rc));
     663                return rc;
     664        }
     665
     666        return inet_link_check_new();
     667}
     668
     669/** Start DHCP autoconfiguration on IP link.
     670 *
     671 * @param info Link information
     672 */
     673void inet_link_autoconf_link(inet_link_cfg_info_t *info)
     674{
     675        errno_t rc;
     676
     677        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf_link");
     678
     679        if (str_lcmp(info->svc_name, "net/eth", str_length("net/eth")) == 0) {
     680                log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf_link : dhcp link add for link '%s' (%u)",
     681                    info->svc_name, (unsigned)info->svc_id);
     682                rc = dhcp_link_add(info->svc_id);
     683                log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf_link : dhcp link add for link '%s' (%u) DONE",
     684                    info->svc_name, (unsigned)info->svc_id);
     685                if (rc != EOK) {
     686                        log_msg(LOG_DEFAULT, LVL_WARN, "Failed configuring "
     687                            "DHCP on  link '%s'.\n", info->svc_name);
     688                }
     689        }
     690}
     691
     692/** Start DHCP autoconfiguration on IP links. */
     693errno_t inet_link_autoconf(void)
     694{
     695        inet_link_cfg_info_t *link_info;
     696        size_t link_cnt;
     697        size_t acnt;
     698        size_t i;
     699        errno_t rc;
     700
     701        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf : initialize DHCP");
     702        rc = dhcp_init();
     703        if (rc != EOK) {
     704                log_msg(LOG_DEFAULT, LVL_WARN, "Failed initializing DHCP "
     705                    "service.");
     706                return rc;
     707        }
     708
     709        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf : initialize DHCP done");
     710
     711        fibril_mutex_lock(&inet_links_lock);
     712        link_cnt = list_count(&inet_links);
     713
     714        link_info = calloc(link_cnt, sizeof(inet_link_cfg_info_t));
     715        if (link_info == NULL) {
     716                fibril_mutex_unlock(&inet_links_lock);
     717                return ENOMEM;
     718        }
     719
     720        i = 0;
     721        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     722                assert(i < link_cnt);
     723
     724                acnt = inet_addrobj_cnt_by_link(ilink);
     725                if (acnt != 0) {
     726                        /*
     727                         * No autoconfiguration if link has configured
     728                         * addresses.
     729                         */
     730                        continue;
     731                }
     732
     733                link_info[i].svc_id = ilink->svc_id;
     734                link_info[i].svc_name = str_dup(ilink->svc_name);
     735                if (link_info[i].svc_name == NULL) {
     736                        fibril_mutex_unlock(&inet_links_lock);
     737                        goto error;
     738                }
     739
     740                ++i;
     741        }
     742
     743        fibril_mutex_unlock(&inet_links_lock);
     744
     745        /* Update link_cnt to include only links slated for autoconfig. */
     746        link_cnt = i;
     747
     748        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf : autoconf links...");
     749
     750        for (i = 0; i < link_cnt; i++)
     751                inet_link_autoconf_link(&link_info[i]);
     752
     753        for (i = 0; i < link_cnt; i++) {
     754                if (link_info[i].svc_name != NULL)
     755                        free(link_info[i].svc_name);
     756        }
     757
     758        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_link_autoconf : autoconf links done");
     759        return EOK;
     760error:
     761        for (i = 0; i < link_cnt; i++) {
     762                if (link_info[i].svc_name != NULL)
     763                        free(link_info[i].svc_name);
     764        }
     765        free(link_info);
     766        return ENOMEM;
     767}
     768
    506769/** @}
    507770 */
  • uspace/srv/net/inetsrv/inet_link.h

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4949    uint8_t, uint8_t, int);
    5050extern inet_link_t *inet_link_get_by_id(sysarg_t);
     51extern inet_link_t *inet_link_get_by_svc_name(const char *);
    5152extern errno_t inet_link_get_id_list(sysarg_t **, size_t *);
     53extern errno_t inet_link_discovery_start(void);
     54extern errno_t inet_link_autoconf(void);
     55extern void inet_link_autoconf_link(inet_link_cfg_info_t *);
    5256
    5357#endif
  • uspace/srv/net/inetsrv/inetcfg.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9292        }
    9393
     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
    94100        return EOK;
    95101}
     
    98104{
    99105        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()");
    100112
    101113        addr = inet_addrobj_get_by_id(addr_id);
     
    103115                return ENOENT;
    104116
     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
    105122        inet_addrobj_remove(addr);
    106123        inet_addrobj_delete(addr);
    107124
     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");
    108151        return EOK;
    109152}
     
    193236    inet_addr_t *router, sysarg_t *sroute_id)
    194237{
     238        errno_t rc;
    195239        inet_sroute_t *sroute;
    196240
     
    207251
    208252        *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
    209260        return EOK;
    210261}
     
    212263static errno_t inetcfg_sroute_delete(sysarg_t sroute_id)
    213264{
     265        errno_t rc;
    214266        inet_sroute_t *sroute;
    215267
     
    220272        inet_sroute_remove(sroute);
    221273        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        }
    222280
    223281        return EOK;
     
    805863}
    806864
     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
    8071004/** @}
    8081005 */
  • uspace/srv/net/inetsrv/inetcfg.h

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#define INETCFG_H_
    3939
     40#include <errno.h>
     41#include "inetsrv.h"
     42
    4043extern void inet_cfg_conn(ipc_call_t *, void *);
     44extern errno_t inet_cfg_open(const char *, inet_cfg_t **);
     45extern errno_t inet_cfg_sync(inet_cfg_t *);
     46extern void inet_cfg_close(inet_cfg_t *);
    4147
    4248#endif
  • uspace/srv/net/inetsrv/inetsrv.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    7979};
    8080
     81static const char *inet_cfg_path = "/w/cfg/inetsrv.sif";
     82
    8183static FIBRIL_MUTEX_INITIALIZE(client_list_lock);
    8284static LIST_INITIALIZE(client_list);
     85inet_cfg_t *cfg;
    8386
    8487static void inet_default_conn(ipc_call_t *, void *);
     
    8689static errno_t inet_init(void)
    8790{
     91        port_id_t port;
     92        errno_t rc;
    8893        loc_srv_t *srv;
    8994
    9095        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_init()");
    9196
    92         port_id_t port;
    93         errno_t rc = async_create_port(INTERFACE_INET,
     97        rc = inet_link_discovery_start();
     98        if (rc != EOK)
     99                return rc;
     100
     101        rc = inet_cfg_open(inet_cfg_path, &cfg);
     102        if (rc != EOK)
     103                return rc;
     104
     105        rc = async_create_port(INTERFACE_INET,
    94106            inet_default_conn, NULL, &port);
    95107        if (rc != EOK)
     
    556568
    557569        printf(NAME ": Accepting connections.\n");
     570
    558571        task_retval(0);
     572
     573        (void)inet_link_autoconf();
    559574        async_manager();
    560575
  • uspace/srv/net/inetsrv/inetsrv.h

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4444#include <inet/iplink.h>
    4545#include <ipc/loc.h>
     46#include <sif.h>
    4647#include <stddef.h>
    4748#include <stdint.h>
     
    114115} inet_link_t;
    115116
     117/** Link information needed for autoconfiguration */
    116118typedef struct {
     119        service_id_t svc_id;
     120        char *svc_name;
     121} inet_link_cfg_info_t;
     122
     123/** Address object */
     124typedef struct {
     125        /** Link to list of addresses */
    117126        link_t addr_list;
     127        /** Address object ID */
    118128        sysarg_t id;
     129        /** Network address */
    119130        inet_naddr_t naddr;
     131        /** Underlying IP link */
    120132        inet_link_t *ilink;
     133        /** Address name */
    121134        char *name;
     135        /** Temporary object */
     136        bool temp;
    122137} inet_addrobj_t;
    123138
     
    125140typedef struct {
    126141        link_t sroute_list;
     142        /** ID */
    127143        sysarg_t id;
    128144        /** Destination network */
     
    130146        /** Router via which to route packets */
    131147        inet_addr_t router;
     148        /** Route name */
    132149        char *name;
     150        /** Temporary route */
     151        bool temp;
    133152} inet_sroute_t;
    134153
     
    152171} inet_dir_t;
    153172
     173/** Internet server configuration */
     174typedef struct {
     175        /** Configuration file path */
     176        char *cfg_path;
     177} inet_cfg_t;
     178
     179extern inet_cfg_t *cfg;
     180
    154181extern errno_t inet_ev_recv(inet_client_t *, inet_dgram_t *);
    155182extern errno_t inet_recv_packet(inet_packet_t *);
  • uspace/srv/net/inetsrv/meson.build

    r096c0786 r1bbc6dc  
    11#
    2 # Copyright (c) 2021 Jiri Svoboda
     2# Copyright (c) 2024 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 deps = [ 'inet' ]
     29deps = [ 'inet', 'sif' ]
    3030src = files(
    3131        'addrobj.c',
  • uspace/srv/net/inetsrv/sroute.c

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040#include <io/log.h>
    4141#include <ipc/loc.h>
     42#include <sif.h>
     43#include <stdio.h>
    4244#include <stdlib.h>
    4345#include <str.h>
     
    210212}
    211213
     214/** Load static route from SIF node.
     215 *
     216 * @param nroute SIF node to load static route from
     217 * @return EOK on success or an error code
     218 */
     219static errno_t inet_sroute_load(sif_node_t *nroute)
     220{
     221        errno_t rc;
     222        const char *sid;
     223        const char *sdest;
     224        const char *srouter;
     225        const char *name;
     226        char *endptr;
     227        int id;
     228        inet_naddr_t dest;
     229        inet_addr_t router;
     230        inet_sroute_t *sroute;
     231
     232        sid = sif_node_get_attr(nroute, "id");
     233        if (sid == NULL)
     234                return EIO;
     235
     236        sdest = sif_node_get_attr(nroute, "dest");
     237        if (sdest == NULL)
     238                return EIO;
     239
     240        srouter = sif_node_get_attr(nroute, "router");
     241        if (srouter == NULL)
     242                return EIO;
     243
     244        name = sif_node_get_attr(nroute, "name");
     245        if (name == NULL)
     246                return EIO;
     247
     248        id = strtoul(sid, &endptr, 10);
     249        if (*endptr != '\0')
     250                return EIO;
     251
     252        rc = inet_naddr_parse(sdest, &dest, NULL);
     253        if (rc != EOK)
     254                return EIO;
     255
     256        rc = inet_addr_parse(srouter, &router, NULL);
     257        if (rc != EOK)
     258                return EIO;
     259
     260        sroute = inet_sroute_new();
     261        if (sroute == NULL)
     262                return ENOMEM;
     263
     264        sroute->id = id;
     265        sroute->dest = dest;
     266        sroute->router = router;
     267        sroute->name = str_dup(name);
     268
     269        if (sroute->name == NULL) {
     270                inet_sroute_delete(sroute);
     271                return ENOMEM;
     272        }
     273
     274        inet_sroute_add(sroute);
     275        return EOK;
     276}
     277
     278/** Load static routes from SIF node.
     279 *
     280 * @param nroutes SIF node to load static routes from
     281 * @return EOK on success or an error code
     282 */
     283errno_t inet_sroutes_load(sif_node_t *nroutes)
     284{
     285        sif_node_t *nroute;
     286        const char *ntype;
     287        errno_t rc;
     288
     289        nroute = sif_node_first_child(nroutes);
     290        while (nroute != NULL) {
     291                ntype = sif_node_get_type(nroute);
     292                if (str_cmp(ntype, "route") != 0) {
     293                        rc = EIO;
     294                        goto error;
     295                }
     296
     297                rc = inet_sroute_load(nroute);
     298                if (rc != EOK)
     299                        goto error;
     300
     301                nroute = sif_node_next_child(nroute);
     302        }
     303
     304        return EOK;
     305error:
     306        return rc;
     307}
     308
     309/** Save static route to SIF node.
     310 *
     311 * @param sroute Static route
     312 * @param nroute SIF node to save static route to
     313 * @return EOK on success or an error code
     314 */
     315static errno_t inet_sroute_save(inet_sroute_t *sroute, sif_node_t *nroute)
     316{
     317        char *str = NULL;
     318        errno_t rc;
     319        int rv;
     320
     321        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_save(%p, %p)",
     322            sroute, nroute);
     323
     324        /* id */
     325
     326        rv = asprintf(&str, "%lu", sroute->id);
     327        if (rv < 0) {
     328                str = NULL;
     329                rc = ENOMEM;
     330                goto error;
     331        }
     332
     333        rc = sif_node_set_attr(nroute, "id", str);
     334        if (rc != EOK)
     335                goto error;
     336
     337        free(str);
     338        str = NULL;
     339
     340        /* dest */
     341
     342        rc = inet_naddr_format(&sroute->dest, &str);
     343        if (rc != EOK)
     344                goto error;
     345
     346        rc = sif_node_set_attr(nroute, "dest", str);
     347        if (rc != EOK)
     348                goto error;
     349
     350        free(str);
     351        str = NULL;
     352
     353        /* router */
     354
     355        rc = inet_addr_format(&sroute->router, &str);
     356        if (rc != EOK)
     357                goto error;
     358
     359        rc = sif_node_set_attr(nroute, "router", str);
     360        if (rc != EOK)
     361                goto error;
     362
     363        /* name */
     364
     365        rc = sif_node_set_attr(nroute, "name", sroute->name);
     366        if (rc != EOK)
     367                goto error;
     368
     369        free(str);
     370
     371        return rc;
     372error:
     373        if (str != NULL)
     374                free(str);
     375        return rc;
     376}
     377
     378/** Save static routes to SIF node.
     379 *
     380 * @param nroutes SIF node to save static routes to
     381 * @return EOK on success or an error code
     382 */
     383errno_t inet_sroutes_save(sif_node_t *nroutes)
     384{
     385        sif_node_t *nroute;
     386        errno_t rc;
     387
     388        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroutes_save()");
     389
     390        fibril_mutex_lock(&sroute_list_lock);
     391
     392        list_foreach(sroute_list, sroute_list, inet_sroute_t, sroute) {
     393                if (sroute->temp == false) {
     394                        rc = sif_node_append_child(nroutes, "route", &nroute);
     395                        if (rc != EOK)
     396                                goto error;
     397
     398                        rc = inet_sroute_save(sroute, nroute);
     399                        if (rc != EOK)
     400                                goto error;
     401                }
     402        }
     403
     404        fibril_mutex_unlock(&sroute_list_lock);
     405        return EOK;
     406error:
     407        fibril_mutex_unlock(&sroute_list_lock);
     408        return rc;
     409}
     410
    212411/** @}
    213412 */
  • uspace/srv/net/inetsrv/sroute.h

    r096c0786 r1bbc6dc  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#define INET_SROUTE_H_
    3939
     40#include <sif.h>
    4041#include <stddef.h>
    4142#include <stdint.h>
     
    5253    inet_dgram_t *, uint8_t, uint8_t, int);
    5354extern errno_t inet_sroute_get_id_list(sysarg_t **, size_t *);
     55extern errno_t inet_sroutes_load(sif_node_t *);
     56extern errno_t inet_sroutes_save(sif_node_t *);
    5457
    5558#endif
Note: See TracChangeset for help on using the changeset viewer.