diff options
-rw-r--r-- | src/devices/tests/Makefile.am | 3 | ||||
-rw-r--r-- | src/nm-default-route-manager.c | 5 | ||||
-rw-r--r-- | src/nm-route-manager.c | 3 | ||||
-rw-r--r-- | src/platform/nm-fake-platform.c | 36 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 119 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 133 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 29 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 65 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 4 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 294 | ||||
-rw-r--r-- | src/platform/tests/test-common.h | 59 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 173 | ||||
-rw-r--r-- | src/platform/tests/test-route.c | 68 | ||||
-rw-r--r-- | src/tests/test-route-manager.c | 4 |
14 files changed, 772 insertions, 223 deletions
diff --git a/src/devices/tests/Makefile.am b/src/devices/tests/Makefile.am index cd1ef6edd3..6fd5f8f5a3 100644 --- a/src/devices/tests/Makefile.am +++ b/src/devices/tests/Makefile.am @@ -12,7 +12,8 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(CODE_COVERAGE_LDFLAGS) diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index a637c6cb88..3c5737585f 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -355,7 +355,10 @@ _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); + vtable->vt->route_delete_default (priv->platform, route->ifindex, route->metric, + vtable->vt->is_ip4 + ? (NMIPAddr *) &((NMPlatformIP4Route *) route)->gateway + : (NMIPAddr *) &((NMPlatformIP6Route *) route)->gateway); changed = TRUE; } } diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c index 2d4c7d9595..64b8889a9f 100644 --- a/src/nm-route-manager.c +++ b/src/nm-route-manager.c @@ -1002,7 +1002,8 @@ _ip4_device_routes_idle_cb (IP4DeviceRoutePurgeEntry *entry) entry->obj->ip4_route.ifindex, entry->obj->ip4_route.network, entry->obj->ip4_route.plen, - entry->obj->ip4_route.metric); + entry->obj->ip4_route.metric, + entry->obj->ip4_route.gateway); g_hash_table_remove (priv->ip4_device_routes.entries, entry->obj); _ip4_device_routes_cancel (self); diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 39b5f3c080..1971149229 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -1131,7 +1131,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric, guint32 gateway) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1143,7 +1143,8 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p if ( route->ifindex != ifindex || route->network != network || route->plen != plen - || route->metric != metric) + || route->metric != metric + || route->gateway != gateway) continue; memcpy (&deleted_route, route, sizeof (deleted_route)); @@ -1155,7 +1156,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric, const struct in6_addr *gateway) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1169,7 +1170,8 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, gu if ( route->ifindex != ifindex || !IN6_ARE_ADDR_EQUAL (&route->network, &network) || route->plen != plen - || route->metric != metric) + || route->metric != metric + || !IN6_ARE_ADDR_EQUAL (&route->gateway, gateway ?: &nm_ip_addr_zero.addr6)) continue; memcpy (&deleted_route, route, sizeof (deleted_route)); @@ -1232,7 +1234,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, continue; if (item->ifindex != route.ifindex) { - ip4_route_delete (platform, item->ifindex, item->network, item->plen, item->metric); + ip4_route_delete (platform, item->ifindex, item->network, item->plen, item->metric, item->gateway); i--; continue; } @@ -1298,7 +1300,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, continue; if (item->ifindex != route.ifindex) { - ip6_route_delete (platform, item->ifindex, item->network, item->plen, item->metric); + ip6_route_delete (platform, item->ifindex, item->network, item->plen, item->metric, &item->gateway); i--; continue; } @@ -1315,7 +1317,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, } static const NMPlatformIP4Route * -ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric, guint32 gateway) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1323,10 +1325,11 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen for (i = 0; i < priv->ip4_routes->len; i++) { NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i); - if (route->ifindex == ifindex - && route->network == network - && route->plen == plen - && route->metric == metric) + if ( route->ifindex == ifindex + && route->network == network + && route->plen == plen + && route->metric == metric + && route->gateway == gateway) return route; } @@ -1334,7 +1337,7 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen } static const NMPlatformIP6Route * -ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric, const struct in6_addr *gateway) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1344,10 +1347,11 @@ ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint for (i = 0; i < priv->ip6_routes->len; i++) { NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i); - if (route->ifindex == ifindex - && IN6_ARE_ADDR_EQUAL (&route->network, &network) - && route->plen == plen - && route->metric == metric) + if ( route->ifindex == ifindex + && IN6_ARE_ADDR_EQUAL (&route->network, &network) + && route->plen == plen + && route->metric == metric + && IN6_ARE_ADDR_EQUAL (&route->gateway, gateway ?: &nm_ip_addr_zero.addr6)) return route; } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 11c2e965b2..885b066b17 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -304,6 +304,16 @@ _support_user_ipv6ll_detect (struct nlattr **tb) ******************************************************************/ static void +_ip6_route_normalize_metric (const NMPlatformIP6Route **route, NMPlatformIP6Route *r_storage) +{ + if ((*route)->metric != nm_utils_ip6_route_metric_normalize ((*route)->metric)) { + *r_storage = **route; + r_storage->metric = nm_utils_ip6_route_metric_normalize ((*route)->metric); + *route = r_storage; + } +} + +static void clear_host_address (int family, const void *network, guint8 plen, void *dst) { g_return_if_fail (network); @@ -3876,6 +3886,16 @@ do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * event_handler_read_netlink (platform, FALSE); + if (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_id), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)) { + /* for routes, we set the flags to NLM_F_CREATE | NLM_F_APPEND. This will fail with EEXIST + * if the route already exists, which is just splendind. + * + * So, first check the cache whether we expect the route to exist, and if so, set the + * flags to REPLACE. */ + if (nmp_cache_lookup_obj (priv->cache, obj_id)) + nlmsg_hdr (nlmsg)->nlmsg_flags |= NLM_F_REPLACE; + } + nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL); if (nle < 0) { _LOGE ("do-add-%s[%s]: failure sending netlink request \"%s\" (%d)", @@ -5548,65 +5568,64 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - in_addr_t network, guint8 plen, in_addr_t gateway, - in_addr_t pref_src, guint32 metric, guint32 mss) +ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route) { NMPObject obj_id; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; nlmsg = _nl_msg_new_route (RTM_NEWROUTE, - NLM_F_CREATE | NLM_F_REPLACE, + NLM_F_CREATE | NLM_F_APPEND, AF_INET, - ifindex, - source, - gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, - &network, - plen, - &gateway, - metric, - mss, - pref_src ? &pref_src : NULL); - - nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric); + route->ifindex, + route->rt_source, + route->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, + &route->network, + route->plen, + &route->gateway, + route->metric, + route->mss, + route->pref_src ? &route->pref_src : NULL); + + nmp_object_stackinit_id_ip4_route (&obj_id, route); return do_add_addrroute (platform, &obj_id, nlmsg); } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - struct in6_addr network, guint8 plen, struct in6_addr gateway, - guint32 metric, guint32 mss) +ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route) { NMPObject obj_id; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + NMPlatformIP6Route r_storage; + + _ip6_route_normalize_metric (&route, &r_storage); nlmsg = _nl_msg_new_route (RTM_NEWROUTE, - NLM_F_CREATE | NLM_F_REPLACE, + NLM_F_CREATE | NLM_F_APPEND, AF_INET6, - ifindex, - source, - !IN6_IS_ADDR_UNSPECIFIED (&gateway) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, - &network, - plen, - &gateway, - metric, - mss, + route->ifindex, + route->rt_source, + !IN6_IS_ADDR_UNSPECIFIED (&route->gateway) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, + &route->network, + route->plen, + &route->gateway, + route->metric, + route->mss, NULL); - nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric); + nmp_object_stackinit_id_ip6_route (&obj_id, route); return do_add_addrroute (platform, &obj_id, nlmsg); } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip4_route_delete (NMPlatform *platform, const NMPlatformIP4Route *route) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; - nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric); + nmp_object_stackinit_id_ip4_route (&obj_id, route); - if (metric == 0) { + if (route->metric == 0) { /* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route. * If no route with metric 0 exists, it might delete another route to the same destination. * For nm_platform_ip4_route_delete() we don't want this semantic. @@ -5638,13 +5657,13 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, AF_INET, - ifindex, + route->ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN, RT_SCOPE_NOWHERE, - &network, - plen, - NULL, - metric, + &route->network, + route->plen, + &route->gateway, + route->metric, 0, NULL); if (!nlmsg) @@ -5654,40 +5673,41 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 p } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +ip6_route_delete (NMPlatform *platform, const NMPlatformIP6Route *route) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; + NMPlatformIP6Route r_storage; - metric = nm_utils_ip6_route_metric_normalize (metric); + _ip6_route_normalize_metric (&route, &r_storage); nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, AF_INET6, - ifindex, + route->ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN, RT_SCOPE_NOWHERE, - &network, - plen, - NULL, - metric, + &route->network, + route->plen, + &route->gateway, + route->metric, 0, NULL); if (!nlmsg) return FALSE; - nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric); + nmp_object_stackinit_id_ip6_route (&obj_id, route); return do_delete_object (platform, &obj_id, nlmsg); } static const NMPlatformIP4Route * -ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +ip4_route_get (NMPlatform *platform, const NMPlatformIP4Route *route) { NMPObject obj_id; const NMPObject *obj; - nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric); + nmp_object_stackinit_id_ip4_route (&obj_id, route); obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_id); if (nmp_object_is_visible (obj)) return &obj->ip4_route; @@ -5695,14 +5715,15 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen } static const NMPlatformIP6Route * -ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +ip6_route_get (NMPlatform *platform, const NMPlatformIP6Route *route) { NMPObject obj_id; const NMPObject *obj; + NMPlatformIP6Route r_storage; - metric = nm_utils_ip6_route_metric_normalize (metric); + _ip6_route_normalize_metric (&route, &r_storage); - nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric); + nmp_object_stackinit_id_ip6_route (&obj_id, route); obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_id); if (nmp_object_is_visible (obj)) return &obj->ip6_route; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index afbe5f8263..e382370446 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -2908,45 +2908,49 @@ nm_platform_ip6_route_add (NMPlatform *self, } gboolean -nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric, guint32 gateway) { char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_gateway[NM_UTILS_INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, FALSE); - _LOGD ("route: deleting IPv4 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", + _LOGD ("route: deleting IPv4 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s, gateway=%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); + _to_string_dev (self, ifindex, str_dev, sizeof (str_dev)), + nm_utils_inet4_ntop (gateway, str_gateway)); + return klass->ip4_route_delete (self, ifindex, network, plen, metric, gateway); } gboolean -nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric, const struct in6_addr *gateway) { char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_gateway[NM_UTILS_INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, FALSE); - _LOGD ("route: deleting IPv6 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", + _LOGD ("route: deleting IPv6 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s, gateway=%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); + _to_string_dev (self, ifindex, str_dev, sizeof (str_dev)), + nm_utils_inet6_ntop (gateway ?: &nm_ip_addr_zero.addr6, str_gateway)); + return klass->ip6_route_delete (self, ifindex, network, plen, metric, gateway); } const NMPlatformIP4Route * -nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric, guint32 gateway) { _CHECK_SELF (self, klass, FALSE); - return klass->ip4_route_get (self ,ifindex, network, plen, metric); + return klass->ip4_route_get (self ,ifindex, network, plen, metric, gateway); } const NMPlatformIP6Route * -nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric, const struct in6_addr *gateway) { _CHECK_SELF (self, klass, FALSE); - return klass->ip6_route_get (self, ifindex, network, plen, metric); + return klass->ip6_route_get (self, ifindex, network, plen, metric, gateway); } /******************************************************************/ @@ -3917,6 +3921,9 @@ int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b) { _CMP_SELF (a, b); + + /* for nmp_object_id_equal(), all fields of the route are considered here. */ + _CMP_FIELD (a, b, ifindex); _CMP_FIELD (a, b, network); _CMP_FIELD (a, b, plen); @@ -3930,10 +3937,35 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route return 0; } +guint +nm_platform_ip4_route_hash (const NMPlatformIP4Route *a) +{ + guint h = 0x8202baf9; + + /* goes together with nm_platform_ip4_route_cmp(). */ + + if (a) { + h += (h * 33) + ((guint) a->ifindex); + h += (h * 33) + ((guint) a->network); + h += (h * 33) + ((guint) a->plen); + h += (h * 33) + ((guint) a->metric); + h += (h * 33) + ((guint) a->gateway); + h += (h * 33) + ((guint) a->rt_source); + h += (h * 33) + ((guint) a->mss); + h += (h * 33) + ((guint) a->scope_inv); + h += (h * 33) + ((guint) a->pref_src); + h += (h * 33) + ((guint) a->rt_cloned); + } + return h; +} + int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b) { _CMP_SELF (a, b); + + /* for nmp_object_id_equal(), all fields of the route are considered here. */ + _CMP_FIELD (a, b, ifindex); _CMP_FIELD_MEMCMP (a, b, network); _CMP_FIELD (a, b, plen); @@ -3945,6 +3977,32 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route return 0; } +guint +nm_platform_ip6_route_hash (const NMPlatformIP6Route *a) +{ + guint h = 0x0569b8f4; + + /* goes together with nm_platform_ip6_route_cmp(). */ + + if (a) { + h += (h * 33) + ((guint) a->ifindex); + h += (h * 33) + ((guint) a->network.s6_addr32[0]); + h += (h * 33) + ((guint) a->network.s6_addr32[1]); + h += (h * 33) + ((guint) a->network.s6_addr32[2]); + h += (h * 33) + ((guint) a->network.s6_addr32[3]); + h += (h * 33) + ((guint) a->plen); + h += (h * 33) + ((guint) a->metric); + h += (h * 33) + ((guint) a->gateway.s6_addr32[0]); + h += (h * 33) + ((guint) a->gateway.s6_addr32[1]); + h += (h * 33) + ((guint) a->gateway.s6_addr32[2]); + h += (h * 33) + ((guint) a->gateway.s6_addr32[3]); + h += (h * 33) + ((guint) a->rt_source); + h += (h * 33) + ((guint) a->mss); + h += (h * 33) + ((guint) a->rt_cloned); + } + return h; +} + /** * nm_platform_ip_address_cmp_expiry: * @a: a NMPlatformIPAddress to compare @@ -4072,28 +4130,31 @@ nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns) static gboolean _vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric) { - return nm_platform_ip4_route_add (self, - ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.rt_source, - route->r4.network, - route->rx.plen, - route->r4.gateway, - route->r4.pref_src, - metric >= 0 ? (guint32) metric : route->rx.metric, - route->rx.mss); + NMPlatformIPXRoute r_storage; + + if ( ifindex > 0 + || (metric >= 0 && route->metric != metric)) { + r_storage.r4 = route->r4; + r_storage.rx.ifindex = ifindex; + r_storage.rx.metric = metric; + route = &r_storage; + } + return nm_platform_ip4_route_add (self, route); } static gboolean _vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric) { - return nm_platform_ip6_route_add (self, - ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.rt_source, - route->r6.network, - route->rx.plen, - route->r6.gateway, - metric >= 0 ? (guint32) metric : route->rx.metric, - route->rx.mss); + NMPlatformIPXRoute r_storage; + + if ( ifindex > 0 + || (metric >= 0 && route->metric != metric)) { + r_storage.r6 = route->r6; + r_storage.rx.ifindex = ifindex; + r_storage.rx.metric = nm_utils_ip6_route_metric_normalize (metric); + route = &r_storage; + } + return nm_platform_ip6_route_add (self, route); } static gboolean @@ -4103,7 +4164,8 @@ _vtr_v4_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *r ifindex > 0 ? ifindex : route->rx.ifindex, route->r4.network, route->rx.plen, - route->rx.metric); + route->rx.metric, + route->r4.gateway); } static gboolean @@ -4113,7 +4175,8 @@ _vtr_v6_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *r ifindex > 0 ? ifindex : route->rx.ifindex, route->r6.network, route->rx.plen, - route->rx.metric); + route->rx.metric, + &route->r6.gateway); } static guint32 @@ -4123,15 +4186,15 @@ _vtr_v4_metric_normalize (guint32 metric) } static gboolean -_vtr_v4_route_delete_default (NMPlatform *self, int ifindex, guint32 metric) +_vtr_v4_route_delete_default (NMPlatform *self, int ifindex, guint32 metric, const NMIPAddr *gateway) { - return nm_platform_ip4_route_delete (self, ifindex, 0, 0, metric); + return nm_platform_ip4_route_delete (self, ifindex, 0, 0, metric, gateway ? gateway->addr4 : 0); } static gboolean -_vtr_v6_route_delete_default (NMPlatform *self, int ifindex, guint32 metric) +_vtr_v6_route_delete_default (NMPlatform *self, int ifindex, guint32 metric, const NMIPAddr *gateway) { - return nm_platform_ip6_route_delete (self, ifindex, in6addr_any, 0, metric); + return nm_platform_ip6_route_delete (self, ifindex, in6addr_any, 0, metric, gateway ? &gateway->addr6 : NULL); } /******************************************************************/ diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 2c1823c21d..ee3d849078 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -374,7 +374,7 @@ typedef struct { GArray *(*route_get_all) (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags); 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); + gboolean (*route_delete_default) (NMPlatform *self, int ifindex, guint32 metric, const NMIPAddr *gateway); guint32 (*metric_normalize) (guint32 metric); } NMPlatformVTableRoute; @@ -635,10 +635,10 @@ typedef struct { gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source, struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss); - 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); - const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric); - const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); + gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric, guint32 gateway); + gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric, const struct in6_addr *gateway); + const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, const NMPlatformIP4Route *route); + const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, const NMPlatformIP6Route *route); gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *); gboolean (*check_support_user_ipv6ll) (NMPlatform *); @@ -903,18 +903,14 @@ gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArr gboolean nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, gboolean keep_link_local); gboolean nm_platform_address_flush (NMPlatform *self, int ifindex); -const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric); -const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); +const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, const NMPlatformIP4Route *route); +const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, const NMPlatformIP6Route *route); GArray *nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags); GArray *nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags); -gboolean nm_platform_ip4_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - in_addr_t network, guint8 plen, in_addr_t gateway, - in_addr_t pref_src, guint32 metric, guint32 mss); -gboolean nm_platform_ip6_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - struct in6_addr network, guint8 plen, struct in6_addr gateway, - guint32 metric, guint32 mss); -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_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, const NMPlatformIP4Route *route); +gboolean nm_platform_ip6_route_delete (NMPlatform *self, const NMPlatformIP6Route *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); @@ -950,6 +946,9 @@ int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatform int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b); int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b); +guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *a); +guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *a); + gboolean nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self); gboolean nm_platform_check_support_user_ipv6ll (NMPlatform *self); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 55ffd7cffb..50a9a0d860 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -377,38 +377,33 @@ _vt_cmd_obj_stackinit_id_ip6_address (NMPObject *obj, const NMPObject *src) } const NMPObject * -nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric) +nmp_object_stackinit_id_ip4_route (NMPObject *obj, const NMPlatformIP4Route *route) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ROUTE, NULL); - obj->ip4_route.ifindex = ifindex; - obj->ip4_route.network = network; - obj->ip4_route.plen = plen; - obj->ip4_route.metric = metric; + if (route) + obj->ip4_route = *route; return obj; } static void _vt_cmd_obj_stackinit_id_ip4_route (NMPObject *obj, const NMPObject *src) { - nmp_object_stackinit_id_ip4_route (obj, src->ip_route.ifindex, src->ip4_route.network, src->ip_route.plen, src->ip_route.metric); + nmp_object_stackinit_id_ip4_route (obj, &src->ip4_route); } const NMPObject * -nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric) +nmp_object_stackinit_id_ip6_route (NMPObject *obj, const NMPlatformIP6Route *route) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL); - obj->ip6_route.ifindex = ifindex; - if (network) - obj->ip6_route.network = *network; - obj->ip6_route.plen = plen; - obj->ip6_route.metric = metric; + if (route) + obj->ip6_route = *route; return obj; } static void _vt_cmd_obj_stackinit_id_ip6_route (NMPObject *obj, const NMPObject *src) { - nmp_object_stackinit_id_ip6_route (obj, src->ip_route.ifindex, &src->ip6_route.network, src->ip_route.plen, src->ip_route.metric); + nmp_object_stackinit_id_ip6_route (obj, &src->ip6_route); } /******************************************************************/ @@ -567,8 +562,6 @@ _vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s", obj->peer_address != obj->address ? "," : "", obj->peer_address != obj->address ? nm_utils_inet4_ntop (obj->peer_address & nm_utils_ip4_prefix_to_netmask (obj->plen), buf2) : ""); _vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1)); -_vt_cmd_plobj_to_string_id (ip4_route, NMPlatformIP4Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet4_ntop ( obj->network, buf1), obj->plen, obj->metric); -_vt_cmd_plobj_to_string_id (ip6_route, NMPlatformIP6Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet6_ntop (&obj->network, buf1), obj->plen, obj->metric); int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) @@ -733,16 +726,10 @@ _vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, { dst->address = src->address; }); _vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, { - dst->ifindex = src->ifindex; - dst->plen = src->plen; - dst->metric = src->metric; - dst->network = src->network; + *dst = *src; }); _vt_cmd_plobj_id_copy (ip6_route, NMPlatformIP6Route, { - dst->ifindex = src->ifindex; - dst->plen = src->plen; - dst->metric = src->metric; - dst->network = src->network; + *dst = *src; }); /* Uses internally nmp_object_copy(), hence it also violates the const @@ -804,15 +791,9 @@ _vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address, /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ && IN6_ARE_ADDR_EQUAL (&obj1->address, &obj2->address)); _vt_cmd_plobj_id_equal (ip4_route, NMPlatformIP4Route, - obj1->ifindex == obj2->ifindex - && obj1->plen == obj2->plen - && obj1->metric == obj2->metric - && obj1->network == obj2->network); + nm_platform_ip4_route_cmp (obj1, obj2) == 0); _vt_cmd_plobj_id_equal (ip6_route, NMPlatformIP6Route, - obj1->ifindex == obj2->ifindex - && obj1->plen == obj2->plen - && obj1->metric == obj2->metric - && IN6_ARE_ADDR_EQUAL( &obj1->network, &obj2->network)); + nm_platform_ip6_route_cmp (obj1, obj2) == 0); guint nmp_object_id_hash (const NMPObject *obj) @@ -861,20 +842,6 @@ _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, { /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ hash = hash * 33 + _id_hash_ip6_addr (&obj->address); }) -_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, { - hash = (guint) 2569857221u; - hash = hash + ((guint) obj->ifindex); - hash = hash * 33 + ((guint) obj->plen); - hash = hash * 33 + ((guint) obj->metric); - hash = hash * 33 + ((guint) obj->network); -}) -_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, { - hash = (guint) 3999787007u; - hash = hash + ((guint) obj->ifindex); - hash = hash * 33 + ((guint) obj->plen); - hash = hash * 33 + ((guint) obj->metric); - hash = hash * 33 + _id_hash_ip6_addr (&obj->network); -}) gboolean nmp_object_is_alive (const NMPObject *obj) @@ -2171,8 +2138,8 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, .cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip4_route, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_route, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_route, + .cmd_plobj_id_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash, + .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp, }, @@ -2191,8 +2158,8 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, .cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip6_route, - .cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_route, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_route, + .cmd_plobj_id_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash, + .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp, }, diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index c5241037d5..95d7fab1c1 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -372,8 +372,8 @@ const NMPObject *nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src) const NMPObject *nmp_object_stackinit_id_link (NMPObject *obj, int ifindex); const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address); const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, guint8 plen); -const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric); -const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric); +const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, const NMPlatformIP4Route *route); +const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, const NMPlatformIP6Route *route); const char *nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index b1947a6d11..34783c3ea4 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -25,6 +25,8 @@ #include <sys/wait.h> #include <fcntl.h> +#include "nm-platform-utils.h" + #include "test-common.h" #define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)" @@ -197,7 +199,7 @@ link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlat /*****************************************************************************/ gboolean -nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) +nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric, const guint32 *gateway) { gs_free char *arg_network = NULL; const char *argv[] = { @@ -216,6 +218,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 gboolean success; gs_free_error GError *error = NULL; gs_free char *metric_pattern = NULL; + gs_free char *via_pattern = NULL; g_assert (ifname && nm_utils_iface_valid_name (ifname)); g_assert (!strstr (ifname, " metric ")); @@ -253,6 +256,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 g_assert (std_out); metric_pattern = g_strdup_printf (" metric %u", metric); + via_pattern = gateway ? g_strdup_printf (" via %s", nm_utils_inet4_ntop (*gateway, NULL)) : NULL; out = std_out; while (out) { char *eol = strchr (out, '\n'); @@ -264,45 +268,104 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 continue; if (metric == 0) { - if (!strstr (line, " metric ")) - return TRUE; + if (strstr (line, " metric ")) + continue; + } else { + p = strstr (line, metric_pattern); + if (!p || !NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0')) + continue; } - p = strstr (line, metric_pattern); - if (p && NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0')) - return TRUE; + + if (gateway) { + if (*gateway == 0) { + if (strstr (line, " via ")) + continue; + } else { + p = strstr (line, via_pattern); + if (!p || !NM_IN_SET (p[strlen (via_pattern)], ' ', '\0')) + continue; + } + } + return TRUE; } return FALSE; } void -_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) +_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric, const guint32 *gateway) { int ifindex; gboolean exists_checked; + char s_buf[NM_UTILS_INET_ADDRSTRLEN]; + guint32 g = 0; + gboolean found_fuzzy = FALSE; _init_platform (&platform, FALSE); /* Check for existance of the route by spawning iproute2. Do this because platform * code might be entirely borked, but we expect ip-route to give a correct result. * If the ip command cannot be found, we accept this as success. */ - exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric); + exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric, gateway); if (exists_checked != -1 && !exists_checked != !exists) { - g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s", + g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d%s metric %u %s, but it %s", file, line, func, - nm_utils_inet4_ntop (network, NULL), plen, metric, + nm_utils_inet4_ntop (network, NULL), plen, + gateway ? nm_sprintf_bufa (100, " gateway %s", nm_utils_inet4_ntop (*gateway, s_buf)) : " no-gateway", + metric, exists ? "to exist" : "not to exist", exists ? "doesn't" : "does"); } ifindex = nm_platform_link_get_ifindex (platform, ifname); g_assert (ifindex > 0); - if (!nm_platform_ip4_route_get (platform, ifindex, network, plen, metric) != !exists) { - g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s", + + if (gateway) + g = *gateway; + else { + gs_unref_array GArray *routes = NULL; + guint i; + + routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL); + for (i = 0; routes && i < routes->len; i++) { + const NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i); + + g_assert (r->ifindex == ifindex); + if ( r->network == network + && r->plen == plen + && r->metric == metric) { + g_assert (!found_fuzzy); + found_fuzzy = TRUE; + g = r->gateway; + } + } + if (found_fuzzy) + goto found; + if (exists) { + g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s", + file, line, func, + nm_utils_inet4_ntop (network, NULL), + plen, + metric, + exists ? "exists" : "does not exist", + exists ? "it doesn't" : "it does"); + } + return; + } +found: + if (!nm_platform_ip4_route_get (platform, ifindex, network, plen, metric, g) != !exists) { + g_error ("[%s:%u] %s(): The ip4 route %s/%d via %s metric %u %s, but platform thinks %s", file, line, func, - nm_utils_inet4_ntop (network, NULL), plen, metric, + nm_utils_inet4_ntop (network, NULL), + plen, + nm_utils_inet4_ntop (g, s_buf), + metric, exists ? "exists" : "does not exist", exists ? "it doesn't" : "it does"); } + + /* when we found the route via fuzzy-match (without gateway), we expect that + * exists and nm_platform_ip4_route_get() agree. */ + g_assert (!found_fuzzy || exists); } /*****************************************************************************/ @@ -414,7 +477,7 @@ nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms) const NMPlatformLink * nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms) { - return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms); + return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms); } const NMPlatformLink * @@ -443,7 +506,7 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType const NMPlatformLink * nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms) { - return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms); + return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms); } const NMPlatformLink * @@ -458,6 +521,61 @@ nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NML /*****************************************************************************/ +static const void * +_wait_for_ip_route_until (NMPlatform *platform, int is_v4, int ifindex, const NMIPAddr *network, guint8 plen, guint32 metric, const NMIPAddr *gateway, gint64 until_ms) +{ + const void *plroute = NULL; + gint64 now; + + _init_platform (&platform, FALSE); + + while (TRUE) { + now = nm_utils_get_monotonic_timestamp_ms (); + + if (is_v4) + plroute = nm_platform_ip4_route_get (platform, ifindex, network->addr4, plen, metric, gateway->addr4); + else { + plroute = nm_platform_ip6_route_get (platform, ifindex, + network ? network->addr6 : in6addr_any, + plen, metric, + gateway ? &gateway->addr6 : &in6addr_any); + } + if (plroute) + return plroute; + + if (until_ms < now) + return NULL; + + nmtstp_wait_for_signal (platform, MAX (1, until_ms - now)); + } +} + +const NMPlatformIP4Route * +nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms) +{ + return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms); +} + +const NMPlatformIP4Route * +nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms) +{ + return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, until_ms); +} + +const NMPlatformIP6Route * +nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms) +{ + return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms); +} + +const NMPlatformIP6Route * +nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms) +{ + return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, until_ms); +} + +/*****************************************************************************/ + int nmtstp_run_command_check_external_global (void) { @@ -903,6 +1021,152 @@ nmtstp_ip6_address_del (NMPlatform *platform, /*****************************************************************************/ +static gconstpointer +_ip_route_add (NMPlatform *platform, + gboolean external_command, + gboolean is_v4, + int ifindex, + NMIPConfigSource source, + const NMIPAddr *network, + guint8 plen, + const NMIPAddr *gateway, + guint32 *pref_src, + guint32 metric, + guint32 mss) +{ + gint64 end_time; + char s_network[NM_UTILS_INET_ADDRSTRLEN]; + char s_gateway[NM_UTILS_INET_ADDRSTRLEN]; + char s_pref_src[NM_UTILS_INET_ADDRSTRLEN]; + const NMPlatformLink *pllink; + + external_command = nmtstp_run_command_check_external (external_command); + + _init_platform (&platform, external_command); + + pllink = nmtstp_link_get (platform, ifindex, NULL); + g_assert (pllink); + + if (external_command) { + s_network[0] = '\0'; + s_gateway[0] = '\0'; + s_pref_src[0] = '\0'; + if (is_v4) { + nm_utils_inet4_ntop (network->addr4, s_network); + if (gateway->addr4) + nm_utils_inet4_ntop (gateway->addr4, s_gateway); + if (*pref_src) + nm_utils_inet4_ntop (*pref_src, s_pref_src); + } else { + nm_utils_inet6_ntop (network ? &network->addr6 : &in6addr_any, s_network); + if (gateway && !IN6_IS_ADDR_UNSPECIFIED (&gateway->addr6)) + nm_utils_inet6_ntop (&gateway->addr6, s_gateway); + g_assert (!pref_src); + } + + nmtstp_run_command_check ("ip route append %s/%u%s dev '%s' metric %u protocol %d%s%s", + s_network, + plen, + s_gateway[0] ? nm_sprintf_bufa (100, " via %s", s_gateway) : "", + pllink->name, + metric, + nmp_utils_ip_config_source_coerce_to_rtprot (source), + s_pref_src[0] ? nm_sprintf_bufa (100, " src %s", s_pref_src) : "", + mss ? nm_sprintf_bufa (100, " advmss %u", mss) : ""); + } else { + gboolean success; + + if (is_v4) { + success = nm_platform_ip4_route_add (platform, + ifindex, + source, + network->addr4, + plen, + gateway->addr4, + *pref_src, + metric, + mss); + } else { + g_assert (pref_src == NULL); + success = nm_platform_ip6_route_add (platform, + ifindex, + source, + network ? network->addr6 : in6addr_any, + plen, + gateway ? gateway->addr6 : in6addr_any, + metric, + mss); + } + g_assert (success); + } + + /* Let's wait until we see the address. */ + end_time = nm_utils_get_monotonic_timestamp_ms () + 250; + do { + if (external_command) + nm_platform_process_events (platform); + + /* let's wait until we see the address as we added it. */ + if (is_v4) { + const NMPlatformIP4Route *r; + + r = nm_platform_ip4_route_get (platform, ifindex, network->addr4, plen, metric, gateway->addr4); + if (r) { + g_assert (r->ifindex == ifindex); + g_assert (r->network == network->addr4); + g_assert (r->plen == plen); + g_assert (r->metric == metric); + g_assert (r->gateway == gateway->addr4); + if ( r->mss == mss + && r->pref_src == *pref_src + && r->rt_source == nmp_utils_ip_config_source_round_trip_rtprot (source)) + return r; + } + } else { + const NMPlatformIP6Route *r; + + r = nm_platform_ip6_route_get (platform, ifindex, network ? network->addr6 : in6addr_any, plen, metric, gateway ? &gateway->addr6 : NULL); + if (r) { + g_assert (r->ifindex == ifindex); + g_assert (IN6_ARE_ADDR_EQUAL (&r->network, network ? &network->addr6 : &in6addr_any)); + g_assert (r->plen == plen); + g_assert (r->metric == metric); + g_assert (IN6_ARE_ADDR_EQUAL (&r->gateway, gateway ? &gateway->addr6 : &in6addr_any)); + if ( r->mss == mss + && r->rt_source == nmp_utils_ip_config_source_round_trip_rtprot (source)) + return r; + } + } + + /* for internal command, we expect not to reach this line.*/ + g_assert (external_command); + + nmtstp_assert_wait_for_signal_until (platform, end_time); + } while (TRUE); +} + +const NMPlatformIP4Route * +nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command, + int ifindex, NMIPConfigSource source, + guint32 network, guint8 plen, + guint32 gateway, guint32 pref_src, + guint32 metric, guint32 mss) +{ + return _ip_route_add (platform, external_command, TRUE, ifindex, source, (NMIPAddr *) &network, plen, (NMIPAddr *) &gateway, &pref_src, metric, mss); +} + +const NMPlatformIP4Route * +nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command, + int ifindex, NMIPConfigSource source, + const struct in6_addr *network, guint8 plen, + const struct in6_addr *gateway, + guint32 metric, guint32 mss) +{ + return _ip_route_add (platform, external_command, FALSE, ifindex, source, (NMIPAddr *) &network, plen, (NMIPAddr *) &gateway, NULL, metric, mss); +} + +/*****************************************************************************/ + #define _assert_pllink(platform, success, pllink, name, type) \ G_STMT_START { \ const NMPlatformLink *_pllink = (pllink); \ diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 0e3cf10ba4..5a7c8963d1 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -109,6 +109,47 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms); const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms); +const NMPlatformIP4Route *nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms); +const NMPlatformIP4Route *nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms); +const NMPlatformIP6Route *nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms); +const NMPlatformIP6Route *nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms); + +#define nmtstp_assert_wait_for_ip4_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \ + ({ \ + const NMPlatformIP4Route *_plroute; \ + \ + _plroute = nmtstp_wait_for_ip4_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \ + g_assert (_plroute); \ + _plroute; \ + }) + +#define nmtstp_assert_wait_for_ip4_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \ + ({ \ + const NMPlatformIP4Route *_plroute; \ + \ + _plroute = nmtstp_wait_for_ip4_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \ + g_assert (_plroute); \ + _plroute; \ + }) + +#define nmtstp_assert_wait_for_ip6_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \ + ({ \ + const NMPlatformIP6Route *_plroute; \ + \ + _plroute = nmtstp_wait_for_ip6_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \ + g_assert (_plroute); \ + _plroute; \ + }) + +#define nmtstp_assert_wait_for_ip6_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \ + ({ \ + const NMPlatformIP6Route *_plroute; \ + \ + _plroute = nmtstp_wait_for_ip6_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \ + g_assert (_plroute); \ + _plroute; \ + }) + /*****************************************************************************/ int nmtstp_run_command_check_external_global (void); @@ -116,10 +157,10 @@ gboolean nmtstp_run_command_check_external (int external_command); /*****************************************************************************/ -gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); +gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric, const guint32 *gateway); -void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); -#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric) +void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric, const guint32 *gateway); +#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric, gateway) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric, gateway) /*****************************************************************************/ @@ -163,6 +204,18 @@ void nmtstp_ip6_address_del (NMPlatform *platform, struct in6_addr address, int plen); +const NMPlatformIP4Route *nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command, + int ifindex, NMIPConfigSource source, + guint32 network, guint8 plen, + guint32 gateway, guint32 pref_src, + guint32 metric, guint32 mss); + +const NMPlatformIP4Route *nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command, + int ifindex, NMIPConfigSource source, + const struct in6_addr *network, guint8 plen, + const struct in6_addr *gateway, + guint32 metric, guint32 mss); + /*****************************************************************************/ const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 9d548aabdb..c834944b97 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -2292,6 +2292,174 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data) /*****************************************************************************/ +static void +test_route_external (gconstpointer user_data) +{ + const gboolean EX = (nmtst_get_rand_int () % 3) - 1; + const char *const MODE = user_data; + const char *IF[2] = { "IF0", "IF1" }; + int ifindex[2]; + const char *gateway[2] = { + "192.168.171.1", + "192.168.172.1", + }; + gs_unref_object NMPlatform *pl = NULL; + int delete_idx;; + + g_object_unref (NM_PLATFORM_GET); + + g_assert (NM_IN_STRSET (MODE, "change", "append")); + + pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + + ifindex[0] = nmtstp_link_dummy_add (pl, EX, IF[0])->ifindex; + ifindex[1] = nmtstp_link_dummy_add (pl, EX, IF[1])->ifindex; + nmtstp_link_set_updown (pl, EX, ifindex[0], TRUE); + nmtstp_link_set_updown (pl, EX, ifindex[1], TRUE); + + nmtstp_ip4_address_add (pl, EX, ifindex[0], + nmtst_inet4_from_string ("192.168.171.5"), 24, + nmtst_inet4_from_string ("192.168.171.5"), + NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL); + nmtstp_ip4_address_add (pl, EX, ifindex[1], + nmtst_inet4_from_string ("192.168.172.5"), 24, + nmtst_inet4_from_string ("192.168.172.5"), + NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL); + + nmtstp_run_command_check ("ip route add 192.168.200.0/24 via %s metric 423", gateway[0]); + nmtstp_assert_wait_for_ip4_route (pl, ifindex[0], nmtst_inet4_from_string ("192.168.200.0"), 24, + 423, nmtst_inet4_from_string (gateway[0]), 100); + + nmtstp_run_command_check ("ip route %s 192.168.200.0/24 via 192.168.172.1 metric 423", MODE); + + if (NM_IN_STRSET (MODE, "changed")) { + nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24, + 423, nmtst_inet4_from_string (gateway[1]), 100); + /* is the route still on ifindex[0]? */ + if (nm_platform_ip4_route_get (pl, ifindex[0], + nmtst_inet4_from_string ("192.168.200.0"), 24, + 423, nmtst_inet4_from_string (gateway[0]))) + g_assert_not_reached (); + } else if (NM_IN_STRSET (MODE, "append")) { + nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24, + 423, nmtst_inet4_from_string (gateway[1]), 100); + /* the route on ifindex[0] should continue to exist */ + if (!nm_platform_ip4_route_get (pl, ifindex[0], + nmtst_inet4_from_string ("192.168.200.0"), 24, + 423, nmtst_inet4_from_string (gateway[0]))) + g_assert_not_reached (); + + delete_idx = nmtst_get_rand_int () % 2; + + if (!nm_platform_ip4_route_delete (pl, ifindex[delete_idx], + nmtst_inet4_from_string ("192.168.200.0"), 24, 423, + nmtst_inet4_from_string (gateway[delete_idx]))) + g_assert_not_reached (); + if (nm_platform_ip4_route_get (pl, ifindex[delete_idx], + nmtst_inet4_from_string ("192.168.200.0"), 24, 423, + nmtst_inet4_from_string (gateway[delete_idx]))) + g_assert_not_reached (); + if (!nm_platform_ip4_route_get (pl, ifindex[!delete_idx], + nmtst_inet4_from_string ("192.168.200.0"), 24, 423, + nmtst_inet4_from_string (gateway[!delete_idx]))) + g_assert_not_reached (); + } + + nmtstp_link_del (pl, EX, ifindex[0], IF[0]); + nmtstp_link_del (pl, EX, ifindex[1], IF[1]); + + SETUP (); +} + +/*****************************************************************************/ + +static void +test_route_modify (gconstpointer test_data) +{ + const char *const MODE = test_data; + const gboolean EX = (nmtst_get_rand_int () % 3) - 1; + const char *IF = "IF0"; + int ifindex; + const char *gateway[2] = { + "192.168.181.1", + "192.168.181.2", + }; + guint idx[2] = { 0, 1, }; + guint i; + gs_unref_object NMPlatform *pl = NULL; + + g_assert (NM_IN_STRSET (MODE, "delete", "update")); + + g_object_unref (NM_PLATFORM_GET); + + pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + + nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx)); + + ifindex = nmtstp_link_dummy_add (pl, EX, IF)->ifindex; + nmtstp_link_set_updown (pl, EX, ifindex, TRUE); + + nmtstp_ip4_address_add (pl, EX, ifindex, + nmtst_inet4_from_string ("192.168.181.5"), 24, + nmtst_inet4_from_string ("192.168.181.5"), + NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL); + + nmtstp_run_command_check ("ip route add 192.168.213.0/24 via %s metric 423", gateway[idx[0]]); + if (nmtst_get_rand_int () % 2) { + nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24, + 423, nmtst_inet4_from_string (gateway[idx[0]]), 100); + } + + if (nmtst_get_rand_int () % 2) { + nmtstp_run_command_check ("ip route append 192.168.213.0/24 via %s metric 423", gateway[idx[1]]); + nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24, + 423, nmtst_inet4_from_string (gateway[idx[1]]), 100); + } else { + nmtstp_ip4_route_add (pl, EX, ifindex, NM_IP_CONFIG_SOURCE_RTPROT_BOOT, + nmtst_inet4_from_string ("192.168.213.0"), 24, + nmtst_inet4_from_string (gateway[idx[1]]), 0, + 423, 0); + } + + g_assert (nm_platform_ip4_route_get (pl, ifindex, + nmtst_inet4_from_string ("192.168.213.0"), 24, 423, + nmtst_inet4_from_string (gateway[idx[0]]))); + g_assert (nm_platform_ip4_route_get (pl, ifindex, + nmtst_inet4_from_string ("192.168.213.0"), 24, 423, + nmtst_inet4_from_string (gateway[idx[1]]))); + + nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx)); + + for (i = 0; i < G_N_ELEMENTS (idx); i++) { + const NMPlatformIP4Route *plroute; + + if (NM_IN_STRSET (MODE, "delete")) { + g_assert (nm_platform_ip4_route_delete (pl, ifindex, + nmtst_inet4_from_string ("192.168.213.0"), 24, 423, + nmtst_inet4_from_string (gateway[idx[i]]))); + g_assert (!nm_platform_ip4_route_get (pl, ifindex, + nmtst_inet4_from_string ("192.168.213.0"), 24, 423, + nmtst_inet4_from_string (gateway[idx[i]]))); + + plroute = nm_platform_ip4_route_get (pl, ifindex, + nmtst_inet4_from_string ("192.168.213.0"), 24, 423, + nmtst_inet4_from_string (gateway[idx[!i]])); + g_assert ((i == 0 && plroute) || (i == 1 && !plroute)); + } else if (NM_IN_STRSET (MODE, "update")) { + plroute = nmtstp_ip4_route_add (pl, FALSE, ifindex, NM_IP_CONFIG_SOURCE_USER, + nmtst_inet4_from_string ("192.168.213.0"), 24, + nmtst_inet4_from_string (gateway[idx[i]]), 0, + 423, 1400); + } + } + + nmtstp_link_del (pl, EX, ifindex, IF); + + SETUP (); +} + +/*****************************************************************************/ + void _nmtstp_init_tests (int *argc, char ***argv) { @@ -2335,6 +2503,11 @@ _nmtstp_setup_tests (void) g_test_add_data_func ("/link/create-many-links/20", GUINT_TO_POINTER (20), test_create_many_links); g_test_add_data_func ("/link/create-many-links/1000", GUINT_TO_POINTER (1000), test_create_many_links); + g_test_add_data_func ("/route/external/change", "change", test_route_external); + g_test_add_data_func ("/route/external/append", "append", test_route_external); + g_test_add_data_func ("/route/modify/delete", "delete", test_route_modify); + g_test_add_data_func ("/route/modify/update", "update", test_route_modify); + g_test_add_func ("/link/nl-bugs/veth", test_nl_bugs_veth); g_test_add_func ("/link/nl-bugs/spurious-newlink", test_nl_bugs_spuroius_newlink); g_test_add_func ("/link/nl-bugs/spurious-dellink", test_nl_bugs_spuroius_dellink); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 360404e944..a0b70c4e89 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -82,50 +82,50 @@ test_ip4_route_metric0 (void) int mss = 1000; /* No routes initially */ - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL); /* add the first route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss)); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); /* Deleting route with metric 0 does nothing */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0, INADDR_ANY)); 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); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); /* add the second route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss)); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); /* Delete route with metric 0 */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0, INADDR_ANY)); 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); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); /* 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 (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0, INADDR_ANY)); 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); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); /* Delete the other route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric, INADDR_ANY)); accept_signal (route_removed); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL); free_signal (route_added); free_signal (route_changed); @@ -156,9 +156,9 @@ test_ip4_route (void) accept_signal (route_added); /* Add route */ - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL); accept_signal (route_added); /* Add route again */ @@ -166,9 +166,9 @@ test_ip4_route (void) accept_signals (route_changed, 0, 1); /* Add default route */ - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric, NULL); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric, NULL); accept_signal (route_added); /* Add default route again */ @@ -207,12 +207,12 @@ test_ip4_route (void) g_array_unref (routes); /* Remove route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); + g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric, gateway)); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric, gateway)); free_signal (route_added); free_signal (route_changed); @@ -243,9 +243,9 @@ test_ip6_route (void) accept_signal (route_added); /* Add route */ - g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric, &gateway)); g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss)); - g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric, &gateway)); accept_signal (route_added); /* Add route again */ @@ -253,9 +253,9 @@ test_ip6_route (void) accept_signals (route_changed, 0, 1); /* Add default route */ - g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); + g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric, &gateway)); g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); - g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); + g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric, &gateway)); accept_signal (route_added); /* Add default route again */ @@ -291,12 +291,12 @@ test_ip6_route (void) g_array_unref (routes); /* Remove route */ - g_assert (nm_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)); + g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric, &gateway)); + g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric, &gateway)); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric, &gateway)); free_signal (route_added); free_signal (route_changed); @@ -315,8 +315,8 @@ test_ip4_zero_gateway (void) NMTST_WAIT_ASSERT (100, { nmtstp_wait_for_signal (NM_PLATFORM_GET, 10); - if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.1"), 32, 0) - && nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.2"), 32, 0)) + if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.1"), 32, 0, 0) + && nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.2"), 32, 0, 0)) break; }); diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c index b81c263c08..6fa5d72bff 100644 --- a/src/tests/test-route-manager.c +++ b/src/tests/test-route-manager.c @@ -791,9 +791,9 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM g_assert (route); if (vtable->is_ip4) - r = (const NMPlatformIPXRoute *) nm_platform_ip4_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r4.network, route->rx.plen, route->rx.metric); + r = (const NMPlatformIPXRoute *) nm_platform_ip4_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r4.network, route->rx.plen, route->rx.metric, route->r4.gateway); else - r = (const NMPlatformIPXRoute *) nm_platform_ip6_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r6.network, route->rx.plen, route->rx.metric); + r = (const NMPlatformIPXRoute *) nm_platform_ip6_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r6.network, route->rx.plen, route->rx.metric, &route->r6.gateway); if (!has) { g_assert (!r); |