Beispiel #1
0
int get_addr_len(int afi)
{
    switch (afi) {                      /* == eid_afi */
    case AF_UNSPEC:
        return (0);
    case AF_INET:
        return(sizeof(struct in_addr));
    case AF_INET6:
        return(sizeof(struct in6_addr));
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2, "get_addr_len: unknown AFI (%d)", afi);
        return(ERR_AFI);
    }
}
Beispiel #2
0
struct udphdr *build_ip_header(
        uint8_t               *cur_ptr,
        lisp_addr_t           *src_addr,
        lisp_addr_t           *dst_addr,
        int                   ip_len)
{
    struct ip      *iph;
    struct ip6_hdr *ip6h;
    struct udphdr  *udph;

    switch (src_addr->afi) {
    case AF_INET:
        ip_len = ip_len + sizeof(struct ip);
        iph                = (struct ip *) cur_ptr;
        iph->ip_hl         = 5;
        iph->ip_v          = IPVERSION;
        iph->ip_tos        = 0;
        iph->ip_len        = htons(ip_len);
        iph->ip_id         = htons(get_IP_ID());
        iph->ip_off        = 0;   /* XXX Control packets can be fragmented  */
        iph->ip_ttl        = 255;
        iph->ip_p          = IPPROTO_UDP;
        iph->ip_src.s_addr = src_addr->address.ip.s_addr;
        iph->ip_dst.s_addr = dst_addr->address.ip.s_addr;
        iph->ip_sum        = 0;
        iph->ip_sum        = ip_checksum((uint16_t *)cur_ptr, sizeof(struct ip));

        udph              = (struct udphdr *) CO(iph,sizeof(struct ip));
        break;
    case AF_INET6:
        ip6h           = (struct ip6_hdr *) cur_ptr;
        ip6h->ip6_hops = 255;
        ip6h->ip6_vfc  = (IP6VERSION << 4);
        ip6h->ip6_nxt  = IPPROTO_UDP;
        ip6h->ip6_plen = htons(ip_len);
        memcpy(ip6h->ip6_src.s6_addr,
               src_addr->address.ipv6.s6_addr,
               sizeof(struct in6_addr));
        memcpy(ip6h->ip6_dst.s6_addr,
                dst_addr->address.ipv6.s6_addr,
               sizeof(struct in6_addr));
        udph = (struct udphdr *) CO(ip6h,sizeof(struct ip6_hdr));
        break;
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2,"build_ip_header: Uknown AFI of the source address: %d",src_addr->afi);
        return(NULL);
    }
    return(udph);
}
Beispiel #3
0
/*
 * Fill the tuple with the 5 tuples of a packet: (SRC IP, DST IP, PROTOCOL, SRC PORT, DST PORT)
 */
int extract_5_tuples_from_packet (
        uint8_t         *packet ,
        packet_tuple    *tuple)
{
    struct iphdr        *iph    = NULL;
    struct ip6_hdr      *ip6h   = NULL;
    struct udphdr       *udp    = NULL;
    struct tcphdr       *tcp    = NULL;
    int                 len     = 0;

    iph = (struct iphdr *) packet;

    switch (iph->version) {
    case 4:
        tuple->src_addr.afi = AF_INET;
        tuple->dst_addr.afi = AF_INET;
        tuple->src_addr.address.ip.s_addr = iph->saddr;
        tuple->dst_addr.address.ip.s_addr = iph->daddr;
        tuple->protocol = iph->protocol;
        len = iph->ihl*4;
        break;
    case 6:
        ip6h = (struct ip6_hdr *) packet;
        tuple->src_addr.afi = AF_INET6;
        tuple->dst_addr.afi = AF_INET6;
        memcpy(&(tuple->src_addr.address.ipv6),&(ip6h->ip6_src),sizeof(struct in6_addr));
        memcpy(&(tuple->dst_addr.address.ipv6),&(ip6h->ip6_dst),sizeof(struct in6_addr));
        tuple->protocol = ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt;
        len = sizeof(struct ip6_hdr);
        break;
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2,"extract_5_tuples_from_packet: No ip packet identified");
        return (BAD);
    }

    if (tuple->protocol == IPPROTO_UDP){
        udp = (struct udphdr *)CO(packet,len);
        tuple->src_port = ntohs(udp->source);
        tuple->dst_port = ntohs(udp->dest);
    }else if (tuple->protocol == IPPROTO_TCP){
        tcp = (struct tcphdr *)CO(packet,len);
        tuple->src_port = ntohs(tcp->source);
        tuple->dst_port = ntohs(tcp->dest);
    }else{//If protocol is not TCP or UDP, ports of the tuple set to 0
        tuple->src_port = 0;
        tuple->dst_port = 0;
    }
    return (GOOD);
}
Beispiel #4
0
/*
 * Remove a referral and all its offspring
 */
int referral_expiry(
        timer   *t,
        void    *arg)
{
    lispd_referral_cache_entry *referral_entry = (lispd_referral_cache_entry *)arg;

    lispd_log_msg(LISP_LOG_DEBUG_1,"referral_expiry: The referral entry with prefix %s/%d has expired. "
            "Removing it and all its offspring", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix),
            referral_entry->mapping->eid_prefix_length);

    remove_referral_cache_entry_from_parent_node(referral_entry);
    del_referral_cache_entry_from_db(referral_entry);
    dump_referral_cache_db(LISP_LOG_DEBUG_3);
    return (GOOD);
}
Beispiel #5
0
int lispd_get_iface_address_nl(
        char                *ifacename,
        lisp_addr_t         *addr,
        int                 afi)
{
    int ifa_index = if_nametoindex(ifacename);

    if (request_address(ifa_index, afi)!=GOOD){
        return (BAD);
    }
    if (read_address_nl(ifa_index, addr)!=GOOD){
    	lispd_log_msg(LISP_LOG_DEBUG_2,"lispd_get_iface_address_nl: Couldn't get iface address from afi");
    	return (BAD);
    }
    return (GOOD);
}
Beispiel #6
0
lisp_addr_t *get_map_resolver()
{
    lisp_addr_t *dst_rloc = NULL;

    if (default_ctrl_iface_v4 != NULL){
        dst_rloc = get_server(map_resolvers, AF_INET);
    }
    if (dst_rloc == NULL && default_ctrl_iface_v6 != NULL){
        dst_rloc = get_server(map_resolvers, AF_INET6);
    }

    if (dst_rloc == NULL){
        lispd_log_msg(LISP_LOG_ERR,"No Map Resolver with a RLOC compatible with local RLOCs");
    }
    return dst_rloc;
}
Beispiel #7
0
int lisp2inetafi(uint16_t afi)
{
    switch (afi) {
    case LISP_AFI_NO_ADDR:
        return(AF_UNSPEC);
    case LISP_AFI_IP:
        return(AF_INET);
    case LISP_AFI_IPV6:
        return(AF_INET6);
    case LISP_AFI_LCAF:
        return(LISP_AFI_LCAF);
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2, "lisp2inetafi: unknown AFI (%d)", afi);
        return(ERR_AFI);
    }
}
Beispiel #8
0
int inet2lispafi(int afi)

{
    switch (afi) {
    case AF_UNSPEC:
        return (LISP_AFI_NO_ADDR);
    case AF_INET:
        return (LISP_AFI_IP);
    case AF_INET6:
        return (LISP_AFI_IPV6);
    case LISP_AFI_LCAF:
        return(LISP_AFI_LCAF);
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2, "inet2lispafi: unknown AFI (%d)", afi);
        return (0);
    }
}
int del_route(
        int                 afi,
        uint32_t            ifindex,
        lisp_addr_t         *dest,
        lisp_addr_t         *src,
        lisp_addr_t         *gw,
        uint32_t            prefix_len,
        uint32_t            metric,
        uint32_t            table)
{
    int result = BAD;
    result = modify_route(RTM_DELROUTE, afi, ifindex, dest, src, gw, prefix_len, metric, table);
    if (result == GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_1, "del_route: deleted route  from the system");
    }
    return (result);
}
/*
 * Request to the kernel the routing table with the selected afi
 */
int request_route_table(uint32_t table, int afi)
{
    struct nlmsghdr *nlh    = NULL;
    struct rtmsg    *rtm    = NULL;
    char   sndbuf[4096];
    int    rta_len          = 0;
    int    retval           = 0;

    /*
     * Build the command
     */
    memset(sndbuf, 0, 4096);

    nlh = (struct nlmsghdr *)sndbuf;
    rtm = (struct rtmsg *)(CO(sndbuf,sizeof(struct nlmsghdr)));

    rta_len = sizeof(struct rtmsg);

    nlh->nlmsg_len =   NLMSG_LENGTH(rta_len);
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    nlh->nlmsg_type  = RTM_GETROUTE;


    rtm->rtm_family    = afi;
    if (table == 0){
        rtm->rtm_table     = RT_TABLE_MAIN;
    }else{
        rtm->rtm_table     = table;
    }

    rtm->rtm_protocol  = RTPROT_STATIC;
    rtm->rtm_scope     = RT_SCOPE_UNIVERSE;
    rtm->rtm_type      = RTN_UNICAST;
    rtm->rtm_src_len   = 0;
    rtm->rtm_tos       = 0;
    rtm->rtm_dst_len   = 0;


    retval = send(netlink_fd, sndbuf, NLMSG_LENGTH(rta_len), 0);

    if (retval < 0) {
        lispd_log_msg(LISP_LOG_CRIT, "request_route_table: send netlink command failed %s", strerror(errno));
        exit_cleanup();
    }
    return(GOOD);
}
int add_pending_referral_cache_entry_to_list(lispd_pending_referral_cache_entry *pending_referral_cache_entry)
{
    lispd_pending_referral_cache_list *pending_referral_list_elt = NULL;
    pending_referral_list_elt = (lispd_pending_referral_cache_list *)malloc(sizeof(lispd_pending_referral_cache_list));
    if (pending_referral_list_elt == NULL){
        lispd_log_msg(LISP_LOG_WARNING,"add_pending_referral_cache_entry_to_list: Unable to allocate memory for a lispd_pending_referral_cache_list");
        return (BAD);
    }
    pending_referral_list_elt->pending_referral_cache_entry = pending_referral_cache_entry;
    if (pening_referrals_list == NULL){
        pening_referrals_list = pending_referral_list_elt;
        pending_referral_list_elt->next = NULL;
    }else{
        pending_referral_list_elt->next = pening_referrals_list;
        pening_referrals_list = pending_referral_list_elt;
    }
    return (GOOD);
}
Beispiel #12
0
/*
 * Reseve and fill the memory required by a lcl_mapping_extended_info
 */
inline lcl_mapping_extended_info *new_lcl_mapping_extended_info()
{
    lcl_mapping_extended_info   *extended_info  = NULL;
    if ((extended_info=(lcl_mapping_extended_info *)malloc(sizeof(lcl_mapping_extended_info)))==NULL){
        lispd_log_msg(LISP_LOG_WARNING,"new_lcl_mapping_extended_info: Couldn't allocate memory for lcl_mapping_extended_info: %s", strerror(errno));
        err = ERR_MALLOC;
        return (NULL);
    }
    extended_info->outgoing_balancing_locators_vecs.v4_balancing_locators_vec = NULL;
    extended_info->outgoing_balancing_locators_vecs.v6_balancing_locators_vec = NULL;
    extended_info->outgoing_balancing_locators_vecs.balancing_locators_vec = NULL;
    extended_info->outgoing_balancing_locators_vecs.v4_locators_vec_length = 0;
    extended_info->outgoing_balancing_locators_vecs.v6_locators_vec_length = 0;
    extended_info->outgoing_balancing_locators_vecs.locators_vec_length = 0;
    extended_info->head_not_init_locators_list = NULL;

    return(extended_info);
}
Beispiel #13
0
uint8_t *build_map_reply_pkt(
         lispd_mapping_elt   *mapping,
         lisp_addr_t        *probed_rloc,
         map_reply_opts     opts,
         uint64_t           nonce,
         int                *map_reply_msg_len)
{
    uint8_t *packet;
    lispd_pkt_map_reply_t *map_reply_msg;
    lispd_pkt_mapping_record_t *mapping_record;


    *map_reply_msg_len = sizeof(lispd_pkt_map_reply_t) +
            pkt_get_mapping_record_length(mapping);

    if ((packet = malloc(*map_reply_msg_len)) == NULL) {
        lispd_log_msg(LISP_LOG_WARNING, "build_map_reply_pkt: Unable to allocate memory for  Map Reply message(%d) %s",
                *map_reply_msg_len, strerror(errno));
        return(NULL);
    }
    memset(packet, 0, *map_reply_msg_len);

    map_reply_msg = (lispd_pkt_map_reply_t *)packet;

    map_reply_msg->type = 2;
    if (opts.rloc_probe)
        map_reply_msg->rloc_probe = 1;
    if (opts.echo_nonce)
        map_reply_msg->echo_nonce = 1;
    map_reply_msg->record_count = 1;
    map_reply_msg->nonce = nonce;


    if (opts.send_rec) {
        mapping_record = (lispd_pkt_mapping_record_t *)
                     CO(map_reply_msg, sizeof(lispd_pkt_map_reply_t));

        if (pkt_fill_mapping_record(mapping_record, mapping, probed_rloc) == NULL) {
            free(packet);
            return(NULL);
        }
    }
    return(packet);
}
Beispiel #14
0
int process_map_reply_probe_locator(
        uint8_t                 **offset,
        lispd_mapping_elt       *mapping,
        uint64_t                nonce,
        lispd_locator_elt       **locator)
{
    lispd_pkt_mapping_record_locator_t  *pkt_locator    = NULL;
    lispd_locator_elt                   *aux_locator    = NULL;
    uint8_t                             *cur_ptr        = NULL;


    *locator = NULL;
    cur_ptr = *offset;
    pkt_locator = (lispd_pkt_mapping_record_locator_t *)(cur_ptr);

    cur_ptr = (uint8_t *)&(pkt_locator->locator_afi);

    /* Extract locator from packet */
    aux_locator = new_rmt_locator (&cur_ptr,UP,
            pkt_locator->priority, pkt_locator->weight,
            pkt_locator->mpriority, pkt_locator->mweight);

    if (aux_locator != NULL){
        /* If the locator of the packed is probed, search the structure of the locator that represents the locator of tha packet */
        if (pkt_locator->probed == TRUE){
            *locator = get_locator_from_mapping(mapping, aux_locator->locator_addr);
            if (*locator == NULL){
                lispd_log_msg(LISP_LOG_DEBUG_2,"get_map_reply_locator_from_mapping: The locator %s is not found in the mapping %s/%d",
                        get_char_from_lisp_addr_t(*(aux_locator->locator_addr)),
                        get_char_from_lisp_addr_t(mapping->eid_prefix),
                        mapping->eid_prefix_length);
                return (ERR_NO_EXIST);
            }
        }
    }else{
        if (err != ERR_AFI_LCAF_TYPE){

            return (err);
        }
    }

    *offset = cur_ptr;
    return (GOOD);
}
Beispiel #15
0
int process_ms_ack_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{
    lispd_referral_cache_entry              *db_referral_entry = NULL;

    db_referral_entry = lookup_referral_cache_exact(
            referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES);

    /* Add referral cache entry to database */
    if (db_referral_entry == NULL){
        if (add_referral_cache_entry_to_db(referral_entry) != GOOD){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_ack_reply: Coudn't add referral cache entry for prefix %s/%d",
                    get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length);
            free_referral_cache_entry(referral_entry);
            remove_pending_referral_cache_entry_from_list(pending_referral_entry);
            return (BAD);
        }
        add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry);
    }else{
        /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */
        update_referral_cache_data(db_referral_entry, referral_entry);
        free_referral_cache_entry(referral_entry);
        referral_entry = db_referral_entry;
    }

    /* Program expiry time */
    program_referral_expiry_timer(referral_entry);
    /* Finish process and remove the pending referral cache from the list */
    if (pending_referral_entry->map_cache_entry->active == TRUE){
        // We have received a map reply
        remove_pending_referral_cache_entry_from_list(pending_referral_entry);
    }
    else{
        if (pending_referral_entry->ddt_request_retry_timer == NULL){
            pending_referral_entry->ddt_request_retry_timer = create_timer (DDT_MAP_REQ_RETRY_MS_ACK_TIMER);
        }
        pending_referral_entry->previous_referral = referral_entry;
        start_timer(pending_referral_entry->ddt_request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT,
                send_map_request_ddt_map_reply_miss, (void *)pending_referral_entry);
    }

    return (GOOD);
}
Beispiel #16
0
uint16_t get_lisp_afi(
     int        afi,
     int        *len)
{

    switch (afi) {
    case AF_INET:
        if (len)
            *len = sizeof(struct in_addr);
        return((uint16_t)LISP_AFI_IP);
    case AF_INET6:
        if (len)
            *len = sizeof(struct in6_addr);
        return((uint16_t)LISP_AFI_IPV6);
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2, "get_lisp_afi: unknown AFI (%d)", afi);
        return (BAD);
    }
}
Beispiel #17
0
int copy_addr_from_sockaddr(
        struct sockaddr     *addr,
        lisp_addr_t         *lisp_addr)
{

    lisp_addr->afi = addr->sa_family;
    switch(lisp_addr->afi ) {
        case AF_INET:
            lisp_addr->address.ip = ((struct sockaddr_in *)addr)->sin_addr;
            return (GOOD);

        case AF_INET6:
            lisp_addr->address.ipv6 = ((struct sockaddr_in6 *)addr)->sin6_addr;
            return (GOOD);
    }

    lispd_log_msg( LISP_LOG_WARNING, "copy_addr_from_sockaddr: Unknown address family %d", addr->sa_family);
    return (BAD);
}
Beispiel #18
0
void exit_cleanup(void) {
    /* Remove source routing tables */
    remove_created_rules();
    /* Close timer file descriptors */
    close(timers_fd);
    /* Close receive sockets */
    close(tun_receive_fd);
    close(ipv4_data_input_fd);
    close(ipv4_control_input_fd);
    close(ipv6_data_input_fd);
    close(ipv6_control_input_fd);
    /* Close send sockets */
    close_output_sockets();
    /* Close netlink socket */
    close(netlink_fd);
    lispd_log_msg(LISP_LOG_INFO,"Exiting ...");

    exit(EXIT_SUCCESS);
}
Beispiel #19
0
void dump_iface_list(int log_level)
{

    lispd_iface_list_elt        *interface_list    = head_interface_list;
    lispd_iface_mappings_list   *mapping_list      = NULL;
    char                        str[4000];

    if (head_interface_list == NULL || is_loggable(log_level) == FALSE){
        return;
    }

    sprintf(str,"*** LISP RLOC Interfaces List ***\n\n");

    while (interface_list){
        sprintf(str + strlen(str),"== %s   (%s)==\n",interface_list->iface->iface_name, interface_list->iface->status ? "Up" : "Down");
        if (interface_list->iface->ipv4_address){
            sprintf(str + strlen(str),"  IPv4 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv4_address)));
            sprintf(str + strlen(str),"    -- LIST mappings -- \n");
            mapping_list = interface_list->iface->head_mappings_list;
            while (mapping_list){
                if (mapping_list->use_ipv4_address == TRUE){
                    sprintf(str + strlen(str),"    %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix),
                            mapping_list->mapping->eid_prefix_length);
                }
                mapping_list = mapping_list->next;
            }
        }
        if (interface_list->iface->ipv6_address){
            sprintf(str + strlen(str),"  IPv6 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv6_address)));
            sprintf(str + strlen(str),"    -- LIST mappings -- \n");
            mapping_list = interface_list->iface->head_mappings_list;
            while (mapping_list){
                if (mapping_list->use_ipv6_address == TRUE){
                    sprintf(str + strlen(str),"    %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix),
                            mapping_list->mapping->eid_prefix_length);
                }
                mapping_list = mapping_list->next;
            }
        }
        interface_list = interface_list->next;
    }
    lispd_log_msg(log_level,"%s",str);
}
Beispiel #20
0
/*
 * Reseve and fill the memory required by a rmt_mapping_extended_info
 */
inline rmt_mapping_extended_info *new_rmt_mapping_extended_info()
{
    rmt_mapping_extended_info   *extended_info  = NULL;

    if ((extended_info=(rmt_mapping_extended_info *)malloc(sizeof(rmt_mapping_extended_info)))==NULL){
        lispd_log_msg(LISP_LOG_WARNING,"new_rmt_mapping_extended_info: Couldn't allocate memory for rmt_mapping_extended_info: %s", strerror(errno));
        err = ERR_MALLOC;
        return (NULL);
    }

    extended_info->rmt_balancing_locators_vecs.v4_balancing_locators_vec = NULL;
    extended_info->rmt_balancing_locators_vecs.v6_balancing_locators_vec = NULL;
    extended_info->rmt_balancing_locators_vecs.balancing_locators_vec = NULL;
    extended_info->rmt_balancing_locators_vecs.v4_locators_vec_length = 0;
    extended_info->rmt_balancing_locators_vecs.v6_locators_vec_length = 0;
    extended_info->rmt_balancing_locators_vecs.locators_vec_length = 0;

    return (extended_info);
}
Beispiel #21
0
int process_delegation_hole_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{

    lispd_referral_cache_entry              *db_referral_entry = NULL;

    db_referral_entry = lookup_referral_cache_exact(
            referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES);

    if (db_referral_entry != NULL && db_referral_entry->act_entry_type != DELEGATION_HOLE){
        del_referral_cache_entry_from_db(db_referral_entry);
        db_referral_entry = NULL;
    }
    if (db_referral_entry == NULL){
        /* Add referral cache entry to database */

        if (add_referral_cache_entry_to_db(referral_entry) != GOOD){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_delegation_hole_reply: Coudn't add referral cache entry for prefix %s/%d",
                    get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length);
            free_referral_cache_entry(referral_entry);
            remove_pending_referral_cache_entry_from_list(pending_referral_entry);
            return (BAD);
        }
        add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry);
    }else{
        /* Entry already exist. Replace it with the new data.*/
        update_referral_cache_data(db_referral_entry, referral_entry);
        free_referral_cache_entry(referral_entry);
        referral_entry = db_referral_entry;
    }
    /*Remove entry from pending list and activate map cache*/
    if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix,
            referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION)!=GOOD){
        del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix,
                           pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);
    }
    remove_pending_referral_cache_entry_from_list(pending_referral_entry);
    /* Program expiry time */
    program_referral_expiry_timer(referral_entry);
    return(GOOD);
}
void process_nl_add_address (struct nlmsghdr *nlh)
{
    struct ifaddrmsg            *ifa                = NULL;
    struct rtattr               *rth                = NULL;
    int                         iface_index         = 0;
    int                         rt_length           = 0;
    lispd_iface_elt             *iface              = NULL;
    lisp_addr_t                 new_addr;
    char                        iface_name[IF_NAMESIZE];

    /*
     * Get the new address from the net link message
     */
    ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh);
    iface_index = ifa->ifa_index;

    iface = get_interface_from_index(iface_index);

    if (iface == NULL) {
        if_indextoname(iface_index, iface_name);
        lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_add_address: the netlink message is not for any interface associated with RLOCs  (%s / %d)",
                      iface_name, iface_index);
        return;
    }
    rth = IFA_RTA (ifa);

    rt_length = IFA_PAYLOAD (nlh);
    for (; rt_length && RTA_OK (rth, rt_length); rth = RTA_NEXT (rth,rt_length))
    {
        if (rth->rta_type == IFA_ADDRESS) {
            if (ifa->ifa_family == AF_INET) {
                memcpy (&(new_addr.address),(struct in_addr *)RTA_DATA(rth),sizeof(struct in_addr));
                new_addr.afi = AF_INET;
            } else if (ifa->ifa_family == AF_INET6) {
                memcpy (&(new_addr.address),(struct in6_addr *)RTA_DATA(rth),sizeof(struct in6_addr));
                new_addr.afi = AF_INET6;
            }
            process_address_change (iface, new_addr);
        }
    }
}
Beispiel #23
0
int get_locators_length(lispd_locators_list *locators_list)
{
    int sum = 0;
    while (locators_list) {
        switch (locators_list->locator->locator_addr->afi) {
        case AF_INET:
            sum += sizeof(struct in_addr);
            break;
        case AF_INET6:
            sum += sizeof(struct in6_addr);
            break;
        default:
            /* It should never happen*/
            lispd_log_msg(LISP_LOG_DEBUG_2, "get_locators_length: Uknown AFI (%d) - It should never happen",
               locators_list->locator->locator_addr->afi);
            break;
        }
        locators_list = locators_list->next;
    }
    return(sum);
}
/*
 * This function deletes a specific ip rule to
 * kernel's rule list
 */
int del_rule(
        int         afi,
        int         if_index,
        uint8_t     table,
        uint32_t    priority,
        uint8_t     type,
        lisp_addr_t *src_addr,
        int         src_plen,
        lisp_addr_t *dst_addr,
        int         dst_plen,
        int         flags)
{
    int result = BAD;
    result = modify_rule(afi, if_index, RTM_DELRULE, table,priority, type, src_addr, src_plen, dst_addr, dst_plen, flags);
    if (result == GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_1, "del_rule: Removed rule for source routing of src addr: %s",
                get_char_from_lisp_addr_t(*src_addr));
    }

    return (result);
}
Beispiel #25
0
/*
 * Generates a basic mapping
 */
lispd_mapping_elt *new_mapping(
        lisp_addr_t     eid_prefix,
        uint8_t         eid_prefix_length,
        int             iid)
{
    lispd_mapping_elt *mapping = NULL;

    if ((mapping = (lispd_mapping_elt *)malloc(sizeof(lispd_mapping_elt)))==NULL){
        lispd_log_msg(LISP_LOG_WARNING,"Couldn't allocate memory for lispd_mapping_elt: %s", strerror(errno));
        return (NULL);
    }
    mapping->eid_prefix =  eid_prefix;
    mapping->eid_prefix_length = eid_prefix_length;
    mapping->iid = iid;
    mapping->locator_count = 0;
    mapping->head_v4_locators_list = NULL;
    mapping->head_v6_locators_list = NULL;
    mapping->extended_info = NULL;

    return (mapping);
}
Beispiel #26
0
void *pkt_fill_eid(
        void                    *offset,
        lispd_mapping_elt       *mapping)
{
    uint16_t                *afi_ptr;
    lispd_pkt_lcaf_t        *lcaf_ptr;
    lispd_pkt_lcaf_iid_t    *iid_ptr;
    void                    *eid_ptr;
    int                     eid_addr_len;

    afi_ptr = (uint16_t *)offset;
    eid_addr_len = get_addr_len(mapping->eid_prefix.afi);

    /* For negative IID values, we skip LCAF/IID field */
    if (mapping->iid < 0) {
        *afi_ptr = htons(get_lisp_afi(mapping->eid_prefix.afi, NULL));
        eid_ptr  = CO(offset, sizeof(uint16_t));
    } else {
        *afi_ptr = htons(LISP_AFI_LCAF);
        lcaf_ptr = (lispd_pkt_lcaf_t *) CO(offset, sizeof(uint16_t));
        iid_ptr  = (lispd_pkt_lcaf_iid_t *) CO(lcaf_ptr, sizeof(lispd_pkt_lcaf_t));
        eid_ptr  = (void *) CO(iid_ptr, sizeof(lispd_pkt_lcaf_iid_t));

        lcaf_ptr->rsvd1 = 0;
        lcaf_ptr->flags = 0;
        lcaf_ptr->type  = 2;
        lcaf_ptr->rsvd2 = 0;    /* This can be IID mask-len, not yet supported */
        lcaf_ptr->len   = htons(sizeof(lispd_pkt_lcaf_iid_t) + eid_addr_len);

        iid_ptr->iid = htonl(mapping->iid);
        iid_ptr->afi = htons(mapping->eid_prefix.afi);
    }

    if ((copy_addr(eid_ptr,&(mapping->eid_prefix), 0)) == 0) {
        lispd_log_msg(LISP_LOG_DEBUG_3, "pkt_fill_eid: copy_addr failed");
        return NULL;
    }

    return CO(eid_ptr, eid_addr_len);
}
lispd_referral_cache_entry *new_referral_cache_entry(
        lispd_mapping_elt                   *mapping,
        int                                 act_entry_type,
        int                                 ttl)
{
    lispd_referral_cache_entry *referral_cache_entry = NULL;

    referral_cache_entry = (lispd_referral_cache_entry *)malloc(sizeof(lispd_referral_cache_entry));
    if (referral_cache_entry == NULL){
        lispd_log_msg(LISP_LOG_WARNING,"new_referral_cache_entry: Unable to allocate memory for a referral cache entry");
        return (NULL);
    }
    referral_cache_entry->mapping                           = mapping;
    referral_cache_entry->act_entry_type                    = act_entry_type;
    referral_cache_entry->ttl                               = ttl;
    referral_cache_entry->parent_node                       = NULL;
    referral_cache_entry->children_nodes                    = NULL;
    referral_cache_entry->expiry_ddt_cache_timer            = NULL;
    referral_cache_entry->src_inf_ddt_node_locator_addr.afi = AF_UNSPEC;

    return (referral_cache_entry);
}
Beispiel #28
0
/*
 * Request to the kernel the address associated with the interface and afi selected
 */
int request_address(
        int ifa_index,
        int afi)
{
    struct nlmsghdr     *nlh        = NULL;
    struct ifaddrmsg    *addr_msg   = NULL;
    char   sndbuf[4096];
    int    addr_msg_len             = 0;
    int    retval                   = 0;

    /*
     * Build the command
     */
    memset(sndbuf, 0, 4096);

    nlh     = (struct nlmsghdr *)sndbuf;
    addr_msg = (struct ifaddrmsg *)(CO(sndbuf,sizeof(struct nlmsghdr)));

    addr_msg_len = sizeof(struct ifaddrmsg);

    nlh->nlmsg_len   = NLMSG_LENGTH(addr_msg_len);
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    nlh->nlmsg_type  = RTM_GETADDR;


    addr_msg->ifa_family    = afi;
    addr_msg->ifa_prefixlen = 0;
    addr_msg->ifa_flags     = IFA_F_PERMANENT;
    addr_msg->ifa_scope     = IFA_LOCAL;
    addr_msg->ifa_index     = ifa_index;

    retval = send(netlink_fd, sndbuf, NLMSG_LENGTH(addr_msg_len), 0);

    if (retval < 0) {
        lispd_log_msg(LISP_LOG_CRIT, "request_address: send netlink command failed %s", strerror(errno));
        return(BAD);
    }
    return(GOOD);
}
Beispiel #29
0
int copy_addr(
     void           *a1,
     lisp_addr_t    *a2,
     int            convert)
{
    switch (a2->afi) {
    case AF_INET:
        if (convert)
            ((struct in_addr *) a1)->s_addr = htonl(a2->address.ip.s_addr);
        else
            ((struct in_addr *) a1)->s_addr = a2->address.ip.s_addr;
        return(sizeof(struct in_addr));
    case AF_INET6:
        memcpy(((struct in6_addr *) a1)->s6_addr,
               a2->address.ipv6.s6_addr,
               sizeof(struct in6_addr));
        return(sizeof(struct in6_addr));
    default:
        lispd_log_msg(LISP_LOG_DEBUG_2, "copy_addr: Unknown AFI (%d)", a2->afi);
        return(ERR_AFI);
    }
}
int opent_netlink_socket()
{
    int netlink_fd          = 0;
    struct sockaddr_nl addr;


    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;


    netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

    if (netlink_fd < 0) {
        lispd_log_msg(LISP_LOG_ERR, "opent_netlink_socket: Failed to connect to netlink socket");
        return(BAD);
    }

    bind(netlink_fd, (struct sockaddr *) &addr, sizeof(addr));

    return (netlink_fd);
}