mirror of
https://github.com/systemd/systemd.git
synced 2025-01-31 05:47:30 +03:00
network: move manager_rtnl_process_neighbor() to networkd-neighbor.c
This commit is contained in:
parent
58f1fe9af9
commit
eab052d2b3
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user