summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-07-26 09:25:21 +0200
committerThomas Haller <thaller@redhat.com>2017-08-03 18:33:00 +0200
commit8fc669c02ac3ec37161ba10b22eec8e3997ac501 (patch)
tree607d7ac7d8abe11f47463f2411bfe91809670e28
parent415e00d086d52a6fddc1442bc058df951d630db1 (diff)
downloadNetworkManager-8fc669c02ac3ec37161ba10b22eec8e3997ac501.tar.gz
platform: use route src/src_plen when deleting IPv6 route
-rw-r--r--src/platform/nm-linux-platform.c27
-rw-r--r--src/platform/nm-platform.c22
-rw-r--r--src/platform/nm-platform.h8
3 files changed, 39 insertions, 18 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 7022dc0bb9..85f63e777d 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -2018,9 +2018,11 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
memcpy (&obj->ip6_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len);
}
- if (!is_v4 && tb[RTA_SRC]) {
- _check_addr_or_errout (tb, RTA_SRC, addr_len);
- memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
+ if (!is_v4) {
+ if (tb[RTA_SRC]) {
+ _check_addr_or_errout (tb, RTA_SRC, addr_len);
+ memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
+ }
obj->ip6_route.src_plen = rtm->rtm_src_len;
}
@@ -2419,8 +2421,6 @@ static struct nl_msg *
_nl_msg_new_route (int nlmsg_type,
int nlmsg_flags,
const NMPObject *obj,
- gconstpointer src,
- guint8 src_plen,
guint32 window,
guint32 cwnd,
guint32 initcwnd,
@@ -2442,7 +2442,9 @@ _nl_msg_new_route (int nlmsg_type,
.rtm_type = RTN_UNICAST,
.rtm_flags = 0,
.rtm_dst_len = obj->ip_route.plen,
- .rtm_src_len = src ? src_plen : 0,
+ .rtm_src_len = is_v4
+ ? 0
+ : NMP_OBJECT_CAST_IP6_ROUTE (obj)->src_plen,
};
gsize addr_len;
@@ -2466,8 +2468,10 @@ _nl_msg_new_route (int nlmsg_type,
? (gconstpointer) &obj->ip4_route.network
: (gconstpointer) &obj->ip6_route.network);
- if (src)
- NLA_PUT (msg, RTA_SRC, addr_len, src);
+ if (!is_v4) {
+ if (!IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (obj)->src))
+ NLA_PUT (msg, RTA_SRC, addr_len, &obj->ip6_route.src);
+ }
NLA_PUT_U32 (msg, RTA_PRIORITY, obj->ip_route.metric);
@@ -5708,8 +5712,6 @@ ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_REPLACE,
&obj,
- NULL,
- 0,
route->window,
route->cwnd,
route->initcwnd,
@@ -5730,12 +5732,11 @@ ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *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),
+ nm_utils_ip6_address_clear_host_address (&r->src, &r->src, r->src_plen);
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_REPLACE,
&obj,
- !IN6_IS_ADDR_UNSPECIFIED (&route->src) ? &route->src : NULL,
- route->src_plen,
route->window,
route->cwnd,
route->initcwnd,
@@ -5792,8 +5793,6 @@ ip_route_delete (NMPlatform *platform,
nlmsg = _nl_msg_new_route (RTM_DELROUTE,
0,
obj,
- NULL,
- 0,
0,
0,
0,
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 47d4946009..9b2d1adb70 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -4864,6 +4864,8 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT
h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen);
h = NM_HASH_COMBINE (h, obj->plen);
h = NM_HASH_COMBINE (h, obj->metric);
+ h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->src, obj->src_plen);
+ h = NM_HASH_COMBINE (h, obj->src_plen);
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
h = NM_HASH_COMBINE (h, obj->ifindex);
h = NM_HASH_COMBINE_IN6ADDR (h, &obj->gateway);
@@ -4880,8 +4882,13 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT
h = NM_HASH_COMBINE (h, obj->metric);
h = NM_HASH_COMBINE_IN6ADDR (h, &obj->gateway);
h = NM_HASH_COMBINE_IN6ADDR (h, &obj->pref_src);
- h = NM_HASH_COMBINE_IN6ADDR (h, &obj->src);
- h = NM_HASH_COMBINE (h, obj->src_plen);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
+ h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->src, obj->src_plen);
+ h = NM_HASH_COMBINE (h, obj->src_plen);
+ } else {
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->src);
+ h = NM_HASH_COMBINE (h, obj->src_plen);
+ }
h = NM_HASH_COMBINE (h, obj->rt_source);
h = NM_HASH_COMBINE (h, obj->mss);
h = NM_HASH_COMBINE (h, obj->rt_cloned);
@@ -4918,6 +4925,8 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen));
NM_CMP_FIELD (a, b, plen);
NM_CMP_FIELD (a, b, metric);
+ NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->src, &b->src, MIN (a->src_plen, b->src_plen));
+ NM_CMP_FIELD (a, b, src_plen);
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
NM_CMP_FIELD (a, b, ifindex);
NM_CMP_FIELD_IN6ADDR (a, b, gateway);
@@ -4934,8 +4943,13 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
NM_CMP_FIELD (a, b, metric);
NM_CMP_FIELD_IN6ADDR (a, b, gateway);
NM_CMP_FIELD_IN6ADDR (a, b, pref_src);
- NM_CMP_FIELD_IN6ADDR (a, b, src);
- NM_CMP_FIELD (a, b, src_plen);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
+ NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->src, &b->src, MIN (a->src_plen, b->src_plen));
+ NM_CMP_FIELD (a, b, src_plen);
+ } else {
+ NM_CMP_FIELD_IN6ADDR (a, b, src);
+ NM_CMP_FIELD (a, b, src_plen);
+ }
NM_CMP_FIELD (a, b, rt_source);
NM_CMP_FIELD (a, b, mss);
NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 9b2e789c37..66c720aee1 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -426,6 +426,14 @@ struct _NMPlatformIP6Route {
* When deleting a route, pref_src is ignored by kernel. */
struct in6_addr pref_src;
+ /* RTA_SRC and rtm_src_len (called "from" by iproute2).
+ *
+ * Kernel clears the host part of src/src_plen.
+ *
+ * src/src_plen is part of the ID of a route just like network/plen. That is,
+ * Not only `ip route append`, but also `ip route add` allows to add routes that only
+ * differ in their src/src_plen.
+ */
struct in6_addr src;
guint8 src_plen;
};