Ignore:
File:
1 edited

Legend:

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

    r02a09ed rf9b2cb4c  
    4343#include <io/log.h>
    4444#include <loc.h>
    45 #include <device/nic.h>
     45#include <nic_iface.h>
    4646#include <stdlib.h>
    47 
     47#include <mem.h>
    4848#include "ethip.h"
    4949#include "ethip_nic.h"
     
    8383                already_known = false;
    8484
    85                 list_foreach(ethip_nic_list, nic_link) {
    86                         ethip_nic_t *nic = list_get_instance(nic_link,
    87                             ethip_nic_t, nic_list);
     85                list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
    8886                        if (nic->svc_id == svcs[i]) {
    8987                                already_known = true;
     
    108106{
    109107        ethip_nic_t *nic = calloc(1, sizeof(ethip_nic_t));
    110 
    111108        if (nic == NULL) {
    112109                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC structure. "
     
    114111                return NULL;
    115112        }
    116 
    117         link_initialize(&nic->nic_list);
     113       
     114        link_initialize(&nic->link);
    118115        list_initialize(&nic->addr_list);
    119 
     116       
    120117        return nic;
    121118}
     
    130127        }
    131128       
    132         link_initialize(&laddr->addr_list);
     129        link_initialize(&laddr->link);
    133130        laddr->addr = *addr;
    134131       
     
    140137        if (nic->svc_name != NULL)
    141138                free(nic->svc_name);
     139       
    142140        free(nic);
    143141}
     
    164162        }
    165163       
    166         nic->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
     164        nic->sess = loc_service_connect(sid, INTERFACE_DDF, 0);
    167165        if (nic->sess == NULL) {
    168166                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting '%s'", nic->svc_name);
     
    180178
    181179        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened NIC '%s'", nic->svc_name);
    182         list_append(&nic->nic_list, &ethip_nic_list);
     180        list_append(&nic->link, &ethip_nic_list);
    183181        in_list = true;
    184182
     
    203201        }
    204202
     203        rc = nic_broadcast_set_mode(nic->sess, NIC_BROADCAST_ACCEPTED);
     204        if (rc != EOK) {
     205                log_msg(LOG_DEFAULT, LVL_ERROR, "Error enabling "
     206                    "reception of broadcast frames on '%s'.", nic->svc_name);
     207                goto error;
     208        }
     209
    205210        log_msg(LOG_DEFAULT, LVL_DEBUG, "Initialized IP link service,");
    206211
     
    209214error:
    210215        if (in_list)
    211                 list_remove(&nic->nic_list);
     216                list_remove(&nic->link);
     217       
    212218        if (nic->sess != NULL)
    213219                async_hangup(nic->sess);
     220       
    214221        ethip_nic_delete(nic);
    215222        return rc;
     
    224231    ipc_call_t *call)
    225232{
    226         log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_changed()");
    227         async_answer_0(callid, ENOTSUP);
     233        uint8_t *addr;
     234        size_t size;
     235        int rc;
     236
     237        rc = async_data_write_accept((void **)&addr, false, 0, 0, 0, &size);
     238        if (rc != EOK) {
     239                log_msg(LOG_DEFAULT, LVL_DEBUG, "data_write_accept() failed");
     240                return;
     241        }
     242
     243        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_changed(): "
     244            "new addr=%02x:%02x:%02x:%02x:%02x:%02x",
     245            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
     246
     247        memcpy(&nic->mac_addr, addr, sizeof(nic->mac_addr));
     248
     249        rc = iplink_ev_change_addr(&nic->iplink, &nic->mac_addr);
     250        if (rc != EOK) {
     251                log_msg(LOG_DEFAULT, LVL_DEBUG, "iplink_ev_change_addr() failed");
     252                return;
     253        }
     254
     255        free(addr);
     256        async_answer_0(callid, EOK);
    228257}
    229258
     
    288317                        break;
    289318                default:
     319                        log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, IPC_GET_IMETHOD(call));
    290320                        async_answer_0(callid, ENOTSUP);
    291321                }
     
    310340            (unsigned) iplink_sid);
    311341
    312         list_foreach(ethip_nic_list, link) {
     342        list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
    313343                log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
    314                 ethip_nic_t *nic = list_get_instance(link, ethip_nic_t,
    315                     nic_list);
    316 
    317344                if (nic->iplink_sid == iplink_sid) {
    318345                        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - found %p", nic);
     
    334361}
    335362
     363/** Setup accepted multicast addresses
     364 *
     365 * Currently the set of accepted multicast addresses is
     366 * determined only based on IPv6 addresses.
     367 *
     368 */
     369static int ethip_nic_setup_multicast(ethip_nic_t *nic)
     370{
     371        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_setup_multicast()");
     372       
     373        /* Count the number of multicast addresses */
     374       
     375        size_t count = 0;
     376       
     377        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
     378                ip_ver_t ver = inet_addr_get(&laddr->addr, NULL, NULL);
     379                if (ver == ip_v6)
     380                        count++;
     381        }
     382       
     383        if (count == 0)
     384                return nic_multicast_set_mode(nic->sess, NIC_MULTICAST_BLOCKED,
     385                    NULL, 0);
     386       
     387        nic_address_t *mac_list = calloc(count, sizeof(nic_address_t));
     388        if (mac_list == NULL)
     389                return ENOMEM;
     390       
     391        /* Create the multicast MAC list */
     392       
     393        size_t i = 0;
     394       
     395        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
     396                addr128_t v6;
     397                ip_ver_t ver = inet_addr_get(&laddr->addr, NULL, &v6);
     398                if (ver != ip_v6)
     399                        continue;
     400               
     401                assert(i < count);
     402               
     403                addr48_t mac;
     404                addr48_solicited_node(v6, mac);
     405               
     406                /* Avoid duplicate addresses in the list */
     407               
     408                bool found = false;
     409               
     410                for (size_t j = 0; j < i; j++) {
     411                        if (addr48_compare(mac_list[j].address, mac)) {
     412                                found = true;
     413                                break;
     414                        }
     415                }
     416               
     417                if (!found) {
     418                        addr48(mac, mac_list[i].address);
     419                        i++;
     420                } else
     421                        count--;
     422        }
     423       
     424        /* Setup the multicast MAC list */
     425       
     426        int rc = nic_multicast_set_mode(nic->sess, NIC_MULTICAST_LIST,
     427            mac_list, count);
     428       
     429        free(mac_list);
     430        return rc;
     431}
     432
    336433int ethip_nic_addr_add(ethip_nic_t *nic, inet_addr_t *addr)
    337434{
     
    342439                return ENOMEM;
    343440       
    344         list_append(&laddr->addr_list, &nic->addr_list);
    345         return EOK;
     441        list_append(&laddr->link, &nic->addr_list);
     442       
     443        return ethip_nic_setup_multicast(nic);
    346444}
    347445
     
    354452                return ENOENT;
    355453       
    356         list_remove(&laddr->addr_list);
     454        list_remove(&laddr->link);
    357455        ethip_link_addr_delete(laddr);
    358         return EOK;
     456       
     457        return ethip_nic_setup_multicast(nic);
    359458}
    360459
     
    364463        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_find()");
    365464       
    366         list_foreach(nic->addr_list, link) {
    367                 ethip_link_addr_t *laddr = list_get_instance(link,
    368                     ethip_link_addr_t, addr_list);
    369                
     465        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
    370466                if (inet_addr_compare(addr, &laddr->addr))
    371467                        return laddr;
Note: See TracChangeset for help on using the changeset viewer.