2014-10-29 09:12:18 -05:00
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Copyright ( C ) 2014 Red Hat , Inc .
*/
2014-11-13 10:07:02 -05:00
# include "config.h"
2014-10-29 09:12:18 -05:00
# include <glib-unix.h>
# include <getopt.h>
# include <locale.h>
# include <errno.h>
# include <stdlib.h>
# include <unistd.h>
# include <fcntl.h>
# include <string.h>
# include <sys/resource.h>
# include <sys/stat.h>
# include <signal.h>
2015-03-15 17:18:59 +01:00
/* Cannot include <net/if.h> due to conflict with <linux/if.h>.
* Forward declare if_nametoindex . */
extern unsigned int if_nametoindex ( const char * __ifname ) ;
2015-07-17 14:38:54 +02:00
# include "nm-default.h"
2014-10-29 09:12:18 -05:00
# include "NetworkManagerUtils.h"
# include "nm-linux-platform.h"
# include "nm-dhcp-manager.h"
# include "main-utils.h"
# include "nm-rdisc.h"
# include "nm-lndp-rdisc.h"
# include "nm-utils.h"
# if !defined(NM_DIST_VERSION)
# define NM_DIST_VERSION VERSION
# endif
# define NMIH_PID_FILE_FMT NMRUNDIR " / nm-iface-helper-%d.pid"
static GMainLoop * main_loop = NULL ;
static int ifindex = - 1 ;
2015-03-13 19:59:32 +01:00
static struct {
gboolean slaac ;
gboolean show_version ;
gboolean become_daemon ;
gboolean debug ;
gboolean g_fatal_warnings ;
gboolean slaac_required ;
gboolean dhcp4_required ;
int tempaddr ;
char * ifname ;
char * uuid ;
char * dhcp4_address ;
char * dhcp4_clientid ;
char * dhcp4_hostname ;
char * iid_str ;
2015-07-08 19:34:34 +02:00
char * logging_backend ;
2015-03-13 19:59:32 +01:00
char * opt_log_level ;
char * opt_log_domains ;
2015-03-13 20:09:46 +01:00
guint32 priority_v4 ;
guint32 priority_v6 ;
2015-03-13 19:59:32 +01:00
} global_opt = {
. tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN ,
2015-03-13 20:09:46 +01:00
. priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4 ,
. priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6 ,
2015-03-13 19:59:32 +01:00
} ;
2014-10-29 09:12:18 -05:00
static void
dhcp4_state_changed ( NMDhcpClient * client ,
NMDhcpState state ,
NMIP4Config * ip4_config ,
GHashTable * options ,
gpointer user_data )
{
static NMIP4Config * last_config = NULL ;
NMIP4Config * existing ;
g_return_if_fail ( ! ip4_config | | NM_IS_IP4_CONFIG ( ip4_config ) ) ;
2015-03-13 19:59:32 +01:00
nm_log_dbg ( LOGD_DHCP4 , " (%s): new DHCPv4 client state %d " , global_opt . ifname , state ) ;
2014-10-29 09:12:18 -05:00
switch ( state ) {
case NM_DHCP_STATE_BOUND :
g_assert ( ip4_config ) ;
existing = nm_ip4_config_capture ( ifindex , FALSE ) ;
if ( last_config )
nm_ip4_config_subtract ( existing , last_config ) ;
nm_ip4_config_merge ( existing , ip4_config ) ;
2015-07-13 19:20:08 +02:00
if ( ! nm_ip4_config_commit ( existing , ifindex , TRUE , global_opt . priority_v4 ) )
2015-03-13 19:59:32 +01:00
nm_log_warn ( LOGD_DHCP4 , " (%s): failed to apply DHCPv4 config " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
2015-04-24 22:38:21 -04:00
if ( last_config )
2014-10-29 09:12:18 -05:00
g_object_unref ( last_config ) ;
2015-04-24 22:38:21 -04:00
last_config = nm_ip4_config_new ( nm_dhcp_client_get_ifindex ( client ) ) ;
nm_ip4_config_replace ( last_config , ip4_config , NULL ) ;
2014-10-29 09:12:18 -05:00
break ;
case NM_DHCP_STATE_TIMEOUT :
case NM_DHCP_STATE_DONE :
case NM_DHCP_STATE_FAIL :
2015-03-13 19:59:32 +01:00
if ( global_opt . dhcp4_required ) {
nm_log_warn ( LOGD_DHCP4 , " (%s): DHCPv4 timed out or failed, quitting... " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
g_main_loop_quit ( main_loop ) ;
} else
2015-03-13 19:59:32 +01:00
nm_log_warn ( LOGD_DHCP4 , " (%s): DHCPv4 timed out or failed " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
break ;
default :
break ;
}
}
static void
rdisc_config_changed ( NMRDisc * rdisc , NMRDiscConfigMap changed , gpointer user_data )
{
static NMIP6Config * last_config = NULL ;
NMIP6Config * existing ;
NMIP6Config * ip6_config ;
static int system_support = - 1 ;
guint ifa_flags = 0x00 ;
int i ;
if ( system_support = = - 1 ) {
/*
* Check , if both libnl and the kernel are recent enough ,
* to help user space handling RA . If it ' s not supported ,
* we have no ipv6 - privacy and must add autoconf addresses
* as / 128. The reason for the / 128 is to prevent the kernel
* from adding a prefix route for this address .
* */
system_support = nm_platform_check_support_libnl_extended_ifa_flags ( ) & &
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
nm_platform_check_support_kernel_extended_ifa_flags ( NM_PLATFORM_GET ) ;
2014-10-29 09:12:18 -05:00
}
if ( system_support )
ifa_flags = IFA_F_NOPREFIXROUTE ;
2015-03-13 19:59:32 +01:00
if ( global_opt . tempaddr = = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
| | global_opt . tempaddr = = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR )
2014-10-29 09:12:18 -05:00
{
/* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
ifa_flags | = IFA_F_MANAGETEMPADDR ;
}
2015-02-27 16:49:42 +01:00
ip6_config = nm_ip6_config_new ( ifindex ) ;
2014-10-29 09:12:18 -05:00
if ( changed & NM_RDISC_CONFIG_GATEWAYS ) {
/* Use the first gateway as ordered in router discovery cache. */
if ( rdisc - > gateways - > len ) {
NMRDiscGateway * gateway = & g_array_index ( rdisc - > gateways , NMRDiscGateway , 0 ) ;
nm_ip6_config_set_gateway ( ip6_config , & gateway - > address ) ;
} else
nm_ip6_config_set_gateway ( ip6_config , NULL ) ;
}
if ( changed & NM_RDISC_CONFIG_ADDRESSES ) {
/* Rebuild address list from router discovery cache. */
nm_ip6_config_reset_addresses ( ip6_config ) ;
/* rdisc->addresses contains at most max_addresses entries.
* This is different from what the kernel does , which
* also counts static and temporary addresses when checking
* max_addresses .
* */
for ( i = 0 ; i < rdisc - > addresses - > len ; i + + ) {
NMRDiscAddress * discovered_address = & g_array_index ( rdisc - > addresses , NMRDiscAddress , i ) ;
NMPlatformIP6Address address ;
memset ( & address , 0 , sizeof ( address ) ) ;
address . address = discovered_address - > address ;
address . plen = system_support ? 64 : 128 ;
address . timestamp = discovered_address - > timestamp ;
address . lifetime = discovered_address - > lifetime ;
address . preferred = discovered_address - > preferred ;
if ( address . preferred > address . lifetime )
address . preferred = address . lifetime ;
address . source = NM_IP_CONFIG_SOURCE_RDISC ;
address . flags = ifa_flags ;
nm_ip6_config_add_address ( ip6_config , & address ) ;
}
}
if ( changed & NM_RDISC_CONFIG_ROUTES ) {
/* Rebuild route list from router discovery cache. */
nm_ip6_config_reset_routes ( ip6_config ) ;
for ( i = 0 ; i < rdisc - > routes - > len ; i + + ) {
NMRDiscRoute * discovered_route = & g_array_index ( rdisc - > routes , NMRDiscRoute , i ) ;
NMPlatformIP6Route route ;
/* Only accept non-default routes. The router has no idea what the
* local configuration or user preferences are , so sending routes
* with a prefix length of 0 is quite rude and thus ignored .
*/
if ( discovered_route - > plen > 0 ) {
memset ( & route , 0 , sizeof ( route ) ) ;
route . network = discovered_route - > network ;
route . plen = discovered_route - > plen ;
route . gateway = discovered_route - > gateway ;
route . source = NM_IP_CONFIG_SOURCE_RDISC ;
2015-03-13 20:09:46 +01:00
route . metric = global_opt . priority_v6 ;
2014-10-29 09:12:18 -05:00
nm_ip6_config_add_route ( ip6_config , & route ) ;
}
}
}
if ( changed & NM_RDISC_CONFIG_DHCP_LEVEL ) {
/* Unsupported until systemd DHCPv6 is ready */
}
2015-04-08 15:54:30 +02:00
if ( changed & NM_RDISC_CONFIG_HOP_LIMIT )
nm_platform_sysctl_set_ip6_hop_limit_safe ( NM_PLATFORM_GET , global_opt . ifname , rdisc - > hop_limit ) ;
2014-10-29 09:12:18 -05:00
if ( changed & NM_RDISC_CONFIG_MTU ) {
char val [ 16 ] ;
g_snprintf ( val , sizeof ( val ) , " %d " , rdisc - > mtu ) ;
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip6_property_path ( global_opt . ifname , " mtu " ) , val ) ;
2014-10-29 09:12:18 -05:00
}
2015-03-13 19:59:32 +01:00
existing = nm_ip6_config_capture ( ifindex , FALSE , global_opt . tempaddr ) ;
2014-10-29 09:12:18 -05:00
if ( last_config )
nm_ip6_config_subtract ( existing , last_config ) ;
nm_ip6_config_merge ( existing , ip6_config ) ;
2015-07-13 19:20:08 +02:00
if ( ! nm_ip6_config_commit ( existing , ifindex , TRUE ) )
2015-03-13 19:59:32 +01:00
nm_log_warn ( LOGD_IP6 , " (%s): failed to apply IPv6 config " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
2015-04-24 22:38:21 -04:00
if ( last_config )
2014-10-29 09:12:18 -05:00
g_object_unref ( last_config ) ;
2015-04-24 22:38:21 -04:00
last_config = nm_ip6_config_new ( ifindex ) ;
nm_ip6_config_replace ( last_config , ip6_config , NULL ) ;
2014-10-29 09:12:18 -05:00
}
static void
rdisc_ra_timeout ( NMRDisc * rdisc , gpointer user_data )
{
2015-03-13 19:59:32 +01:00
if ( global_opt . slaac_required ) {
nm_log_warn ( LOGD_IP6 , " (%s): IPv6 timed out or failed, quitting... " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
g_main_loop_quit ( main_loop ) ;
} else
2015-03-13 19:59:32 +01:00
nm_log_warn ( LOGD_IP6 , " (%s): IPv6 timed out or failed " , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
}
static gboolean
quit_handler ( gpointer user_data )
{
g_main_loop_quit ( main_loop ) ;
2015-01-12 11:36:26 -05:00
return G_SOURCE_REMOVE ;
2014-10-29 09:12:18 -05:00
}
static void
2015-01-12 11:36:26 -05:00
setup_signals ( void )
2014-10-29 09:12:18 -05:00
{
signal ( SIGPIPE , SIG_IGN ) ;
2015-01-12 11:36:26 -05:00
g_unix_signal_add ( SIGINT , quit_handler , NULL ) ;
g_unix_signal_add ( SIGTERM , quit_handler , NULL ) ;
2014-10-29 09:12:18 -05:00
}
2015-03-13 20:09:46 +01:00
static void
do_early_setup ( int * argc , char * * argv [ ] )
2014-10-29 09:12:18 -05:00
{
2015-03-13 20:09:46 +01:00
gint64 priority64_v4 = - 1 ;
gint64 priority64_v6 = - 1 ;
2014-10-29 09:12:18 -05:00
GOptionEntry options [ ] = {
/* Interface/IP config */
2015-03-13 19:59:32 +01:00
{ " ifname " , ' i ' , 0 , G_OPTION_ARG_STRING , & global_opt . ifname , N_ ( " The interface to manage " ) , N_ ( " eth0 " ) } ,
{ " uuid " , ' u ' , 0 , G_OPTION_ARG_STRING , & global_opt . uuid , N_ ( " Connection UUID " ) , N_ ( " 661e8cd0-b618-46b8-9dc9-31a52baaa16b " ) } ,
{ " slaac " , ' s ' , 0 , G_OPTION_ARG_NONE , & global_opt . slaac , N_ ( " Whether to manage IPv6 SLAAC " ) , NULL } ,
{ " slaac-required " , ' 6 ' , 0 , G_OPTION_ARG_NONE , & global_opt . slaac_required , N_ ( " Whether SLAAC must be successful " ) , NULL } ,
{ " slaac-tempaddr " , ' t ' , 0 , G_OPTION_ARG_INT , & global_opt . tempaddr , N_ ( " Use an IPv6 temporary privacy address " ) , NULL } ,
{ " dhcp4 " , ' d ' , 0 , G_OPTION_ARG_STRING , & global_opt . dhcp4_address , N_ ( " Current DHCPv4 address " ) , NULL } ,
{ " dhcp4-required " , ' 4 ' , 0 , G_OPTION_ARG_NONE , & global_opt . dhcp4_required , N_ ( " Whether DHCPv4 must be successful " ) , NULL } ,
{ " dhcp4-clientid " , ' c ' , 0 , G_OPTION_ARG_STRING , & global_opt . dhcp4_clientid , N_ ( " Hex-encoded DHCPv4 client ID " ) , NULL } ,
{ " dhcp4-hostname " , ' h ' , 0 , G_OPTION_ARG_STRING , & global_opt . dhcp4_hostname , N_ ( " Hostname to send to DHCP server " ) , N_ ( " barbar " ) } ,
2015-03-13 20:09:46 +01:00
{ " priority4 " , ' \0 ' , 0 , G_OPTION_ARG_INT64 , & priority64_v4 , N_ ( " Route priority for IPv4 " ) , N_ ( " 0 " ) } ,
{ " priority6 " , ' \0 ' , 0 , G_OPTION_ARG_INT64 , & priority64_v6 , N_ ( " Route priority for IPv6 " ) , N_ ( " 1024 " ) } ,
2015-05-04 19:10:29 +03:00
{ " iid " , ' e ' , 0 , G_OPTION_ARG_STRING , & global_opt . iid_str , N_ ( " Hex-encoded Interface Identifier " ) , " " } ,
2015-07-08 19:34:34 +02:00
{ " logging-backend " , ' \0 ' , 0 , G_OPTION_ARG_STRING , & global_opt . logging_backend , N_ ( " The logging backend configuration value. See logging.backend in NetworkManager.conf " ) , NULL } ,
2014-10-29 09:12:18 -05:00
/* Logging/debugging */
2015-03-13 19:59:32 +01:00
{ " version " , ' V ' , 0 , G_OPTION_ARG_NONE , & global_opt . show_version , N_ ( " Print NetworkManager version and exit " ) , NULL } ,
{ " no-daemon " , ' n ' , G_OPTION_FLAG_REVERSE , G_OPTION_ARG_NONE , & global_opt . become_daemon , N_ ( " Don't become a daemon " ) , NULL } ,
{ " debug " , ' b ' , 0 , G_OPTION_ARG_NONE , & global_opt . debug , N_ ( " Don't become a daemon, and log to stderr " ) , NULL } ,
{ " log-level " , 0 , 0 , G_OPTION_ARG_STRING , & global_opt . opt_log_level , N_ ( " Log level: one of [%s] " ) , " INFO " } ,
{ " log-domains " , 0 , 0 , G_OPTION_ARG_STRING , & global_opt . opt_log_domains ,
2014-10-29 09:12:18 -05:00
N_ ( " Log domains separated by ',': any combination of [%s] " ) ,
" PLATFORM,RFKILL,WIFI " } ,
2015-03-13 19:59:32 +01:00
{ " g-fatal-warnings " , 0 , 0 , G_OPTION_ARG_NONE , & global_opt . g_fatal_warnings , N_ ( " Make all warnings fatal " ) , NULL } ,
2014-10-29 09:12:18 -05:00
{ NULL }
} ;
if ( ! nm_main_utils_early_setup ( " nm-iface-helper " ,
2015-03-13 20:09:46 +01:00
argc ,
argv ,
2014-10-29 09:12:18 -05:00
options ,
NULL ,
2014-07-09 15:17:01 +02:00
NULL ,
2014-10-29 09:12:18 -05:00
_ ( " nm-iface-helper is a small, standalone process that manages a single network interface. " ) ) )
exit ( 1 ) ;
2015-03-13 20:09:46 +01:00
if ( priority64_v4 > = 0 & & priority64_v4 < = G_MAXUINT32 )
global_opt . priority_v4 = ( guint32 ) priority64_v4 ;
if ( priority64_v6 > = 0 & & priority64_v6 < = G_MAXUINT32 )
global_opt . priority_v6 = ( guint32 ) priority64_v6 ;
}
int
main ( int argc , char * argv [ ] )
{
char * bad_domains = NULL ;
GError * error = NULL ;
gboolean wrote_pidfile = FALSE ;
gs_free char * pidfile = NULL ;
gs_unref_object NMDhcpClient * dhcp4_client = NULL ;
gs_unref_object NMRDisc * rdisc = NULL ;
GByteArray * hwaddr = NULL ;
size_t hwaddr_len = 0 ;
gconstpointer tmp ;
gs_free NMUtilsIPv6IfaceId * iid = NULL ;
2014-07-10 10:41:31 +02:00
nm_g_type_init ( ) ;
2015-03-13 20:09:46 +01:00
setpgid ( getpid ( ) , getpid ( ) ) ;
do_early_setup ( & argc , & argv ) ;
2015-03-13 23:24:05 +01:00
if ( global_opt . g_fatal_warnings ) {
GLogLevelFlags fatal_mask ;
fatal_mask = g_log_set_always_fatal ( G_LOG_FATAL_MASK ) ;
fatal_mask | = G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL ;
g_log_set_always_fatal ( fatal_mask ) ;
}
2015-03-13 19:59:32 +01:00
if ( global_opt . show_version ) {
2014-10-29 09:12:18 -05:00
fprintf ( stdout , NM_DIST_VERSION " \n " ) ;
exit ( 0 ) ;
}
2015-03-13 20:57:18 +01:00
nm_main_utils_ensure_root ( ) ;
2015-03-13 19:59:32 +01:00
if ( ! global_opt . ifname | | ! global_opt . uuid ) {
2014-10-29 09:12:18 -05:00
fprintf ( stderr , _ ( " An interface name and UUID are required \n " ) ) ;
exit ( 1 ) ;
}
2015-03-14 17:58:23 +01:00
ifindex = if_nametoindex ( global_opt . ifname ) ;
if ( ifindex < = 0 ) {
fprintf ( stderr , _ ( " Failed to find interface index for %s (%s) \n " ) , global_opt . ifname , strerror ( errno ) ) ;
exit ( 1 ) ;
}
pidfile = g_strdup_printf ( NMIH_PID_FILE_FMT , ifindex ) ;
nm_main_utils_ensure_not_running_pidfile ( pidfile ) ;
2015-03-15 15:59:02 +01:00
nm_main_utils_ensure_rundir ( ) ;
2015-03-13 19:59:32 +01:00
if ( ! nm_logging_setup ( global_opt . opt_log_level ,
global_opt . opt_log_domains ,
2014-10-29 09:12:18 -05:00
& bad_domains ,
& error ) ) {
fprintf ( stderr ,
_ ( " %s. Please use --help to see a list of valid options. \n " ) ,
error - > message ) ;
exit ( 1 ) ;
} else if ( bad_domains ) {
fprintf ( stderr ,
_ ( " Ignoring unrecognized log domain(s) '%s' passed on command line. \n " ) ,
bad_domains ) ;
g_clear_pointer ( & bad_domains , g_free ) ;
}
2015-03-13 19:59:32 +01:00
if ( global_opt . become_daemon & & ! global_opt . debug ) {
2014-10-29 09:12:18 -05:00
if ( daemon ( 0 , 0 ) < 0 ) {
int saved_errno ;
saved_errno = errno ;
fprintf ( stderr , _ ( " Could not daemonize: %s [error %u] \n " ) ,
g_strerror ( saved_errno ) ,
saved_errno ) ;
exit ( 1 ) ;
}
if ( nm_main_utils_write_pidfile ( pidfile ) )
wrote_pidfile = TRUE ;
}
/* Set up unix signal handling - before creating threads, but after daemonizing! */
main_loop = g_main_loop_new ( NULL , FALSE ) ;
2015-01-12 11:36:26 -05:00
setup_signals ( ) ;
2014-10-29 09:12:18 -05:00
2015-07-08 19:34:34 +02:00
nm_logging_syslog_openlog ( global_opt . logging_backend
? global_opt . logging_backend
: ( global_opt . debug ? " debug " : NULL ) ) ;
2014-10-29 09:12:18 -05:00
nm_log_info ( LOGD_CORE , " nm-iface-helper (version " NM_DIST_VERSION " ) is starting... " ) ;
/* Set up platform interaction layer */
nm_linux_platform_setup ( ) ;
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
tmp = nm_platform_link_get_address ( NM_PLATFORM_GET , ifindex , & hwaddr_len ) ;
2014-10-29 09:12:18 -05:00
if ( tmp ) {
hwaddr = g_byte_array_sized_new ( hwaddr_len ) ;
g_byte_array_append ( hwaddr , tmp , hwaddr_len ) ;
}
2015-03-13 19:59:32 +01:00
if ( global_opt . iid_str ) {
2014-10-29 09:12:18 -05:00
GBytes * bytes ;
gsize ignored = 0 ;
2015-03-13 19:59:32 +01:00
bytes = nm_utils_hexstr2bin ( global_opt . iid_str ) ;
2014-10-29 09:12:18 -05:00
if ( ! bytes | | g_bytes_get_size ( bytes ) ! = sizeof ( * iid ) ) {
2015-03-13 19:59:32 +01:00
fprintf ( stderr , _ ( " (%s): Invalid IID %s \n " ) , global_opt . ifname , global_opt . iid_str ) ;
2014-10-29 09:12:18 -05:00
exit ( 1 ) ;
}
iid = g_bytes_unref_to_data ( bytes , & ignored ) ;
}
2015-03-13 19:59:32 +01:00
if ( global_opt . dhcp4_address ) {
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip4_property_path ( global_opt . ifname , " promote_secondaries " ) , " 1 " ) ;
2014-10-29 09:12:18 -05:00
2015-01-05 19:30:00 +01:00
dhcp4_client = nm_dhcp_manager_start_ip4 ( nm_dhcp_manager_get ( ) ,
2015-03-13 19:59:32 +01:00
global_opt . ifname ,
2014-10-29 09:12:18 -05:00
ifindex ,
hwaddr ,
2015-03-13 19:59:32 +01:00
global_opt . uuid ,
2015-03-13 20:09:46 +01:00
global_opt . priority_v4 ,
2015-03-13 19:59:32 +01:00
! ! global_opt . dhcp4_hostname ,
global_opt . dhcp4_hostname ,
global_opt . dhcp4_clientid ,
2014-10-29 09:12:18 -05:00
45 ,
NULL ,
2015-03-13 19:59:32 +01:00
global_opt . dhcp4_address ) ;
2014-10-29 09:12:18 -05:00
g_assert ( dhcp4_client ) ;
g_signal_connect ( dhcp4_client ,
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED ,
G_CALLBACK ( dhcp4_state_changed ) ,
NULL ) ;
}
2015-03-13 19:59:32 +01:00
if ( global_opt . slaac ) {
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
nm_platform_link_set_user_ipv6ll_enabled ( NM_PLATFORM_GET , ifindex , TRUE ) ;
2014-10-29 09:12:18 -05:00
2015-03-13 19:59:32 +01:00
rdisc = nm_lndp_rdisc_new ( ifindex , global_opt . ifname ) ;
2014-10-29 09:12:18 -05:00
g_assert ( rdisc ) ;
if ( iid )
nm_rdisc_set_iid ( rdisc , * iid ) ;
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip6_property_path ( global_opt . ifname , " accept_ra " ) , " 1 " ) ;
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip6_property_path ( global_opt . ifname , " accept_ra_defrtr " ) , " 0 " ) ;
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip6_property_path ( global_opt . ifname , " accept_ra_pinfo " ) , " 0 " ) ;
nm_platform_sysctl_set ( NM_PLATFORM_GET , nm_utils_ip6_property_path ( global_opt . ifname , " accept_ra_rtr_pref " ) , " 0 " ) ;
2014-10-29 09:12:18 -05:00
g_signal_connect ( rdisc ,
NM_RDISC_CONFIG_CHANGED ,
G_CALLBACK ( rdisc_config_changed ) ,
NULL ) ;
g_signal_connect ( rdisc ,
NM_RDISC_RA_TIMEOUT ,
G_CALLBACK ( rdisc_ra_timeout ) ,
NULL ) ;
nm_rdisc_start ( rdisc ) ;
}
2015-01-12 11:36:26 -05:00
g_main_loop_run ( main_loop ) ;
2014-10-29 09:12:18 -05:00
g_clear_pointer ( & hwaddr , g_byte_array_unref ) ;
if ( pidfile & & wrote_pidfile )
unlink ( pidfile ) ;
nm_log_info ( LOGD_CORE , " exiting " ) ;
exit ( 0 ) ;
}
/*******************************************************/
/* Stub functions */
2014-07-09 18:36:20 +02:00
void
2015-06-25 21:10:32 +02:00
nm_main_config_reload ( int signal )
2014-07-09 18:36:20 +02:00
{
nm_log_info ( LOGD_CORE , " reloading configuration not supported " ) ;
}
2014-10-29 09:12:18 -05:00
gconstpointer nm_config_get ( void ) ;
const char * nm_config_get_dhcp_client ( gpointer unused ) ;
gboolean nm_config_get_configure_and_quit ( gpointer unused ) ;
2015-04-16 14:20:51 -04:00
gconstpointer nm_bus_manager_get ( void ) ;
void nm_bus_manager_register_object ( gpointer unused , const char * path , gpointer object ) ;
void nm_bus_manager_unregister_object ( gpointer unused , gpointer object ) ;
2014-10-29 09:12:18 -05:00
gconstpointer
nm_config_get ( void )
{
return GUINT_TO_POINTER ( 1 ) ;
}
const char *
nm_config_get_dhcp_client ( gpointer unused )
{
return " internal " ;
}
gboolean
nm_config_get_configure_and_quit ( gpointer unused )
{
return TRUE ;
}
gconstpointer
2015-04-16 14:20:51 -04:00
nm_bus_manager_get ( void )
2014-10-29 09:12:18 -05:00
{
return GUINT_TO_POINTER ( 1 ) ;
}
void
2015-04-16 14:20:51 -04:00
nm_bus_manager_register_object ( gpointer unused , const char * path , gpointer object )
2014-10-29 09:12:18 -05:00
{
}
void
2015-04-16 14:20:51 -04:00
nm_bus_manager_unregister_object ( gpointer unused , gpointer object )
2015-04-03 10:08:52 -04:00
{
}