summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-07-19 12:51:22 +0200
committerThomas Haller <thaller@redhat.com>2017-08-03 18:32:59 +0200
commit5a422af0d1a128989313727d787b585afb2451c4 (patch)
tree8fb41f173a31a05c1ff78a3ae7eb3efea5f143d5
parentb94e25e26969cad4703b3a2ceab2be798106ee2b (diff)
downloadNetworkManager-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.c8
-rw-r--r--src/platform/nm-platform.c8
-rw-r--r--src/platform/nm-platform.h10
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; \