Skip to content

Commit a0f89a0

Browse files
authored
Merge pull request #10848 from amastbaum/vrf_ipv6_reachability
UCS/SYS/NETLINK: Iteratively receive netlink messages until 'done' is set
2 parents e3cb7d6 + 6d96bec commit a0f89a0

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

src/ucs/sys/netlink.c

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ KHASH_INIT(ucs_netlink_rt_cache, khint32_t, ucs_netlink_rt_rules_t, 1,
4444
kh_int_hash_func, kh_int_hash_equal);
4545
static khash_t(ucs_netlink_rt_cache) ucs_netlink_routing_table_cache;
4646

47+
static inline int ucs_netlink_is_msg_done(const struct nlmsghdr *nlh)
48+
{
49+
return (nlh->nlmsg_type == NLMSG_DONE);
50+
}
51+
4752
static ucs_status_t ucs_netlink_socket_init(int *fd_p, int protocol)
4853
{
4954
struct sockaddr_nl sa = {.nl_family = AF_NETLINK};
@@ -78,7 +83,7 @@ ucs_netlink_parse_msg(const void *msg, size_t msg_len,
7883
const struct nlmsghdr *nlh = (const struct nlmsghdr *)msg;
7984

8085
while ((status == UCS_INPROGRESS) && NLMSG_OK(nlh, msg_len) &&
81-
(nlh->nlmsg_type != NLMSG_DONE)) {
86+
!ucs_netlink_is_msg_done(nlh)) {
8287
if (nlh->nlmsg_type == NLMSG_ERROR) {
8388
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nlh);
8489
ucs_error("received error response from netlink err=%d: %s\n",
@@ -100,9 +105,10 @@ ucs_netlink_send_request(int protocol, unsigned short nlmsg_type,
100105
ucs_netlink_parse_cb_t parse_cb, void *arg)
101106
{
102107
struct nlmsghdr nlh = {0};
103-
char *recv_msg = NULL;
104-
size_t recv_msg_len = 0;
105108
int netlink_fd = -1;
109+
size_t recv_msg_len;
110+
char *recv_msg;
111+
int msg_done;
106112
ucs_status_t status;
107113
struct iovec iov[2];
108114
size_t bytes_sent;
@@ -131,33 +137,38 @@ ucs_netlink_send_request(int protocol, unsigned short nlmsg_type,
131137
}
132138

133139
/* get message size */
134-
status = ucs_socket_recv_nb(netlink_fd, NULL, MSG_PEEK | MSG_TRUNC,
135-
&recv_msg_len);
136-
if (status != UCS_OK) {
137-
ucs_error("failed to get netlink message size %d (%s)",
138-
status, ucs_status_string(status));
139-
goto out;
140-
}
140+
do {
141+
recv_msg_len = 0;
142+
status = ucs_socket_recv_nb(netlink_fd, NULL, MSG_PEEK | MSG_TRUNC,
143+
&recv_msg_len);
144+
if (status != UCS_OK) {
145+
ucs_error("failed to get netlink message size %d (%s)",
146+
status, ucs_status_string(status));
147+
goto out;
148+
}
141149

142-
recv_msg = ucs_malloc(recv_msg_len, "netlink recv message");
143-
if (recv_msg == NULL) {
144-
ucs_error("failed to allocate a buffer for netlink receive message of"
145-
" size %zu", recv_msg_len);
146-
goto out;
147-
}
150+
recv_msg = ucs_malloc(recv_msg_len, "netlink recv message");
151+
if (recv_msg == NULL) {
152+
ucs_error("failed to allocate a buffer for netlink receive message"
153+
" of size %zu", recv_msg_len);
154+
goto out;
155+
}
148156

149-
status = ucs_socket_recv(netlink_fd, recv_msg, recv_msg_len);
150-
if (status != UCS_OK) {
151-
ucs_error("failed to receive netlink message on fd=%d: %s",
152-
netlink_fd, ucs_status_string(status));
153-
goto out;
154-
}
157+
status = ucs_socket_recv(netlink_fd, recv_msg, recv_msg_len);
158+
if (status != UCS_OK) {
159+
ucs_error("failed to receive netlink message on fd=%d: %s",
160+
netlink_fd, ucs_status_string(status));
161+
ucs_free(recv_msg);
162+
goto out;
163+
}
155164

156-
status = ucs_netlink_parse_msg(recv_msg, recv_msg_len, parse_cb, arg);
165+
status = ucs_netlink_parse_msg(recv_msg, recv_msg_len, parse_cb, arg);
166+
msg_done = ucs_netlink_is_msg_done((const struct nlmsghdr *)recv_msg);
167+
ucs_free(recv_msg);
168+
} while ((nlmsg_flags & NLM_F_DUMP) && !msg_done);
157169

158170
out:
159171
ucs_close_fd(&netlink_fd);
160-
ucs_free(recv_msg);
161172
return status;
162173
}
163174

@@ -262,8 +273,8 @@ int ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote)
262273
ucs_netlink_route_info_t info;
263274

264275
UCS_INIT_ONCE(&init_once) {
276+
rtm.rtm_table = RT_TABLE_UNSPEC; /* fetch all the tables */
265277
rtm.rtm_family = AF_INET;
266-
rtm.rtm_table = RT_TABLE_MAIN;
267278
ucs_netlink_send_request(NETLINK_ROUTE, RTM_GETROUTE, NLM_F_DUMP, &rtm,
268279
sizeof(rtm), ucs_netlink_parse_rt_entry_cb,
269280
NULL);

0 commit comments

Comments
 (0)