Changeset 4255

Show
Ignore:
Timestamp:
08/18/08 13:07:26 (5 months ago)
Author:
martin
Message:

roam jobs for routing table changes not fired for virtual IP routes

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/charon/kernel/kernel_interface.c

    r4254 r4255  
    654654 
    655655/** 
     656 * get the refcount of a virtual ip 
     657 */ 
     658static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip) 
     659{ 
     660    iterator_t *ifaces, *addrs; 
     661    iface_entry_t *iface; 
     662    addr_entry_t *addr; 
     663    int refcount = 0; 
     664     
     665    ifaces = this->ifaces->create_iterator(this->ifaces, TRUE); 
     666    while (ifaces->iterate(ifaces, (void**)&iface)) 
     667    { 
     668        addrs = iface->addrs->create_iterator(iface->addrs, TRUE); 
     669        while (addrs->iterate(addrs, (void**)&addr)) 
     670        { 
     671            if (addr->virtual && (iface->flags & IFF_UP) && 
     672                ip->ip_equals(ip, addr->ip)) 
     673            { 
     674                refcount = addr->refcount; 
     675                break; 
     676            } 
     677        } 
     678        addrs->destroy(addrs); 
     679        if (refcount) 
     680        { 
     681            break; 
     682        } 
     683    } 
     684    ifaces->destroy(ifaces); 
     685     
     686    return refcount; 
     687} 
     688 
     689/** 
    656690 * process RTM_NEWLINK/RTM_DELLINK from kernel 
    657691 */ 
     
    869903 
    870904/** 
     905 * process RTM_NEWROUTE from kernel 
     906 */ 
     907static void process_route(private_kernel_interface_t *this, struct nlmsghdr *hdr) 
     908{ 
     909    struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr)); 
     910    struct rtattr *rta = RTM_RTA(msg); 
     911    size_t rtasize = RTM_PAYLOAD(hdr); 
     912    host_t *host = NULL; 
     913     
     914    while(RTA_OK(rta, rtasize)) 
     915    { 
     916        switch (rta->rta_type) 
     917        { 
     918            case RTA_PREFSRC: 
     919                host = host_create_from_chunk(msg->rtm_family, 
     920                            chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0); 
     921                break; 
     922        } 
     923        rta = RTA_NEXT(rta, rtasize); 
     924    } 
     925    if (host) 
     926    { 
     927        if (!get_vip_refcount(this, host)) 
     928        {   /* ignore routes added for virtual IPs */ 
     929            fire_roam_job(this, FALSE); 
     930        } 
     931        host->destroy(host); 
     932    } 
     933} 
     934 
     935/** 
    871936 * Receives events from kernel 
    872937 */ 
     
    9621027                case RTM_NEWROUTE: 
    9631028                case RTM_DELROUTE: 
    964                     /* TODO: ignore route changes due to virtual IPs */ 
    965                     /* fire_roam_job(this, FALSE); */ 
     1029                    process_route(this, hdr); 
    9661030                    break; 
    9671031                default: 
     
    14321496    } 
    14331497    return ifindex; 
    1434 } 
    1435  
    1436 /** 
    1437  * get the refcount of a virtual ip 
    1438  */ 
    1439 static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip) 
    1440 { 
    1441     iterator_t *ifaces, *addrs; 
    1442     iface_entry_t *iface; 
    1443     addr_entry_t *addr; 
    1444     int refcount = 0; 
    1445      
    1446     ifaces = this->ifaces->create_iterator(this->ifaces, TRUE); 
    1447     while (ifaces->iterate(ifaces, (void**)&iface)) 
    1448     { 
    1449         addrs = iface->addrs->create_iterator(iface->addrs, TRUE); 
    1450         while (addrs->iterate(addrs, (void**)&addr)) 
    1451         { 
    1452             if (addr->virtual && (iface->flags & IFF_UP) && 
    1453                 ip->ip_equals(ip, addr->ip)) 
    1454             { 
    1455                 refcount = addr->refcount; 
    1456                 break; 
    1457             } 
    1458         } 
    1459         addrs->destroy(addrs); 
    1460         if (refcount) 
    1461         { 
    1462             break; 
    1463         } 
    1464     } 
    1465     ifaces->destroy(ifaces); 
    1466      
    1467     return refcount; 
    14681498} 
    14691499