@@ -29,6 +29,8 @@ typedef struct {
2929 const struct sockaddr * sa_remote ;
3030 int if_index ;
3131 int found ;
32+ int allow_default_gw ; /* Allow matching default
33+ gateway routes */
3234} ucs_netlink_route_info_t ;
3335
3436
@@ -174,7 +176,7 @@ ucs_netlink_send_request(int protocol, unsigned short nlmsg_type,
174176
175177static ucs_status_t
176178ucs_netlink_get_route_info (const struct rtattr * rta , int len , int * if_index_p ,
177- const void * * dst_in_addr )
179+ const void * * dst_in_addr , size_t rtm_dst_len )
178180{
179181 * if_index_p = -1 ;
180182 * dst_in_addr = NULL ;
@@ -187,7 +189,10 @@ ucs_netlink_get_route_info(const struct rtattr *rta, int len, int *if_index_p,
187189 }
188190 }
189191
190- if ((* if_index_p == -1 ) || (* dst_in_addr == NULL )) {
192+ if (/* Network interface index is not valid */
193+ (* if_index_p == -1 ) ||
194+ /* dst_in_addr required but not present */
195+ ((rtm_dst_len != 0 ) && (* dst_in_addr == NULL ))) {
191196 return UCS_ERR_INVALID_PARAM ;
192197 }
193198
@@ -206,7 +211,8 @@ ucs_netlink_parse_rt_entry_cb(const struct nlmsghdr *nlh, void *arg)
206211 int khret ;
207212
208213 if (ucs_netlink_get_route_info (RTM_RTA (rt_msg ), RTM_PAYLOAD (nlh ),
209- & iface_index , & dst_in_addr ) != UCS_OK ) {
214+ & iface_index , & dst_in_addr ,
215+ rt_msg -> rtm_dst_len ) != UCS_OK ) {
210216 return UCS_INPROGRESS ;
211217 }
212218
@@ -228,12 +234,14 @@ ucs_netlink_parse_rt_entry_cb(const struct nlmsghdr *nlh, void *arg)
228234 ucs_error ("could not allocate route entry" );
229235 return UCS_ERR_NO_MEMORY );
230236
231- memset (& new_rule -> dest , 0 , sizeof (sizeof ( new_rule -> dest ) ));
237+ memset (& new_rule -> dest , 0 , sizeof (new_rule -> dest ));
232238 new_rule -> dest .ss_family = rt_msg -> rtm_family ;
233- if (UCS_OK != ucs_sockaddr_set_inet_addr ((struct sockaddr * )& new_rule -> dest ,
234- dst_in_addr )) {
235- ucs_array_pop_back (iface_rules );
236- return UCS_ERR_IO_ERROR ;
239+ if (dst_in_addr != NULL ) {
240+ if (ucs_sockaddr_set_inet_addr ((struct sockaddr * )& new_rule -> dest ,
241+ dst_in_addr ) != UCS_OK ) {
242+ ucs_array_pop_back (iface_rules );
243+ return UCS_ERR_IO_ERROR ;
244+ }
237245 }
238246
239247 new_rule -> subnet_prefix_len = rt_msg -> rtm_dst_len ;
@@ -256,6 +264,13 @@ static void ucs_netlink_lookup_route(ucs_netlink_route_info_t *info)
256264
257265 iface_rules = & kh_val (& ucs_netlink_routing_table_cache , iter );
258266 ucs_array_for_each (curr_entry , iface_rules ) {
267+
268+ if ((curr_entry -> subnet_prefix_len == 0 ) && !info -> allow_default_gw ) {
269+ ucs_trace ("iface_index=%d: skipping default gateway route" ,
270+ info -> if_index );
271+ continue ;
272+ }
273+
259274 if (ucs_sockaddr_is_same_subnet (
260275 info -> sa_remote ,
261276 (const struct sockaddr * )& curr_entry -> dest ,
@@ -266,7 +281,8 @@ static void ucs_netlink_lookup_route(ucs_netlink_route_info_t *info)
266281 }
267282}
268283
269- int ucs_netlink_route_exists (int if_index , const struct sockaddr * sa_remote )
284+ int ucs_netlink_route_exists (int if_index , const struct sockaddr * sa_remote ,
285+ int allow_default_gw )
270286{
271287 static ucs_init_once_t init_once = UCS_INIT_ONCE_INITIALIZER ;
272288 struct rtmsg rtm = {0 };
@@ -285,9 +301,11 @@ int ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote)
285301 NULL );
286302 }
287303
288- info .if_index = if_index ;
289- info .sa_remote = sa_remote ;
290- info .found = 0 ;
304+ info .if_index = if_index ;
305+ info .sa_remote = sa_remote ;
306+ info .found = 0 ;
307+ info .allow_default_gw = allow_default_gw ;
308+
291309 ucs_netlink_lookup_route (& info );
292310
293311 return info .found ;
0 commit comments