Skip to content

UCT: prioritize routes with longer subnet masks in the reachability check - #11033

Merged
yosefe merged 1 commit into
openucx:masterfrom
amastbaum:deprioritize_default_gw_routes
Dec 10, 2025
Merged

yosefe merged 1 commit into
openucx:masterfrom
amastbaum:deprioritize_default_gw_routes

Conversation

@amastbaum

Copy link
Copy Markdown
Contributor

What?

Use a default GW routes only when no specific routes exist.

Found in a CI issue when running ./test/gtest/gtest --gtest_filter=*all/test_ucp_sockaddr_protocols_diff_net_devices.restricted_net_devices/0*

@amastbaum amastbaum added the WIP-DNM Work in progress / Do not review label Dec 2, 2025
Comment thread src/ucs/sys/netlink.h Outdated
Comment on lines +60 to +64
int ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote,
int allow_default_gw);
int *has_default_gw_p);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the information about default gw rules is retrieved implicitly via the out parameter but I can create a separate function for that.

@amastbaum
amastbaum force-pushed the deprioritize_default_gw_routes branch from 133dd3e to 379c114 Compare December 2, 2025 13:58
@amastbaum amastbaum added Ready for Review and removed WIP-DNM Work in progress / Do not review labels Dec 2, 2025
@amastbaum
amastbaum requested a review from gleon99 December 2, 2025 13:59
@gleon99

gleon99 commented Dec 2, 2025

Copy link
Copy Markdown
Contributor

@amastbaum

  1. The title is a bit clumsy, plz rephrase (for example, from the "description").
  2. Use what/why/how template.
  3. plz explain not that "it was found in CI", but what is the root issue, when it appears, what is the impact..

@amastbaum amastbaum changed the title Deprioritize default gw routes UCT: prioritize non-default GW rules in the reachability check Dec 2, 2025
Comment thread src/ucs/sys/netlink.h Outdated
* interface, as assigned by the system
* (e.g., obtained via if_nametoindex()).
* @param [in] sa_remote Pointer to the destination address.
* @param [out] has_default_gw_p Optional pointer to store whether a default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt of: instead of returning 0/1 and an optional _p, have a single return value with an enum like {None,Route,Gateway} (roughly)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment thread src/ucs/sys/netlink.h Outdated
int *has_default_gw_p);

/**
* Check whether a specific route exists for a given destination address

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the word "specific" come from? Is it used in netlink terminology?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So not really. It's only relative to the "default GW/route" term. I need to emphasize their difference (can also be "non-default route")

Comment thread src/uct/ib/base/ib_iface.c Outdated
return 1;
/* No route found at all */
if (lo_status == UCS_OK) {
uct_iface_fill_info_str_buf(params,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can eliminate code duplication here?

Comment thread src/uct/tcp/tcp_iface.c Outdated
return 1;
}

/* Going to search for a default GW route on this interface. If found, and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move to lines 286-293 block, make more concise (w/o "going to..", only explain the reasoning)

Comment thread src/uct/ib/base/ib_iface.c Outdated
UCT_IB_IFACE_ARG(iface),
ndev_index, lo_ndev_index);
return 0;
/* Going to search a default GW route on this interface. If found, and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment appears twice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gleon99 It appears once in tcp_iface.c and once in ib_iface.c.
You mean to eliminate duplications between them? Maybe need some ip category, or tcp_iface.c is enough?

@gleon99
gleon99 requested a review from roiedanino December 2, 2025 17:35
@yosefe

yosefe commented Dec 2, 2025

Copy link
Copy Markdown
Member

should we prioritize routes by subnet prefix length in general (i.e longest prefix matching), not just for default gw?

Comment thread src/ucs/sys/netlink.c Outdated
int ucs_netlink_has_any_specific_route(const struct sockaddr *sa_remote)
{
ucs_netlink_rt_rules_t iface_rules;
ucs_netlink_route_info_t info = {.sa_remote = sa_remote};

@roiedanino roiedanino Dec 3, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ucs_netlink_route_info_t info = {.sa_remote = sa_remote};
ucs_netlink_route_info_t info = {
.sa_remote = sa_remote,
.found = 0,
.found_default_gw = 0
};

Comment thread src/ucs/sys/netlink.c Outdated
Comment on lines +306 to +307
ucs_netlink_route_info_t info = {.if_index = if_index,
.sa_remote = sa_remote};

@roiedanino roiedanino Dec 3, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize found_defualt_gw to 0

Comment thread src/ucs/sys/netlink.h Outdated
Comment on lines +66 to +74
/**
* Check whether a specific route exists for a given destination address
* in ANY network interface.
*
* @param [in] sa_remote Pointer to the destination address.
*
* @return 1 if a specific route exists in any interface, or 0 otherwise.
*/
int ucs_netlink_has_any_specific_route(const struct sockaddr *sa_remote);

@roiedanino roiedanino Dec 3, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* Check whether a specific route exists for a given destination address
* in ANY network interface.
*
* @param [in] sa_remote Pointer to the destination address.
*
* @return 1 if a specific route exists in any interface, or 0 otherwise.
*/
int ucs_netlink_has_any_specific_route(const struct sockaddr *sa_remote);
/**
* Check whether a non-default route exists for a given destination address
* in ANY network interface.
*
* @param [in] sa_remote Pointer to the destination address.
*
* @return 1 if a non-default route exists in any interface, or 0 otherwise.
*/
int ucs_netlink_has_non_default_route(const struct sockaddr *sa_remote);

Comment thread src/uct/ib/base/ib_iface.c Outdated
uct_iface_fill_info_str_buf(params,
"loopback iface index is not found");
return 0;
if (ucs_netlink_route_exists(ndev_index, sa_remote, &has_default_gw)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has_default_gw is not used, so it would be a bit cleaner to use an enum as a return type like @gleon99 suggested

@roiedanino

Copy link
Copy Markdown
Contributor

This PR might solve #11035?

@yosefe yosefe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is not trivial to fix the review comments, pls submit a PR to workaround the failing CI test in meantime, or push this PR as is and then rework/revert it

Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/ucs/sys/netlink.h Resolved
Comment thread src/uct/ib/base/ib_iface.c Outdated
Comment on lines +718 to +722
/* No route found - first, try loopback interface for reachability
* check, because it may be used for routing in case of an interface with
* VRF is configured and a RoCE IP interface uses this VRF table for
* routing. */
if (uct_ib_iface_get_loopback_ndev_index(&lo_ndev_index) == UCS_OK) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, shouldn't VRF be inside "netlink" code because it is also relevant for TCP?

@amastbaum amastbaum closed this Dec 7, 2025
@amastbaum
amastbaum deleted the deprioritize_default_gw_routes branch December 7, 2025 09:23
@amastbaum
amastbaum restored the deprioritize_default_gw_routes branch December 7, 2025 09:30
@amastbaum amastbaum reopened this Dec 7, 2025
@amastbaum
amastbaum force-pushed the deprioritize_default_gw_routes branch from 1bd31fa to 37bcdb7 Compare December 7, 2025 12:39
@amastbaum
amastbaum requested a review from yosefe December 7, 2025 12:40
Comment thread src/ucs/sys/netlink.c

int ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote,
int allow_default_gw)
static void ucs_netlink_init_routing_table_cache(void)

@amastbaum amastbaum Dec 7, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could actually leave it as before and only trigger the cache initialization from ucs_netlink_route_exists, because ucs_netlink_route_exists is eventually called from ucs_netlink_is_best_route as well.
I just wasn't sure what is the best way to initialize the cache because I want to promise it will be triggered from each api call, and it's currently done quite implicitly. @yosefe @gleon99

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe init the cache in ucs_netlink_lookup_route?

Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/ucs/sys/netlink.c Outdated
info.sa_remote = sa_remote;
info.found = 0;
info.allow_default_gw = allow_default_gw;
static int ucs_netlink_has_better_route(const struct sockaddr *sa_remote,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe return the longest matching netmask length (-1 if not found)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we should rename this function to ucs_netlink_max_netmask_len

Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/uct/tcp/tcp_iface.c
}

allow_default_gw = !!(tcp_dev_addr->flags &
UCT_TCP_DEVICE_ADDR_FLAG_ALLOW_DEFAULT_GW);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove UCT_TCP_DEVICE_ADDR_FLAG_ALLOW_DEFAULT_GW flag and related logic?

Comment thread src/ucs/sys/netlink.h Outdated
Comment on lines +74 to +75
int ucs_netlink_is_this_the_route(int if_index,
const struct sockaddr *sa_remote);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ucs_netlink_is_preferred_route

@amastbaum amastbaum Dec 8, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yosefe This is outdated, currently called ucs_netlink_is_best_route.
preferred is better?

@amastbaum
amastbaum requested a review from yosefe December 8, 2025 08:55
Comment thread src/ucs/sys/netlink.c Outdated
int found;
int allow_default_gw; /* Allow matching default
gateway routes */
int found_netmask_len;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe just

Suggested change
int found_netmask_len;
int netmask_len;

Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/ucs/sys/netlink.c Outdated

ucs_array_for_each(curr_entry, iface_rules) {
if (curr_entry->subnet_prefix_len > info->found_netmask_len &&
if (curr_entry->subnet_prefix_len > found_netmask_len &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add ( )

Comment thread src/ucs/sys/netlink.c Resolved
Comment thread src/ucs/sys/netlink.c Outdated
Comment on lines +325 to +327
ucs_netlink_route_info_t info = {.if_index = if_index,
.sa_remote = sa_remote,
.netmask_len = -1};

@roiedanino roiedanino Dec 9, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: formatting

Suggested change
ucs_netlink_route_info_t info = {.if_index = if_index,
.sa_remote = sa_remote,
.netmask_len = -1};
ucs_netlink_route_info_t info = {
.if_index = if_index,
.sa_remote = sa_remote,
.netmask_len = -1
};

It seems that there are multiple clang-format issues
check git-clang-format --diff HEAD~13

Other than that, it's approved on my side

roiedanino
roiedanino previously approved these changes Dec 9, 2025
Comment thread src/ucs/sys/netlink.c Outdated
}
});
})
;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove this ;

@gleon99

gleon99 commented Dec 10, 2025

Copy link
Copy Markdown
Contributor

@amastbaum please squash

@amastbaum
amastbaum force-pushed the deprioritize_default_gw_routes branch from e67e15b to 9cce62c Compare December 10, 2025 11:19
@amastbaum amastbaum changed the title UCT: prioritize non-default GW rules in the reachability check UCT: prioritize routes with longer subnet masks in the reachability check Dec 10, 2025
@yosefe
yosefe enabled auto-merge December 10, 2025 16:57
@yosefe
yosefe merged commit 992ee5f into openucx:master Dec 10, 2025
147 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants