diff options
author | Thomas Haller <thaller@redhat.com> | 2017-07-26 09:25:21 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-08-03 18:33:00 +0200 |
commit | 8fc669c02ac3ec37161ba10b22eec8e3997ac501 (patch) | |
tree | 607d7ac7d8abe11f47463f2411bfe91809670e28 | |
parent | 415e00d086d52a6fddc1442bc058df951d630db1 (diff) | |
download | NetworkManager-8fc669c02ac3ec37161ba10b22eec8e3997ac501.tar.gz |
platform: use route src/src_plen when deleting IPv6 route
-rw-r--r-- | src/platform/nm-linux-platform.c | 27 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 22 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 8 |
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; }; |