Changeset b86a32e in mainline for uspace/srv/net/inetsrv/inet_link.c


Ignore:
Timestamp:
2013-07-15T12:14:55Z (12 years ago)
Author:
Manuele Conti <conti.ma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c84146d3
Parents:
87159eb8 (diff), 956d4281 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with mainline changes.

File:
1 edited

Legend:

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

    r87159eb8 rb86a32e  
    4949#include "pdu.h"
    5050
     51static bool first_link = true;
     52static bool first_link6 = true;
     53
    5154static int inet_link_open(service_id_t);
    5255static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
     
    5861static LIST_INITIALIZE(inet_link_list);
    5962static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
     63
     64static addr128_t link_local_node_ip =
     65    {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0, 0, 0};
     66
     67static void inet_link_local_node_ip(addr48_t mac_addr,
     68    addr128_t ip_addr)
     69{
     70        memcpy(ip_addr, link_local_node_ip, 16);
     71       
     72        ip_addr[8] = mac_addr[0] ^ 0x02;
     73        ip_addr[9] = mac_addr[1];
     74        ip_addr[10] = mac_addr[2];
     75        ip_addr[13] = mac_addr[3];
     76        ip_addr[14] = mac_addr[4];
     77        ip_addr[15] = mac_addr[5];
     78}
    6079
    6180static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
     
    159178        if (ilink->svc_name != NULL)
    160179                free(ilink->svc_name);
     180       
    161181        free(ilink);
    162182}
     
    201221                goto error;
    202222        }
     223       
     224        /*
     225         * Get the MAC address of the link. If the link has a MAC
     226         * address, we assume that it supports NDP.
     227         */
     228        rc = iplink_get_mac48(ilink->iplink, &ilink->mac);
     229        ilink->mac_valid = (rc == EOK);
    203230
    204231        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    205232        list_append(&ilink->link_list, &inet_link_list);
    206233
    207         inet_addrobj_t *addr;
    208         inet_addrobj_t *addr6;
    209 
    210         static int first = 1;
    211        
    212         addr = inet_addrobj_new();
    213         addr6 = inet_addrobj_new();
    214        
    215         if (first) {
     234        inet_addrobj_t *addr = NULL;
     235       
     236        if (first_link) {
     237                addr = inet_addrobj_new();
     238               
    216239                inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
    217                 inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
    218                 first = 0;
     240                first_link = false;
    219241        } else {
    220242                /*
    221243                 * FIXME
    222                  * Setting static IP addresses for testing purposes
     244                 * Setting static IPv4 address for testing purposes:
    223245                 * 10.0.2.15/24
    224                  * fd19:1680::4/120
    225246                 */
     247                addr = inet_addrobj_new();
     248               
    226249                inet_naddr(&addr->naddr, 10, 0, 2, 15, 24);
    227                 inet_naddr6(&addr6->naddr, 0xfd19, 0x1680, 0, 0, 0, 0, 0, 4, 120);
    228         }
    229        
    230         addr->ilink = ilink;
    231         addr6->ilink = ilink;
    232         addr->name = str_dup("v4a");
    233         addr6->name = str_dup("v6a");
    234        
    235         rc = inet_addrobj_add(addr);
    236         if (rc != EOK) {
    237                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
    238                 inet_addrobj_delete(addr);
    239                 /* XXX Roll back */
    240                 return rc;
    241         }
    242        
    243         rc = inet_addrobj_add(addr6);
    244         if (rc != EOK) {
    245                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
    246                 inet_addrobj_delete(addr6);
    247                 /* XXX Roll back */
    248                 return rc;
    249         }
    250        
    251         inet_naddr_addr(&addr->naddr, &iaddr);
    252         rc = iplink_addr_add(ilink->iplink, &iaddr);
    253         if (rc != EOK) {
    254                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IPv4 address on internet link.");
    255                 inet_addrobj_remove(addr);
    256                 inet_addrobj_delete(addr);
    257                 /* XXX Roll back */
    258                 return rc;
    259         }
    260        
    261         inet_naddr_addr(&addr6->naddr, &iaddr);
    262         rc = iplink_addr_add(ilink->iplink, &iaddr);
    263         if (rc != EOK) {
    264                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IPv6 address on internet link.");
    265                 inet_addrobj_remove(addr6);
    266                 inet_addrobj_delete(addr6);
    267                 /* XXX Roll back */
    268                 return rc;
     250        }
     251       
     252        if (addr != NULL) {
     253                addr->ilink = ilink;
     254                addr->name = str_dup("v4a");
     255               
     256                rc = inet_addrobj_add(addr);
     257                if (rc == EOK) {
     258                        inet_naddr_addr(&addr->naddr, &iaddr);
     259                        rc = iplink_addr_add(ilink->iplink, &iaddr);
     260                        if (rc != EOK) {
     261                                log_msg(LOG_DEFAULT, LVL_ERROR,
     262                                    "Failed setting IPv4 address on internet link.");
     263                                inet_addrobj_remove(addr);
     264                                inet_addrobj_delete(addr);
     265                        }
     266                } else {
     267                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
     268                        inet_addrobj_delete(addr);
     269                }
     270        }
     271       
     272        inet_addrobj_t *addr6 = NULL;
     273       
     274        if (first_link6) {
     275                addr6 = inet_addrobj_new();
     276               
     277                inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
     278                first_link6 = false;
     279        } else if (ilink->mac_valid) {
     280                addr6 = inet_addrobj_new();
     281               
     282                addr128_t link_local;
     283                inet_link_local_node_ip(ilink->mac, link_local);
     284               
     285                inet_naddr_set6(link_local, 64, &addr6->naddr);
     286        }
     287       
     288        if (addr6 != NULL) {
     289                addr6->ilink = ilink;
     290                addr6->name = str_dup("v6a");
     291               
     292                rc = inet_addrobj_add(addr6);
     293                if (rc == EOK) {
     294                        inet_naddr_addr(&addr6->naddr, &iaddr);
     295                        rc = iplink_addr_add(ilink->iplink, &iaddr);
     296                        if (rc != EOK) {
     297                                log_msg(LOG_DEFAULT, LVL_ERROR,
     298                                    "Failed setting IPv6 address on internet link.");
     299                                inet_addrobj_remove(addr6);
     300                                inet_addrobj_delete(addr6);
     301                        }
     302                } else {
     303                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
     304                        inet_addrobj_delete(addr6);
     305                }
    269306        }
    270307       
     
    298335}
    299336
    300 /** Send datagram over Internet link */
    301 int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc,
    302     inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
    303 {
     337/** Send IPv4 datagram over Internet link */
     338int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest,
     339    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
     340{
     341        addr32_t src_v4;
     342        uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL);
     343        if (src_af != AF_INET)
     344                return EINVAL;
     345       
     346        addr32_t dest_v4;
     347        uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL);
     348        if (dest_af != AF_INET)
     349                return EINVAL;
     350       
    304351        /*
    305352         * Fill packet structure. Fragmentation is performed by
    306353         * inet_pdu_encode().
    307354         */
     355       
     356        iplink_sdu_t sdu;
     357       
     358        sdu.src = lsrc;
     359        sdu.dest = ldest;
    308360       
    309361        inet_packet_t packet;
     
    318370        packet.size = dgram->size;
    319371       
    320         iplink_sdu_t sdu;
    321372        size_t offs = 0;
    322373        int rc;
    323        
    324         sdu.src = *lsrc;
    325         sdu.dest = *ldest;
    326374       
    327375        do {
    328376                /* Encode one fragment */
     377               
    329378                size_t roffs;
    330                 rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,
    331                     &sdu.size, &roffs);
     379                rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu,
     380                    &sdu.data, &sdu.size, &roffs);
    332381                if (rc != EOK)
    333382                        return rc;
     
    335384                /* Send the PDU */
    336385                rc = iplink_send(ilink->iplink, &sdu);
     386               
    337387                free(sdu.data);
    338                
     388                offs = roffs;
     389        } while (offs < packet.size);
     390       
     391        return rc;
     392}
     393
     394/** Send IPv6 datagram over Internet link */
     395int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest,
     396    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
     397{
     398        addr128_t src_v6;
     399        uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6);
     400        if (src_af != AF_INET6)
     401                return EINVAL;
     402       
     403        addr128_t dest_v6;
     404        uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6);
     405        if (dest_af != AF_INET6)
     406                return EINVAL;
     407       
     408        iplink_sdu6_t sdu6;
     409        addr48(ldest, sdu6.dest);
     410       
     411        /*
     412         * Fill packet structure. Fragmentation is performed by
     413         * inet_pdu_encode6().
     414         */
     415       
     416        inet_packet_t packet;
     417       
     418        packet.src = dgram->src;
     419        packet.dest = dgram->dest;
     420        packet.tos = dgram->tos;
     421        packet.proto = proto;
     422        packet.ttl = ttl;
     423        packet.df = df;
     424        packet.data = dgram->data;
     425        packet.size = dgram->size;
     426       
     427        int rc;
     428        size_t offs = 0;
     429       
     430        do {
     431                /* Encode one fragment */
     432               
     433                size_t roffs;
     434                rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu,
     435                    &sdu6.data, &sdu6.size, &roffs);
     436                if (rc != EOK)
     437                        return rc;
     438               
     439                /* Send the PDU */
     440                rc = iplink_send6(ilink->iplink, &sdu6);
     441               
     442                free(sdu6.data);
    339443                offs = roffs;
    340444        } while (offs < packet.size);
Note: See TracChangeset for help on using the changeset viewer.