@@ -310,47 +310,57 @@ if_init(struct interface *ifp)
310310 return if_writepathuint (ifp -> ctx , path , 1 ) == -1 ? -1 : 0 ;
311311}
312312
313- /* @maxlen should be greater than or equal to 32; see ethtool_drvinfo. */
314- static int
315- if_get_driver (const char * ifname , char * driver , const size_t maxlen )
313+ /* Returns number of bytes written to driver, 0 on error.
314+ * @driverlen note that sizeof(ethtool_drvinfo.driver) = 32 */
315+ static size_t
316+ if_get_driver (const char * ifname , char * driver , const size_t driverlen )
316317{
317- struct ifreq ifr ;
318+ struct ifreq ifr = { . ifr_flags = 0 } ;
318319 struct ethtool_drvinfo drvinfo ;
319320 int fd ;
320- if (!ifname || !* ifname )
321- return -1 ;
321+ size_t n = 0 ;
322322
323323 fd = socket (AF_INET , SOCK_STREAM , 0 );
324324 if (fd == -1 ) {
325- logerr ("if_get_driver: failed socket creation: %s" , strerror ( errno ) );
326- return -1 ;
325+ logerr ("%s: socket ifname= %s" , __func__ , ifname );
326+ goto eexit ;
327327 }
328-
329328 memset (& ifr , 0 , sizeof (ifr ));
330329 strlcpy (ifr .ifr_name , ifname , sizeof (ifr .ifr_name ));
331330 drvinfo .cmd = ETHTOOL_GDRVINFO ;
332331 ifr .ifr_data = (void * )& drvinfo ;
333- if (ioctl (fd , SIOCETHTOOL , & ifr ) < 0 ) {
334- const int err = errno ;
335- logerr ("if_get_driver: failed ethtool ioctl on interface %s: %s" ,
336- ifname , strerror (errno ));
337- close (fd );
338- return -1 ;
332+ if (ioctl (fd , SIOCETHTOOL , & ifr ) == -1 ) {
333+ logerr ("%s: SIOCETHTOOL ifname=%s" , __func__ , ifname );
334+ goto eexit ;
339335 }
340- close (fd );
341- return strlcpy (driver , drvinfo .driver ,
342- MIN (sizeof (drvinfo .driver ), maxlen ));
336+ n = strlcpy (driver , drvinfo .driver , driverlen );
337+ eexit :
338+ if (fd != -1 )
339+ close (fd );
340+ return n ;
343341}
344342
345343static bool
346- if_ipvlan (const char * ifname )
344+ if_cmp_driver (const char * ifname , const char * driver )
347345{
348- char driver [32 ]; /* sizeof(ethtool_drvinfo.driver) = 32 */
349- if (if_get_driver (ifname , driver , sizeof (driver )) < 0 ) {
350- logerr ("if_ipvlan: failed to get driver name %s." , ifname );
346+ char ifdriver [32 ]; /* see ethtool_drvinfo.driver declaration */
347+ size_t n = if_get_driver (ifname , ifdriver , sizeof (ifdriver ));
348+
349+ if (n == 0 ) {
350+ logerr ("%s: if_get_driver ifname=%s" , __func__ , ifname );
351351 return false;
352352 }
353- return (strncmp (driver , "ipvlan" , sizeof (driver )) == 0 );
353+ if (strncmp (ifdriver , driver , n ) == 0 )
354+ return true;
355+ return false;
356+ }
357+
358+ static bool
359+ if_ipvlan (struct interface * ifp )
360+ {
361+ if (if_cmp_driver (ifp -> name , "ipvlan" ))
362+ return true;
363+ return false;
354364}
355365
356366int
@@ -359,10 +369,10 @@ if_conf(struct interface *ifp)
359369 char path [sizeof (SYS_LAYER2 ) + IF_NAMESIZE ];
360370 int n ;
361371
362- /* Set broadcast flag for ipvlan interfaces. */
363- if (if_ipvlan (ifp -> name )) {
372+ /* Set broadcast flag for ipvlan interfaces.
373+ * XXX: move this out to dhcpcd if needed on other platforms. */
374+ if (if_ipvlan (ifp ))
364375 ifp -> options -> options |= DHCPCD_BROADCAST ;
365- }
366376
367377 /* Some qeth setups require the use of the broadcast flag. */
368378 snprintf (path , sizeof (path ), SYS_LAYER2 , ifp -> name );
0 commit comments