Esempio n. 1
0
void process_nl_del_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];

    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)",
                      iface_name);
        return;
    }
    rth = IFA_RTA (ifa);

    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;
            }
            break;
        }
    }
    /* Actions to be done when address is removed */
    lispd_log_msg(LISP_LOG_DEBUG_2,"   deleted address: %s\n", get_char_from_lisp_addr_t(new_addr));
}
Esempio n. 2
0
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 (ifa->ifa_family == AF_INET && rth->rta_type == IFA_LOCAL){
    		memcpy (&(new_addr.address),(struct in_addr *)RTA_DATA(rth),sizeof(struct in_addr));
    		new_addr.afi = AF_INET;
    		process_address_change (iface, new_addr);
    	}
    	if (ifa->ifa_family == AF_INET6 && rth->rta_type == IFA_ADDRESS){
    		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);
    	}
    }
}
Esempio n. 3
0
void process_nl_new_route (struct nlmsghdr *nlh)
{
    struct rtmsg             *rtm                       = NULL;
    struct rtattr            *rt_attr                   = NULL;
    int                      rt_length                  = 0;
    lispd_iface_elt          *iface                     = NULL;
    int                      iface_index                = 0;
    char                     iface_name[IF_NAMESIZE];
    lisp_addr_t              gateway                    = {.afi=AF_UNSPEC};
    lisp_addr_t              dst                        = {.afi=AF_UNSPEC};;


    rtm = (struct rtmsg *) NLMSG_DATA (nlh);

    if ((rtm->rtm_family != AF_INET) && (rtm->rtm_family != AF_INET6)) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"process_nl_new_route: Unknown adddress family");
        return;
    }

    if (rtm->rtm_table != RT_TABLE_MAIN) {
        /* Not interested in routes/gateways affecting tables other the main routing table */
        return;
    }

    rt_attr = (struct rtattr *)RTM_RTA(rtm);
    rt_length = RTM_PAYLOAD(nlh);

    for (; RTA_OK(rt_attr, rt_length); rt_attr = RTA_NEXT(rt_attr, rt_length)) {
        switch (rt_attr->rta_type) {
        case RTA_OIF:
            iface_index = *(int *)RTA_DATA(rt_attr);
            iface = get_interface_from_index(iface_index);
            if_indextoname(iface_index, iface_name);
            if (iface == NULL) {
                lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_new_route: the netlink message is not for any interface associated with RLOCs (%s)",
                              iface_name);
                return;
            }
            break;
        case RTA_GATEWAY:
            gateway.afi = rtm->rtm_family;
            switch (gateway.afi) {
            case AF_INET:
                memcpy(&(gateway.address),(struct in_addr *)RTA_DATA(rt_attr), sizeof(struct in_addr));
                break;
            case AF_INET6:
                memcpy(&(gateway.address),(struct in6_addr *)RTA_DATA(rt_attr), sizeof(struct in6_addr));
                break;
            default:
                break;
            }
            break;
        case RTA_DST: // We check if the new route message contains a destintaion. If it is, then the gateway address is not a default route. Discard it
            dst.afi = rtm->rtm_family;
            switch (dst.afi) {
            case AF_INET:
                memcpy(&(dst.address),(struct in_addr *)RTA_DATA(rt_attr), sizeof(struct in_addr));
                break;
            case AF_INET6:
                memcpy(&(dst.address),(struct in6_addr *)RTA_DATA(rt_attr), sizeof(struct in6_addr));
                break;
            default:
                break;
            }
            break;
        default:
            break;
        }
    }
    if (gateway.afi != AF_UNSPEC && iface_index != 0 && dst.afi == AF_UNSPEC) {
        /* Check default afi*/
        if (default_rloc_afi != AF_UNSPEC && default_rloc_afi != gateway.afi) {
            lispd_log_msg(LISP_LOG_DEBUG_1,  "process_nl_new_route: Default RLOC afi defined (-a #): Skipped %s gateway in iface %s",
                          (gateway.afi == AF_INET) ? "IPv4" : "IPv6",iface->iface_name);
            return;
        }

        /* Check if the addres is a global address*/
        if (is_link_local_addr(gateway) == TRUE) {
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_nl_new_route: the extractet address from the netlink "
                          "messages is a local link address: %s discarded", get_char_from_lisp_addr_t(gateway));
            return;
        }

        /* Process the new gateway */
        lispd_log_msg(LISP_LOG_DEBUG_1,  "process_nl_new_route: Process new gateway associated to the interface %s:  %s",
                      iface_name, get_char_from_lisp_addr_t(gateway));
        process_new_gateway(gateway,iface);
    }
}
Esempio n. 4
0
void process_nl_new_link (struct nlmsghdr *nlh)
{
    struct ifinfomsg                    *ifi            = NULL;
    lispd_iface_elt                     *iface          = NULL;
    int                                 iface_index     = 0;
    uint8_t                             status          = UP;
    char                                iface_name[IF_NAMESIZE];
    uint32_t                            old_iface_index = 0;

    ifi = (struct ifinfomsg *) NLMSG_DATA (nlh);
    iface_index = ifi->ifi_index;


    iface = get_interface_from_index(iface_index);

    if (iface == NULL) {
        /*
         * In some OS when a virtual interface is removed and added again, the index of the interface change.
         * Search lispd_iface_elt by the interface name and update the index.
         */
        if (if_indextoname(iface_index, iface_name) != NULL) {
            iface = get_interface(iface_name);
        }
        if (iface == NULL) {
            lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_new_link: the netlink message is not for any interface associated with RLOCs  (%s)",
                          iface_name);
            return;
        } else {
            old_iface_index = iface->iface_index;
            iface->iface_index = iface_index;
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_nl_new_link: The new index of the interface %s is: %d. Updating tables",
                          iface_name, iface->iface_index);
            /* Update routing tables and reopen sockets*/
            if (iface->ipv4_address->afi != AF_UNSPEC) {
                del_rule(AF_INET,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0);
                add_rule(AF_INET,0,iface_index,iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0);
                close(iface->out_socket_v4);
                iface->out_socket_v4 = open_device_binded_raw_socket(iface->iface_name,AF_INET);
                bind_socket_src_address(iface->out_socket_v4,iface->ipv4_address);
            }
            if (iface->ipv6_address->afi != AF_UNSPEC) {
                del_rule(AF_INET6,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0);
                add_rule(AF_INET6,0,iface_index,iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0);
                close(iface->out_socket_v6);
                iface->out_socket_v6 = open_device_binded_raw_socket(iface->iface_name,AF_INET6);
                bind_socket_src_address(iface->out_socket_v6,iface->ipv6_address);
            }
        }
    }

    if ((ifi->ifi_flags & IFF_RUNNING) != 0) {
        lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to UP",iface->iface_name);
        status = UP;
    }
    else {
        lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to DOWN",iface->iface_name);
        status = DOWN;
    }

    process_link_status_change (iface, status);
}