mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-15 22:58:18 +02:00
merge: branch 'bg/route-dump'
platform: dump only selected route protocols https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1978
This commit is contained in:
commit
63f2401ebe
1 changed files with 93 additions and 23 deletions
|
|
@ -3908,10 +3908,16 @@ _new_from_nl_addr(const struct nlmsghdr *nlh, gboolean id_only)
|
|||
return g_steal_pointer(&obj);
|
||||
}
|
||||
|
||||
#define IP_ROUTE_TRACKED_PROTOCOLS \
|
||||
RTPROT_UNSPEC, RTPROT_REDIRECT, RTPROT_KERNEL, RTPROT_BOOT, RTPROT_STATIC, RTPROT_RA, \
|
||||
RTPROT_DHCP
|
||||
|
||||
static const guint8 ip_route_tracked_protocols[] = {IP_ROUTE_TRACKED_PROTOCOLS};
|
||||
|
||||
static gboolean
|
||||
ip_route_is_tracked(guint8 proto, guint8 type)
|
||||
{
|
||||
if (proto > RTPROT_STATIC && !NM_IN_SET(proto, RTPROT_DHCP, RTPROT_RA)) {
|
||||
if (!NM_IN_SET(proto, IP_ROUTE_TRACKED_PROTOCOLS)) {
|
||||
/* We ignore certain rtm_protocol, because NetworkManager would only ever
|
||||
* configure certain protocols. Other routes are not configured by NetworkManager
|
||||
* and we don't track them in the platform cache.
|
||||
|
|
@ -5604,6 +5610,7 @@ _nl_msg_new_route(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPObject *ob
|
|||
nm_assert(
|
||||
NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
|
||||
nm_assert(NM_IN_SET(nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE));
|
||||
nm_assert(NM_IN_SET(rtmsg.rtm_protocol, IP_ROUTE_TRACKED_PROTOCOLS));
|
||||
|
||||
if (NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, ((unsigned) (RTNH_F_ONLINK)))) {
|
||||
if (IS_IPv4 && obj->ip4_route.gateway == 0) {
|
||||
|
|
@ -7899,13 +7906,11 @@ do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action
|
|||
FOR_EACH_DELAYED_ACTION (iflags, action_type) {
|
||||
RefreshAllType refresh_all_type = delayed_action_type_to_refresh_all_type(iflags);
|
||||
const RefreshAllInfo *refresh_all_info = refresh_all_type_get_info(refresh_all_type);
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
int *out_refresh_all_in_progress;
|
||||
int *out_refresh_all_in_progress;
|
||||
|
||||
out_refresh_all_in_progress =
|
||||
&priv->delayed_action.refresh_all_in_progress[refresh_all_type];
|
||||
nm_assert(*out_refresh_all_in_progress >= 0);
|
||||
*out_refresh_all_in_progress += 1;
|
||||
|
||||
/* clear any delayed action that request a refresh of this object type. */
|
||||
priv->delayed_action.flags &= ~iflags;
|
||||
|
|
@ -7924,29 +7929,94 @@ do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action
|
|||
}
|
||||
}
|
||||
|
||||
event_handler_read_netlink(platform, refresh_all_info->protocol, FALSE);
|
||||
/* Routes are handled specially because we want to request only routes
|
||||
* for protocols we track. The reason is that there might be millions of
|
||||
* BGP routes we don't track and it would be very inefficient to dump them
|
||||
* all. Therefore, perform separate dumps, each for a specific protocol we
|
||||
* track. */
|
||||
if (NM_IN_SET(refresh_all_type,
|
||||
REFRESH_ALL_TYPE_RTNL_IP4_ROUTES,
|
||||
REFRESH_ALL_TYPE_RTNL_IP6_ROUTES)) {
|
||||
struct rtmsg rtm = {
|
||||
.rtm_family = refresh_all_info->addr_family_for_dump,
|
||||
};
|
||||
guint retry_count = 0;
|
||||
guint i;
|
||||
|
||||
if (refresh_all_info->protocol == NMP_NETLINK_ROUTE) {
|
||||
nlmsg = _nl_msg_new_dump_rtnl(refresh_all_info->obj_type,
|
||||
refresh_all_info->addr_family_for_dump);
|
||||
for (i = 0; i < G_N_ELEMENTS(ip_route_tracked_protocols); i++) {
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
|
||||
if (retry_count > 0) {
|
||||
/* Try again previous protocol */
|
||||
i--;
|
||||
}
|
||||
|
||||
/* If we try to request a new dump while the previous is still
|
||||
* in progress, kernel returns -EBUSY. Complete the previous
|
||||
* dump by reading from the socket. */
|
||||
event_handler_read_netlink(platform, refresh_all_info->protocol, FALSE);
|
||||
|
||||
nlmsg = nlmsg_alloc_new(0, RTM_GETROUTE, NLM_F_DUMP);
|
||||
if (!nlmsg)
|
||||
goto next_after_fail;
|
||||
|
||||
rtm.rtm_protocol = ip_route_tracked_protocols[i];
|
||||
|
||||
if (nlmsg_append_struct(nlmsg, &rtm) < 0)
|
||||
g_return_if_fail(FALSE);
|
||||
|
||||
*out_refresh_all_in_progress += 1;
|
||||
|
||||
if (_netlink_send_nlmsg(platform,
|
||||
refresh_all_info->protocol,
|
||||
nlmsg,
|
||||
NULL,
|
||||
NULL,
|
||||
DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS,
|
||||
out_refresh_all_in_progress)
|
||||
< 0) {
|
||||
*out_refresh_all_in_progress -= 1;
|
||||
retry_count++;
|
||||
if (retry_count > 4) {
|
||||
_LOGE("failed dumping IPv%c routes with protocol %u, cache might be "
|
||||
"inconsistent",
|
||||
nm_utils_addr_family_to_char(rtm.rtm_family),
|
||||
rtm.rtm_protocol);
|
||||
retry_count = 0;
|
||||
/* Give up and try the next protocol */
|
||||
}
|
||||
} else {
|
||||
retry_count = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nm_assert(refresh_all_type == REFRESH_ALL_TYPE_GENL_FAMILIES);
|
||||
nlmsg = _nl_msg_new_dump_genl_families();
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
|
||||
*out_refresh_all_in_progress += 1;
|
||||
event_handler_read_netlink(platform, refresh_all_info->protocol, FALSE);
|
||||
|
||||
if (refresh_all_info->protocol == NMP_NETLINK_ROUTE) {
|
||||
nlmsg = _nl_msg_new_dump_rtnl(refresh_all_info->obj_type,
|
||||
refresh_all_info->addr_family_for_dump);
|
||||
} else {
|
||||
nm_assert(refresh_all_type == REFRESH_ALL_TYPE_GENL_FAMILIES);
|
||||
nlmsg = _nl_msg_new_dump_genl_families();
|
||||
}
|
||||
|
||||
if (!nlmsg)
|
||||
goto next_after_fail;
|
||||
|
||||
if (_netlink_send_nlmsg(platform,
|
||||
refresh_all_info->protocol,
|
||||
nlmsg,
|
||||
NULL,
|
||||
NULL,
|
||||
DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS,
|
||||
out_refresh_all_in_progress)
|
||||
< 0)
|
||||
goto next_after_fail;
|
||||
}
|
||||
|
||||
if (!nlmsg)
|
||||
goto next_after_fail;
|
||||
|
||||
if (_netlink_send_nlmsg(platform,
|
||||
refresh_all_info->protocol,
|
||||
nlmsg,
|
||||
NULL,
|
||||
NULL,
|
||||
DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS,
|
||||
out_refresh_all_in_progress)
|
||||
< 0)
|
||||
goto next_after_fail;
|
||||
|
||||
continue;
|
||||
next_after_fail:
|
||||
nm_assert(*out_refresh_all_in_progress > 0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue