Ignore:
File:
1 edited

Legend:

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

    r1f97352 r4a5a18be  
    4343#include <stdlib.h>
    4444#include <str.h>
    45 #include <net/socket_codes.h>
     45
    4646#include "addrobj.h"
    4747#include "inetsrv.h"
     
    4949#include "pdu.h"
    5050
    51 static bool first_link = true;
    52 static bool first_link6 = true;
    53 
    54 static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
    55 static uint16_t ip_ident = 0;
    56 
    57 static int inet_link_open(service_id_t);
    58 static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
     51static int inet_link_open(service_id_t sid);
     52static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu);
    5953
    6054static iplink_ev_ops_t inet_iplink_ev_ops = {
     
    6559static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
    6660
    67 static addr128_t link_local_node_ip =
    68     {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0, 0, 0};
    69 
    70 static void inet_link_local_node_ip(addr48_t mac_addr,
    71     addr128_t ip_addr)
    72 {
    73         memcpy(ip_addr, link_local_node_ip, 16);
    74        
    75         ip_addr[8] = mac_addr[0] ^ 0x02;
    76         ip_addr[9] = mac_addr[1];
    77         ip_addr[10] = mac_addr[2];
    78         ip_addr[13] = mac_addr[3];
    79         ip_addr[14] = mac_addr[4];
    80         ip_addr[15] = mac_addr[5];
    81 }
    82 
    83 static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
    84 {
     61static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu)
     62{
     63        inet_packet_t packet;
     64        int rc;
     65
    8566        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
    86        
    87         int rc;
    88         inet_packet_t packet;
    89        
    90         switch (af) {
    91         case AF_INET:
    92                 rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
    93                 break;
    94         case AF_INET6:
    95                 rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
    96                 break;
    97         default:
    98                 log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid address family");
    99                 return EINVAL;
    100         }
    101        
     67        rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
    10268        if (rc != EOK) {
    10369                log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
    10470                return rc;
    10571        }
    106        
     72
    10773        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
    10874        rc = inet_recv_packet(&packet);
    10975        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
    11076        free(packet.data);
    111        
     77
    11278        return rc;
    11379}
     
    181147        if (ilink->svc_name != NULL)
    182148                free(ilink->svc_name);
    183        
    184149        free(ilink);
    185150}
     
    188153{
    189154        inet_link_t *ilink;
    190         inet_addr_t iaddr;
     155        iplink_addr_t iaddr;
    191156        int rc;
    192157
     
    224189                goto error;
    225190        }
    226        
    227         /*
    228          * Get the MAC address of the link. If the link has a MAC
    229          * address, we assume that it supports NDP.
    230          */
    231         rc = iplink_get_mac48(ilink->iplink, &ilink->mac);
    232         ilink->mac_valid = (rc == EOK);
    233191
    234192        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    235193        list_append(&ilink->link_list, &inet_link_list);
    236194
    237         inet_addrobj_t *addr = NULL;
    238        
    239         if (first_link) {
    240                 addr = inet_addrobj_new();
    241                
    242                 inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
    243                 first_link = false;
     195        inet_addrobj_t *addr;
     196
     197        static int first = 1;
     198        /* XXX For testing: set static IP address 10.0.2.15/24 */
     199        addr = inet_addrobj_new();
     200        if (first) {
     201                addr->naddr.ipv4 = (127 << 24) + (0 << 16) + (0 << 8) + 1;
     202                first = 0;
    244203        } 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);
    253         }
    254        
    255         if (addr != NULL) {
    256                 addr->ilink = ilink;
    257                 addr->name = str_dup("v4a");
    258                
    259                 rc = inet_addrobj_add(addr);
    260                 if (rc == EOK) {
    261                         inet_naddr_addr(&addr->naddr, &iaddr);
    262                         rc = iplink_addr_add(ilink->iplink, &iaddr);
    263                         if (rc != EOK) {
    264                                 log_msg(LOG_DEFAULT, LVL_ERROR,
    265                                     "Failed setting IPv4 address on internet link.");
    266                                 inet_addrobj_remove(addr);
    267                                 inet_addrobj_delete(addr);
    268                         }
    269                 } else {
    270                         log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
    271                         inet_addrobj_delete(addr);
    272                 }
    273         }
    274        
    275         inet_addrobj_t *addr6 = NULL;
    276        
    277         if (first_link6) {
    278                 addr6 = inet_addrobj_new();
    279                
    280                 inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
    281                 first_link6 = false;
    282         } else if (ilink->mac_valid) {
    283                 addr6 = inet_addrobj_new();
    284                
    285                 addr128_t link_local;
    286                 inet_link_local_node_ip(ilink->mac, link_local);
    287                
    288                 inet_naddr_set6(link_local, 64, &addr6->naddr);
    289         }
    290        
    291         if (addr6 != NULL) {
    292                 addr6->ilink = ilink;
    293                 addr6->name = str_dup("v6a");
    294                
    295                 rc = inet_addrobj_add(addr6);
    296                 if (rc == EOK) {
    297                         inet_naddr_addr(&addr6->naddr, &iaddr);
    298                         rc = iplink_addr_add(ilink->iplink, &iaddr);
    299                         if (rc != EOK) {
    300                                 log_msg(LOG_DEFAULT, LVL_ERROR,
    301                                     "Failed setting IPv6 address on internet link.");
    302                                 inet_addrobj_remove(addr6);
    303                                 inet_addrobj_delete(addr6);
    304                         }
    305                 } else {
    306                         log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
    307                         inet_addrobj_delete(addr6);
    308                 }
    309         }
    310        
     204                addr->naddr.ipv4 = (10 << 24) + (0 << 16) + (2 << 8) + 15;
     205        }
     206        addr->naddr.bits = 24;
     207        addr->ilink = ilink;
     208        addr->name = str_dup("v4a");
     209        rc = inet_addrobj_add(addr);
     210        if (rc != EOK) {
     211                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
     212                inet_addrobj_delete(addr);
     213                /* XXX Roll back */
     214                return rc;
     215        }
     216
     217        iaddr.ipv4 = addr->naddr.ipv4;
     218        rc = iplink_addr_add(ilink->iplink, &iaddr);
     219        if (rc != EOK) {
     220                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
     221                inet_addrobj_remove(addr);
     222                inet_addrobj_delete(addr);
     223                /* XXX Roll back */
     224                return rc;
     225        }
     226
    311227        return EOK;
    312        
     228
    313229error:
    314230        if (ilink->iplink != NULL)
    315231                iplink_close(ilink->iplink);
    316        
    317232        inet_link_delete(ilink);
    318233        return rc;
     
    338253}
    339254
    340 /** Send IPv4 datagram over Internet link
    341  *
    342  * @param ilink Internet link
    343  * @param lsrc  Source IPv4 address
    344  * @param ldest Destination IPv4 address
    345  * @param dgram IPv4 datagram body
    346  * @param proto Protocol
    347  * @param ttl   Time-to-live
    348  * @param df    Do-not-Fragment flag
    349  *
    350  * @return EOK on success
    351  * @return ENOMEM when not enough memory to create the datagram
    352  * @return ENOTSUP if networking mode is not supported
    353  *
    354  */
    355 int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest,
    356     inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
    357 {
    358         addr32_t src_v4;
    359         uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL);
    360         if (src_af != AF_INET)
    361                 return EINVAL;
    362        
    363         addr32_t dest_v4;
    364         uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL);
    365         if (dest_af != AF_INET)
    366                 return EINVAL;
    367        
     255/** Send datagram over Internet link */
     256int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc,
     257    inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
     258{
     259        iplink_sdu_t sdu;
     260        inet_packet_t packet;
     261        int rc;
     262        size_t offs, roffs;
     263
    368264        /*
    369265         * Fill packet structure. Fragmentation is performed by
    370266         * inet_pdu_encode().
    371267         */
    372        
    373         iplink_sdu_t sdu;
    374        
    375         sdu.src = lsrc;
    376         sdu.dest = ldest;
    377        
    378         inet_packet_t packet;
    379        
    380268        packet.src = dgram->src;
    381269        packet.dest = dgram->dest;
     
    383271        packet.proto = proto;
    384272        packet.ttl = ttl;
    385        
    386         /* Allocate identifier */
    387         fibril_mutex_lock(&ip_ident_lock);
    388         packet.ident = ++ip_ident;
    389         fibril_mutex_unlock(&ip_ident_lock);
    390        
    391273        packet.df = df;
    392274        packet.data = dgram->data;
    393275        packet.size = dgram->size;
    394        
    395         int rc;
    396         size_t offs = 0;
    397        
     276
     277        sdu.lsrc.ipv4 = lsrc->ipv4;
     278        sdu.ldest.ipv4 = ldest->ipv4;
     279
     280        offs = 0;
    398281        do {
    399282                /* Encode one fragment */
    400                
    401                 size_t roffs;
    402                 rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu,
    403                     &sdu.data, &sdu.size, &roffs);
     283                rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,
     284                    &sdu.size, &roffs);
    404285                if (rc != EOK)
    405286                        return rc;
    406                
     287
    407288                /* Send the PDU */
    408289                rc = iplink_send(ilink->iplink, &sdu);
    409                
    410290                free(sdu.data);
     291
    411292                offs = roffs;
    412293        } while (offs < packet.size);
    413        
    414         return rc;
    415 }
    416 
    417 /** Send IPv6 datagram over Internet link
    418  *
    419  * @param ilink Internet link
    420  * @param ldest Destination MAC address
    421  * @param dgram IPv6 datagram body
    422  * @param proto Next header
    423  * @param ttl   Hop limit
    424  * @param df    Do-not-Fragment flag (unused)
    425  *
    426  * @return EOK on success
    427  * @return ENOMEM when not enough memory to create the datagram
    428  *
    429  */
    430 int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest,
    431     inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
    432 {
    433         addr128_t src_v6;
    434         uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6);
    435         if (src_af != AF_INET6)
    436                 return EINVAL;
    437        
    438         addr128_t dest_v6;
    439         uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6);
    440         if (dest_af != AF_INET6)
    441                 return EINVAL;
    442        
    443         iplink_sdu6_t sdu6;
    444         addr48(ldest, sdu6.dest);
    445        
    446         /*
    447          * Fill packet structure. Fragmentation is performed by
    448          * inet_pdu_encode6().
    449          */
    450        
    451         inet_packet_t packet;
    452        
    453         packet.src = dgram->src;
    454         packet.dest = dgram->dest;
    455         packet.tos = dgram->tos;
    456         packet.proto = proto;
    457         packet.ttl = ttl;
    458        
    459         /* Allocate identifier */
    460         fibril_mutex_lock(&ip_ident_lock);
    461         packet.ident = ++ip_ident;
    462         fibril_mutex_unlock(&ip_ident_lock);
    463        
    464         packet.df = df;
    465         packet.data = dgram->data;
    466         packet.size = dgram->size;
    467        
    468         int rc;
    469         size_t offs = 0;
    470        
    471         do {
    472                 /* Encode one fragment */
    473                
    474                 size_t roffs;
    475                 rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu,
    476                     &sdu6.data, &sdu6.size, &roffs);
    477                 if (rc != EOK)
    478                         return rc;
    479                
    480                 /* Send the PDU */
    481                 rc = iplink_send6(ilink->iplink, &sdu6);
    482                
    483                 free(sdu6.data);
    484                 offs = roffs;
    485         } while (offs < packet.size);
    486        
     294
    487295        return rc;
    488296}
Note: See TracChangeset for help on using the changeset viewer.