platform: use route src/src_plen when deleting IPv6 route

This commit is contained in:
Thomas Haller 2017-07-26 09:25:21 +02:00
parent 415e00d086
commit 8fc669c02a
3 changed files with 39 additions and 18 deletions

View file

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

View file

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

View file

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