static gboolean component_added (NMDevice *device, GObject *component) { NMDeviceVlan *self = NM_DEVICE_VLAN (device); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); NMDevice *added_device; int parent_ifindex = -1; if (priv->parent) return FALSE; if (!NM_IS_DEVICE (component)) return FALSE; added_device = NM_DEVICE (component); if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, nm_device_get_ifindex (device), &parent_ifindex, NULL)) { _LOGW (LOGD_VLAN, "failed to get VLAN interface info while checking added component."); return FALSE; } if ( parent_ifindex <= 0 || nm_device_get_ifindex (added_device) != parent_ifindex) return FALSE; nm_device_vlan_set_parent (self, added_device); /* Don't claim parent exclusively */ return FALSE; }
static void reload_tun_properties (NMDeviceTun *self) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); GObject *object = G_OBJECT (self); NMPlatformTunProperties props; if (!nm_platform_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), &props)) { _LOGD (LOGD_HW, "could not read tun properties"); return; } g_object_freeze_notify (object); if (priv->props.owner != props.owner) g_object_notify (object, NM_DEVICE_TUN_OWNER); if (priv->props.group != props.group) g_object_notify (object, NM_DEVICE_TUN_GROUP); if (priv->props.no_pi != props.no_pi) g_object_notify (object, NM_DEVICE_TUN_NO_PI); if (priv->props.vnet_hdr != props.vnet_hdr) g_object_notify (object, NM_DEVICE_TUN_VNET_HDR); if (priv->props.multi_queue != props.multi_queue) g_object_notify (object, NM_DEVICE_TUN_MULTI_QUEUE); memcpy (&priv->props, &props, sizeof (NMPlatformTunProperties)); g_object_thaw_notify (object); }
static void update_properties (NMDevice *device) { NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); const NMPlatformLnkMacvlan *props; const NMPlatformLink *plink; props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink); if (!props) { _LOGW (LOGD_HW, "could not get macvlan properties"); return; } g_object_freeze_notify (object); if (priv->parent_ifindex != plink->parent) g_object_notify (object, NM_DEVICE_MACVLAN_PARENT); if (g_strcmp0 (priv->props.mode, props->mode) != 0) g_object_notify (object, NM_DEVICE_MACVLAN_MODE); if (priv->props.no_promisc != props->no_promisc) g_object_notify (object, NM_DEVICE_MACVLAN_NO_PROMISC); priv->parent_ifindex = plink->parent; priv->props = *props; g_object_thaw_notify (object); }
static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingBond *s_bond = nm_connection_get_setting_bond (connection); int ifindex = nm_device_get_ifindex (device); const char **options; if (!s_bond) { s_bond = (NMSettingBond *) nm_setting_bond_new (); nm_connection_add_setting (connection, (NMSetting *) s_bond); } /* Read bond options from sysfs and update the Bond setting to match */ options = nm_setting_bond_get_valid_options (s_bond); while (options && *options) { gs_free char *value = nm_platform_sysctl_master_get_option (nm_device_get_platform(device), ifindex, *options); const char *defvalue = nm_setting_bond_get_option_default (s_bond, *options); if (value && !ignore_if_zero (*options, value) && (g_strcmp0 (value, defvalue) != 0)) { /* Replace " " with "," for arp_ip_targets from the kernel */ if (strcmp (*options, "arp_ip_target") == 0) { char *p = value; while (p && *p) { if (*p == ' ') *p = ','; p++; } } nm_setting_bond_add_option (s_bond, *options, value); } options++; } }
static void update_connection (NMDevice *device, NMConnection *connection) { NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); int ifindex = nm_device_get_ifindex (device); const Option *option; if (!s_bridge) { s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); nm_connection_add_setting (connection, (NMSetting *) s_bridge); } for (option = master_options; option->name; option++) { gs_free char *str = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, option->sysname); int value; if (str) { value = strtol (str, NULL, 10); /* See comments in set_sysfs_uint() about centiseconds. */ if (option->user_hz_compensate) value /= 100; g_object_set (s_bridge, option->name, value, NULL); } else _LOGW (LOGD_BRIDGE, "failed to read bridge setting '%s'", option->sysname); } }
static void carrier_off (NMNetlinkMonitor *monitor, int idx, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); NMDeviceWired *self = NM_DEVICE_WIRED (device); guint32 caps; /* Make sure signal is for us */ if (idx == nm_device_get_ifindex (device)) { NMDeviceState state; gboolean defer = FALSE; caps = nm_device_get_capabilities (device); g_return_if_fail (caps & NM_DEVICE_CAP_CARRIER_DETECT); /* Defer carrier-off event actions while connected by a few seconds * so that tripping over a cable, power-cycling a switch, or breaking * off the RJ45 locking tab isn't so catastrophic. */ state = nm_device_get_state (device); if (state > NM_DEVICE_STATE_DISCONNECTED) defer = TRUE; set_carrier (self, FALSE, defer); } }
static void update_properties (NMDevice *device) { NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformMacvlanProperties props; if (!nm_platform_macvlan_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) { _LOGW (LOGD_HW, "could not read macvlan properties"); return; } g_object_freeze_notify (object); if (priv->props.parent_ifindex != props.parent_ifindex) g_object_notify (object, NM_DEVICE_MACVLAN_PARENT); if (g_strcmp0 (priv->props.mode, props.mode) != 0) g_object_notify (object, NM_DEVICE_MACVLAN_MODE); if (priv->props.no_promisc != props.no_promisc) g_object_notify (object, NM_DEVICE_MACVLAN_NO_PROMISC); memcpy (&priv->props, &props, sizeof (NMPlatformMacvlanProperties)); g_object_thaw_notify (object); }
static GObject* constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { GObject *object; GObjectClass *klass; NMDeviceOlpcMesh *self; NMDeviceWifiCapabilities caps; klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class); object = klass->constructor (type, n_construct_params, construct_params); if (!object) return NULL; self = NM_DEVICE_OLPC_MESH (object); if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &caps)) { _LOGW (LOGD_HW | LOGD_OLPC, "failed to initialize WiFi driver"); g_object_unref (object); return NULL; } g_signal_connect (nm_manager_get (), "device-added", G_CALLBACK (device_added_cb), self); g_signal_connect (nm_manager_get (), "device-removed", G_CALLBACK (device_removed_cb), self); /* shorter timeout for mesh connectivity */ nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); return object; }
static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); NMConnection *connection; NMSettingOlpcMesh *s_mesh; guint32 channel; GBytes *ssid; const char *anycast_addr; connection = nm_device_get_connection (device); g_assert (connection); s_mesh = nm_connection_get_setting_olpc_mesh (connection); g_assert (s_mesh); channel = nm_setting_olpc_mesh_get_channel (s_mesh); if (channel != 0) _mesh_set_channel (self, channel); ssid = nm_setting_olpc_mesh_get_ssid (s_mesh); nm_platform_mesh_set_ssid (nm_device_get_ifindex (device), g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); nm_device_set_dhcp_anycast_address (device, anycast_addr); return NM_ACT_STAGE_RETURN_SUCCESS; }
static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); const char *ifname = nm_device_get_iface (device); int ifindex = nm_device_get_ifindex (device); const Option *option; if (!s_bridge) { s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); nm_connection_add_setting (connection, (NMSetting *) s_bridge); g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, ifname, NULL); } for (option = master_options; option->name; option++) { gs_free char *str = nm_platform_master_get_option (ifindex, option->sysname); int value = strtol (str, NULL, 10); /* See comments in set_sysfs_uint() about centiseconds. */ if (option->user_hz_compensate) value /= 100; g_object_set (s_bridge, option->name, value, NULL); } }
gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) { NMSettingTeamPort *s_port; const char *iface = nm_device_get_iface (slave); char *port_config = NULL; gboolean with_teamdctl = FALSE; int err = 0; #if WITH_TEAMDCTL const char *master_iface; int master_ifindex; struct teamdctl *tdc; const char *team_port_config = NULL; #endif g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); #if WITH_TEAMDCTL master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave)); g_assert (master_ifindex > 0); master_iface = nm_platform_link_get_name (master_ifindex); g_assert (master_iface); tdc = teamdctl_alloc (); g_assert (tdc); err = teamdctl_connect (tdc, master_iface, NULL, NULL); if (err) { nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)", iface, master_iface, err); teamdctl_free (tdc); return FALSE; } err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config); port_config = g_strdup (team_port_config); teamdctl_free (tdc); with_teamdctl = TRUE; #endif s_port = nm_connection_get_setting_team_port (connection); if (!s_port) { s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); nm_connection_add_setting (connection, NM_SETTING (s_port)); } g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free (port_config); if (!with_teamdctl || err != 0) { if (!with_teamdctl) nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration " " (compiled without libteamdctl support)", iface); else nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)", iface, err); return FALSE; } return TRUE; }
static NMDeviceCapabilities get_generic_capabilities (NMDevice *dev) { if (nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, nm_device_get_ifindex (dev))) return NM_DEVICE_CAP_CARRIER_DETECT; else return NM_DEVICE_CAP_NONE; }
static void constructed (GObject *object) { G_OBJECT_CLASS (nm_device_bridge_parent_class)->constructed (object); nm_log_dbg (LOGD_HW | LOGD_BRIDGE, "(%s): kernel ifindex %d", nm_device_get_iface (NM_DEVICE (object)), nm_device_get_ifindex (NM_DEVICE (object))); }
static void update_properties (NMDevice *device) { NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformVxlanProperties props; if (!nm_platform_vxlan_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) { _LOGW (LOGD_HW, "could not read vxlan properties"); return; } g_object_freeze_notify (object); if (priv->props.parent_ifindex != props.parent_ifindex) g_object_notify (object, NM_DEVICE_VXLAN_PARENT); if (priv->props.id != props.id) g_object_notify (object, NM_DEVICE_VXLAN_ID); if (priv->props.group != props.group) g_object_notify (object, NM_DEVICE_VXLAN_GROUP); if (priv->props.local != props.local) g_object_notify (object, NM_DEVICE_VXLAN_LOCAL); if (memcmp (&priv->props.group6, &props.group6, sizeof (props.group6)) != 0) g_object_notify (object, NM_DEVICE_VXLAN_GROUP); if (memcmp (&priv->props.local6, &props.local6, sizeof (props.local6)) != 0) g_object_notify (object, NM_DEVICE_VXLAN_LOCAL); if (priv->props.tos != props.tos) g_object_notify (object, NM_DEVICE_VXLAN_TOS); if (priv->props.ttl != props.ttl) g_object_notify (object, NM_DEVICE_VXLAN_TTL); if (priv->props.learning != props.learning) g_object_notify (object, NM_DEVICE_VXLAN_LEARNING); if (priv->props.ageing != props.ageing) g_object_notify (object, NM_DEVICE_VXLAN_AGEING); if (priv->props.limit != props.limit) g_object_notify (object, NM_DEVICE_VXLAN_LIMIT); if (priv->props.dst_port != props.dst_port) g_object_notify (object, NM_DEVICE_VXLAN_DST_PORT); if (priv->props.src_port_min != props.src_port_min) g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MIN); if (priv->props.src_port_max != props.src_port_max) g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MAX); if (priv->props.proxy != props.proxy) g_object_notify (object, NM_DEVICE_VXLAN_PROXY); if (priv->props.rsc != props.rsc) g_object_notify (object, NM_DEVICE_VXLAN_RSC); if (priv->props.l2miss != props.l2miss) g_object_notify (object, NM_DEVICE_VXLAN_L2MISS); if (priv->props.l3miss != props.l3miss) g_object_notify (object, NM_DEVICE_VXLAN_L3MISS); memcpy (&priv->props, &props, sizeof (NMPlatformVxlanProperties)); g_object_thaw_notify (object); }
static void _mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) { int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); if (nm_platform_mesh_get_channel (ifindex) != channel) { if (nm_platform_mesh_set_channel (ifindex, channel)) g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL); } }
static gboolean set_bond_attr (NMDevice *device, const char *attr, const char *value) { NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean ret; int ifindex = nm_device_get_ifindex (device); ret = nm_platform_sysctl_master_set_option (nm_device_get_platform(device), ifindex, attr, value); if (!ret) _LOGW (LOGD_HW, "failed to set bonding attribute '%s' to '%s'", attr, value); return ret; }
static void notify_new_device_added (NMDevice *device, NMDevice *new_device) { NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self); if (priv->parent) return; if (!nm_device_is_real (device)) return; update_properties (device); if ( priv->parent_ifindex <= 0 || nm_device_get_ifindex (new_device) != priv->parent_ifindex) return; priv->parent_ifindex = nm_device_get_ifindex (new_device); nm_device_macvlan_set_parent (self, new_device); }
static void update_connection (NMDevice *device, NMConnection *connection) { NMDeviceVlan *self = NM_DEVICE_VLAN (device); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); int ifindex = nm_device_get_ifindex (device); int parent_ifindex = -1, vlan_id = -1; NMDevice *parent; const char *setting_parent, *new_parent; if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); nm_connection_add_setting (connection, (NMSetting *) s_vlan); } if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, ifindex, &parent_ifindex, &vlan_id)) { _LOGW (LOGD_VLAN, "failed to get VLAN interface info while updating connection."); return; } if (priv->vlan_id != vlan_id) { priv->vlan_id = vlan_id; g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID); } if (vlan_id != nm_setting_vlan_get_id (s_vlan)) g_object_set (s_vlan, NM_SETTING_VLAN_ID, priv->vlan_id, NULL); if (parent_ifindex != NM_PLATFORM_LINK_OTHER_NETNS) parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex); else parent = NULL; nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent); /* Update parent in the connection; default to parent's interface name */ if (parent) { new_parent = nm_device_get_iface (parent); setting_parent = nm_setting_vlan_get_parent (s_vlan); if (setting_parent && nm_utils_is_uuid (setting_parent)) { NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent); if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection)) new_parent = NULL; } if (new_parent) g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, new_parent, NULL); } else g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, NULL, NULL); }
static gboolean create_and_realize (NMDevice *device, NMConnection *connection, NMDevice *parent, NMPlatformLink *out_plink, GError **error) { NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); const char *iface = nm_device_get_iface (device); NMSettingVlan *s_vlan; int parent_ifindex, vlan_id; NMPlatformError plerr; g_assert (out_plink); s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); if (!nm_device_supports_vlans (parent)) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "no support for VLANs on interface %s of type %s", nm_device_get_iface (parent), nm_device_get_type_desc (parent)); return FALSE; } parent_ifindex = nm_device_get_ifindex (parent); g_warn_if_fail (parent_ifindex > 0); vlan_id = nm_setting_vlan_get_id (s_vlan); plerr = nm_platform_vlan_add (NM_PLATFORM_GET, iface, parent_ifindex, vlan_id, nm_setting_vlan_get_flags (s_vlan), out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create VLAN interface '%s' for '%s': %s", iface, nm_connection_get_id (connection), nm_platform_error_to_string (plerr)); return FALSE; } g_warn_if_fail (priv->parent == NULL); nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent); priv->vlan_id = vlan_id; return TRUE; }
static gboolean set_bond_attr (NMDevice *device, const char *attr, const char *value) { gboolean ret; int ifindex = nm_device_get_ifindex (device); ret = nm_platform_master_set_option (ifindex, attr, value); if (!ret) { nm_log_warn (LOGD_HW, "(%s): failed to set bonding attribute " "'%s' to '%s'", nm_device_get_ip_iface (device), attr, value); } return ret; }
static NMActStageReturn act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { NMActRequest *req; NMConnection *connection; NMSettingVlan *s_vlan; NMSettingWired *s_wired; const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->act_stage1_prepare (dev, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; req = nm_device_get_act_request (dev); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); connection = nm_act_request_get_connection (req); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); s_wired = nm_connection_get_setting_wired (connection); if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); if (cloned_mac) nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN); } s_vlan = nm_connection_get_setting_vlan (connection); if (s_vlan) { int ifindex = nm_device_get_ifindex (dev); int num, i; guint32 from, to; num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP); for (i = 0; i < num; i++) { if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, i, &from, &to)) nm_platform_vlan_set_ingress_map (ifindex, from, to); } num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP); for (i = 0; i < num; i++) { if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, i, &from, &to)) nm_platform_vlan_set_egress_map (ifindex, from, to); } } return ret; }
static gboolean create_and_realize (NMDevice *device, NMConnection *connection, NMDevice *parent, const NMPlatformLink **out_plink, GError **error) { const char *iface = nm_device_get_iface (device); NMPlatformError plerr; NMSettingMacvlan *s_macvlan; NMPlatformLnkMacvlan lnk = { }; int parent_ifindex; s_macvlan = nm_connection_get_setting_macvlan (connection); g_assert (s_macvlan); if (!parent) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "MACVLAN devices can not be created without a parent interface"); return FALSE; } parent_ifindex = nm_device_get_ifindex (parent); g_warn_if_fail (parent_ifindex > 0); lnk.mode = setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)); if (!lnk.mode) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "unsupported MACVLAN mode %u in connection %s", nm_setting_macvlan_get_mode (s_macvlan), nm_connection_get_uuid (connection)); return FALSE; } lnk.no_promisc = !nm_setting_macvlan_get_promiscuous (s_macvlan); lnk.tap = nm_setting_macvlan_get_tap (s_macvlan); plerr = nm_platform_link_macvlan_add (NM_PLATFORM_GET, iface, parent_ifindex, &lnk, out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create %s interface '%s' for '%s': %s", lnk.tap ? "macvtap" : "macvlan", iface, nm_connection_get_id (connection), nm_platform_error_to_string (plerr)); return FALSE; } return TRUE; }
static void commit_option (NMDevice *device, NMSetting *setting, const Option *option, gboolean slave) { int ifindex = nm_device_get_ifindex (device); GParamSpec *pspec; GValue val = G_VALUE_INIT; guint32 uval = 0; gs_free char *value = NULL; g_assert (setting); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), option->name); g_assert (pspec); /* Get the property's value */ g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_object_get_property ((GObject *) setting, option->name, &val); if (G_VALUE_HOLDS_BOOLEAN (&val)) uval = g_value_get_boolean (&val) ? 1 : 0; else if (G_VALUE_HOLDS_UINT (&val)) { uval = g_value_get_uint (&val); /* zero means "unspecified" for some NM properties but isn't in the * allowed kernel range, so reset the property to the default value. */ if (option->default_if_zero && uval == 0) { g_value_unset (&val); g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_param_value_set_default (pspec, &val); uval = g_value_get_uint (&val); } /* Linux kernel bridge interfaces use 'centiseconds' for time-based values. * In reality it's not centiseconds, but depends on HZ and USER_HZ, which * is almost always works out to be a multiplier of 100, so we can assume * centiseconds. See clock_t_to_jiffies(). */ if (option->user_hz_compensate) uval *= 100; } else g_assert_not_reached (); g_value_unset (&val); value = g_strdup_printf ("%u", uval); if (slave) nm_platform_slave_set_option (ifindex, option->sysname, value); else nm_platform_master_set_option (ifindex, option->sysname, value); }
static GObject* constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { GObject *object; GObjectClass *klass; NMDeviceOlpcMesh *self; NMDeviceOlpcMeshPrivate *priv; klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class); object = klass->constructor (type, n_construct_params, construct_params); if (!object) return NULL; self = NM_DEVICE_OLPC_MESH (object); priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d", nm_device_get_iface (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); priv->wifi_data = wifi_utils_init (nm_device_get_iface (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self)), FALSE); if (priv->wifi_data == NULL) { nm_log_warn (LOGD_HW | LOGD_OLPC_MESH, "(%s): failed to initialize WiFi driver", nm_device_get_iface (NM_DEVICE (self))); g_object_unref (object); return NULL; } /* shorter timeout for mesh connectivity */ nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); return object; }
static void update_properties (NMDevice *device) { NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); const NMPlatformLnkMacvlan *props; const NMPlatformLink *plink; NMDevice *parent = NULL; if (priv->props.tap) props = nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink); else props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink); if (!props) { _LOGW (LOGD_HW, "could not get %s properties", priv->props.tap ? "macvtap" : "macvlan"); return; } g_object_freeze_notify (object); if (priv->parent_ifindex != plink->parent) { parent = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->parent); nm_device_macvlan_set_parent (self, parent); } if (priv->props.mode != props->mode) g_object_notify (object, NM_DEVICE_MACVLAN_MODE); if (priv->props.no_promisc != props->no_promisc) g_object_notify (object, NM_DEVICE_MACVLAN_NO_PROMISC); priv->parent_ifindex = plink->parent; priv->props = *props; g_object_thaw_notify (object); }
static void update_connection (NMDevice *device, NMConnection *connection) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMSettingTun *s_tun = nm_connection_get_setting_tun (connection); NMPlatformTunProperties props; NMSettingTunMode mode; gint64 user, group; char *str; if (!s_tun) { s_tun = (NMSettingTun *) nm_setting_tun_new (); nm_connection_add_setting (connection, (NMSetting *) s_tun); } if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) { _LOGW (LOGD_HW, "failed to get TUN interface info while updating connection."); return; } mode = tun_mode_from_string (props.mode); if (mode != nm_setting_tun_get_mode (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MODE, mode, NULL); user = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_owner (s_tun), 10, 0, G_MAXINT32, -1); group = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_group (s_tun), 10, 0, G_MAXINT32, -1); if (props.owner != user) { str = props.owner >= 0 ? g_strdup_printf ("%" G_GINT32_FORMAT, (gint32) props.owner) : NULL; g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_OWNER, str, NULL); g_free (str); } if (props.group != group) { str = props.group >= 0 ? g_strdup_printf ("%" G_GINT32_FORMAT, (gint32) props.group) : NULL; g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_GROUP, str, NULL); g_free (str); } if ((!props.no_pi) != nm_setting_tun_get_pi (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_PI, !props.no_pi, NULL); if (props.vnet_hdr != nm_setting_tun_get_vnet_hdr (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_VNET_HDR, props.vnet_hdr, NULL); if (props.multi_queue != nm_setting_tun_get_multi_queue (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MULTI_QUEUE, props.multi_queue, NULL); }
NMDevice * nm_device_vlan_new_for_connection (NMConnection *connection, NMDevice *parent) { NMDevice *device; NMSettingVlan *s_vlan; char *iface; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); s_vlan = nm_connection_get_setting_vlan (connection); g_return_val_if_fail (s_vlan != NULL, NULL); iface = g_strdup (nm_connection_get_interface_name (connection)); if (!iface) { iface = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), nm_setting_vlan_get_id (s_vlan)); } if ( !nm_platform_vlan_add (iface, nm_device_get_ifindex (parent), nm_setting_vlan_get_id (s_vlan), nm_setting_vlan_get_flags (s_vlan)) && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { nm_log_warn (LOGD_DEVICE | LOGD_VLAN, "(%s) failed to add VLAN interface for '%s'", iface, nm_connection_get_id (connection)); g_free (iface); return NULL; } device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, NM_DEVICE_IFACE, iface, NM_DEVICE_VLAN_PARENT, parent, NM_DEVICE_DRIVER, "8021q", NM_DEVICE_TYPE_DESC, "VLAN", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, NULL); g_free (iface); if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { g_object_unref (device); device = NULL; } return device; }
static void carrier_on (NMNetlinkMonitor *monitor, int idx, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); NMDeviceWired *self = NM_DEVICE_WIRED (device); guint32 caps; /* Make sure signal is for us */ if (idx == nm_device_get_ifindex (device)) { caps = nm_device_get_capabilities (device); g_return_if_fail (caps & NM_DEVICE_CAP_CARRIER_DETECT); set_carrier (self, TRUE, FALSE); set_speed (self, ethtool_get_speed (self)); } }
static void constructed (GObject *object) { NMDeviceVlan *self = NM_DEVICE_VLAN (object); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); int parent_ifindex = -1, itype; int vlan_id; if (G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed) G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed (object); if (!priv->parent) { _LOGE (LOGD_VLAN, "no parent specified."); priv->invalid = TRUE; return; } itype = nm_platform_link_get_type (ifindex); if (itype != NM_LINK_TYPE_VLAN) { _LOGE (LOGD_VLAN, "failed to get VLAN interface type."); priv->invalid = TRUE; return; } if (!nm_platform_vlan_get_info (ifindex, &parent_ifindex, &vlan_id)) { _LOGW (LOGD_VLAN, "failed to get VLAN interface info."); priv->invalid = TRUE; return; } if ( parent_ifindex < 0 || parent_ifindex != nm_device_get_ip_ifindex (priv->parent) || vlan_id < 0) { _LOGW (LOGD_VLAN, "VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", parent_ifindex, priv->vlan_id); priv->invalid = TRUE; return; } priv->vlan_id = vlan_id; _LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s", priv->vlan_id, nm_device_get_iface (priv->parent)); }
static void reload_tun_properties (NMDeviceTun *self) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); GObject *object = G_OBJECT (self); NMPlatformTunProperties props; int ifindex; ifindex = nm_device_get_ifindex (NM_DEVICE (self)); if (ifindex > 0) { if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, ifindex, &props)) { _LOGD (LOGD_DEVICE, "tun-properties: cannot loading tun properties from platform for ifindex %d", ifindex); ifindex = 0; } else if (g_strcmp0 (priv->mode, props.mode) != 0) { /* if the mode differs, we ignore what we loaded. A NMDeviceTun cannot * change the mode after construction. */ _LOGD (LOGD_DEVICE, "tun-properties: loading tun properties yielded tun-mode %s%s%s, but %s%s%s expected (ifindex %d)", NM_PRINT_FMT_QUOTE_STRING (props.mode), NM_PRINT_FMT_QUOTE_STRING (priv->mode), ifindex); ifindex = 0; } } else _LOGD (LOGD_DEVICE, "tun-properties: ignore loading properties due to missing ifindex"); if (ifindex <= 0) memset (&props, 0, sizeof (props)); g_object_freeze_notify (object); if (priv->props.owner != props.owner) g_object_notify (object, NM_DEVICE_TUN_OWNER); if (priv->props.group != props.group) g_object_notify (object, NM_DEVICE_TUN_GROUP); if (priv->props.no_pi != props.no_pi) g_object_notify (object, NM_DEVICE_TUN_NO_PI); if (priv->props.vnet_hdr != props.vnet_hdr) g_object_notify (object, NM_DEVICE_TUN_VNET_HDR); if (priv->props.multi_queue != props.multi_queue) g_object_notify (object, NM_DEVICE_TUN_MULTI_QUEUE); memcpy (&priv->props, &props, sizeof (NMPlatformTunProperties)); g_object_thaw_notify (object); }