@@ -44,6 +44,11 @@ KHASH_INIT(ucs_netlink_rt_cache, khint32_t, ucs_netlink_rt_rules_t, 1,
44
44
kh_int_hash_func , kh_int_hash_equal );
45
45
static khash_t (ucs_netlink_rt_cache ) ucs_netlink_routing_table_cache ;
46
46
47
+ static inline int ucs_netlink_is_msg_done (const struct nlmsghdr * nlh )
48
+ {
49
+ return (nlh -> nlmsg_type == NLMSG_DONE );
50
+ }
51
+
47
52
static ucs_status_t ucs_netlink_socket_init (int * fd_p , int protocol )
48
53
{
49
54
struct sockaddr_nl sa = {.nl_family = AF_NETLINK };
@@ -78,7 +83,7 @@ ucs_netlink_parse_msg(const void *msg, size_t msg_len,
78
83
const struct nlmsghdr * nlh = (const struct nlmsghdr * )msg ;
79
84
80
85
while ((status == UCS_INPROGRESS ) && NLMSG_OK (nlh , msg_len ) &&
81
- (nlh -> nlmsg_type != NLMSG_DONE )) {
86
+ ! ucs_netlink_is_msg_done (nlh )) {
82
87
if (nlh -> nlmsg_type == NLMSG_ERROR ) {
83
88
struct nlmsgerr * err = (struct nlmsgerr * )NLMSG_DATA (nlh );
84
89
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,
100
105
ucs_netlink_parse_cb_t parse_cb , void * arg )
101
106
{
102
107
struct nlmsghdr nlh = {0 };
103
- char * recv_msg = NULL ;
104
- size_t recv_msg_len = 0 ;
105
108
int netlink_fd = -1 ;
109
+ size_t recv_msg_len ;
110
+ char * recv_msg ;
111
+ int msg_done ;
106
112
ucs_status_t status ;
107
113
struct iovec iov [2 ];
108
114
size_t bytes_sent ;
@@ -131,33 +137,38 @@ ucs_netlink_send_request(int protocol, unsigned short nlmsg_type,
131
137
}
132
138
133
139
/* 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
+ }
141
149
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
+ }
148
156
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
+ }
155
164
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 );
157
169
158
170
out :
159
171
ucs_close_fd (& netlink_fd );
160
- ucs_free (recv_msg );
161
172
return status ;
162
173
}
163
174
@@ -262,8 +273,8 @@ int ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote)
262
273
ucs_netlink_route_info_t info ;
263
274
264
275
UCS_INIT_ONCE (& init_once ) {
276
+ rtm .rtm_table = RT_TABLE_UNSPEC ; /* fetch all the tables */
265
277
rtm .rtm_family = AF_INET ;
266
- rtm .rtm_table = RT_TABLE_MAIN ;
267
278
ucs_netlink_send_request (NETLINK_ROUTE , RTM_GETROUTE , NLM_F_DUMP , & rtm ,
268
279
sizeof (rtm ), ucs_netlink_parse_rt_entry_cb ,
269
280
NULL );
0 commit comments