From: Yu Watanabe Date: Tue, 29 Sep 2020 14:20:14 +0000 (+0900) Subject: network: move manager_rtnl_process_neighbor() to networkd-neighbor.c X-Git-Tag: v247-rc1~117^2~105 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eab052d2b3e73b6b3787d00131ae2d191e7a4ec6;p=thirdparty%2Fsystemd.git network: move manager_rtnl_process_neighbor() to networkd-neighbor.c --- diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 0a0fb36f95a..37a9745df87 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -538,186 +538,6 @@ static int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *mess return 1; } -static int manager_rtnl_process_neighbor_lladdr(sd_netlink_message *message, union lladdr_union *lladdr, size_t *size, char **str) { - int r; - - assert(message); - assert(lladdr); - assert(size); - assert(str); - - *str = NULL; - - r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in6), &lladdr->ip.in6); - if (r >= 0) { - *size = sizeof(lladdr->ip.in6); - if (in_addr_to_string(AF_INET6, &lladdr->ip, str) < 0) - log_warning_errno(r, "Could not print lower address: %m"); - return r; - } - - r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->mac), &lladdr->mac); - if (r >= 0) { - *size = sizeof(lladdr->mac); - *str = new(char, ETHER_ADDR_TO_STRING_MAX); - if (!*str) { - log_oom(); - return r; - } - ether_addr_to_string(&lladdr->mac, *str); - return r; - } - - r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in), &lladdr->ip.in); - if (r >= 0) { - *size = sizeof(lladdr->ip.in); - if (in_addr_to_string(AF_INET, &lladdr->ip, str) < 0) - log_warning_errno(r, "Could not print lower address: %m"); - return r; - } - - return r; -} - -static int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { - Link *link = NULL; - Neighbor *neighbor = NULL; - int ifindex, family, r; - uint16_t type, state; - union in_addr_union in_addr = IN_ADDR_NULL; - _cleanup_free_ char *addr_str = NULL; - union lladdr_union lladdr; - size_t lladdr_size = 0; - _cleanup_free_ char *lladdr_str = NULL; - - assert(rtnl); - assert(message); - assert(m); - - if (sd_netlink_message_is_error(message)) { - r = sd_netlink_message_get_errno(message); - if (r < 0) - log_message_warning_errno(message, r, "rtnl: failed to receive neighbor message, ignoring"); - - return 0; - } - - r = sd_netlink_message_get_type(message, &type); - if (r < 0) { - log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); - return 0; - } else if (!IN_SET(type, RTM_NEWNEIGH, RTM_DELNEIGH)) { - log_warning("rtnl: received unexpected message type %u when processing neighbor, ignoring.", type); - return 0; - } - - r = sd_rtnl_message_neigh_get_state(message, &state); - if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid state, ignoring: %m"); - return 0; - } else if (!FLAGS_SET(state, NUD_PERMANENT)) { - log_debug("rtnl: received non-static neighbor, ignoring."); - return 0; - } - - r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex); - if (r < 0) { - log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m"); - return 0; - } else if (ifindex <= 0) { - log_warning("rtnl: received neighbor message with invalid ifindex %d, ignoring.", ifindex); - return 0; - } - - r = link_get(m, ifindex, &link); - if (r < 0 || !link) { - /* when enumerating we might be out of sync, but we will get the neighbor again, so just - * ignore it */ - if (!m->enumerating) - log_warning("rtnl: received neighbor for link '%d' we don't know about, ignoring.", ifindex); - return 0; - } - - r = sd_rtnl_message_neigh_get_family(message, &family); - if (r < 0) { - log_link_warning(link, "rtnl: received neighbor message without family, ignoring."); - return 0; - } else if (!IN_SET(family, AF_INET, AF_INET6)) { - log_link_debug(link, "rtnl: received neighbor message with invalid family '%i', ignoring.", family); - return 0; - } - - switch (family) { - case AF_INET: - r = sd_netlink_message_read_in_addr(message, NDA_DST, &in_addr.in); - if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m"); - return 0; - } - - break; - - case AF_INET6: - r = sd_netlink_message_read_in6_addr(message, NDA_DST, &in_addr.in6); - if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m"); - return 0; - } - - break; - - default: - assert_not_reached("Received unsupported address family"); - } - - if (in_addr_to_string(family, &in_addr, &addr_str) < 0) - log_link_warning_errno(link, r, "Could not print address: %m"); - - r = manager_rtnl_process_neighbor_lladdr(message, &lladdr, &lladdr_size, &lladdr_str); - if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid lladdr, ignoring: %m"); - return 0; - } - - (void) neighbor_get(link, family, &in_addr, &lladdr, lladdr_size, &neighbor); - - switch (type) { - case RTM_NEWNEIGH: - if (neighbor) - log_link_debug(link, "Received remembered neighbor: %s->%s", - strnull(addr_str), strnull(lladdr_str)); - else { - /* A neighbor appeared that we did not request */ - r = neighbor_add_foreign(link, family, &in_addr, &lladdr, lladdr_size, &neighbor); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to remember foreign neighbor %s->%s, ignoring: %m", - strnull(addr_str), strnull(lladdr_str)); - return 0; - } else - log_link_debug(link, "Remembering foreign neighbor: %s->%s", - strnull(addr_str), strnull(lladdr_str)); - } - - break; - - case RTM_DELNEIGH: - if (neighbor) { - log_link_debug(link, "Forgetting neighbor: %s->%s", - strnull(addr_str), strnull(lladdr_str)); - (void) neighbor_free(neighbor); - } else - log_link_debug(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.", - strnull(addr_str), strnull(lladdr_str)); - - break; - - default: - assert_not_reached("Received invalid RTNL message type"); - } - - return 1; -} - int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { _cleanup_free_ char *buf = NULL; Link *link = NULL; diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index b9c149121c8..3eec9655333 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -383,6 +383,186 @@ int neighbor_remove(Neighbor *neighbor, Link *link, link_netlink_message_handler return 0; } +static int manager_rtnl_process_neighbor_lladdr(sd_netlink_message *message, union lladdr_union *lladdr, size_t *size, char **str) { + int r; + + assert(message); + assert(lladdr); + assert(size); + assert(str); + + *str = NULL; + + r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in6), &lladdr->ip.in6); + if (r >= 0) { + *size = sizeof(lladdr->ip.in6); + if (in_addr_to_string(AF_INET6, &lladdr->ip, str) < 0) + log_warning_errno(r, "Could not print lower address: %m"); + return r; + } + + r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->mac), &lladdr->mac); + if (r >= 0) { + *size = sizeof(lladdr->mac); + *str = new(char, ETHER_ADDR_TO_STRING_MAX); + if (!*str) { + log_oom(); + return r; + } + ether_addr_to_string(&lladdr->mac, *str); + return r; + } + + r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in), &lladdr->ip.in); + if (r >= 0) { + *size = sizeof(lladdr->ip.in); + if (in_addr_to_string(AF_INET, &lladdr->ip, str) < 0) + log_warning_errno(r, "Could not print lower address: %m"); + return r; + } + + return r; +} + +int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { + Link *link = NULL; + Neighbor *neighbor = NULL; + int ifindex, family, r; + uint16_t type, state; + union in_addr_union in_addr = IN_ADDR_NULL; + _cleanup_free_ char *addr_str = NULL; + union lladdr_union lladdr; + size_t lladdr_size = 0; + _cleanup_free_ char *lladdr_str = NULL; + + assert(rtnl); + assert(message); + assert(m); + + if (sd_netlink_message_is_error(message)) { + r = sd_netlink_message_get_errno(message); + if (r < 0) + log_message_warning_errno(message, r, "rtnl: failed to receive neighbor message, ignoring"); + + return 0; + } + + r = sd_netlink_message_get_type(message, &type); + if (r < 0) { + log_warning_errno(r, "rtnl: could not get message type, ignoring: %m"); + return 0; + } else if (!IN_SET(type, RTM_NEWNEIGH, RTM_DELNEIGH)) { + log_warning("rtnl: received unexpected message type %u when processing neighbor, ignoring.", type); + return 0; + } + + r = sd_rtnl_message_neigh_get_state(message, &state); + if (r < 0) { + log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid state, ignoring: %m"); + return 0; + } else if (!FLAGS_SET(state, NUD_PERMANENT)) { + log_debug("rtnl: received non-static neighbor, ignoring."); + return 0; + } + + r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex); + if (r < 0) { + log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m"); + return 0; + } else if (ifindex <= 0) { + log_warning("rtnl: received neighbor message with invalid ifindex %d, ignoring.", ifindex); + return 0; + } + + r = link_get(m, ifindex, &link); + if (r < 0 || !link) { + /* when enumerating we might be out of sync, but we will get the neighbor again, so just + * ignore it */ + if (!m->enumerating) + log_warning("rtnl: received neighbor for link '%d' we don't know about, ignoring.", ifindex); + return 0; + } + + r = sd_rtnl_message_neigh_get_family(message, &family); + if (r < 0) { + log_link_warning(link, "rtnl: received neighbor message without family, ignoring."); + return 0; + } else if (!IN_SET(family, AF_INET, AF_INET6)) { + log_link_debug(link, "rtnl: received neighbor message with invalid family '%i', ignoring.", family); + return 0; + } + + switch (family) { + case AF_INET: + r = sd_netlink_message_read_in_addr(message, NDA_DST, &in_addr.in); + if (r < 0) { + log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m"); + return 0; + } + + break; + + case AF_INET6: + r = sd_netlink_message_read_in6_addr(message, NDA_DST, &in_addr.in6); + if (r < 0) { + log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m"); + return 0; + } + + break; + + default: + assert_not_reached("Received unsupported address family"); + } + + if (in_addr_to_string(family, &in_addr, &addr_str) < 0) + log_link_warning_errno(link, r, "Could not print address: %m"); + + r = manager_rtnl_process_neighbor_lladdr(message, &lladdr, &lladdr_size, &lladdr_str); + if (r < 0) { + log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid lladdr, ignoring: %m"); + return 0; + } + + (void) neighbor_get(link, family, &in_addr, &lladdr, lladdr_size, &neighbor); + + switch (type) { + case RTM_NEWNEIGH: + if (neighbor) + log_link_debug(link, "Received remembered neighbor: %s->%s", + strnull(addr_str), strnull(lladdr_str)); + else { + /* A neighbor appeared that we did not request */ + r = neighbor_add_foreign(link, family, &in_addr, &lladdr, lladdr_size, &neighbor); + if (r < 0) { + log_link_warning_errno(link, r, "Failed to remember foreign neighbor %s->%s, ignoring: %m", + strnull(addr_str), strnull(lladdr_str)); + return 0; + } else + log_link_debug(link, "Remembering foreign neighbor: %s->%s", + strnull(addr_str), strnull(lladdr_str)); + } + + break; + + case RTM_DELNEIGH: + if (neighbor) { + log_link_debug(link, "Forgetting neighbor: %s->%s", + strnull(addr_str), strnull(lladdr_str)); + (void) neighbor_free(neighbor); + } else + log_link_debug(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.", + strnull(addr_str), strnull(lladdr_str)); + + break; + + default: + assert_not_reached("Received invalid RTNL message type"); + } + + return 1; +} + int neighbor_section_verify(Neighbor *neighbor) { if (section_is_invalid(neighbor->section)) return -EINVAL; diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h index bba59f02272..3f21a25c2f7 100644 --- a/src/network/networkd-neighbor.h +++ b/src/network/networkd-neighbor.h @@ -49,6 +49,8 @@ int neighbor_section_verify(Neighbor *neighbor); int link_set_neighbors(Link *link); +int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); + CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address); CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_hwaddr); CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_lladdr);