Changeset ebb1489 in mainline for uspace/srv/net/inetsrv/inet_link.c


Ignore:
Timestamp:
2024-10-13T08:23:40Z (2 months ago)
Author:
GitHub <noreply@…>
Children:
0472cf17
Parents:
2a0c827c (diff), b3b79981 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
boba-buba <120932204+boba-buba@…> (2024-10-13 08:23:40)
git-committer:
GitHub <noreply@…> (2024-10-13 08:23:40)
Message:

Merge branch 'HelenOS:master' into topic/packet-capture

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/inetsrv/inet_link.c

    r2a0c827c rebb1489  
    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 */
Note: See TracChangeset for help on using the changeset viewer.