@@ -781,10 +781,12 @@ netdev_set_advertisements(struct netdev *netdev, uint32_t advertise)
781781 return do_ethtool (netdev , & ecmd , ETHTOOL_SSET , "ETHTOOL_SSET" );
782782}
783783
784- /* If 'netdev' has an assigned IPv4 address, sets '*in4' to that address (if
785- * 'in4' is non-null) and returns true. Otherwise, returns false. */
784+ /* If 'netdev' has an assigned IPv4 address, sets '*in4' to that address
785+ * and '*mask' to the netmask (if they are non-null) and returns true.
786+ * Otherwise, returns false. */
786787bool
787- netdev_nodev_get_in4 (const char * netdev_name , struct in_addr * in4 )
788+ netdev_nodev_get_in4 (const char * netdev_name , struct in_addr * in4 ,
789+ struct in_addr * mask )
788790{
789791 struct ifreq ifr ;
790792 struct in_addr ip = { INADDR_ANY };
@@ -804,13 +806,25 @@ netdev_nodev_get_in4(const char *netdev_name, struct in_addr *in4)
804806 if (in4 ) {
805807 * in4 = ip ;
806808 }
809+
810+ if (mask ) {
811+ if (ioctl (af_inet_sock , SIOCGIFNETMASK , & ifr ) == 0 ) {
812+ struct sockaddr_in * sin = (struct sockaddr_in * ) & ifr .ifr_addr ;
813+ * mask = sin -> sin_addr ;
814+ } else {
815+ VLOG_DBG_RL (& rl , "%s: ioctl(SIOCGIFNETMASK) failed: %s" ,
816+ netdev_name , strerror (errno ));
817+ }
818+ }
819+
807820 return ip .s_addr != INADDR_ANY ;
808821}
809822
810823bool
811- netdev_get_in4 (const struct netdev * netdev , struct in_addr * in4 )
824+ netdev_get_in4 (const struct netdev * netdev , struct in_addr * in4 , struct
825+ in_addr * mask )
812826{
813- return netdev_nodev_get_in4 (netdev -> name , in4 );
827+ return netdev_nodev_get_in4 (netdev -> name , in4 , mask );
814828}
815829
816830static void
@@ -1309,7 +1323,7 @@ netdev_find_dev_by_in4(const struct in_addr *in4, char **netdev_name)
13091323 struct svec dev_list ;
13101324
13111325 /* Check the hint first. */
1312- if (* netdev_name && (netdev_nodev_get_in4 (* netdev_name , & dev_in4 ))
1326+ if (* netdev_name && (netdev_nodev_get_in4 (* netdev_name , & dev_in4 , NULL ))
13131327 && (dev_in4 .s_addr == in4 -> s_addr )) {
13141328 return true;
13151329 }
@@ -1319,7 +1333,7 @@ netdev_find_dev_by_in4(const struct in_addr *in4, char **netdev_name)
13191333 netdev_enumerate (& dev_list );
13201334
13211335 for (i = 0 ; i < dev_list .n ; i ++ ) {
1322- if ((netdev_nodev_get_in4 (dev_list .names [i ], & dev_in4 ))
1336+ if ((netdev_nodev_get_in4 (dev_list .names [i ], & dev_in4 , NULL ))
13231337 && (dev_in4 .s_addr == in4 -> s_addr )) {
13241338 * netdev_name = xstrdup (dev_list .names [i ]);
13251339 svec_destroy (& dev_list );
0 commit comments