Ignore:
File:
1 edited

Legend:

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

    r3e6a98c5 r695b6ff  
    4545#include <device/nic.h>
    4646#include <stdlib.h>
    47 
     47#include <net/socket_codes.h>
     48#include <mem.h>
    4849#include "ethip.h"
    4950#include "ethip_nic.h"
     
    8384                already_known = false;
    8485
    85                 list_foreach(ethip_nic_list, nic_link) {
    86                         ethip_nic_t *nic = list_get_instance(nic_link,
    87                             ethip_nic_t, nic_list);
     86                list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
    8887                        if (nic->svc_id == svcs[i]) {
    8988                                already_known = true;
     
    108107{
    109108        ethip_nic_t *nic = calloc(1, sizeof(ethip_nic_t));
    110 
    111109        if (nic == NULL) {
    112110                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC structure. "
     
    114112                return NULL;
    115113        }
    116 
    117         link_initialize(&nic->nic_list);
     114       
     115        link_initialize(&nic->link);
    118116        list_initialize(&nic->addr_list);
    119 
     117       
    120118        return nic;
    121119}
    122120
    123 static ethip_link_addr_t *ethip_nic_addr_new(iplink_srv_addr_t *addr)
     121static ethip_link_addr_t *ethip_nic_addr_new(inet_addr_t *addr)
    124122{
    125123        ethip_link_addr_t *laddr = calloc(1, sizeof(ethip_link_addr_t));
    126 
    127124        if (laddr == NULL) {
    128125                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC address structure. "
     
    130127                return NULL;
    131128        }
    132 
    133         link_initialize(&laddr->addr_list);
    134         laddr->addr.ipv4 = addr->ipv4;
     129       
     130        link_initialize(&laddr->link);
     131        laddr->addr = *addr;
     132       
    135133        return laddr;
    136134}
     
    140138        if (nic->svc_name != NULL)
    141139                free(nic->svc_name);
     140       
    142141        free(nic);
    143142}
     
    180179
    181180        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened NIC '%s'", nic->svc_name);
    182         list_append(&nic->nic_list, &ethip_nic_list);
     181        list_append(&nic->link, &ethip_nic_list);
    183182        in_list = true;
    184183
     
    193192                goto error;
    194193        }
    195 
    196         mac48_decode(nic_address.address, &nic->mac_addr);
     194       
     195        addr48(nic_address.address, nic->mac_addr);
    197196
    198197        rc = nic_set_state(nic->sess, NIC_STATE_ACTIVE);
     
    203202        }
    204203
    205         log_msg(LOG_DEFAULT, LVL_DEBUG, "Initialized IP link service, MAC = 0x%" PRIx64,
    206             nic->mac_addr.addr);
     204        rc = nic_broadcast_set_mode(nic->sess, NIC_BROADCAST_ACCEPTED);
     205        if (rc != EOK) {
     206                log_msg(LOG_DEFAULT, LVL_ERROR, "Error enabling "
     207                    "reception of broadcast frames on '%s'.", nic->svc_name);
     208                goto error;
     209        }
     210
     211        log_msg(LOG_DEFAULT, LVL_DEBUG, "Initialized IP link service,");
    207212
    208213        return EOK;
     
    210215error:
    211216        if (in_list)
    212                 list_remove(&nic->nic_list);
     217                list_remove(&nic->link);
     218       
    213219        if (nic->sess != NULL)
    214220                async_hangup(nic->sess);
     221       
    215222        ethip_nic_delete(nic);
    216223        return rc;
     
    311318            (unsigned) iplink_sid);
    312319
    313         list_foreach(ethip_nic_list, link) {
     320        list_foreach(ethip_nic_list, link, ethip_nic_t, nic) {
    314321                log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
    315                 ethip_nic_t *nic = list_get_instance(link, ethip_nic_t,
    316                     nic_list);
    317 
    318322                if (nic->iplink_sid == iplink_sid) {
    319323                        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - found %p", nic);
     
    335339}
    336340
    337 int ethip_nic_addr_add(ethip_nic_t *nic, iplink_srv_addr_t *addr)
    338 {
    339         ethip_link_addr_t *laddr;
    340 
     341/** Setup accepted multicast addresses
     342 *
     343 * Currently the set of accepted multicast addresses is
     344 * determined only based on IPv6 addresses.
     345 *
     346 */
     347static int ethip_nic_setup_multicast(ethip_nic_t *nic)
     348{
     349        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_setup_multicast()");
     350       
     351        /* Count the number of multicast addresses */
     352       
     353        size_t count = 0;
     354       
     355        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
     356                uint16_t af = inet_addr_get(&laddr->addr, NULL, NULL);
     357                if (af == AF_INET6)
     358                        count++;
     359        }
     360       
     361        if (count == 0)
     362                return nic_multicast_set_mode(nic->sess, NIC_MULTICAST_BLOCKED,
     363                    NULL, 0);
     364       
     365        nic_address_t *mac_list = calloc(count, sizeof(nic_address_t));
     366        if (mac_list == NULL)
     367                return ENOMEM;
     368       
     369        /* Create the multicast MAC list */
     370       
     371        size_t i = 0;
     372       
     373        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
     374                addr128_t v6;
     375                uint16_t af = inet_addr_get(&laddr->addr, NULL, &v6);
     376                if (af != AF_INET6)
     377                        continue;
     378               
     379                assert(i < count);
     380               
     381                addr48_t mac;
     382                addr48_solicited_node(v6, mac);
     383               
     384                /* Avoid duplicate addresses in the list */
     385               
     386                bool found = false;
     387               
     388                for (size_t j = 0; j < i; j++) {
     389                        if (addr48_compare(mac_list[j].address, mac)) {
     390                                found = true;
     391                                break;
     392                        }
     393                }
     394               
     395                if (!found) {
     396                        addr48(mac, mac_list[i].address);
     397                        i++;
     398                } else
     399                        count--;
     400        }
     401       
     402        /* Setup the multicast MAC list */
     403       
     404        int rc = nic_multicast_set_mode(nic->sess, NIC_MULTICAST_LIST,
     405            mac_list, count);
     406       
     407        free(mac_list);
     408        return rc;
     409}
     410
     411int ethip_nic_addr_add(ethip_nic_t *nic, inet_addr_t *addr)
     412{
    341413        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_add()");
    342         laddr = ethip_nic_addr_new(addr);
     414       
     415        ethip_link_addr_t *laddr = ethip_nic_addr_new(addr);
    343416        if (laddr == NULL)
    344417                return ENOMEM;
    345 
    346         list_append(&laddr->addr_list, &nic->addr_list);
    347         return EOK;
    348 }
    349 
    350 int ethip_nic_addr_remove(ethip_nic_t *nic, iplink_srv_addr_t *addr)
    351 {
    352         ethip_link_addr_t *laddr;
    353 
     418       
     419        list_append(&laddr->link, &nic->addr_list);
     420       
     421        return ethip_nic_setup_multicast(nic);
     422}
     423
     424int ethip_nic_addr_remove(ethip_nic_t *nic, inet_addr_t *addr)
     425{
    354426        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_remove()");
    355 
    356         laddr = ethip_nic_addr_find(nic, addr);
     427       
     428        ethip_link_addr_t *laddr = ethip_nic_addr_find(nic, addr);
    357429        if (laddr == NULL)
    358430                return ENOENT;
    359 
    360         list_remove(&laddr->addr_list);
     431       
     432        list_remove(&laddr->link);
    361433        ethip_link_addr_delete(laddr);
    362         return EOK;
     434       
     435        return ethip_nic_setup_multicast(nic);
    363436}
    364437
    365438ethip_link_addr_t *ethip_nic_addr_find(ethip_nic_t *nic,
    366     iplink_srv_addr_t *addr)
     439    inet_addr_t *addr)
    367440{
    368441        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_find()");
    369 
    370         list_foreach(nic->addr_list, link) {
    371                 ethip_link_addr_t *laddr = list_get_instance(link,
    372                     ethip_link_addr_t, addr_list);
    373 
    374                 if (addr->ipv4 == laddr->addr.ipv4)
     442       
     443        list_foreach(nic->addr_list, link, ethip_link_addr_t, laddr) {
     444                if (inet_addr_compare(addr, &laddr->addr))
    375445                        return laddr;
    376446        }
    377 
     447       
    378448        return NULL;
    379449}
Note: See TracChangeset for help on using the changeset viewer.