Changeset 4655

Show
Ignore:
Timestamp:
11/14/08 14:04:22 (2 months ago)
Author:
martin
Message:

do not use a route if outgoing interface is down
other cleanups

Files:

Legend:

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

    r4639 r4655  
    257257    host->destroy(host); 
    258258     
    259     addrs = this->public.create_address_enumerator(&this->public, TRUE, TRUE); 
     259    addrs = create_address_enumerator(this, TRUE, TRUE); 
    260260    while (addrs->enumerate(addrs, (void**)&host)) 
    261261    { 
  • trunk/src/charon/plugins/kernel_netlink/kernel_netlink_net.c

    r4579 r4655  
    159159     */ 
    160160    int routing_table_prio; 
    161  
     161     
    162162    /** 
    163163     * whether to react to RTM_NEWROUTE or RTM_DELROUTE events 
     
    208208{ 
    209209    struct timeval now; 
    210         
     210     
    211211    if (gettimeofday(&now, NULL) == 0) 
    212212    { 
     
    702702 
    703703/** 
     704 * Check if an interface with a given index is up 
     705 */ 
     706static bool is_interface_up(private_kernel_netlink_net_t *this, int index) 
     707{ 
     708    enumerator_t *ifaces; 
     709    iface_entry_t *iface; 
     710    bool up = FALSE; 
     711     
     712    ifaces = this->ifaces->create_enumerator(this->ifaces); 
     713    while (ifaces->enumerate(ifaces, &iface)) 
     714    { 
     715        if (iface->ifindex == index) 
     716        { 
     717            up = iface->flags & IFF_UP; 
     718            break; 
     719        } 
     720    } 
     721    ifaces->destroy(ifaces); 
     722    return up; 
     723} 
     724 
     725/** 
    704726 * check if an address (chunk) addr is in subnet (net with net_len net bits) 
    705727 */ 
     
    787809                chunk_t rta_gtw, rta_src, rta_dst; 
    788810                u_int32_t rta_oif = 0; 
     811                enumerator_t *ifaces, *addrs; 
     812                iface_entry_t *iface; 
     813                addr_entry_t *addr; 
    789814                 
    790815                rta_gtw = rta_src = rta_dst = chunk_empty; 
     
    814839                    rta = RTA_NEXT(rta, rtasize); 
    815840                } 
     841                if (rta_oif && !is_interface_up(this, rta_oif)) 
     842                {   /* interface is down */ 
     843                    goto next; 
     844                } 
     845                if (this->routing_table != 0 && 
     846                    msg->rtm_table == this->routing_table) 
     847                {   /* route is from our own ipsec routing table */ 
     848                    goto next; 
     849                } 
     850                if (msg->rtm_dst_len <= best) 
     851                {   /* not better than a previous one */ 
     852                    goto next; 
     853                } 
     854                if (msg->rtm_dst_len != 0 && 
     855                    (!rta_dst.ptr || 
     856                     !addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len))) 
     857                {   /* is not the default route and not contained in our dst */ 
     858                    goto next; 
     859                } 
    816860                 
    817                 /* apply the route if: 
    818                  * - it is not from our own ipsec routing table 
    819                  * - is better than a previous one 
    820                  * - is the default route or 
    821                  * - its destination net contains our destination 
    822                  */ 
    823                 if ((this->routing_table == 0 ||msg->rtm_table != this->routing_table) 
    824                     &&  msg->rtm_dst_len > best 
    825                     && (msg->rtm_dst_len == 0 || /* default route */ 
    826                     (rta_dst.ptr && addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len)))) 
     861                best = msg->rtm_dst_len; 
     862                if (nexthop) 
    827863                { 
    828                     enumerator_t *ifaces, *addrs; 
    829                     iface_entry_t *iface; 
    830                     addr_entry_t *addr; 
    831                      
    832                     best = msg->rtm_dst_len; 
    833                     if (nexthop) 
     864                    DESTROY_IF(gtw); 
     865                    gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0); 
     866                    goto next; 
     867                } 
     868                if (rta_src.ptr) 
     869                { 
     870                    DESTROY_IF(src); 
     871                    src = host_create_from_chunk(msg->rtm_family, rta_src, 0); 
     872                    if (get_vip_refcount(this, src)) 
     873                    {   /* skip source address if it is installed by us */ 
     874                        DESTROY_IF(src); 
     875                        src = NULL; 
     876                    } 
     877                    goto next; 
     878                } 
     879                /* no source addr, get one from the interfaces */ 
     880                ifaces = this->ifaces->create_enumerator(this->ifaces); 
     881                while (ifaces->enumerate(ifaces, &iface)) 
     882                { 
     883                    if (iface->ifindex == rta_oif &&  
     884                        iface->flags & IFF_UP) 
    834885                    { 
    835                         DESTROY_IF(gtw); 
    836                         gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0); 
    837                     } 
    838                     else if (rta_src.ptr) 
    839                     { 
    840                         DESTROY_IF(src); 
    841                         src = host_create_from_chunk(msg->rtm_family, rta_src, 0); 
    842                         if (get_vip_refcount(this, src)) 
    843                         {   /* skip source address if it is installed by us */ 
    844                             DESTROY_IF(src); 
    845                             src = NULL; 
    846                             current = NLMSG_NEXT(current, len); 
    847                             continue; 
    848                         } 
    849                     } 
    850                     else 
    851                     { 
    852                         /* no source addr, get one from the interfaces */ 
    853                         ifaces = this->ifaces->create_enumerator(this->ifaces); 
    854                         while (ifaces->enumerate(ifaces, &iface)) 
     886                        addrs = iface->addrs->create_enumerator(iface->addrs); 
     887                        while (addrs->enumerate(addrs, &addr)) 
    855888                        { 
    856                             if (iface->ifindex == rta_oif) 
     889                            chunk_t ip = addr->ip->get_address(addr->ip); 
     890                            if ((msg->rtm_dst_len == 0 &&  
     891                                 addr->ip->get_family(addr->ip) == 
     892                                    dest->get_family(dest)) || 
     893                                addr_in_subnet(ip, rta_dst, msg->rtm_dst_len)) 
    857894                            { 
    858                                 addrs = iface->addrs->create_enumerator(iface->addrs); 
    859                                 while (addrs->enumerate(addrs, &addr)) 
    860                                 { 
    861                                     chunk_t ip = addr->ip->get_address(addr->ip); 
    862                                     if ((msg->rtm_dst_len == 0 &&  
    863                                          addr->ip->get_family(addr->ip) == 
    864                                             dest->get_family(dest)) || 
    865                                         addr_in_subnet(ip, rta_dst, msg->rtm_dst_len)) 
    866                                     { 
    867                                         DESTROY_IF(src); 
    868                                         src = addr->ip->clone(addr->ip); 
    869                                         break; 
    870                                     } 
    871                                 } 
    872                                 addrs->destroy(addrs); 
     895                                DESTROY_IF(src); 
     896                                src = addr->ip->clone(addr->ip); 
     897                                break; 
    873898                            } 
    874899                        } 
    875                         ifaces->destroy(ifaces); 
     900                        addrs->destroy(addrs); 
    876901                    } 
    877902                } 
    878                 /* FALL through */ 
     903                ifaces->destroy(ifaces); 
     904                goto next; 
    879905            } 
    880906            default: 
     907            next: 
    881908                current = NLMSG_NEXT(current, len); 
    882909                continue;