diff --git a/src/nm-device.c b/src/nm-device.c index 4a932a91f4..6a2db4804b 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3117,12 +3117,14 @@ nm_device_set_ip6_config (NMDevice *self, gboolean success = TRUE; NMIP6ConfigCompareFlags diff = NM_IP6_COMPARE_FLAG_ALL; NMDnsManager *dns_mgr; + int ip_ifindex; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (reason != NULL, FALSE); priv = NM_DEVICE_GET_PRIVATE (self); ip_iface = nm_device_get_ip_iface (self); + ip_ifindex = nm_device_get_ip_ifindex (self); old_config = priv->ip6_config; @@ -3148,7 +3150,7 @@ nm_device_set_ip6_config (NMDevice *self, * assumed when NM starts. */ if (!assumed) - success = nm_system_apply_ip6_config (ip_iface, new_config, nm_device_get_priority (self), diff); + success = nm_system_apply_ip6_config (ip_ifindex, new_config, nm_device_get_priority (self), diff); if (success || assumed) { /* Export over D-Bus */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 20729fdc94..56c79f3d38 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -425,6 +425,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) NMConnection *connection = NULL; NMSettingConnection *s_con = NULL; const char *connection_id; + int ip_ifindex = 0; best = get_best_ip4_device (policy->manager, &best_req); if (!best) @@ -461,17 +462,18 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) NMDevice *parent; ip_iface = nm_vpn_connection_get_ip_iface (candidate); + ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate); connection = nm_vpn_connection_get_connection (candidate); addr = nm_ip4_config_get_address (ip4_config, 0); parent = nm_vpn_connection_get_parent_device (candidate); parent_ip4 = nm_device_get_ip4_config (parent); - nm_system_replace_default_ip4_route_vpn (ip_iface, + nm_system_replace_default_ip4_route_vpn (ip_ifindex, nm_ip4_address_get_gateway (addr), nm_vpn_connection_get_ip4_internal_gateway (candidate), nm_ip4_config_get_mss (ip4_config), - nm_device_get_ip_iface (parent), + nm_device_get_ip_ifindex (parent), nm_ip4_config_get_mss (parent_ip4)); dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; @@ -483,12 +485,14 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) if (!ip_iface || !ip4_config) { connection = nm_act_request_get_connection (best_req); ip_iface = nm_device_get_ip_iface (best); + ip_ifindex = nm_device_get_ip_ifindex (best); ip4_config = nm_device_get_ip4_config (best); g_assert (ip4_config); addr = nm_ip4_config_get_address (ip4_config, 0); - nm_system_replace_default_ip4_route (ip_iface, nm_ip4_address_get_gateway (addr), nm_ip4_config_get_mss (ip4_config)); - + nm_system_replace_default_ip4_route (ip_ifindex, + nm_ip4_address_get_gateway (addr), + nm_ip4_config_get_mss (ip4_config)); dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; } @@ -551,6 +555,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) NMIP6Config *ip6_config = NULL; NMIP6Address *addr; const char *ip_iface = NULL; + int ip_ifindex = -1; NMConnection *connection = NULL; NMSettingConnection *s_con = NULL; const char *connection_id; @@ -608,11 +613,12 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) if (!ip_iface || !ip6_config) { connection = nm_act_request_get_connection (best_req); ip_iface = nm_device_get_ip_iface (best); + ip_ifindex = nm_device_get_ip_ifindex (best); ip6_config = nm_device_get_ip6_config (best); g_assert (ip6_config); addr = nm_ip6_config_get_address (ip6_config, 0); - nm_system_replace_default_ip6_route (ip_iface, nm_ip6_address_get_gateway (addr)); + nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_address_get_gateway (addr)); dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; } diff --git a/src/nm-system.c b/src/nm-system.c index 78c069a404..144d0c4ee8 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -58,9 +58,9 @@ #include #include -static void nm_system_device_set_priority (const char *iface, - NMIP4Config *config, - int priority); +static void nm_system_device_set_priority (int ifindex, + NMIP4Config *config, + int priority); static gboolean ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix) @@ -488,7 +488,7 @@ nm_system_apply_ip4_config (int ifindex, } if (priority > 0) - nm_system_device_set_priority (iface, config, priority); + nm_system_device_set_priority (ifindex, config, priority); return TRUE; } @@ -618,16 +618,20 @@ add_ip6_addresses (NMIP6Config *config, const char *iface) * */ gboolean -nm_system_apply_ip6_config (const char *iface, +nm_system_apply_ip6_config (int ifindex, NMIP6Config *config, int priority, NMIP6ConfigCompareFlags flags) { + const char *iface; int i; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (config != NULL, FALSE); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + if (flags & NM_IP6_COMPARE_FLAG_ADDRESSES) { if (!add_ip6_addresses (config, iface)) return FALSE; @@ -635,8 +639,6 @@ nm_system_apply_ip6_config (const char *iface, } if (flags & NM_IP6_COMPARE_FLAG_ROUTES) { - int ifindex = nm_netlink_iface_to_index (iface); - for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) { NMIP6Route *route = nm_ip6_config_get_route (config, i); int err; @@ -850,20 +852,20 @@ nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac) } static struct rtnl_route * -add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss) +add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) { struct nl_handle *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; - int iface_idx, err; + const char *iface; + int err; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, NULL); - iface_idx = nm_netlink_iface_to_index (iface); - if (iface_idx < 0) - return NULL; - /* Gateway might be over a bridge; try adding a route to gateway first */ route = rtnl_route_alloc (); if (route == NULL) @@ -871,7 +873,7 @@ add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss) rtnl_route_set_family (route, AF_INET); rtnl_route_set_table (route, RT_TABLE_MAIN); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); rtnl_route_set_scope (route, RT_SCOPE_LINK); gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw)); @@ -903,31 +905,27 @@ error: } static int -replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) +replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *route = NULL; struct nl_handle *nlh; struct nl_addr *dst_addr = NULL; guint32 dst = 0; struct nl_addr *gw_addr = NULL; - int iface_idx, err = -1; + int err = -1; - g_return_val_if_fail (iface != NULL, -ENODEV); + g_return_val_if_fail (ifindex > 0, -ENODEV); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, -ENOMEM); - iface_idx = nm_netlink_iface_to_index (iface); - if (iface_idx < 0) - return -ENODEV; - route = rtnl_route_alloc(); g_return_val_if_fail (route != NULL, -ENOMEM); rtnl_route_set_family (route, AF_INET); rtnl_route_set_table (route, RT_TABLE_MAIN); rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); /* Build up the destination address */ dst_addr = nl_addr_build (AF_INET, &dst, sizeof (dst)); @@ -972,22 +970,26 @@ out: * */ gboolean -nm_system_replace_default_ip4_route_vpn (const char *iface, +nm_system_replace_default_ip4_route_vpn (int ifindex, guint32 ext_gw, guint32 int_gw, guint32 mss, - const char *parent_iface, + int parent_ifindex, guint32 parent_mss) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; int err; + const char *iface; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip4_route (iface, int_gw, mss); + err = replace_default_ip4_route (ifindex, int_gw, mss); if (err == 0) { return TRUE; } else if (err != -ESRCH) { @@ -998,12 +1000,12 @@ nm_system_replace_default_ip4_route_vpn (const char *iface, } /* Try adding a direct route to the gateway first */ - gw_route = add_ip4_route_to_gateway (parent_iface, ext_gw, parent_mss); + gw_route = add_ip4_route_to_gateway (parent_ifindex, ext_gw, parent_mss); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip4_route (iface, int_gw, mss); + err = replace_default_ip4_route (ifindex, int_gw, mss); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP4, @@ -1023,17 +1025,21 @@ nm_system_replace_default_ip4_route_vpn (const char *iface, * */ gboolean -nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) +nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; + const char *iface; int err; + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip4_route (iface, gw, mss); + err = replace_default_ip4_route (ifindex, gw, mss); if (err == 0) { return TRUE; } else if (err != -ESRCH) { @@ -1044,12 +1050,12 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) } /* Try adding a direct route to the gateway first */ - gw_route = add_ip4_route_to_gateway (iface, gw, mss); + gw_route = add_ip4_route_to_gateway (ifindex, gw, mss); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip4_route (iface, gw, mss); + err = replace_default_ip4_route (ifindex, gw, mss); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP4, @@ -1063,20 +1069,20 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) } static struct rtnl_route * -add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw) +add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) { struct nl_handle *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; - int iface_idx, err; + const char *iface; + int err; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, NULL); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, NULL); - iface_idx = nm_netlink_iface_to_index (iface); - if (iface_idx < 0) - return NULL; - /* Gateway might be over a bridge; try adding a route to gateway first */ route = rtnl_route_alloc (); if (route == NULL) @@ -1084,7 +1090,7 @@ add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw) rtnl_route_set_family (route, AF_INET6); rtnl_route_set_table (route, RT_TABLE_MAIN); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); rtnl_route_set_scope (route, RT_SCOPE_LINK); gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw)); @@ -1111,29 +1117,29 @@ error: } static int -replace_default_ip6_route (const char *iface, const struct in6_addr *gw) +replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *route = NULL; struct nl_handle *nlh; struct nl_addr *gw_addr = NULL; - int iface_idx, err = -1; + const char *iface; + int err = -1; - g_return_val_if_fail (iface != NULL, -ENODEV); + g_return_val_if_fail (ifindex > 0, FALSE); + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, -ENOMEM); - iface_idx = nm_netlink_iface_to_index (iface); - if (iface_idx < 0) - return -ENODEV; - route = rtnl_route_alloc(); g_return_val_if_fail (route != NULL, -ENOMEM); rtnl_route_set_family (route, AF_INET6); rtnl_route_set_table (route, RT_TABLE_MAIN); rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) { /* Build up the gateway address */ @@ -1170,20 +1176,24 @@ out: * */ gboolean -nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *gw) +nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; + const char *iface; int err; + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip6_route (iface, gw); - if (err == 0) { + err = replace_default_ip6_route (ifindex, gw); + if (err == 0) return TRUE; - } else if (err != -ESRCH) { + if (err != -ESRCH) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 default route: %d", iface, err); @@ -1191,12 +1201,12 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g } /* Try adding a direct route to the gateway first */ - gw_route = add_ip6_route_to_gateway (iface, gw); + gw_route = add_ip6_route_to_gateway (ifindex, gw); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip6_route (iface, gw); + err = replace_default_ip6_route (ifindex, gw); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP6, @@ -1379,7 +1389,7 @@ nm_system_iface_flush_routes (int ifindex, int family) typedef struct { struct rtnl_route *route; NMIP4Config *config; - int iface; + int ifindex; } SetPriorityInfo; static void @@ -1393,7 +1403,7 @@ find_route (struct nl_object *object, gpointer user_data) int i; if (info->route || - rtnl_route_get_oif (route) != info->iface || + rtnl_route_get_oif (route) != info->ifindex || rtnl_route_get_scope (route) != RT_SCOPE_LINK) return; @@ -1420,21 +1430,19 @@ find_route (struct nl_object *object, gpointer user_data) } static void -nm_system_device_set_priority (const char *iface, - NMIP4Config *config, - int priority) +nm_system_device_set_priority (int ifindex, + NMIP4Config *config, + int priority) { SetPriorityInfo info; + struct nl_handle *nlh; info.route = NULL; info.config = config; - info.iface = nm_netlink_iface_to_index (iface); - g_return_if_fail (info.iface >= 0); + info.ifindex = ifindex; foreach_route (find_route, &info); if (info.route) { - struct nl_handle *nlh; - nlh = nm_netlink_get_default_handle (); rtnl_route_del (nlh, info.route, 0); diff --git a/src/nm-system.h b/src/nm-system.h index f5f7ea22a9..ae4e7d91f8 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -37,18 +37,18 @@ gboolean nm_system_iface_flush_routes (int ifindex, int family); -gboolean nm_system_replace_default_ip4_route (const char *iface, +gboolean nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss); -gboolean nm_system_replace_default_ip6_route (const char *iface, +gboolean nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw); -gboolean nm_system_replace_default_ip4_route_vpn (const char *iface, +gboolean nm_system_replace_default_ip4_route_vpn (int ifindex, guint32 ext_gw, guint32 int_gw, guint32 mss, - const char *parent_iface, + int parent_ifindex, guint32 parent_mss); struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config); @@ -74,7 +74,7 @@ int nm_system_set_ip6_route (int ifindex, int table, struct rtnl_route **out_route); -gboolean nm_system_apply_ip6_config (const char *iface, +gboolean nm_system_apply_ip6_config (int ifindex, NMIP6Config *config, int priority, NMIP6ConfigCompareFlags flags); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index a7fb879e10..3520f292d2 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -773,6 +773,14 @@ nm_vpn_connection_get_ip_iface (NMVPNConnection *connection) return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_iface; } +int +nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), -1); + + return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_ifindex; +} + NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection) { diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index ee8eb5b6ea..daf9483c6b 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -72,6 +72,7 @@ void nm_vpn_connection_disconnect (NMVPNConnection *connect NMVPNConnectionStateReason reason); NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection); const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection); +int nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection); NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection); guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection);