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.
This commit is contained in:
Thomas Haller 2017-07-19 12:51:22 +02:00
parent b94e25e269
commit 5a422af0d1
3 changed files with 18 additions and 8 deletions

View file

@ -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,

View file

@ -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:

View file

@ -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; \