Changeset 04ecc6d in mainline


Ignore:
Timestamp:
2013-09-24T22:50:15Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b243da3
Parents:
884c56b (diff), c6bf6be (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.
Message:

Merge DHCP changes.

Files:
12 added
15 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r884c56b r04ecc6d  
    269269uspace/dist/srv/dhcp
    270270uspace/srv/net/dhcp/dhcp
     271uspace/dist/srv/nconfsrv
     272uspace/srv/net/nconfsrv/nconfsrv
    271273uspace/app/netspeed/netspeed
    272274uspace/dist/app/netspeed
  • boot/Makefile.common

    r884c56b r04ecc6d  
    118118        $(USPACE_PATH)/srv/net/inetsrv/inetsrv \
    119119        $(USPACE_PATH)/srv/net/loopip/loopip \
     120        $(USPACE_PATH)/srv/net/nconfsrv/nconfsrv \
    120121        $(USPACE_PATH)/srv/net/slip/slip \
    121122        $(USPACE_PATH)/srv/net/tcp/tcp \
  • uspace/Makefile

    r884c56b r04ecc6d  
    9797        srv/net/inetsrv \
    9898        srv/net/loopip \
     99        srv/net/nconfsrv \
    99100        srv/net/slip \
    100101        srv/net/tcp \
  • uspace/app/init/init.c

    r884c56b r04ecc6d  
    360360        srv_start("/srv/udp");
    361361        srv_start("/srv/dnsrsrv");
     362        srv_start("/srv/dhcp");
     363        srv_start("/srv/nconfsrv");
    362364       
    363365        srv_start("/srv/clipboard");
  • uspace/lib/c/Makefile

    r884c56b r04ecc6d  
    7777        generic/device/pci.c \
    7878        generic/device/ahci.c \
     79        generic/dhcp.c \
    7980        generic/dnsr.c \
    8081        generic/dlfcn.c \
  • uspace/lib/c/generic/inetcfg.c

    r884c56b r04ecc6d  
    267267}
    268268
     269int inetcfg_link_add(sysarg_t link_id)
     270{
     271        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     272
     273        int rc = async_req_1_0(exch, INETCFG_LINK_ADD, link_id);
     274        async_exchange_end(exch);
     275
     276        return rc;
     277}
     278
    269279int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
    270280{
     
    305315}
    306316
     317int inetcfg_link_remove(sysarg_t link_id)
     318{
     319        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     320
     321        int rc = async_req_1_0(exch, INETCFG_LINK_REMOVE, link_id);
     322        async_exchange_end(exch);
     323
     324        return rc;
     325}
     326
    307327int inetcfg_sroute_create(const char *name, inet_naddr_t *dest,
    308328    inet_addr_t *router, sysarg_t *sroute_id)
  • uspace/lib/c/include/inet/inetcfg.h

    r884c56b r04ecc6d  
    4848extern int inetcfg_get_link_list(sysarg_t **, size_t *);
    4949extern int inetcfg_get_sroute_list(sysarg_t **, size_t *);
     50extern int inetcfg_link_add(sysarg_t);
    5051extern int inetcfg_link_get(sysarg_t, inet_link_info_t *);
     52extern int inetcfg_link_remove(sysarg_t);
    5153extern int inetcfg_sroute_get(sysarg_t, inet_sroute_info_t *);
    5254extern int inetcfg_sroute_get_id(const char *, sysarg_t *);
  • uspace/lib/c/include/ipc/inet.h

    r884c56b r04ecc6d  
    7272        INETCFG_GET_LINK_LIST,
    7373        INETCFG_GET_SROUTE_LIST,
     74        INETCFG_LINK_ADD,
    7475        INETCFG_LINK_GET,
     76        INETCFG_LINK_REMOVE,
    7577        INETCFG_SROUTE_CREATE,
    7678        INETCFG_SROUTE_DELETE,
  • uspace/lib/c/include/ipc/services.h

    r884c56b r04ecc6d  
    5454
    5555#define SERVICE_NAME_CORECFG    "corecfg"
     56#define SERVICE_NAME_DHCP       "net/dhcp"
    5657#define SERVICE_NAME_DNSR       "net/dnsr"
    5758#define SERVICE_NAME_INET       "net/inet"
     
    5960#define SERVICE_NAME_INETPING   "net/inetping"
    6061#define SERVICE_NAME_INETPING6  "net/inetping6"
     62#define SERVICE_NAME_NETCONF    "net/netconf"
    6163
    6264#endif
  • uspace/srv/net/dhcp/Makefile

    r884c56b r04ecc6d  
    3131
    3232SOURCES = \
    33         dhcp.c
     33        dhcp.c \
     34        main.c \
     35        transport.c
    3436
    3537include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/dhcp/dhcp.c

    r884c56b r04ecc6d  
    3535 */
    3636
     37#include <adt/list.h>
    3738#include <bitops.h>
     39#include <fibril_synch.h>
    3840#include <inet/addr.h>
    3941#include <inet/dnsr.h>
    4042#include <inet/inetcfg.h>
     43#include <io/log.h>
    4144#include <loc.h>
    4245#include <net/in.h>
     
    4649#include <stdlib.h>
    4750
     51#include "dhcp.h"
    4852#include "dhcp_std.h"
    49 
    50 #define NAME "dhcp"
     53#include "transport.h"
     54
     55enum {
     56        /** In microseconds */
     57        dhcp_discover_timeout_val = 5 * 1000 * 1000,
     58        /** In microseconds */
     59        dhcp_request_timeout_val = 1 * 1000 * 1000,
     60        dhcp_discover_retries = 5,
     61        dhcp_request_retries = 3
     62};
    5163
    5264#define MAX_MSG_SIZE 1024
    53 
    54 static int transport_fd = -1;
    55 static inet_link_info_t link_info;
    5665static uint8_t msgbuf[MAX_MSG_SIZE];
     66
     67/** List of registered links (of dhcp_link_t) */
     68static list_t dhcp_links;
     69
     70static void dhcpsrv_discover_timeout(void *);
     71static void dhcpsrv_request_timeout(void *);
     72
     73typedef enum {
     74        ds_bound,
     75        ds_fail,
     76        ds_init,
     77        ds_init_reboot,
     78        ds_rebinding,
     79        ds_renewing,
     80        ds_requesting,
     81        ds_selecting
     82} dhcp_state_t;
    5783
    5884typedef struct {
     
    6995} dhcp_offer_t;
    7096
     97typedef struct {
     98        /** Link to dhcp_links list */
     99        link_t links;
     100        /** Link service ID */
     101        service_id_t link_id;
     102        /** Link info */
     103        inet_link_info_t link_info;
     104        /** Transport */
     105        dhcp_transport_t dt;
     106        /** Transport timeout */
     107        fibril_timer_t *timeout;
     108        /** Number of retries */
     109        int retries_left;
     110        /** Link state */
     111        dhcp_state_t state;
     112        /** Last received offer */
     113        dhcp_offer_t offer;
     114} dhcp_link_t;
     115
     116static void dhcpsrv_recv(void *, void *, size_t);
     117
    71118/** Decode subnet mask into subnet prefix length. */
    72119static int subnet_mask_decode(uint32_t mask, int *bits)
     
    101148}
    102149
    103 static int dhcp_send(void *msg, size_t size)
    104 {
    105         struct sockaddr_in addr;
    106         int rc;
    107 
    108         addr.sin_family = AF_INET;
    109         addr.sin_port = htons(dhcp_server_port);
    110         addr.sin_addr.s_addr = htonl(addr32_broadcast_all_hosts);
    111 
    112         rc = sendto(transport_fd, msg, size, 0,
    113             (struct sockaddr *)&addr, sizeof(addr));
    114         if (rc != EOK) {
    115                 printf("Sending failed\n");
    116                 return rc;
    117         }
    118 
    119         return EOK;
    120 }
    121 
    122 static int dhcp_send_discover(void)
     150static int dhcp_send_discover(dhcp_link_t *dlink)
    123151{
    124152        dhcp_hdr_t *hdr = (dhcp_hdr_t *)msgbuf;
     
    132160        hdr->flags = flag_broadcast;
    133161
    134         addr48(link_info.mac_addr, hdr->chaddr);
     162        addr48(dlink->link_info.mac_addr, hdr->chaddr);
    135163        hdr->opt_magic = host2uint32_t_be(dhcp_opt_magic);
    136164
     
    140168        opt[3] = opt_end;
    141169
    142         return dhcp_send(msgbuf, sizeof(dhcp_hdr_t) + 4);
    143 }
    144 
    145 static int dhcp_recv_msg(void **rmsg, size_t *rsize)
    146 {
    147         struct sockaddr_in src_addr;
    148         socklen_t src_addr_size;
    149         size_t recv_size;
    150         int rc;
    151 
    152         src_addr_size = sizeof(src_addr);
    153         rc = recvfrom(transport_fd, msgbuf, MAX_MSG_SIZE, 0,
    154             (struct sockaddr *)&src_addr, &src_addr_size);
    155         if (rc < 0) {
    156                 printf("recvfrom failed (%d)\n", rc);
    157                 return rc;
    158         }
    159 
    160         recv_size = (size_t)rc;
    161         *rmsg = msgbuf;
    162         *rsize = recv_size;
    163 
    164         return EOK;
    165 }
    166 
    167 static int dhcp_send_request(dhcp_offer_t *offer)
     170        return dhcp_send(&dlink->dt, msgbuf, sizeof(dhcp_hdr_t) + 4);
     171}
     172
     173static int dhcp_send_request(dhcp_link_t *dlink, dhcp_offer_t *offer)
    168174{
    169175        dhcp_hdr_t *hdr = (dhcp_hdr_t *)msgbuf;
     
    178184        hdr->flags = flag_broadcast;
    179185        hdr->ciaddr = host2uint32_t_be(offer->oaddr.addr);
    180         addr48(link_info.mac_addr, hdr->chaddr);
     186        addr48(dlink->link_info.mac_addr, hdr->chaddr);
    181187        hdr->opt_magic = host2uint32_t_be(dhcp_opt_magic);
    182188
     
    203209        opt[i++] = opt_end;
    204210
    205         return dhcp_send(msgbuf, sizeof(dhcp_hdr_t) + i);
    206 }
    207 
    208 static int dhcp_recv_reply(void *msg, size_t size, dhcp_offer_t *offer)
     211        return dhcp_send(&dlink->dt, msgbuf, sizeof(dhcp_hdr_t) + i);
     212}
     213
     214static int dhcp_parse_reply(void *msg, size_t size, dhcp_offer_t *offer)
    209215{
    210216        dhcp_hdr_t *hdr = (dhcp_hdr_t *)msg;
     
    222228        size_t i;
    223229
    224         printf("Receive reply\n");
     230        log_msg(LOG_DEFAULT, LVL_DEBUG, "Receive reply");
    225231        memset(offer, 0, sizeof(*offer));
    226232
     
    231237                return rc;
    232238
    233         printf("Your IP address: %s\n", saddr);
     239        log_msg(LOG_DEFAULT, LVL_DEBUG, "Your IP address: %s", saddr);
    234240        free(saddr);
    235241
     
    240246                return rc;
    241247
    242         printf("Next server IP address: %s\n", saddr);
     248        log_msg(LOG_DEFAULT, LVL_DEBUG, "Next server IP address: %s", saddr);
    243249        free(saddr);
    244250
     
    249255                return rc;
    250256
    251         printf("Relay agent IP address: %s\n", saddr);
     257        log_msg(LOG_DEFAULT, LVL_DEBUG, "Relay agent IP address: %s", saddr);
    252258        free(saddr);
    253259
     
    320326
    321327        if (!have_server_id) {
    322                 printf("Missing server ID option.\n");
     328                log_msg(LOG_DEFAULT, LVL_ERROR, "Missing server ID option.");
    323329                return rc;
    324330        }
    325331
    326332        if (!have_subnet_mask) {
    327                 printf("Missing subnet mask option.\n");
     333                log_msg(LOG_DEFAULT, LVL_ERROR, "Missing subnet mask option.");
    328334                return rc;
    329335        }
     
    333339                return rc;
    334340
    335         printf("Offered network address: %s\n", saddr);
     341        log_msg(LOG_DEFAULT, LVL_DEBUG, "Offered network address: %s", saddr);
    336342        free(saddr);
    337343
     
    341347                        return rc;
    342348
    343                 printf("Router address: %s\n", saddr);
     349                log_msg(LOG_DEFAULT, LVL_DEBUG, "Router address: %s", saddr);
    344350                free(saddr);
    345351        }
     
    350356                        return rc;
    351357
    352                 printf("DNS server: %s\n", saddr);
     358                log_msg(LOG_DEFAULT, LVL_DEBUG, "DNS server: %s", saddr);
    353359                free(saddr);
    354360        }
     
    367373            &addr_id);
    368374        if (rc != EOK) {
    369                 printf("Error creating IP address %s (%d)\n", "dhcp4a", rc);
     375                log_msg(LOG_DEFAULT, LVL_ERROR,
     376                    "Error creating IP address %s (%d)", "dhcp4a", rc);
    370377                return rc;
    371378        }
     
    378385                rc = inetcfg_sroute_create("dhcpdef", &defr, &offer->router, &sroute_id);
    379386                if (rc != EOK) {
    380                         printf("Error creating default route %s (%d).\n", "dhcpdef",
    381                             rc);
     387                        log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating "
     388                            "default route %s (%d).", "dhcpdef", rc);
    382389                        return rc;
    383390                }
     
    387394                rc = dnsr_set_srvaddr(&offer->dns_server);
    388395                if (rc != EOK) {
    389                         printf("%s: Error setting nameserver address (%d))\n",
    390                             NAME, rc);
     396                        log_msg(LOG_DEFAULT, LVL_ERROR, "Error setting "
     397                            "nameserver address (%d))", rc);
    391398                        return rc;
    392399                }
     
    396403}
    397404
    398 int main(int argc, char *argv[])
    399 {
    400         int fd;
    401         struct sockaddr_in laddr;
    402         void *msg;
    403         service_id_t iplink;
    404         size_t msg_size;
     405void dhcpsrv_links_init(void)
     406{
     407        list_initialize(&dhcp_links);
     408}
     409
     410static dhcp_link_t *dhcpsrv_link_find(service_id_t link_id)
     411{
     412        list_foreach(dhcp_links, links, dhcp_link_t, dlink) {
     413                if (dlink->link_id == link_id)
     414                        return dlink;
     415        }
     416
     417        return NULL;
     418}
     419
     420static void dhcp_link_set_failed(dhcp_link_t *dlink)
     421{
     422        log_msg(LOG_DEFAULT, LVL_NOTE, "Giving up on link %s",
     423            dlink->link_info.name);
     424        dlink->state = ds_fail;
     425}
     426
     427int dhcpsrv_link_add(service_id_t link_id)
     428{
     429        dhcp_link_t *dlink;
     430        int rc;
     431
     432        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id);
     433
     434        if (dhcpsrv_link_find(link_id) != NULL) {
     435                log_msg(LOG_DEFAULT, LVL_NOTE, "Link %zu already added",
     436                    link_id);
     437                return EEXIST;
     438        }
     439
     440        dlink = calloc(1, sizeof(dhcp_link_t));
     441        if (dlink == NULL)
     442                return ENOMEM;
     443
     444        dlink->link_id = link_id;
     445        dlink->timeout = fibril_timer_create();
     446        if (dlink->timeout == NULL) {
     447                rc = ENOMEM;
     448                goto error;
     449        }
     450
     451        /* Get link hardware address */
     452        rc = inetcfg_link_get(link_id, &dlink->link_info);
     453        if (rc != EOK) {
     454                log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting properties "
     455                    "for link %zu.", link_id);
     456                rc = EIO;
     457                goto error;
     458        }
     459
     460        rc = dhcp_transport_init(&dlink->dt, link_id, dhcpsrv_recv, dlink);
     461        if (rc != EOK) {
     462                log_msg(LOG_DEFAULT, LVL_ERROR, "Error initializing DHCP "
     463                    "transport for link %s.", dlink->link_info.name);
     464                rc = EIO;
     465                goto error;
     466        }
     467
     468        dlink->state = ds_selecting;
     469
     470        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
     471        rc = dhcp_send_discover(dlink);
     472        if (rc != EOK) {
     473                log_msg(LOG_DEFAULT, LVL_ERROR, "Error sending DHCPDISCOVER.");
     474                dhcp_link_set_failed(dlink);
     475                rc = EIO;
     476                goto error;
     477        }
     478
     479        dlink->retries_left = dhcp_discover_retries;
     480        fibril_timer_set(dlink->timeout, dhcp_discover_timeout_val,
     481            dhcpsrv_discover_timeout, dlink);
     482
     483        list_append(&dlink->links, &dhcp_links);
     484
     485        return EOK;
     486error:
     487        if (dlink != NULL && dlink->timeout != NULL)
     488                fibril_timer_destroy(dlink->timeout);
     489        free(dlink);
     490        return rc;
     491}
     492
     493int dhcpsrv_link_remove(service_id_t link_id)
     494{
     495        return ENOTSUP;
     496}
     497
     498static void dhcpsrv_recv_offer(dhcp_link_t *dlink, dhcp_offer_t *offer)
     499{
     500        int rc;
     501
     502        if (dlink->state != ds_selecting) {
     503                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received offer in state "
     504                    " %d, ignoring.", (int)dlink->state);
     505                return;
     506        }
     507
     508        fibril_timer_clear(dlink->timeout);
     509        dlink->offer = *offer;
     510        dlink->state = ds_requesting;
     511
     512        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPREQUEST");
     513        rc = dhcp_send_request(dlink, offer);
     514        if (rc != EOK) {
     515                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error sending request.");
     516                return;
     517        }
     518
     519        dlink->retries_left = dhcp_request_retries;
     520        fibril_timer_set(dlink->timeout, dhcp_request_timeout_val,
     521            dhcpsrv_request_timeout, dlink);
     522}
     523
     524static void dhcpsrv_recv_ack(dhcp_link_t *dlink, dhcp_offer_t *offer)
     525{
     526        int rc;
     527
     528        if (dlink->state != ds_requesting) {
     529                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received ack in state "
     530                    " %d, ignoring.", (int)dlink->state);
     531                return;
     532        }
     533
     534        fibril_timer_clear(dlink->timeout);
     535        dlink->offer = *offer;
     536        dlink->state = ds_bound;
     537
     538        rc = dhcp_cfg_create(dlink->link_id, offer);
     539        if (rc != EOK) {
     540                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error creating configuration.");
     541                return;
     542        }
     543
     544        log_msg(LOG_DEFAULT, LVL_NOTE, "%s: Successfully configured.",
     545            dlink->link_info.name);
     546}
     547
     548static void dhcpsrv_recv(void *arg, void *msg, size_t size)
     549{
     550        dhcp_link_t *dlink = (dhcp_link_t *)arg;
    405551        dhcp_offer_t offer;
    406552        int rc;
    407553
    408         if (argc < 2) {
    409                 printf("syntax: %s <ip-link>\n", NAME);
    410                 return 1;
    411         }
    412 
    413         rc = inetcfg_init();
    414         if (rc != EOK) {
    415                 printf("Error contacting inet configuration service.\n");
    416                 return 1;
    417         }
    418 
    419         rc = loc_service_get_id(argv[1], &iplink, 0);
    420         if (rc != EOK) {
    421                 printf("Error resolving service '%s'.\n", argv[1]);
    422                 return 1;
    423         }
    424 
    425         /* Get link hardware address */
    426         rc = inetcfg_link_get(iplink, &link_info);
    427         if (rc != EOK) {
    428                 printf("Error getting properties for link '%s'.\n", argv[1]);
    429                 return 1;
    430         }
    431 
    432         laddr.sin_family = AF_INET;
    433         laddr.sin_port = htons(dhcp_client_port);
    434         laddr.sin_addr.s_addr = INADDR_ANY;
    435 
    436         fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    437         if (fd < 0)
    438                 return 1;
    439 
    440         printf("Bind socket.\n");
    441         rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    442         if (rc != EOK)
    443                 return 1;
    444 
    445         printf("Set socket options\n");
    446         rc = setsockopt(fd, SOL_SOCKET, SO_IPLINK, &iplink, sizeof(iplink));
    447         if (rc != EOK)
    448                 return 1;
    449 
    450         transport_fd = fd;
    451 
    452         printf("Send DHCPDISCOVER\n");
    453         rc = dhcp_send_discover();
    454         if (rc != EOK)
    455                 return 1;
    456 
    457         rc = dhcp_recv_msg(&msg, &msg_size);
    458         if (rc != EOK)
    459                 return 1;
    460 
    461         printf("Received %zu bytes\n", msg_size);
    462 
    463         rc = dhcp_recv_reply(msg, msg_size, &offer);
    464         if (rc != EOK)
    465                 return 1;
    466 
    467         rc = dhcp_send_request(&offer);
    468         if (rc != EOK)
    469                 return 1;
    470 
    471         rc = dhcp_recv_msg(&msg, &msg_size);
    472         if (rc != EOK)
    473                 return 1;
    474 
    475         printf("Received %zu bytes\n", msg_size);
    476 
    477         rc = dhcp_recv_reply(msg, msg_size, &offer);
    478         if (rc != EOK)
    479                 return 1;
    480 
    481         rc = dhcp_cfg_create(iplink, &offer);
    482         if (rc != EOK)
    483                 return 1;
    484 
    485         closesocket(fd);
    486         return 0;
     554        log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: dhcpsrv_recv() %zu bytes",
     555            dlink->link_info.name, size);
     556
     557        rc = dhcp_parse_reply(msg, size, &offer);
     558        if (rc != EOK) {
     559                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error parsing reply");
     560                return;
     561        }
     562
     563        switch (offer.msg_type) {
     564        case msg_dhcpoffer:
     565                dhcpsrv_recv_offer(dlink, &offer);
     566                break;
     567        case msg_dhcpack:
     568                dhcpsrv_recv_ack(dlink, &offer);
     569                break;
     570        default:
     571                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received unexpected "
     572                    "message type. %d", (int)offer.msg_type);
     573                break;
     574        }
     575}
     576
     577static void dhcpsrv_discover_timeout(void *arg)
     578{
     579        dhcp_link_t *dlink = (dhcp_link_t *)arg;
     580        int rc;
     581
     582        assert(dlink->state == ds_selecting);
     583        log_msg(LOG_DEFAULT, LVL_NOTE, "%s: dcpsrv_discover_timeout",
     584            dlink->link_info.name);
     585
     586        if (dlink->retries_left == 0) {
     587                log_msg(LOG_DEFAULT, LVL_NOTE, "Retries exhausted");
     588                dhcp_link_set_failed(dlink);
     589                return;
     590        }
     591        --dlink->retries_left;
     592
     593        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
     594        rc = dhcp_send_discover(dlink);
     595        if (rc != EOK) {
     596                log_msg(LOG_DEFAULT, LVL_ERROR, "Error sending DHCPDISCOVER");
     597                dhcp_link_set_failed(dlink);
     598                return;
     599        }
     600
     601        fibril_timer_set(dlink->timeout, dhcp_discover_timeout_val,
     602            dhcpsrv_discover_timeout, dlink);
     603}
     604
     605static void dhcpsrv_request_timeout(void *arg)
     606{
     607        dhcp_link_t *dlink = (dhcp_link_t *)arg;
     608        int rc;
     609
     610        assert(dlink->state == ds_requesting);
     611        log_msg(LOG_DEFAULT, LVL_NOTE, "%s: dcpsrv_request_timeout",
     612            dlink->link_info.name);
     613
     614        if (dlink->retries_left == 0) {
     615                log_msg(LOG_DEFAULT, LVL_NOTE, "Retries exhausted");
     616                dhcp_link_set_failed(dlink);
     617                return;
     618        }
     619        --dlink->retries_left;
     620
     621        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPREQUEST");
     622        rc = dhcp_send_request(dlink, &dlink->offer);
     623        if (rc != EOK) {
     624                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error sending request.");
     625                dhcp_link_set_failed(dlink);
     626                return;
     627        }
     628
     629        fibril_timer_set(dlink->timeout, dhcp_request_timeout_val,
     630            dhcpsrv_request_timeout, dlink);
    487631}
    488632
  • uspace/srv/net/inetsrv/inet_link.c

    r884c56b r04ecc6d  
    5555static uint16_t ip_ident = 0;
    5656
    57 static int inet_link_open(service_id_t);
    5857static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
     58static inet_link_t *inet_link_get_by_id_locked(sysarg_t);
    5959
    6060static iplink_ev_ops_t inet_iplink_ev_ops = {
     
    6262};
    6363
    64 static LIST_INITIALIZE(inet_link_list);
    65 static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
     64static LIST_INITIALIZE(inet_links);
     65static FIBRIL_MUTEX_INITIALIZE(inet_links_lock);
    6666
    6767static addr128_t link_local_node_ip =
     
    113113}
    114114
    115 static int inet_link_check_new(void)
    116 {
    117         bool already_known;
    118         category_id_t iplink_cat;
    119         service_id_t *svcs;
    120         size_t count, i;
    121         int rc;
    122 
    123         fibril_mutex_lock(&inet_discovery_lock);
    124 
    125         rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
    126         if (rc != EOK) {
    127                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
    128                 fibril_mutex_unlock(&inet_discovery_lock);
    129                 return ENOENT;
    130         }
    131 
    132         rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
    133         if (rc != EOK) {
    134                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting list of IP links.");
    135                 fibril_mutex_unlock(&inet_discovery_lock);
    136                 return EIO;
    137         }
    138 
    139         for (i = 0; i < count; i++) {
    140                 already_known = false;
    141 
    142                 list_foreach(inet_link_list, link_list, inet_link_t, ilink) {
    143                         if (ilink->svc_id == svcs[i]) {
    144                                 already_known = true;
    145                                 break;
    146                         }
    147                 }
    148 
    149                 if (!already_known) {
    150                         log_msg(LOG_DEFAULT, LVL_DEBUG, "Found IP link '%lu'",
    151                             (unsigned long) svcs[i]);
    152                         rc = inet_link_open(svcs[i]);
    153                         if (rc != EOK)
    154                                 log_msg(LOG_DEFAULT, LVL_ERROR, "Could not open IP link.");
    155                 }
    156         }
    157 
    158         fibril_mutex_unlock(&inet_discovery_lock);
    159         return EOK;
    160 }
    161 
    162115static inet_link_t *inet_link_new(void)
    163116{
     
    183136}
    184137
    185 static int inet_link_open(service_id_t sid)
     138int inet_link_open(service_id_t sid)
    186139{
    187140        inet_link_t *ilink;
     
    231184
    232185        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    233         list_append(&ilink->link_list, &inet_link_list);
     186
     187        fibril_mutex_lock(&inet_links_lock);
     188
     189        if (inet_link_get_by_id_locked(sid) != NULL) {
     190                fibril_mutex_unlock(&inet_links_lock);
     191                log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu already open",
     192                    sid);
     193                rc = EEXIST;
     194                goto error;
     195        }
     196
     197        list_append(&ilink->link_list, &inet_links);
     198        fibril_mutex_unlock(&inet_links_lock);
    234199
    235200        inet_addrobj_t *addr = NULL;
     
    299264        }
    300265       
     266        log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured link '%s'.", ilink->svc_name);
    301267        return EOK;
    302268       
     
    307273        inet_link_delete(ilink);
    308274        return rc;
    309 }
    310 
    311 static void inet_link_cat_change_cb(void)
    312 {
    313         (void) inet_link_check_new();
    314 }
    315 
    316 int inet_link_discovery_start(void)
    317 {
    318         int rc;
    319 
    320         rc = loc_register_cat_change_cb(inet_link_cat_change_cb);
    321         if (rc != EOK) {
    322                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering callback for IP link "
    323                     "discovery (%d).", rc);
    324                 return rc;
    325         }
    326 
    327         return inet_link_check_new();
    328275}
    329276
     
    478425}
    479426
     427static inet_link_t *inet_link_get_by_id_locked(sysarg_t link_id)
     428{
     429        assert(fibril_mutex_is_locked(&inet_links_lock));
     430
     431        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     432                if (ilink->svc_id == link_id)
     433                        return ilink;
     434        }
     435
     436        return NULL;
     437}
     438
    480439inet_link_t *inet_link_get_by_id(sysarg_t link_id)
    481440{
    482         fibril_mutex_lock(&inet_discovery_lock);
    483 
    484         list_foreach(inet_link_list, link_list, inet_link_t, ilink) {
    485                 if (ilink->svc_id == link_id) {
    486                         fibril_mutex_unlock(&inet_discovery_lock);
    487                         return ilink;
    488                 }
    489         }
    490 
    491         fibril_mutex_unlock(&inet_discovery_lock);
    492         return NULL;
     441        inet_link_t *ilink;
     442
     443        fibril_mutex_lock(&inet_links_lock);
     444        ilink = inet_link_get_by_id_locked(link_id);
     445        fibril_mutex_unlock(&inet_links_lock);
     446
     447        return ilink;
    493448}
    494449
     
    499454        size_t count, i;
    500455
    501         fibril_mutex_lock(&inet_discovery_lock);
    502         count = list_count(&inet_link_list);
     456        fibril_mutex_lock(&inet_links_lock);
     457        count = list_count(&inet_links);
    503458
    504459        id_list = calloc(count, sizeof(sysarg_t));
    505460        if (id_list == NULL) {
    506                 fibril_mutex_unlock(&inet_discovery_lock);
     461                fibril_mutex_unlock(&inet_links_lock);
    507462                return ENOMEM;
    508463        }
    509464
    510465        i = 0;
    511         list_foreach(inet_link_list, link_list, inet_link_t, ilink) {
     466        list_foreach(inet_links, link_list, inet_link_t, ilink) {
    512467                id_list[i++] = ilink->svc_id;
    513468                log_msg(LOG_DEFAULT, LVL_NOTE, "add link to list");
    514469        }
    515470
    516         fibril_mutex_unlock(&inet_discovery_lock);
     471        fibril_mutex_unlock(&inet_links_lock);
    517472
    518473        log_msg(LOG_DEFAULT, LVL_NOTE, "return %zu links", count);
  • uspace/srv/net/inetsrv/inet_link.h

    r884c56b r04ecc6d  
    4141#include "inetsrv.h"
    4242
    43 extern int inet_link_discovery_start(void);
     43extern int inet_link_open(service_id_t);
    4444extern int inet_link_send_dgram(inet_link_t *, addr32_t,
    4545    addr32_t, inet_dgram_t *, uint8_t, uint8_t, int);
  • uspace/srv/net/inetsrv/inetcfg.c

    r884c56b r04ecc6d  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2013 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    160160}
    161161
     162static int inetcfg_link_add(sysarg_t link_id)
     163{
     164        return inet_link_open(link_id);
     165}
     166
    162167static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
    163168{
     
    180185}
    181186
     187static int inetcfg_link_remove(sysarg_t link_id)
     188{
     189        return ENOTSUP;
     190}
     191
    182192static int inetcfg_sroute_create(char *name, inet_naddr_t *dest,
    183193    inet_addr_t *router, sysarg_t *sroute_id)
     
    483493}
    484494
     495static void inetcfg_link_add_srv(ipc_callid_t callid, ipc_call_t *call)
     496{
     497        sysarg_t link_id;
     498        int rc;
     499
     500        log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
     501
     502        link_id = IPC_GET_ARG1(*call);
     503
     504        rc = inetcfg_link_add(link_id);
     505        async_answer_0(callid, rc);
     506}
     507
    485508static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
    486509{
     
    536559}
    537560
     561static void inetcfg_link_remove_srv(ipc_callid_t callid, ipc_call_t *call)
     562{
     563        sysarg_t link_id;
     564        int rc;
     565
     566        log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
     567
     568        link_id = IPC_GET_ARG1(*call);
     569
     570        rc = inetcfg_link_remove(link_id);
     571        async_answer_0(callid, rc);
     572}
     573
    538574static void inetcfg_sroute_create_srv(ipc_callid_t iid,
    539575    ipc_call_t *icall)
     
    714750                sysarg_t method = IPC_GET_IMETHOD(call);
    715751
     752                log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
    716753                if (!method) {
    717754                        /* The other side has hung up */
     
    742779                        inetcfg_get_sroute_list_srv(callid, &call);
    743780                        break;
     781                case INETCFG_LINK_ADD:
     782                        inetcfg_link_add_srv(callid, &call);
     783                        break;
    744784                case INETCFG_LINK_GET:
    745785                        inetcfg_link_get_srv(callid, &call);
     786                        break;
     787                case INETCFG_LINK_REMOVE:
     788                        inetcfg_link_remove_srv(callid, &call);
    746789                        break;
    747790                case INETCFG_SROUTE_CREATE:
  • uspace/srv/net/inetsrv/inetsrv.c

    r884c56b r04ecc6d  
    124124        }
    125125       
    126         rc = inet_link_discovery_start();
    127         if (rc != EOK)
    128                 return EEXIST;
    129        
    130126        return EOK;
    131127}
Note: See TracChangeset for help on using the changeset viewer.