2010-08-14 21:59:25 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-05-09 20:02:38 +04:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-05-09 20:02:38 +04:00
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-05-09 20:02:38 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-05-09 20:02:38 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <net/if.h>
# include <stdlib.h>
2015-02-03 15:48:15 +03:00
# include "sd-rtnl.h"
2013-10-30 02:50:07 +04:00
# include "rtnl-util.h"
2015-02-03 15:48:15 +03:00
# include "missing.h"
# include "loopback-setup.h"
2014-01-21 18:55:57 +04:00
2014-08-08 14:12:31 +04:00
static int start_loopback ( sd_rtnl * rtnl ) {
2014-02-13 06:44:14 +04:00
_cleanup_rtnl_message_unref_ sd_rtnl_message * req = NULL ;
2013-10-30 02:50:07 +04:00
int r ;
2010-05-09 20:02:38 +04:00
2014-08-08 14:12:31 +04:00
r = sd_rtnl_message_new_link ( rtnl , & req , RTM_SETLINK , LOOPBACK_IFINDEX ) ;
2013-12-06 21:16:16 +04:00
if ( r < 0 )
return r ;
2014-01-21 18:20:42 +04:00
r = sd_rtnl_message_link_set_flags ( req , IFF_UP , IFF_UP ) ;
2013-10-30 02:50:07 +04:00
if ( r < 0 )
return r ;
2010-05-09 20:02:38 +04:00
2014-08-08 14:12:31 +04:00
r = sd_rtnl_call ( rtnl , req , 0 , NULL ) ;
2013-10-30 02:50:07 +04:00
if ( r < 0 )
return r ;
2010-05-09 20:02:38 +04:00
return 0 ;
}
2014-12-28 15:38:23 +03:00
static bool check_loopback ( sd_rtnl * rtnl ) {
_cleanup_rtnl_message_unref_ sd_rtnl_message * req = NULL , * reply = NULL ;
unsigned flags ;
2013-03-25 03:45:16 +04:00
int r ;
2014-12-28 15:38:23 +03:00
r = sd_rtnl_message_new_link ( rtnl , & req , RTM_GETLINK , LOOPBACK_IFINDEX ) ;
if ( r < 0 )
2014-12-29 15:05:45 +03:00
return false ;
2014-12-28 15:38:23 +03:00
r = sd_rtnl_call ( rtnl , req , 0 , & reply ) ;
if ( r < 0 )
2014-12-29 15:05:45 +03:00
return false ;
2014-12-28 15:38:23 +03:00
r = sd_rtnl_message_link_get_flags ( reply , & flags ) ;
if ( r < 0 )
2014-12-29 15:05:45 +03:00
return false ;
2014-12-28 15:38:23 +03:00
return flags & IFF_UP ;
2012-04-13 19:10:21 +04:00
}
2010-05-09 20:02:38 +04:00
int loopback_setup ( void ) {
2014-02-13 06:44:14 +04:00
_cleanup_rtnl_unref_ sd_rtnl * rtnl = NULL ;
2014-08-08 14:12:31 +04:00
int r ;
2013-12-15 17:00:20 +04:00
2015-06-11 16:55:37 +03:00
r = sd_rtnl_open ( & rtnl ) ;
2012-04-13 19:10:21 +04:00
if ( r < 0 )
2013-10-30 02:50:07 +04:00
return r ;
2010-05-09 20:02:38 +04:00
2014-08-08 14:12:31 +04:00
r = start_loopback ( rtnl ) ;
2015-02-03 15:53:01 +03:00
if ( r < 0 ) {
/* If we lack the permissions to configure the
* loopback device , but we find it to be already
* configured , let ' s exit cleanly , in order to
* supported unprivileged containers . */
if ( r = = - EPERM & & check_loopback ( rtnl ) )
return 0 ;
2010-05-09 20:02:38 +04:00
2015-02-03 15:53:01 +03:00
return log_warning_errno ( r , " Failed to configure loopback device: %m " ) ;
}
2012-04-13 19:10:21 +04:00
2013-03-25 03:45:16 +04:00
return 0 ;
2010-05-09 20:02:38 +04:00
}