Changeset 00d7e1b in mainline for uspace/srv/net/net/net.c


Ignore:
Timestamp:
2011-10-07T20:20:33Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
49bd793b
Parents:
e2c50e1
Message:

networking improvements

  • start the networking stack from init
  • add loopback network interface driver (cherrypicked and sanitized from lp:~helenos-nicf/helenos/nicf)
  • add libnic and various small pieces from lp:~helenos-nicf/helenos/nicf
  • fix client side of NIC_GET_ADDRESS
  • net binary overhaul

Note: "ping 127.0.0.1" works, but the first three pings timeout for some reason

File:
1 edited

Legend:

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

    re2c50e1 r00d7e1b  
    3030/** @addtogroup net
    3131 * @{
    32  */
    33 
    34 /** @file
    35  * Networking subsystem central module implementation.
    36  *
    3732 */
    3833
     
    5550#include <ipc/ip.h>
    5651#include <ipc/nil.h>
    57 #include <net/modules.h>
    5852#include <net/packet.h>
    5953#include <net/device.h>
     
    7266#include "packet_server.h"
    7367
    74 /** Networking module name. */
    75 #define NAME  "net"
    76 
    7768#define MAX_PATH_LENGTH  1024
    7869
     
    8273GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
    8374DEVICE_MAP_IMPLEMENT(netifs, netif_t);
    84 
    85 static int startup(void);
    8675
    8776/** Add the configured setting to the configuration map.
     
    9584 *
    9685 */
    97 int add_configuration(measured_strings_t *configuration, const uint8_t *name,
    98     const uint8_t *value)
     86static int add_configuration(measured_strings_t *configuration,
     87    const uint8_t *name, const uint8_t *value)
    9988{
    10089        int rc;
     
    146135                    (uint8_t *) entry->key, (uint8_t *) entry->value);
    147136                if (rc != EOK) {
    148                         printf("%s: Error processing configuration\n", NAME);
    149137                        cfg_unload(&cfg);
    150138                        return rc;
     
    180168        return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE,
    181169            &net_globals.configuration);
    182 }
    183 
    184 /** Initialize the networking module.
    185  *
    186  * @param[in] client_connection The client connection processing
    187  *                              function. The module skeleton propagates
    188  *                              its own one.
    189  *
    190  * @return EOK on success.
    191  * @return ENOMEM if there is not enough memory left.
    192  *
    193  */
    194 static int net_initialize(async_client_conn_t client_connection)
    195 {
    196         int rc;
    197        
    198         netifs_initialize(&net_globals.netifs);
    199         char_map_initialize(&net_globals.netif_hwpaths);
    200         modules_initialize(&net_globals.modules);
    201         measured_strings_initialize(&net_globals.configuration);
    202        
    203         rc = read_configuration();
    204         if (rc != EOK)
    205                 return rc;
    206        
    207         rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
    208             (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
    209         if (rc != EOK)
    210                 return rc;
    211        
    212         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
    213             (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
    214         if (rc != EOK)
    215                 return rc;
    216        
    217         /* Build specific initialization */
    218         return net_initialize_build(client_connection);
    219 }
    220 
    221 /** Start the networking module.
    222  *
    223  * Initializes the client connection serving function,
    224  * initializes the module, registers the module service
    225  * and starts the async manager, processing IPC messages
    226  * in an infinite loop.
    227  *
    228  * @param[in] client_connection The client connection
    229  *                              processing function. The
    230  *                              module skeleton propagates
    231  *                              its own one.
    232  *
    233  * @return EOK on successful module termination.
    234  * @return Other error codes as defined for the net_initialize() function.
    235  * @return Other error codes as defined for the REGISTER_ME() macro function.
    236  *
    237  */
    238 static int net_module_start(async_client_conn_t client_connection)
    239 {
    240         int rc;
    241        
    242         async_set_client_connection(client_connection);
    243         rc = pm_init();
    244         if (rc != EOK)
    245                 return rc;
    246        
    247         rc = packet_server_init();
    248         if (rc != EOK)
    249                 goto out;
    250        
    251         rc = net_initialize(client_connection);
    252         if (rc != EOK)
    253                 goto out;
    254        
    255         rc = startup();
    256         if (rc != EOK)
    257                 goto out;
    258        
    259         rc = service_register(SERVICE_NETWORKING);
    260         if (rc != EOK)
    261                 goto out;
    262        
    263         task_retval(0);
    264         async_manager();
    265 
    266 out:
    267         pm_destroy();
    268         return rc;
    269170}
    270171
     
    388289static int init_device(netif_t *netif, devman_handle_t handle)
    389290{
     291        printf("%s: Initializing device '%s'\n", NAME, netif->name);
     292       
    390293        netif->handle = handle;
    391294        netif->sess = devman_device_connect(EXCHANGE_SERIALIZE, netif->handle,
     
    459362        }
    460363       
     364        printf("%s: Activating device '%s'\n", NAME, netif->name);
    461365        return nic_set_state(netif->sess, NIC_STATE_ACTIVE);
    462366}
    463367
    464 static int net_driver_port_ready(devman_handle_t handle)
     368static int net_port_ready(devman_handle_t handle)
    465369{
    466370        char hwpath[MAX_PATH_LENGTH];
     
    500404       
    501405        for (size_t i = 0; i < count; i++) {
    502                 rc = net_driver_port_ready(funs[i]);
     406                rc = net_port_ready(funs[i]);
    503407                if (rc != EOK)
    504408                        return rc;
    505409        }
    506410       
    507         return EOK;
    508 }
    509 
    510 /** Read the configuration and start all network interfaces.
    511  *
    512  * @return EOK on success.
    513  * @return EXDEV if there is no available system-unique device identifier.
    514  * @return EINVAL if any of the network interface names are not configured.
    515  * @return ENOMEM if there is not enough memory left.
    516  * @return Other error codes as defined for the read_configuration()
    517  *         function.
    518  * @return Other error codes as defined for the read_netif_configuration()
    519  *         function.
    520  * @return Other error codes as defined for the start_device() function.
    521  *
    522  */
    523 static int startup(void)
    524 {
    525         int rc;
    526        
    527         DIR *config_dir = opendir(CONF_DIR);
    528         if (config_dir == NULL)
    529                 return ENOENT;
    530        
    531         struct dirent *dir_entry;
    532         while ((dir_entry = readdir(config_dir))) {
    533                 if (str_cmp(dir_entry->d_name + str_length(dir_entry->d_name)
    534                         - str_length(CONF_EXT), CONF_EXT) != 0)
    535                         continue;
    536                
    537                 netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
    538                 if (!netif)
    539                         continue;
    540                
    541                 netif->handle = -1;
    542                 netif->sess = NULL;
    543                
    544                 netif->id = generate_new_device_id();
    545                 if (!netif->id) {
    546                         free(netif);
    547                         continue;
    548                 }
    549                
    550                 rc = measured_strings_initialize(&netif->configuration);
    551                 if (rc != EOK) {
    552                         free(netif);
    553                         continue;
    554                 }
    555                
    556                 rc = read_netif_configuration(dir_entry->d_name, netif);
    557                 if (rc != EOK) {
    558                         free(netif);
    559                         continue;
    560                 }
    561                
    562                 /* Mandatory name */
    563                 measured_string_t *name = measured_strings_find(&netif->configuration,
    564                     (uint8_t *) CONF_NAME, 0);
    565                 if (!name) {
    566                         printf("%s: Network interface name is missing\n", NAME);
    567                         measured_strings_destroy(&netif->configuration, free);
    568                         free(netif);
    569                         continue;
    570                 }
    571                
    572                 netif->name = name->value;
    573                
    574                 /* Mandatory hardware path */
    575                 measured_string_t *hwpath = measured_strings_find(
    576                     &netif->configuration, (const uint8_t *) CONF_HWPATH, 0);
    577                 if (!hwpath) {
    578                         measured_strings_destroy(&netif->configuration, free);
    579                         free(netif);
    580                 }
    581                
    582                 /* Add to the netifs map */
    583                 int index = netifs_add(&net_globals.netifs, netif->id, netif);
    584                 if (index < 0) {
    585                         measured_strings_destroy(&netif->configuration, free);
    586                         free(netif);
    587                         continue;
    588                 }
    589                
    590                 /*
    591                  * Add to the hardware paths map and init network interfaces
    592                  * and needed modules.
    593                  */
    594                 rc = char_map_add(&net_globals.netif_hwpaths, hwpath->value, 0, index);
    595                 if (rc != EOK) {
    596                         measured_strings_destroy(&netif->configuration, free);
    597                         netifs_exclude_index(&net_globals.netifs, index, free);
    598                         continue;
    599                 }
    600         }
    601        
    602         closedir(config_dir);
    603411        return EOK;
    604412}
     
    619427 *
    620428 */
    621 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    622     size_t *answer_count)
     429static int net_message(ipc_callid_t callid, ipc_call_t *call,
     430    ipc_call_t *answer, size_t *answer_count)
    623431{
    624432        measured_string_t *strings;
     
    699507                /* Clear the answer structure */
    700508                ipc_call_t answer;
    701                 size_t answer_count;
    702                 refresh_answer(&answer, &answer_count);
     509                size_t count;
     510                refresh_answer(&answer, &count);
    703511               
    704512                /* Fetch the next message */
     
    707515               
    708516                /* Process the message */
    709                 int res = net_module_message(callid, &call, &answer, &answer_count);
     517                int res;
     518                if (IS_NET_PACKET_MESSAGE(call))
     519                        res = packet_server_message(callid, &call, &answer, &count);
     520                else
     521                        res = net_message(callid, &call, &answer, &count);
    710522               
    711523                /* End if told to either by the message or the processing result */
     
    714526               
    715527                /* Answer the message */
    716                 answer_call(callid, res, &answer, answer_count);
     528                answer_call(callid, res, &answer, count);
    717529        }
    718530}
     
    720532int main(int argc, char *argv[])
    721533{
    722         return net_module_start(net_client_connection);
     534        netifs_initialize(&net_globals.netifs);
     535        char_map_initialize(&net_globals.netif_hwpaths);
     536        modules_initialize(&net_globals.modules);
     537        measured_strings_initialize(&net_globals.configuration);
     538        async_set_client_connection(net_client_connection);
     539       
     540        int rc = pm_init();
     541        if (rc != EOK) {
     542                printf("%s: Unable to initialize packet management\n", NAME);
     543                return rc;
     544        }
     545       
     546        rc = packet_server_init();
     547        if (rc != EOK) {
     548                printf("%s: Unable to initialize packet server\n", NAME);
     549                pm_destroy();
     550                return rc;
     551        }
     552       
     553        rc = read_configuration();
     554        if (rc != EOK) {
     555                printf("%s: Error reading configuration\n", NAME);
     556                pm_destroy();
     557                return rc;
     558        }
     559       
     560        DIR *config_dir = opendir(CONF_DIR);
     561        if (config_dir != NULL) {
     562                struct dirent *dir_entry;
     563                while ((dir_entry = readdir(config_dir))) {
     564                        /* Ignore files without the CONF_EXT extension */
     565                        if ((str_size(dir_entry->d_name) < str_size(CONF_EXT)) ||
     566                            (str_cmp(dir_entry->d_name + str_size(dir_entry->d_name) -
     567                            str_size(CONF_EXT), CONF_EXT) != 0))
     568                                continue;
     569                       
     570                       
     571                        netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
     572                        if (!netif)
     573                                continue;
     574                       
     575                        netif->handle = -1;
     576                        netif->sess = NULL;
     577                       
     578                        netif->id = generate_new_device_id();
     579                        if (!netif->id) {
     580                                free(netif);
     581                                continue;
     582                        }
     583                       
     584                        rc = measured_strings_initialize(&netif->configuration);
     585                        if (rc != EOK) {
     586                                free(netif);
     587                                continue;
     588                        }
     589                       
     590                        rc = read_netif_configuration(dir_entry->d_name, netif);
     591                        if (rc != EOK) {
     592                                printf("%s: Error reading configuration %s\n", NAME,
     593                                    dir_entry->d_name);
     594                                free(netif);
     595                                continue;
     596                        }
     597                       
     598                        measured_string_t *name = measured_strings_find(&netif->configuration,
     599                            (uint8_t *) CONF_NAME, 0);
     600                        if (!name) {
     601                                printf("%s: Network interface name is missing in %s\n",
     602                                    NAME, dir_entry->d_name);
     603                                measured_strings_destroy(&netif->configuration, free);
     604                                free(netif);
     605                                continue;
     606                        }
     607                       
     608                        netif->name = name->value;
     609                       
     610                        /* Mandatory hardware path */
     611                        measured_string_t *hwpath = measured_strings_find(
     612                            &netif->configuration, (const uint8_t *) CONF_HWPATH, 0);
     613                        if (!hwpath) {
     614                                printf("%s: Hardware path is missing in %s\n",
     615                                    NAME, dir_entry->d_name);
     616                                measured_strings_destroy(&netif->configuration, free);
     617                                free(netif);
     618                                continue;
     619                        }
     620                       
     621                        int index = netifs_add(&net_globals.netifs, netif->id, netif);
     622                        if (index < 0) {
     623                                measured_strings_destroy(&netif->configuration, free);
     624                                free(netif);
     625                                continue;
     626                        }
     627                       
     628                        /*
     629                         * Add to the hardware paths map and init network interfaces
     630                         * and needed modules.
     631                         */
     632                        rc = char_map_add(&net_globals.netif_hwpaths, hwpath->value, 0, index);
     633                        if (rc != EOK) {
     634                                measured_strings_destroy(&netif->configuration, free);
     635                                netifs_exclude_index(&net_globals.netifs, index, free);
     636                                continue;
     637                        }
     638                }
     639               
     640                closedir(config_dir);
     641        }
     642       
     643        rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
     644            (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
     645        if (rc != EOK) {
     646                printf("%s: Error adding module '%s'\n", NAME, ETHERNET_NAME);
     647                pm_destroy();
     648                return rc;
     649        }
     650       
     651        rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
     652            (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
     653        if (rc != EOK) {
     654                printf("%s: Error adding module '%s'\n", NAME, NILDUMMY_NAME);
     655                pm_destroy();
     656                return rc;
     657        }
     658       
     659        task_id_t task_id = net_spawn((uint8_t *) IP_FILENAME);
     660        if (!task_id) {
     661                printf("%s: Error spawning IP module\n", NAME);
     662                pm_destroy();
     663                return EINVAL;
     664        }
     665       
     666        rc = add_module(NULL, &net_globals.modules, (uint8_t *) IP_NAME,
     667            (uint8_t *) IP_FILENAME, SERVICE_IP, task_id, ip_connect_module);
     668        if (rc != EOK) {
     669                printf("%s: Error adding module '%s'\n", NAME, IP_NAME);
     670                pm_destroy();
     671                return rc;
     672        }
     673       
     674        if (!net_spawn((uint8_t *) "/srv/icmp")) {
     675                printf("%s: Error spawning ICMP module\n", NAME);
     676                pm_destroy();
     677                return EINVAL;
     678        }
     679       
     680        if (!net_spawn((uint8_t *) "/srv/udp")) {
     681                printf("%s: Error spawning UDP module\n", NAME);
     682                pm_destroy();
     683                return EINVAL;
     684        }
     685       
     686        if (!net_spawn((uint8_t *) "/srv/tcp")) {
     687                printf("%s: Error spawning TCP module\n", NAME);
     688                pm_destroy();
     689                return EINVAL;
     690        }
     691       
     692        rc = service_register(SERVICE_NETWORKING);
     693        if (rc != EOK) {
     694                printf("%s: Error registering service\n", NAME);
     695                pm_destroy();
     696                return rc;
     697        }
     698       
     699        task_retval(0);
     700        async_manager();
     701        return 0;
    723702}
    724703
Note: See TracChangeset for help on using the changeset viewer.