diff options
author | Thomas Haller <thaller@redhat.com> | 2017-07-19 12:51:22 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-08-03 18:32:59 +0200 |
commit | 5a422af0d1a128989313727d787b585afb2451c4 (patch) | |
tree | 8fb41f173a31a05c1ff78a3ae7eb3efea5f143d5 | |
parent | b94e25e26969cad4703b3a2ceab2be798106ee2b (diff) | |
download | NetworkManager-5a422af0d1a128989313727d787b585afb2451c4.tar.gz |
platform: use proper rt_source of route for add and delete
_nl_msg_new_route() should not get extra arguments, but instead
use all parameters from the NMPObject argument. This will allow
during nm_platform_ip_route_delete() to pick the exact route
that should be deleted.
Also, in ip4_route_add()/ip6_route_add(), keep the stack-allocated
@obj object consistent with what we expect to add. That is, set
the rt_source argument to the value of what the route will have
after kernel adds it. That might be necessary, because
do_add_addrroute() searches the cache for @obj.
-rw-r--r-- | src/platform/nm-linux-platform.c | 8 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 8 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 10 |
3 files changed, 18 insertions, 8 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 8ee2321fd3..795e4680cd 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2419,7 +2419,6 @@ static struct nl_msg * _nl_msg_new_route (int nlmsg_type, int nlmsg_flags, const NMPObject *obj, - NMIPConfigSource source, unsigned char scope, gconstpointer gateway, guint32 mss, @@ -2440,7 +2439,7 @@ _nl_msg_new_route (int nlmsg_type, .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_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (obj->ip_route.rt_source), .rtm_scope = scope, .rtm_type = RTN_UNICAST, .rtm_flags = 0, @@ -5695,11 +5694,11 @@ ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route) 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); + r->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r->rt_source), nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, &obj, - route->rt_source, route->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, &route->gateway, route->mss, @@ -5725,11 +5724,11 @@ ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route) 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); + r->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r->rt_source), nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, &obj, - route->rt_source, IN6_IS_ADDR_UNSPECIFIED (&route->gateway) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE, &route->gateway, route->mss, @@ -5792,7 +5791,6 @@ ip_route_delete (NMPlatform *platform, nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, obj, - NM_IP_CONFIG_SOURCE_UNKNOWN, RT_SCOPE_NOWHERE, NULL, 0, diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 46d1db345d..b8443ccf1f 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -4749,8 +4749,10 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); h = NM_HASH_COMBINE (h, obj->plen); h = NM_HASH_COMBINE (h, obj->metric); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { h = NM_HASH_COMBINE (h, obj->ifindex); + h = NM_HASH_COMBINE (h, obj->rt_source); + } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: @@ -4800,8 +4802,10 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen)); NM_CMP_FIELD (a, b, plen); NM_CMP_FIELD (a, b, metric); - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { NM_CMP_FIELD (a, b, ifindex); + NM_CMP_FIELD (a, b, rt_source); + } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index e1be802276..7f14626d8f 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -329,7 +329,15 @@ typedef union { /* The NMIPConfigSource. For routes that we receive from cache this corresponds * to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values). * When adding a route, the source will be coerced to the protocol using - * nmp_utils_ip_config_source_coerce_to_rtprot(). */ \ + * nmp_utils_ip_config_source_coerce_to_rtprot(). + * + * rtm_protocol is part of the primary key of an IPv4 route (meaning, you can add + * two IPv4 routes that only differ in their rtm_protocol. For IPv6, that is not + * the case. + * + * When deleting an IPv4/IPv6 route, the rtm_protocol field must match (even + * if it is not part of the primary key for IPv6) -- unless rtm_protocol is set + * to zero, in which case the first matching route (with proto ignored) is deleted. */ \ NMIPConfigSource rt_source; \ \ guint8 plen; \ |