diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index f6362bccf..fc209fc85 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -371,7 +371,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self, */ if ( !entry && (has_ifindex_synced || ifindex_to_flush == route->ifindex)) { - vtable->vt->route_delete_default (priv->platform, route->ifindex, route->metric); + nm_platform_ip_route_delete (priv->platform, NMP_OBJECT_UP_CAST (route)); changed = TRUE; } } diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c index bcf911f12..a54deebe4 100644 --- a/src/nm-route-manager.c +++ b/src/nm-route-manager.c @@ -58,7 +58,8 @@ typedef struct { NMRouteManager *self; gint64 scheduled_at_ns; guint idle_id; - NMPObject *obj; + const NMPObject *obj; + const NMPObject *obj_cached; } IP4DeviceRoutePurgeEntry; /*****************************************************************************/ @@ -490,8 +491,10 @@ _get_next_plat_route (const RouteIndex *index, gboolean start_at_zero, guint *cu ++*cur_idx; /* get next route from the platform index. */ - if (*cur_idx < index->len) + if (*cur_idx < index->len) { + nm_assert (NMP_OBJECT_UP_CAST (index->entries[*cur_idx])); return index->entries[*cur_idx]; + } *cur_idx = index->len; return NULL; } @@ -649,7 +652,8 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const * in platform. Delete it. */ _LOGt (vtable->vt->addr_family, "%3d: platform rt-rm #%u - %s", ifindex, i_plat_routes, vtable->vt->route_to_string (cur_plat_route, NULL, 0)); - vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route); + nm_assert (ifindex == cur_plat_route->rx.ifindex); + nm_platform_ip_route_delete (priv->platform, NMP_OBJECT_UP_CAST (cur_plat_route)); } } } @@ -796,7 +800,7 @@ next: while (cur_plat_route) { int route_dest_cmp_result = 0; - g_assert (cur_plat_route->rx.ifindex == ifindex); + nm_assert (cur_plat_route->rx.ifindex == ifindex); _LOGt (vtable->vt->addr_family, "%3d: platform rt #%u - %s", ifindex, i_plat_routes, vtable->vt->route_to_string (cur_plat_route, NULL, 0)); @@ -816,8 +820,10 @@ next: /* if @cur_ipx_route is not equal to @plat_route, the route must be deleted. */ if ( !cur_ipx_route || route_dest_cmp_result != 0 - || *p_effective_metric != cur_plat_route->rx.metric) - vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route); + || *p_effective_metric != cur_plat_route->rx.metric) { + nm_assert (ifindex == cur_plat_route->rx.ifindex); + nm_platform_ip_route_delete (priv->platform, NMP_OBJECT_UP_CAST (cur_plat_route)); + } cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes); } @@ -1074,6 +1080,7 @@ _ip4_device_routes_purge_entry_create (NMRouteManager *self, const NMPlatformIP4 entry->scheduled_at_ns = now_ns; entry->idle_id = 0; entry->obj = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, (NMPlatformObject *) route); + entry->obj_cached = NULL; return entry; } @@ -1081,6 +1088,7 @@ static void _ip4_device_routes_purge_entry_free (IP4DeviceRoutePurgeEntry *entry) { nmp_object_unref (entry->obj); + nmp_object_unref (entry->obj_cached); nm_clear_g_source (&entry->idle_id); g_slice_free (IP4DeviceRoutePurgeEntry, entry); } @@ -1100,13 +1108,9 @@ _ip4_device_routes_idle_cb (IP4DeviceRoutePurgeEntry *entry) return G_SOURCE_REMOVE; } - _LOGt (vtable_v4.vt->addr_family, "device-route: delete %s", nmp_object_to_string (entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + _LOGt (vtable_v4.vt->addr_family, "device-route: delete %s", nmp_object_to_string (entry->obj_cached, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - nm_platform_ip4_route_delete (priv->platform, - entry->obj->ip4_route.ifindex, - entry->obj->ip4_route.network, - entry->obj->ip4_route.plen, - entry->obj->ip4_route.metric); + nm_platform_ip_route_delete (priv->platform, entry->obj_cached); g_hash_table_remove (priv->ip4_device_routes.entries, entry->obj); _ip4_device_routes_cancel (self); @@ -1123,12 +1127,9 @@ _ip4_device_routes_ip4_route_changed (NMPlatform *platform, { const NMPlatformSignalChangeType change_type = change_type_i; NMRouteManagerPrivate *priv; - NMPObject obj_needle; + const NMPObject *obj; IP4DeviceRoutePurgeEntry *entry; - if (change_type == NM_PLATFORM_SIGNAL_REMOVED) - return; - if ( route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL || route->metric != 0) { /* we don't have an automatically created device route at hand. Bail out early. */ @@ -1137,8 +1138,9 @@ _ip4_device_routes_ip4_route_changed (NMPlatform *platform, priv = NM_ROUTE_MANAGER_GET_PRIVATE (self); - entry = g_hash_table_lookup (priv->ip4_device_routes.entries, - nmp_object_stackinit (&obj_needle, NMP_OBJECT_TYPE_IP4_ROUTE, (NMPlatformObject *) route)); + obj = NMP_OBJECT_UP_CAST (route); + + entry = g_hash_table_lookup (priv->ip4_device_routes.entries, obj); if (!entry) return; @@ -1149,6 +1151,15 @@ _ip4_device_routes_ip4_route_changed (NMPlatform *platform, return; } + entry->obj_cached = nmp_object_unref (entry->obj_cached); + + if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { + if (nm_clear_g_source (&entry->idle_id)) + _LOGt (vtable_v4.vt->addr_family, "device-route: unschedule %s", nmp_object_to_string (entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + return; + } + + entry->obj_cached = nmp_object_ref (obj); if (entry->idle_id == 0) { _LOGt (vtable_v4.vt->addr_family, "device-route: schedule %s", nmp_object_to_string (entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); entry->idle_id = g_idle_add ((GSourceFunc) _ip4_device_routes_idle_cb, entry); diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 718ee974a..f817bfb57 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -106,9 +106,7 @@ static gboolean ipx_address_delete (NMPlatform *platform, static gboolean ipx_route_delete (NMPlatform *platform, int addr_family, int ifindex, - gconstpointer network, - const guint8 *plen, - const guint32 *metric); + const NMPObject *obj); static gboolean ip6_address_add (NMPlatform *platform, int ifindex, @@ -401,8 +399,8 @@ link_delete (NMPlatform *platform, int ifindex) /* Remove addresses and routes which belong to the deleted interface */ ipx_address_delete (platform, AF_INET, ifindex, NULL, NULL, NULL); ipx_address_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL); - ipx_route_delete (platform, AF_INET, ifindex, NULL, NULL, NULL); - ipx_route_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL); + ipx_route_delete (platform, AF_INET, ifindex, NULL); + ipx_route_delete (platform, AF_INET6, ifindex, NULL); nm_platform_cache_update_emit_signal (platform, cache_op, @@ -1115,42 +1113,54 @@ static gboolean ipx_route_delete (NMPlatform *platform, int addr_family, int ifindex, - gconstpointer network, - const guint8 *plen, - const guint32 *metric) + const NMPObject *obj) { gs_unref_ptrarray GPtrArray *objs = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); NMDedupMultiIter iter; const NMPObject *o = NULL; guint i; + NMPObjectType obj_type; - g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + if (addr_family == AF_UNSPEC) { + g_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + g_assert (ifindex == -1); + ifindex = obj->object.ifindex; + obj_type = NMP_OBJECT_GET_TYPE (obj); + } else { + g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + g_assert (!obj); + g_assert (ifindex > 0); + obj_type = addr_family == AF_INET + ? NMP_OBJECT_TYPE_IP4_ROUTE + : NMP_OBJECT_TYPE_IP6_ROUTE; + } nmp_cache_iter_for_each (&iter, nm_platform_lookup_addrroute (platform, - addr_family == AF_INET - ? NMP_OBJECT_TYPE_IP4_ROUTE - : NMP_OBJECT_TYPE_IP6_ROUTE, - 0), + obj_type, + ifindex), &o) { const NMPObject *obj_old = NULL; - if (addr_family == AF_INET) { - const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (o); + if (obj) { + if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) { + const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (o); + const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (obj); - if ( route->ifindex != ifindex - || (network && route->network != *((guint32 *) network)) - || (plen && route->plen != *plen) - || (metric && route->metric != *metric)) - continue; - } else { - const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (o); + if ( route->network != r->network + || route->plen != r->plen + || route->metric != r->metric) + continue; + } else { + const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (o); + const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (obj); - if ( route->ifindex != ifindex - || (network && !IN6_ARE_ADDR_EQUAL (&route->network, network)) - || (plen && route->plen != *plen) - || (metric && route->metric != *metric)) - continue; + if ( !IN6_ARE_ADDR_EQUAL (&route->network, &r->network) + || route->plen != r->plen + || route->metric != r->metric) + continue; + } } if (nmp_cache_remove (nm_platform_get_cache (platform), @@ -1172,16 +1182,13 @@ ipx_route_delete (NMPlatform *platform, } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip_route_delete (NMPlatform *platform, const NMPObject *obj) { - return ipx_route_delete (platform, AF_INET, ifindex, &network, &plen, &metric); -} + g_assert (NM_IS_FAKE_PLATFORM (platform)); + g_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); -static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) -{ - metric = nm_utils_ip6_route_metric_normalize (metric); - return ipx_route_delete (platform, AF_INET6, ifindex, &network, &plen, &metric); + return ipx_route_delete (platform, AF_UNSPEC, -1, obj); } static gboolean @@ -1391,6 +1398,5 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->ip4_route_add = ip4_route_add; platform_class->ip6_route_add = ip6_route_add; - platform_class->ip4_route_delete = ip4_route_delete; - platform_class->ip6_route_delete = ip6_route_delete; + platform_class->ip_route_delete = ip_route_delete; } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index fc2491066..e25091aa9 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2418,19 +2418,14 @@ nla_put_failure: static struct nl_msg * _nl_msg_new_route (int nlmsg_type, int nlmsg_flags, - int family, - int ifindex, + const NMPObject *obj, NMIPConfigSource source, unsigned char scope, - gconstpointer network, - guint8 plen, gconstpointer gateway, - guint32 metric, guint32 mss, gconstpointer pref_src, gconstpointer src, guint8 src_plen, - guint8 tos, guint32 window, guint32 cwnd, guint32 initcwnd, @@ -2439,23 +2434,24 @@ _nl_msg_new_route (int nlmsg_type, guint32 lock) { struct nl_msg *msg; + const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj); + gboolean is_v4 = klass->addr_family == AF_INET; struct rtmsg rtmsg = { - .rtm_family = family, - .rtm_tos = tos, + .rtm_family = klass->addr_family, + .rtm_tos = obj->ip_route.tos, .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source), .rtm_scope = scope, .rtm_type = RTN_UNICAST, .rtm_flags = 0, - .rtm_dst_len = plen, + .rtm_dst_len = obj->ip_route.plen, .rtm_src_len = src ? src_plen : 0, }; gsize addr_len; - nm_assert (NM_IN_SET (family, AF_INET, AF_INET6)); + nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); nm_assert (NM_IN_SET (nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE)); - nm_assert (network); msg = nlmsg_alloc_simple (nlmsg_type, nlmsg_flags); if (!msg) @@ -2464,14 +2460,19 @@ _nl_msg_new_route (int nlmsg_type, if (nlmsg_append (msg, &rtmsg, sizeof (rtmsg), NLMSG_ALIGNTO) < 0) goto nla_put_failure; - addr_len = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); + addr_len = is_v4 + ? sizeof (in_addr_t) + : sizeof (struct in6_addr); - NLA_PUT (msg, RTA_DST, addr_len, network); + NLA_PUT (msg, RTA_DST, addr_len, + is_v4 + ? (gconstpointer) &obj->ip4_route.network + : (gconstpointer) &obj->ip6_route.network); if (src) NLA_PUT (msg, RTA_SRC, addr_len, src); - NLA_PUT_U32 (msg, RTA_PRIORITY, metric); + NLA_PUT_U32 (msg, RTA_PRIORITY, obj->ip_route.metric); if (pref_src) NLA_PUT (msg, RTA_PREFSRC, addr_len, pref_src); @@ -2505,7 +2506,7 @@ _nl_msg_new_route (int nlmsg_type, if ( gateway && memcmp (gateway, &nm_ip_addr_zero, addr_len) != 0) NLA_PUT (msg, RTA_GATEWAY, addr_len, gateway); - NLA_PUT_U32 (msg, RTA_OIF, ifindex); + NLA_PUT_U32 (msg, RTA_OIF, obj->ip_route.ifindex); return msg; @@ -5688,86 +5689,78 @@ ip_route_get_lock_flag (NMPlatformIPRoute *route) static gboolean ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route) { - NMPObject obj_id; + NMPObject obj; + NMPlatformIP4Route *r; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - in_addr_t network; - network = nm_utils_ip4_address_clear_host_address (route->network, route->plen); + nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP4_ROUTE, (const NMPlatformObject *) route); + r = NMP_OBJECT_CAST_IP4_ROUTE (&obj); + r->network = nm_utils_ip4_address_clear_host_address (r->network, r->plen); - /* FIXME: take the scope from route into account */ nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, - AF_INET, - route->ifindex, + &obj, route->rt_source, route->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, - &network, - route->plen, &route->gateway, - route->metric, route->mss, route->pref_src ? &route->pref_src : NULL, NULL, 0, - route->tos, route->window, route->cwnd, route->initcwnd, route->initrwnd, route->mtu, ip_route_get_lock_flag ((NMPlatformIPRoute *) route)); - - nmp_object_stackinit_id_ip4_route (&obj_id, route->ifindex, network, route->plen, route->metric); - return do_add_addrroute (platform, &obj_id, nlmsg); + return do_add_addrroute (platform, &obj, nlmsg); } static gboolean ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route) { - NMPObject obj_id; + NMPObject obj; + NMPlatformIP6Route *r; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct in6_addr network; - nm_utils_ip6_address_clear_host_address (&network, &route->network, route->plen); + nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, (const NMPlatformObject *) route); + r = NMP_OBJECT_CAST_IP6_ROUTE (&obj); + nm_utils_ip6_address_clear_host_address (&r->network, &r->network, r->plen); - /* FIXME: take the scope from route into account */ nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, - AF_INET6, - route->ifindex, + &obj, route->rt_source, IN6_IS_ADDR_UNSPECIFIED (&route->gateway) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE, - &network, - route->plen, &route->gateway, - route->metric, route->mss, !IN6_IS_ADDR_UNSPECIFIED (&route->pref_src) ? &route->pref_src : NULL, !IN6_IS_ADDR_UNSPECIFIED (&route->src) ? &route->src : NULL, route->src_plen, - route->tos, route->window, route->cwnd, route->initcwnd, route->initrwnd, route->mtu, ip_route_get_lock_flag ((NMPlatformIPRoute *) route)); - - nmp_object_stackinit_id_ip6_route (&obj_id, route->ifindex, &network, route->plen, route->metric); - return do_add_addrroute (platform, &obj_id, nlmsg); + return do_add_addrroute (platform, &obj, nlmsg); } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip_route_delete (NMPlatform *platform, + const NMPObject *obj) { + nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - NMPObject obj_id; - network = nm_utils_ip4_address_clear_host_address (network, plen); + nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); - nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric); + if (!NMP_OBJECT_IS_STACKINIT (obj)) + obj_keep_alive = nmp_object_ref (obj); - if (metric == 0) { + if ( NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_IP4_ROUTE + && obj->ip_route.metric == 0) { NMPCache *cache = nm_platform_get_cache (platform); /* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route. @@ -5776,9 +5769,12 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p * * Instead, make sure that we have the most recent state and process all * delayed actions (including re-reading data from netlink). */ + + /* FIXME: later, we only want to pass in here @obj instances that originate + * from the cache, and where we know that the route with metric 0 exists. */ delayed_action_handle_all (platform, TRUE); - if (!nmp_cache_lookup_obj (cache, &obj_id)) { + if (!nmp_cache_lookup_obj (cache, obj)) { /* hmm... we are about to delete an IP4 route with metric 0. We must only * send the delete request if such a route really exists. Above we refreshed * the platform cache, still no such route exists. @@ -5786,32 +5782,23 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p * Be extra careful and reload the routes. We must be sure that such a * route doesn't exists, because when we add an IPv4 address, we immediately * afterwards try to delete the kernel-added device route with metric 0. - * It might be, that we didn't yet get the notification about that route. - * - * FIXME: once our ip4_address_add() is sure that upon return we have - * the latest state from in the platform cache, we might save this - * additional expensive cache-resync. */ + * It might be, that we didn't yet get the notification about that route. */ do_request_one_type (platform, NMP_OBJECT_TYPE_IP4_ROUTE); - if (!nmp_cache_lookup_obj (cache, &obj_id)) + if (!nmp_cache_lookup_obj (cache, obj)) return TRUE; } } nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, - AF_INET, - ifindex, + obj, NM_IP_CONFIG_SOURCE_UNKNOWN, RT_SCOPE_NOWHERE, - &network, - plen, - NULL, - metric, - 0, - NULL, NULL, 0, + NULL, + NULL, 0, 0, 0, @@ -5821,47 +5808,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p 0); if (!nlmsg) return FALSE; - - return do_delete_object (platform, &obj_id, nlmsg); -} - -static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - NMPObject obj_id; - - metric = nm_utils_ip6_route_metric_normalize (metric); - - nm_utils_ip6_address_clear_host_address (&network, &network, plen); - - nlmsg = _nl_msg_new_route (RTM_DELROUTE, - 0, - AF_INET6, - ifindex, - NM_IP_CONFIG_SOURCE_UNKNOWN, - RT_SCOPE_NOWHERE, - &network, - plen, - NULL, - metric, - 0, - NULL, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0); - if (!nlmsg) - return FALSE; - - nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric); - - return do_delete_object (platform, &obj_id, nlmsg); + return do_delete_object (platform, obj, nlmsg); } /*****************************************************************************/ @@ -6593,8 +6540,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->ip4_route_add = ip4_route_add; platform_class->ip6_route_add = ip6_route_add; - platform_class->ip4_route_delete = ip4_route_delete; - platform_class->ip6_route_delete = ip6_route_delete; + platform_class->ip_route_delete = ip_route_delete; platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags; platform_class->check_support_user_ipv6ll = check_support_user_ipv6ll; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 5c330c432..c8c7663e0 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3446,29 +3446,19 @@ nm_platform_ip6_route_add (NMPlatform *self, const NMPlatformIP6Route *route) } gboolean -nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +nm_platform_ip_route_delete (NMPlatform *self, + const NMPObject *obj) { - char str_dev[TO_STRING_DEV_BUF_SIZE]; - _CHECK_SELF (self, klass, FALSE); - _LOGD ("route: deleting IPv4 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", - nm_utils_inet4_ntop (network, NULL), plen, metric, ifindex, - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); - return klass->ip4_route_delete (self, ifindex, network, plen, metric); -} + nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); -gboolean -nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) -{ - char str_dev[TO_STRING_DEV_BUF_SIZE]; + _LOGD ("route: deleting IPv%c route %s", + NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_IP4_ROUTE ? '4' : '6', + nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - _CHECK_SELF (self, klass, FALSE); - - _LOGD ("route: deleting IPv6 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", - nm_utils_inet6_ntop (&network, NULL), plen, metric, ifindex, - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); - return klass->ip6_route_delete (self, ifindex, network, plen, metric); + return klass->ip_route_delete (self, obj); } const NMPlatformIP4Route * @@ -5160,44 +5150,12 @@ _vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout return nm_platform_ip6_route_add (self, &rt); } -static gboolean -_vtr_v4_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route) -{ - return nm_platform_ip4_route_delete (self, - ifindex > 0 ? ifindex : route->rx.ifindex, - route->r4.network, - route->rx.plen, - route->rx.metric); -} - -static gboolean -_vtr_v6_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route) -{ - return nm_platform_ip6_route_delete (self, - ifindex > 0 ? ifindex : route->rx.ifindex, - route->r6.network, - route->rx.plen, - route->rx.metric); -} - static guint32 _vtr_v4_metric_normalize (guint32 metric) { return metric; } -static gboolean -_vtr_v4_route_delete_default (NMPlatform *self, int ifindex, guint32 metric) -{ - return nm_platform_ip4_route_delete (self, ifindex, 0, 0, metric); -} - -static gboolean -_vtr_v6_route_delete_default (NMPlatform *self, int ifindex, guint32 metric) -{ - return nm_platform_ip6_route_delete (self, ifindex, in6addr_any, 0, metric); -} - /*****************************************************************************/ const NMPlatformVTableRoute nm_platform_vtable_route_v4 = { @@ -5208,8 +5166,6 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v4 = { .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part)) nm_platform_ip4_route_cmp_full, .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip4_route_to_string, .route_add = _vtr_v4_route_add, - .route_delete = _vtr_v4_route_delete, - .route_delete_default = _vtr_v4_route_delete_default, .metric_normalize = _vtr_v4_metric_normalize, }; @@ -5221,8 +5177,6 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v6 = { .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part)) nm_platform_ip6_route_cmp_full, .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip6_route_to_string, .route_add = _vtr_v6_route_add, - .route_delete = _vtr_v6_route_delete, - .route_delete_default = _vtr_v6_route_delete_default, .metric_normalize = nm_utils_ip6_route_metric_normalize, }; diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 8ff6d5eda..956e71822 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -367,8 +367,6 @@ typedef struct { int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part); const char *(*route_to_string) (const NMPlatformIPXRoute *route, char *buf, gsize len); gboolean (*route_add) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric); - gboolean (*route_delete) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route); - gboolean (*route_delete_default) (NMPlatform *self, int ifindex, guint32 metric); guint32 (*metric_normalize) (guint32 metric); } NMPlatformVTableRoute; @@ -644,8 +642,7 @@ typedef struct { gboolean (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route); gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route); - gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric); - gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); + gboolean (*ip_route_delete) (NMPlatform *, const NMPObject *obj); gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *); gboolean (*check_support_user_ipv6ll) (NMPlatform *); @@ -931,6 +928,7 @@ NMPlatformError nm_platform_link_sit_add (NMPlatform *self, const NMPlatformLink **out_link); const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address); + gboolean nm_platform_ip4_address_add (NMPlatform *self, int ifindex, in_addr_t address, @@ -958,8 +956,7 @@ const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifind const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); gboolean nm_platform_ip4_route_add (NMPlatform *self, const NMPlatformIP4Route *route); gboolean nm_platform_ip6_route_add (NMPlatform *self, const NMPlatformIP6Route *route); -gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric); -gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); +gboolean nm_platform_ip_route_delete (NMPlatform *self, const NMPObject *route); const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len); const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 10753f1f0..51234cf17 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -100,6 +100,60 @@ nmtstp_platform_ip6_address_get_all (NMPlatform *self, int ifindex) /*****************************************************************************/ +gboolean +nmtstp_platform_ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +{ + NMDedupMultiIter iter; + + nm_platform_process_events (platform); + + nm_dedup_multi_iter_for_each (&iter, + nm_platform_lookup_addrroute (platform, + NMP_OBJECT_TYPE_IP4_ROUTE, + ifindex)) { + const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (iter.current->obj); + + if ( r->ifindex != ifindex + || r->network != network + || r->plen != plen + || r->metric != metric) { + continue; + } + + return nm_platform_ip_route_delete (platform, NMP_OBJECT_UP_CAST (r)); + } + + return TRUE; +} + +gboolean +nmtstp_platform_ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +{ + NMDedupMultiIter iter; + + nm_platform_process_events (platform); + + nm_dedup_multi_iter_for_each (&iter, + nm_platform_lookup_addrroute (platform, + NMP_OBJECT_TYPE_IP6_ROUTE, + ifindex)) { + const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (iter.current->obj); + + if ( r->ifindex != ifindex + || !IN6_ARE_ADDR_EQUAL (&r->network, &network) + || r->plen != plen + || r->metric != metric) { + continue; + } + + return nm_platform_ip_route_delete (platform, NMP_OBJECT_UP_CAST (r)); + } + + return TRUE; +} + +/*****************************************************************************/ + SignalData * add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname) { diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 9cef6f358..4d65a2668 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -217,6 +217,9 @@ nmtstp_ip6_route_get_all (NMPlatform *platform, GArray *nmtstp_platform_ip4_address_get_all (NMPlatform *self, int ifindex); GArray *nmtstp_platform_ip6_address_get_all (NMPlatform *self, int ifindex); +gboolean nmtstp_platform_ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric); +gboolean nmtstp_platform_ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); + const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); const NMPlatformLink *nmtstp_link_get (NMPlatform *platform, int ifindex, const char *name); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 18fe75f90..adaf7e538 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -136,7 +136,7 @@ test_ip4_route_metric0 (void) nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Deleting route with metric 0 does nothing */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); @@ -150,21 +150,21 @@ test_ip4_route_metric0 (void) nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); accept_signal (route_removed); nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 again (we expect nothing to happen) */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete the other route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); accept_signal (route_removed); nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); @@ -250,19 +250,19 @@ test_ip4_route (void) g_ptr_array_unref (routes); /* Remove route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); /* Remove default route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric)); accept_signal (route_removed); /* Remove route to gateway */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric)); accept_signal (route_removed); free_signal (route_added); @@ -352,19 +352,19 @@ test_ip6_route (void) g_ptr_array_unref (routes); /* Remove route */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); /* Remove default route */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); accept_signal (route_removed); /* Remove route to gateway */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric)); accept_signal (route_removed); free_signal (route_added); @@ -438,11 +438,11 @@ test_ip4_route_options (void) rts[0].lock_cwnd = TRUE; g_assert_cmpint (routes->len, ==, 1); nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); - g_ptr_array_unref (routes); /* Remove route */ - /*FIXME */ - //g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, 24, 20)); + g_assert (nm_platform_ip_route_delete (NM_PLATFORM_GET, routes->pdata[0])); + + g_ptr_array_unref (routes); } @@ -537,9 +537,9 @@ test_ip6_route_options (gconstpointer test_data) g_ptr_array_unref (routes); for (i = 0; i < rts_n; i++) { - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, IFINDEX, - rts_add[i].network, rts_add[i].plen, - rts_add[i].metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, IFINDEX, + rts_add[i].network, rts_add[i].plen, + rts_add[i].metric)); } for (i = 0; i < addr_n; i++) {