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)); }
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); } } }
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); } }
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); }