Ignore:
File:
1 edited

Legend:

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

    rf9b2cb4c r1f97352  
    4343#include <stdlib.h>
    4444#include <str.h>
     45#include <net/socket_codes.h>
    4546#include "addrobj.h"
    4647#include "inetsrv.h"
     
    5455static uint16_t ip_ident = 0;
    5556
    56 static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, ip_ver_t);
    57 static int inet_iplink_change_addr(iplink_t *, addr48_t);
    58 static inet_link_t *inet_link_get_by_id_locked(sysarg_t);
     57static int inet_link_open(service_id_t);
     58static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
    5959
    6060static iplink_ev_ops_t inet_iplink_ev_ops = {
    61         .recv = inet_iplink_recv,
    62         .change_addr = inet_iplink_change_addr,
     61        .recv = inet_iplink_recv
    6362};
    6463
    65 static LIST_INITIALIZE(inet_links);
    66 static FIBRIL_MUTEX_INITIALIZE(inet_links_lock);
     64static LIST_INITIALIZE(inet_link_list);
     65static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
    6766
    6867static addr128_t link_local_node_ip =
     
    7372{
    7473        memcpy(ip_addr, link_local_node_ip, 16);
    75 
     74       
    7675        ip_addr[8] = mac_addr[0] ^ 0x02;
    7776        ip_addr[9] = mac_addr[1];
     
    8281}
    8382
    84 static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, ip_ver_t ver)
     83static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
    8584{
    8685        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
    87 
     86       
    8887        int rc;
    8988        inet_packet_t 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);
     89       
     90        switch (af) {
     91        case AF_INET:
     92                rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
    9893                break;
    99         case ip_v6:
    100                 rc = inet_pdu_decode6(sdu->data, sdu->size, ilink->svc_id,
    101                     &packet);
     94        case AF_INET6:
     95                rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
    10296                break;
    10397        default:
    104                 log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid IP version");
     98                log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid address family");
    10599                return EINVAL;
    106100        }
    107 
     101       
    108102        if (rc != EOK) {
    109103                log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
    110104                return rc;
    111105        }
    112 
    113         log_msg(LOG_DEFAULT, LVL_NOTE, "inet_iplink_recv: link_id=%zu", packet.link_id);
     106       
    114107        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
    115108        rc = inet_recv_packet(&packet);
    116109        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
    117110        free(packet.data);
    118 
     111       
    119112        return rc;
    120113}
    121114
    122 static 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 
     115static 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);
    133161        return EOK;
    134162}
     
    157185}
    158186
    159 int inet_link_open(service_id_t sid)
     187static int inet_link_open(service_id_t sid)
    160188{
    161189        inet_link_t *ilink;
     
    177205        }
    178206
    179         ilink->sess = loc_service_connect(sid, INTERFACE_IPLINK, 0);
     207        ilink->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
    180208        if (ilink->sess == NULL) {
    181209                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
     
    183211        }
    184212
    185         rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, ilink, &ilink->iplink);
     213        rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
    186214        if (rc != EOK) {
    187215                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening IP link '%s'",
     
    205233
    206234        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    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);
     235        list_append(&ilink->link_list, &inet_link_list);
    220236
    221237        inet_addrobj_t *addr = NULL;
    222238       
    223         /* XXX FIXME Cannot rely on loopback being the first IP link service!! */
    224239        if (first_link) {
    225240                addr = inet_addrobj_new();
     
    227242                inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
    228243                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);
    229253        }
    230254       
     
    285309        }
    286310       
    287         log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured link '%s'.", ilink->svc_name);
    288311        return EOK;
    289312       
     
    294317        inet_link_delete(ilink);
    295318        return rc;
     319}
     320
     321static void inet_link_cat_change_cb(void)
     322{
     323        (void) inet_link_check_new();
     324}
     325
     326int 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();
    296338}
    297339
     
    315357{
    316358        addr32_t src_v4;
    317         ip_ver_t src_ver = inet_addr_get(&dgram->src, &src_v4, NULL);
    318         if (src_ver != ip_v4)
     359        uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL);
     360        if (src_af != AF_INET)
    319361                return EINVAL;
    320362       
    321363        addr32_t dest_v4;
    322         ip_ver_t dest_ver = inet_addr_get(&dgram->dest, &dest_v4, NULL);
    323         if (dest_ver != ip_v4)
     364        uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL);
     365        if (dest_af != AF_INET)
    324366                return EINVAL;
    325367       
     
    390432{
    391433        addr128_t src_v6;
    392         ip_ver_t src_ver = inet_addr_get(&dgram->src, NULL, &src_v6);
    393         if (src_ver != ip_v6)
     434        uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6);
     435        if (src_af != AF_INET6)
    394436                return EINVAL;
    395437       
    396438        addr128_t dest_v6;
    397         ip_ver_t dest_ver = inet_addr_get(&dgram->dest, NULL, &dest_v6);
    398         if (dest_ver != ip_v6)
     439        uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6);
     440        if (dest_af != AF_INET6)
    399441                return EINVAL;
    400442       
     
    446488}
    447489
    448 static 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)
     490inet_link_t *inet_link_get_by_id(sysarg_t link_id)
     491{
     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);
    454500                        return ilink;
    455         }
    456 
     501                }
     502        }
     503
     504        fibril_mutex_unlock(&inet_discovery_lock);
    457505        return NULL;
    458 }
    459 
    460 inet_link_t *inet_link_get_by_id(sysarg_t link_id)
    461 {
    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. */
    472 int 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;
    497506}
    498507
Note: See TracChangeset for help on using the changeset viewer.