Changeset fe5a9fc in mainline for uspace/srv/net/il/arp/arp.c


Ignore:
Timestamp:
2011-01-12T11:25:54Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
73ac2e9
Parents:
77429d3
Message:

do not send extra ARP requests if a lookup is currently in progress (but remove the half-filled lookup data as soon as the lookup times out for the second time)
cstyle fixes

File:
1 edited

Legend:

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

    r77429d3 rfe5a9fc  
    7272
    7373/** Number of microseconds to wait for an ARP reply. */
    74 #define ARP_TRANS_WAIT  1000000
     74#define ARP_TRANS_WAIT  1000000
    7575
    7676/** ARP global data. */
     
    8787                trans->hw_addr = NULL;
    8888        }
     89       
    8990        fibril_condvar_broadcast(&trans->cv);
    9091}
     
    9394{
    9495        int count;
    95         arp_trans_t *trans;
    96 
     96       
    9797        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
    98                 trans = arp_addr_items_get_index(&addresses->values, count);
     98                arp_trans_t *trans = arp_addr_items_get_index(&addresses->values,
     99                    count);
    99100                if (trans)
    100101                        arp_clear_trans(trans);
     
    102103}
    103104
    104 
    105 /** Clears the device specific data.
    106  *
    107  * @param[in] device    The device specific data.
     105/** Clear the device specific data.
     106 *
     107 * @param[in] device Device specific data.
    108108 */
    109109static void arp_clear_device(arp_device_t *device)
    110110{
    111111        int count;
    112         arp_proto_t *proto;
    113 
     112       
    114113        for (count = arp_protos_count(&device->protos) - 1; count >= 0;
    115114            count--) {
    116                 proto = arp_protos_get_index(&device->protos, count);
     115                arp_proto_t *proto = arp_protos_get_index(&device->protos,
     116                    count);
     117               
    117118                if (proto) {
    118119                        if (proto->addr)
    119120                                free(proto->addr);
     121                       
    120122                        if (proto->addr_data)
    121123                                free(proto->addr_data);
     124                       
    122125                        arp_clear_addr(&proto->addresses);
    123126                        arp_addr_destroy(&proto->addresses);
    124127                }
    125128        }
     129       
    126130        arp_protos_clear(&device->protos);
    127131}
     
    130134{
    131135        int count;
    132         arp_device_t *device;
    133 
     136       
    134137        fibril_mutex_lock(&arp_globals.lock);
    135138        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    136139            count--) {
    137                 device = arp_cache_get_index(&arp_globals.cache, count);
     140                arp_device_t *device = arp_cache_get_index(&arp_globals.cache,
     141                    count);
     142               
    138143                if (device) {
    139144                        arp_clear_device(device);
    140145                        if (device->addr_data)
    141146                                free(device->addr_data);
     147                       
    142148                        if (device->broadcast_data)
    143149                                free(device->broadcast_data);
    144150                }
    145151        }
     152       
    146153        arp_cache_clear(&arp_globals.cache);
    147154        fibril_mutex_unlock(&arp_globals.lock);
    148         printf("Cache cleaned\n");
     155       
    149156        return EOK;
    150157}
     
    153160    services_t protocol, measured_string_t *address)
    154161{
    155         arp_device_t *device;
    156         arp_proto_t *proto;
    157         arp_trans_t *trans;
    158 
    159162        fibril_mutex_lock(&arp_globals.lock);
    160         device = arp_cache_find(&arp_globals.cache, device_id);
     163       
     164        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    161165        if (!device) {
    162166                fibril_mutex_unlock(&arp_globals.lock);
    163167                return ENOENT;
    164168        }
    165         proto = arp_protos_find(&device->protos, protocol);
     169       
     170        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
    166171        if (!proto) {
    167172                fibril_mutex_unlock(&arp_globals.lock);
    168173                return ENOENT;
    169174        }
    170         trans = arp_addr_find(&proto->addresses, address->value, address->length);
     175       
     176        arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value,
     177            address->length);
    171178        if (trans)
    172179                arp_clear_trans(trans);
     180       
    173181        arp_addr_exclude(&proto->addresses, address->value, address->length);
     182       
    174183        fibril_mutex_unlock(&arp_globals.lock);
    175184        return EOK;
    176185}
    177186
    178 
    179187static int arp_clear_device_req(int arp_phone, device_id_t device_id)
    180188{
    181         arp_device_t *device;
    182 
    183189        fibril_mutex_lock(&arp_globals.lock);
    184         device = arp_cache_find(&arp_globals.cache, device_id);
     190       
     191        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    185192        if (!device) {
    186193                fibril_mutex_unlock(&arp_globals.lock);
    187194                return ENOENT;
    188195        }
     196       
    189197        arp_clear_device(device);
    190         printf("Device %d cleared\n", device_id);
     198       
    191199        fibril_mutex_unlock(&arp_globals.lock);
    192200        return EOK;
    193201}
    194202
    195 /** Creates new protocol specific data.
    196  *
    197  * Allocates and returns the needed memory block as the proto parameter.
    198  *
    199  * @param[out] proto    The allocated protocol specific data.
    200  * @param[in] service   The protocol module service.
    201  * @param[in] address   The actual protocol device address.
    202  * @return              EOK on success.
    203  * @return              ENOMEM if there is not enough memory left.
     203/** Create new protocol specific data.
     204 *
     205 * Allocate and return the needed memory block as the proto parameter.
     206 *
     207 * @param[out] proto   Allocated protocol specific data.
     208 * @param[in]  service Protocol module service.
     209 * @param[in]  address Actual protocol device address.
     210 *
     211 * @return EOK on success.
     212 * @return ENOMEM if there is not enough memory left.
     213 *
    204214 */
    205215static int arp_proto_create(arp_proto_t **proto, services_t service,
    206216    measured_string_t *address)
    207217{
    208         int rc;
    209 
    210218        *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t));
    211219        if (!*proto)
     
    216224        (*proto)->addr_data = address->value;
    217225       
    218         rc = arp_addr_initialize(&(*proto)->addresses);
     226        int rc = arp_addr_initialize(&(*proto)->addresses);
    219227        if (rc != EOK) {
    220228                free(*proto);
     
    225233}
    226234
    227 /** Registers the device.
    228  *
    229  * Creates new device entry in the cache or updates the protocol address if the
     235/** Register the device.
     236 *
     237 * Create new device entry in the cache or update the protocol address if the
    230238 * device with the device identifier and the driver service exists.
    231239 *
    232  * @param[in] device_id The device identifier.
    233  * @param[in] service   The device driver service.
    234  * @param[in] protocol  The protocol service.
    235  * @param[in] address   The actual device protocol address.
    236  * @return              EOK on success.
    237  * @return              EEXIST if another device with the same device identifier
    238  *                      and different driver service exists.
    239  * @return              ENOMEM if there is not enough memory left.
    240  * @return              Other error codes as defined for the
    241  *                      measured_strings_return() function.
     240 * @param[in] device_id Device identifier.
     241 * @param[in] service   Device driver service.
     242 * @param[in] protocol  Protocol service.
     243 * @param[in] address   Actual device protocol address.
     244 *
     245 * @return EOK on success.
     246 * @return EEXIST if another device with the same device identifier
     247 *         and different driver service exists.
     248 * @return ENOMEM if there is not enough memory left.
     249 * @return Other error codes as defined for the
     250 *         measured_strings_return() function.
     251 *
    242252 */
    243253static int arp_device_message(device_id_t device_id, services_t service,
    244254    services_t protocol, measured_string_t *address)
    245255{
    246         arp_device_t *device;
    247         arp_proto_t *proto;
    248         hw_type_t hardware;
    249256        int index;
    250257        int rc;
    251 
     258       
    252259        fibril_mutex_lock(&arp_globals.lock);
    253 
     260       
    254261        /* An existing device? */
    255         device = arp_cache_find(&arp_globals.cache, device_id);
    256 
     262        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    257263        if (device) {
    258264                if (device->service != service) {
    259                         printf("Device %d already exists\n", device->device_id);
     265                        printf("%s: Device %d already exists\n", NAME,
     266                            device->device_id);
    260267                        fibril_mutex_unlock(&arp_globals.lock);
    261268                        return EEXIST;
    262269                }
    263                 proto = arp_protos_find(&device->protos, protocol);
     270               
     271                arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
    264272                if (proto) {
    265273                        free(proto->addr);
     
    273281                                return rc;
    274282                        }
     283                       
    275284                        index = arp_protos_add(&device->protos, proto->service,
    276285                            proto);
     
    280289                                return index;
    281290                        }
    282                         printf("New protocol added:\n\tdevice id\t= "
    283                             "%d\n\tproto\t= %d", device_id, protocol);
     291                       
     292                        printf("%s: New protocol added (id: %d, proto: %d)\n", NAME,
     293                            device_id, protocol);
    284294                }
    285295        } else {
    286                 hardware = hardware_map(service);
     296                hw_type_t hardware = hardware_map(service);
    287297                if (!hardware)
    288298                        return ENOENT;
    289299               
    290                 /* Create a new device */
     300                /* Create new device */
    291301                device = (arp_device_t *) malloc(sizeof(arp_device_t));
    292302                if (!device) {
     
    294304                        return ENOMEM;
    295305                }
     306               
    296307                device->hardware = hardware;
    297308                device->device_id = device_id;
     
    302313                        return rc;
    303314                }
     315               
     316                arp_proto_t *proto;
    304317                rc = arp_proto_create(&proto, protocol, address);
    305318                if (rc != EOK) {
     
    308321                        return rc;
    309322                }
     323               
    310324                index = arp_protos_add(&device->protos, proto->service, proto);
    311325                if (index < 0) {
     
    315329                        return index;
    316330                }
     331               
    317332                device->service = service;
    318333               
    319                 /* Bind the new one */
     334                /* Bind */
    320335                device->phone = nil_bind_service(device->service,
    321336                    (sysarg_t) device->device_id, SERVICE_ARP,
     
    376391                    device->service, protocol);
    377392        }
     393       
    378394        fibril_mutex_unlock(&arp_globals.lock);
    379        
    380395        return EOK;
    381396}
    382397
    383 /** Initializes the ARP module.
     398/** Initialize the ARP module.
    384399 *
    385400 *  @param[in] client_connection The client connection processing function.
    386  *                      The module skeleton propagates its own one.
    387  *  @return             EOK on success.
    388  *  @return             ENOMEM if there is not enough memory left.
     401 *                               The module skeleton propagates its own one.
     402 *
     403 *  @return EOK on success.
     404 *  @return ENOMEM if there is not enough memory left.
     405 *
    389406 */
    390407int arp_initialize(async_client_conn_t client_connection)
    391408{
    392         int rc;
    393 
    394409        fibril_mutex_initialize(&arp_globals.lock);
     410       
    395411        fibril_mutex_lock(&arp_globals.lock);
    396412        arp_globals.client_connection = client_connection;
    397         rc = arp_cache_initialize(&arp_globals.cache);
     413        int rc = arp_cache_initialize(&arp_globals.cache);
    398414        fibril_mutex_unlock(&arp_globals.lock);
    399415       
     
    401417}
    402418
    403 /** Updates the device content length according to the new MTU value.
    404  *
    405  * @param[in] device_id The device identifier.
    406  * @param[in] mtu       The new mtu value.
    407  * @return              ENOENT if device is not found.
    408  * @return              EOK on success.
     419/** Update the device content length according to the new MTU value.
     420 *
     421 * @param[in] device_id Device identifier.
     422 * @param[in] mtu       New MTU value.
     423 *
     424 * @return ENOENT if device is not found.
     425 * @return EOK on success.
     426 *
    409427 */
    410428static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
    411429{
    412         arp_device_t *device;
    413 
    414430        fibril_mutex_lock(&arp_globals.lock);
    415         device = arp_cache_find(&arp_globals.cache, device_id);
     431       
     432        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    416433        if (!device) {
    417434                fibril_mutex_unlock(&arp_globals.lock);
    418435                return ENOENT;
    419436        }
     437       
    420438        device->packet_dimension.content = mtu;
     439       
    421440        fibril_mutex_unlock(&arp_globals.lock);
    422         printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu);
     441       
     442        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     443       
    423444        return EOK;
    424445}
    425446
    426 /** Processes the received ARP packet.
    427  *
    428  * Updates the source hardware address if the source entry exists or the packet
     447/** Process the received ARP packet.
     448 *
     449 * Update the source hardware address if the source entry exists or the packet
    429450 * is targeted to my protocol address.
    430  * Responses to the ARP request if the packet is the ARP request and is
     451 *
     452 * Respond to the ARP request if the packet is the ARP request and is
    431453 * targeted to my address.
    432454 *
    433  * @param[in] device_id The source device identifier.
    434  * @param[in,out] packet The received packet.
    435  * @return              EOK on success and the packet is no longer needed.
    436  * @return              One on success and the packet has been reused.
    437  * @return              EINVAL if the packet is too small to carry an ARP
    438  *                      packet.
    439  * @return              EINVAL if the received address lengths differs from
    440  *                      the registered values.
    441  * @return              ENOENT if the device is not found in the cache.
    442  * @return              ENOENT if the protocol for the device is not found in
    443  *                      the cache.
    444  * @return              ENOMEM if there is not enough memory left.
     455 * @param[in]     device_id Source device identifier.
     456 * @param[in,out] packet    Received packet.
     457 *
     458 * @return EOK on success and the packet is no longer needed.
     459 * @return One on success and the packet has been reused.
     460 * @return EINVAL if the packet is too small to carry an ARP
     461 *         packet.
     462 * @return EINVAL if the received address lengths differs from
     463 *         the registered values.
     464 * @return ENOENT if the device is not found in the cache.
     465 * @return ENOENT if the protocol for the device is not found in
     466 *         the cache.
     467 * @return ENOMEM if there is not enough memory left.
     468 *
    445469 */
    446470static int arp_receive_message(device_id_t device_id, packet_t *packet)
    447471{
    448         size_t length;
    449         arp_header_t *header;
    450         arp_device_t *device;
    451         arp_proto_t *proto;
    452         arp_trans_t *trans;
    453         uint8_t *src_hw;
    454         uint8_t *src_proto;
    455         uint8_t *des_hw;
    456         uint8_t *des_proto;
    457472        int rc;
    458473       
    459         length = packet_get_data_length(packet);
     474        size_t length = packet_get_data_length(packet);
    460475        if (length <= sizeof(arp_header_t))
    461476                return EINVAL;
    462 
    463         device = arp_cache_find(&arp_globals.cache, device_id);
     477       
     478        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    464479        if (!device)
    465480                return ENOENT;
    466 
    467         header = (arp_header_t *) packet_get_data(packet);
     481       
     482        arp_header_t *header = (arp_header_t *) packet_get_data(packet);
    468483        if ((ntohs(header->hardware) != device->hardware) ||
    469484            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     
    471486                return EINVAL;
    472487        }
    473 
    474         proto = arp_protos_find(&device->protos,
     488       
     489        arp_proto_t *proto = arp_protos_find(&device->protos,
    475490            protocol_unmap(device->service, ntohs(header->protocol)));
    476491        if (!proto)
    477492                return ENOENT;
    478 
    479         src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    480         src_proto = src_hw + header->hardware_length;
    481         des_hw = src_proto + header->protocol_length;
    482         des_proto = des_hw + header->hardware_length;
    483         trans = arp_addr_find(&proto->addresses, src_proto,
     493       
     494        uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
     495        uint8_t *src_proto = src_hw + header->hardware_length;
     496        uint8_t *des_hw = src_proto + header->protocol_length;
     497        uint8_t *des_proto = des_hw + header->hardware_length;
     498       
     499        arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
    484500            header->protocol_length);
    485         /* Exists? */
    486         if (trans && trans->hw_addr) {
     501       
     502        if ((trans) && (trans->hw_addr)) {
     503                /* Translation exists */
    487504                if (trans->hw_addr->length != header->hardware_length)
    488505                        return EINVAL;
     506               
    489507                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    490508        }
     509       
    491510        /* Is my protocol address? */
    492511        if (proto->addr->length != header->protocol_length)
     
    494513       
    495514        if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
    496                 /* Not already updated? */
    497515                if (!trans) {
     516                        /* Update the translation */
    498517                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    499518                        if (!trans)
    500519                                return ENOMEM;
     520                       
    501521                        trans->hw_addr = NULL;
    502522                        fibril_condvar_initialize(&trans->cv);
     
    508528                        }
    509529                }
     530               
    510531                if (!trans->hw_addr) {
    511532                        trans->hw_addr = measured_string_create_bulk(src_hw,
     
    517538                        fibril_condvar_broadcast(&trans->cv);
    518539                }
     540               
    519541                if (ntohs(header->operation) == ARPOP_REQUEST) {
    520542                        header->operation = htons(ARPOP_REPLY);
     
    537559                }
    538560        }
    539 
     561       
    540562        return EOK;
    541563}
     
    566588        header->protocol_length = (uint8_t) proto->addr->length;
    567589        header->operation = htons(ARPOP_REQUEST);
     590       
    568591        length = sizeof(arp_header_t);
     592       
    569593        memcpy(((uint8_t *) header) + length, device->addr->value,
    570594            device->addr->length);
     
    603627 *
    604628 */
    605 static int
    606 arp_translate_message(device_id_t device_id, services_t protocol,
     629static int arp_translate_message(device_id_t device_id, services_t protocol,
    607630    measured_string_t *target, measured_string_t **translation)
    608631{
    609         arp_device_t *device;
    610         arp_proto_t *proto;
    611         arp_trans_t *trans;
    612632        bool retry = false;
    613633        int rc;
     
    617637                return EBADMEM;
    618638       
    619         device = arp_cache_find(&arp_globals.cache, device_id);
     639        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    620640        if (!device)
    621641                return ENOENT;
    622642       
    623         proto = arp_protos_find(&device->protos, protocol);
     643        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
    624644        if ((!proto) || (proto->addr->length != target->length))
    625645                return ENOENT;
    626646       
    627         trans = arp_addr_find(&proto->addresses, target->value, target->length);
     647        arp_trans_t *trans = arp_addr_find(&proto->addresses, target->value,
     648            target->length);
    628649        if (trans) {
    629650                if (trans->hw_addr) {
     
    632653                }
    633654               
    634                 if (retry)
     655                if (retry) {
     656                        /* Remove the translation from the map */
     657                        arp_clear_trans(trans);
     658                        arp_addr_exclude(&proto->addresses, target->value,
     659                            target->length);
    635660                        return EAGAIN;
    636                
    637                 rc = arp_send_request(device_id, protocol, target, device, proto);
    638                 if (rc != EOK)
    639                         return rc;
     661                }
    640662               
    641663                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     
    654676        if (!trans)
    655677                return ENOMEM;
     678       
    656679        trans->hw_addr = NULL;
    657680        fibril_condvar_initialize(&trans->cv);
     681       
    658682        rc = arp_addr_add(&proto->addresses, target->value, target->length,
    659683            trans);
     
    676700}
    677701
    678 
    679 /** Processes the ARP message.
    680  *
    681  * @param[in] callid    The message identifier.
    682  * @param[in] call      The message parameters.
    683  * @param[out] answer   The message answer parameters.
    684  * @param[out] answer_count The last parameter for the actual answer in the
    685  *                      answer parameter.
    686  * @return              EOK on success.
    687  * @return              ENOTSUP if the message is not known.
     702/** Process the ARP message.
     703 *
     704 * @param[in]  callid Message identifier.
     705 * @param[in]  call   Message parameters.
     706 * @param[out] answer Answer.
     707 * @param[out] count  Number of arguments of the answer.
     708 *
     709 * @return EOK on success.
     710 * @return ENOTSUP if the message is not known.
    688711 *
    689712 * @see arp_interface.h
    690713 * @see IS_NET_ARP_MESSAGE()
    691  */
    692 int
    693 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    694     ipc_call_t *answer, size_t *answer_count)
     714 *
     715 */
     716int arp_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     717    size_t *count)
    695718{
    696719        measured_string_t *address;
     
    701724        int rc;
    702725       
    703         *answer_count = 0;
     726        *count = 0;
    704727        switch (IPC_GET_IMETHOD(*call)) {
    705728        case IPC_M_PHONE_HUNGUP:
     
    717740                        free(data);
    718741                }
     742               
    719743                return rc;
    720744       
     
    729753                free(address);
    730754                free(data);
     755               
    731756                if (rc != EOK) {
    732757                        fibril_mutex_unlock(&arp_globals.lock);
    733758                        return rc;
    734759                }
     760               
    735761                if (!translation) {
    736762                        fibril_mutex_unlock(&arp_globals.lock);
    737763                        return ENOENT;
    738764                }
     765               
    739766                rc = measured_strings_reply(translation, 1);
    740767                fibril_mutex_unlock(&arp_globals.lock);
    741768                return rc;
    742 
     769       
    743770        case NET_ARP_CLEAR_DEVICE:
    744771                return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
    745 
     772       
    746773        case NET_ARP_CLEAR_ADDRESS:
    747774                rc = measured_strings_receive(&address, &data, 1);
     
    793820/** Default thread for new connections.
    794821 *
    795  * @param[in] iid       The initial message identifier.
    796  * @param[in] icall     The initial message call structure.
     822 * @param[in] iid   Initial message identifier.
     823 * @param[in] icall Initial message call structure.
    797824 */
    798825static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    816843               
    817844                /* Process the message */
    818                 int res = il_module_message_standalone(callid, &call, &answer,
     845                int res = il_module_message(callid, &call, &answer,
    819846                    &count);
    820847               
     
    832859}
    833860
    834 /** Starts the module.
    835  *
    836  * @return              EOK on success.
    837  * @return              Other error codes as defined for each specific module
    838  *                      start function.
    839  */
    840861int main(int argc, char *argv[])
    841862{
    842         int rc;
    843        
    844863        /* Start the module */
    845         rc = il_module_start_standalone(il_client_connection);
    846         return rc;
     864        return il_module_start(il_client_connection);
    847865}
    848866
    849867/** @}
    850868 */
    851 
Note: See TracChangeset for help on using the changeset viewer.