Ignore:
File:
1 edited

Legend:

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

    r1f97352 rf9b2cb4c  
    4343#include <stdlib.h>
    4444#include <str.h>
    45 #include <net/socket_codes.h>
    4645#include "addrobj.h"
    4746#include "inetsrv.h"
     
    5554static uint16_t ip_ident = 0;
    5655
    57 static int inet_link_open(service_id_t);
    58 static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
     56static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, ip_ver_t);
     57static int inet_iplink_change_addr(iplink_t *, addr48_t);
     58static inet_link_t *inet_link_get_by_id_locked(sysarg_t);
    5959
    6060static iplink_ev_ops_t inet_iplink_ev_ops = {
    61         .recv = inet_iplink_recv
     61        .recv = inet_iplink_recv,
     62        .change_addr = inet_iplink_change_addr,
    6263};
    6364
    64 static LIST_INITIALIZE(inet_link_list);
    65 static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
     65static LIST_INITIALIZE(inet_links);
     66static FIBRIL_MUTEX_INITIALIZE(inet_links_lock);
    6667
    6768static addr128_t link_local_node_ip =
     
    7273{
    7374        memcpy(ip_addr, link_local_node_ip, 16);
    74        
     75
    7576        ip_addr[8] = mac_addr[0] ^ 0x02;
    7677        ip_addr[9] = mac_addr[1];
     
    8182}
    8283
    83 static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
     84static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, ip_ver_t ver)
    8485{
    8586        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
    86        
     87
    8788        int rc;
    8889        inet_packet_t packet;
    89        
    90         switch (af) {
    91         case AF_INET:
    92                 rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
     90        inet_link_t *ilink;
     91
     92        ilink = (inet_link_t *)iplink_get_userptr(iplink);
     93
     94        switch (ver) {
     95        case ip_v4:
     96                rc = inet_pdu_decode(sdu->data, sdu->size, ilink->svc_id,
     97                    &packet);
    9398                break;
    94         case AF_INET6:
    95                 rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
     99        case ip_v6:
     100                rc = inet_pdu_decode6(sdu->data, sdu->size, ilink->svc_id,
     101                    &packet);
    96102                break;
    97103        default:
    98                 log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid address family");
     104                log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid IP version");
    99105                return EINVAL;
    100106        }
    101        
     107
    102108        if (rc != EOK) {
    103109                log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
    104110                return rc;
    105111        }
    106        
     112
     113        log_msg(LOG_DEFAULT, LVL_NOTE, "inet_iplink_recv: link_id=%zu", packet.link_id);
    107114        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
    108115        rc = inet_recv_packet(&packet);
    109116        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
    110117        free(packet.data);
    111        
     118
    112119        return rc;
    113120}
    114121
    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, ilink_link) {
    143                         inet_link_t *ilink = list_get_instance(ilink_link,
    144                             inet_link_t, link_list);
    145                         if (ilink->svc_id == svcs[i]) {
    146                                 already_known = true;
    147                                 break;
    148                         }
    149                 }
    150 
    151                 if (!already_known) {
    152                         log_msg(LOG_DEFAULT, LVL_DEBUG, "Found IP link '%lu'",
    153                             (unsigned long) svcs[i]);
    154                         rc = inet_link_open(svcs[i]);
    155                         if (rc != EOK)
    156                                 log_msg(LOG_DEFAULT, LVL_ERROR, "Could not open IP link.");
    157                 }
    158         }
    159 
    160         fibril_mutex_unlock(&inet_discovery_lock);
     122static int inet_iplink_change_addr(iplink_t *iplink, addr48_t mac)
     123{
     124        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_change_addr(): "
     125            "new addr=%02x:%02x:%02x:%02x:%02x:%02x",
     126            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
     127
     128        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     129                if (ilink->sess == iplink->sess)
     130                        memcpy(&ilink->mac, mac, sizeof(addr48_t));
     131        }
     132
    161133        return EOK;
    162134}
     
    185157}
    186158
    187 static int inet_link_open(service_id_t sid)
     159int inet_link_open(service_id_t sid)
    188160{
    189161        inet_link_t *ilink;
     
    205177        }
    206178
    207         ilink->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
     179        ilink->sess = loc_service_connect(sid, INTERFACE_IPLINK, 0);
    208180        if (ilink->sess == NULL) {
    209181                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
     
    211183        }
    212184
    213         rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
     185        rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, ilink, &ilink->iplink);
    214186        if (rc != EOK) {
    215187                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening IP link '%s'",
     
    233205
    234206        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    235         list_append(&ilink->link_list, &inet_link_list);
     207
     208        fibril_mutex_lock(&inet_links_lock);
     209
     210        if (inet_link_get_by_id_locked(sid) != NULL) {
     211                fibril_mutex_unlock(&inet_links_lock);
     212                log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu already open",
     213                    sid);
     214                rc = EEXIST;
     215                goto error;
     216        }
     217
     218        list_append(&ilink->link_list, &inet_links);
     219        fibril_mutex_unlock(&inet_links_lock);
    236220
    237221        inet_addrobj_t *addr = NULL;
    238222       
     223        /* XXX FIXME Cannot rely on loopback being the first IP link service!! */
    239224        if (first_link) {
    240225                addr = inet_addrobj_new();
     
    242227                inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
    243228                first_link = false;
    244         } else {
    245                 /*
    246                  * FIXME
    247                  * Setting static IPv4 address for testing purposes:
    248                  * 10.0.2.15/24
    249                  */
    250                 addr = inet_addrobj_new();
    251                
    252                 inet_naddr(&addr->naddr, 10, 0, 2, 15, 24);
    253229        }
    254230       
     
    309285        }
    310286       
     287        log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured link '%s'.", ilink->svc_name);
    311288        return EOK;
    312289       
     
    317294        inet_link_delete(ilink);
    318295        return rc;
    319 }
    320 
    321 static void inet_link_cat_change_cb(void)
    322 {
    323         (void) inet_link_check_new();
    324 }
    325 
    326 int inet_link_discovery_start(void)
    327 {
    328         int rc;
    329 
    330         rc = loc_register_cat_change_cb(inet_link_cat_change_cb);
    331         if (rc != EOK) {
    332                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering callback for IP link "
    333                     "discovery (%d).", rc);
    334                 return rc;
    335         }
    336 
    337         return inet_link_check_new();
    338296}
    339297
     
    357315{
    358316        addr32_t src_v4;
    359         uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL);
    360         if (src_af != AF_INET)
     317        ip_ver_t src_ver = inet_addr_get(&dgram->src, &src_v4, NULL);
     318        if (src_ver != ip_v4)
    361319                return EINVAL;
    362320       
    363321        addr32_t dest_v4;
    364         uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL);
    365         if (dest_af != AF_INET)
     322        ip_ver_t dest_ver = inet_addr_get(&dgram->dest, &dest_v4, NULL);
     323        if (dest_ver != ip_v4)
    366324                return EINVAL;
    367325       
     
    432390{
    433391        addr128_t src_v6;
    434         uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6);
    435         if (src_af != AF_INET6)
     392        ip_ver_t src_ver = inet_addr_get(&dgram->src, NULL, &src_v6);
     393        if (src_ver != ip_v6)
    436394                return EINVAL;
    437395       
    438396        addr128_t dest_v6;
    439         uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6);
    440         if (dest_af != AF_INET6)
     397        ip_ver_t dest_ver = inet_addr_get(&dgram->dest, NULL, &dest_v6);
     398        if (dest_ver != ip_v6)
    441399                return EINVAL;
    442400       
     
    488446}
    489447
     448static inet_link_t *inet_link_get_by_id_locked(sysarg_t link_id)
     449{
     450        assert(fibril_mutex_is_locked(&inet_links_lock));
     451
     452        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     453                if (ilink->svc_id == link_id)
     454                        return ilink;
     455        }
     456
     457        return NULL;
     458}
     459
    490460inet_link_t *inet_link_get_by_id(sysarg_t link_id)
    491461{
    492         fibril_mutex_lock(&inet_discovery_lock);
    493 
    494         list_foreach(inet_link_list, elem) {
    495                 inet_link_t *ilink = list_get_instance(elem, inet_link_t,
    496                     link_list);
    497 
    498                 if (ilink->svc_id == link_id) {
    499                         fibril_mutex_unlock(&inet_discovery_lock);
    500                         return ilink;
    501                 }
    502         }
    503 
    504         fibril_mutex_unlock(&inet_discovery_lock);
    505         return NULL;
     462        inet_link_t *ilink;
     463
     464        fibril_mutex_lock(&inet_links_lock);
     465        ilink = inet_link_get_by_id_locked(link_id);
     466        fibril_mutex_unlock(&inet_links_lock);
     467
     468        return ilink;
     469}
     470
     471/** Get IDs of all links. */
     472int inet_link_get_id_list(sysarg_t **rid_list, size_t *rcount)
     473{
     474        sysarg_t *id_list;
     475        size_t count, i;
     476
     477        fibril_mutex_lock(&inet_links_lock);
     478        count = list_count(&inet_links);
     479
     480        id_list = calloc(count, sizeof(sysarg_t));
     481        if (id_list == NULL) {
     482                fibril_mutex_unlock(&inet_links_lock);
     483                return ENOMEM;
     484        }
     485
     486        i = 0;
     487        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     488                id_list[i++] = ilink->svc_id;
     489        }
     490
     491        fibril_mutex_unlock(&inet_links_lock);
     492
     493        *rid_list = id_list;
     494        *rcount = count;
     495
     496        return EOK;
    506497}
    507498
Note: See TracChangeset for help on using the changeset viewer.