platform: support pref option for IPv6 routes (RTA_PREF)
Support IPv6 router preference (RFC4191) in platform code.
This commit is contained in:
@@ -104,6 +104,11 @@
|
|||||||
#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
|
#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1));
|
||||||
|
#define RTA_PREF 20
|
||||||
|
#undef RTA_MAX
|
||||||
|
#define RTA_MAX (MAX ((__RTA_MAX - 1), RTA_PREF))
|
||||||
|
|
||||||
#ifndef MACVLAN_FLAG_NOPROMISC
|
#ifndef MACVLAN_FLAG_NOPROMISC
|
||||||
#define MACVLAN_FLAG_NOPROMISC 1
|
#define MACVLAN_FLAG_NOPROMISC 1
|
||||||
#endif
|
#endif
|
||||||
@@ -2020,6 +2025,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
[RTA_IIF] = { .type = NLA_U32 },
|
[RTA_IIF] = { .type = NLA_U32 },
|
||||||
[RTA_OIF] = { .type = NLA_U32 },
|
[RTA_OIF] = { .type = NLA_U32 },
|
||||||
[RTA_PRIORITY] = { .type = NLA_U32 },
|
[RTA_PRIORITY] = { .type = NLA_U32 },
|
||||||
|
[RTA_PREF] = { .type = NLA_U8 },
|
||||||
[RTA_FLOW] = { .type = NLA_U32 },
|
[RTA_FLOW] = { .type = NLA_U32 },
|
||||||
[RTA_CACHEINFO] = { .minlen = nm_offsetofend (struct rta_cacheinfo, rta_tsage) },
|
[RTA_CACHEINFO] = { .minlen = nm_offsetofend (struct rta_cacheinfo, rta_tsage) },
|
||||||
[RTA_METRICS] = { .type = NLA_NESTED },
|
[RTA_METRICS] = { .type = NLA_NESTED },
|
||||||
@@ -2224,6 +2230,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
obj->ip_route.lock_initrwnd = NM_FLAGS_HAS (lock, 1 << RTAX_INITRWND);
|
obj->ip_route.lock_initrwnd = NM_FLAGS_HAS (lock, 1 << RTAX_INITRWND);
|
||||||
obj->ip_route.lock_mtu = NM_FLAGS_HAS (lock, 1 << RTAX_MTU);
|
obj->ip_route.lock_mtu = NM_FLAGS_HAS (lock, 1 << RTAX_MTU);
|
||||||
|
|
||||||
|
if ( !is_v4
|
||||||
|
&& tb[RTA_PREF])
|
||||||
|
obj->ip6_route.rt_pref = nla_get_u8 (tb[RTA_PREF]);
|
||||||
|
|
||||||
if (NM_FLAGS_HAS (rtm->rtm_flags, RTM_F_CLONED)) {
|
if (NM_FLAGS_HAS (rtm->rtm_flags, RTM_F_CLONED)) {
|
||||||
/* we must not straight way reject cloned routes, because we might have cached
|
/* we must not straight way reject cloned routes, because we might have cached
|
||||||
* a non-cloned route. If we now receive an update of the route with the route
|
* a non-cloned route. If we now receive an update of the route with the route
|
||||||
@@ -2719,6 +2729,10 @@ _nl_msg_new_route (int nlmsg_type,
|
|||||||
}
|
}
|
||||||
NLA_PUT_U32 (msg, RTA_OIF, obj->ip_route.ifindex);
|
NLA_PUT_U32 (msg, RTA_OIF, obj->ip_route.ifindex);
|
||||||
|
|
||||||
|
if ( !is_v4
|
||||||
|
&& obj->ip6_route.rt_pref != NM_ICMPV6_ROUTER_PREF_MEDIUM)
|
||||||
|
NLA_PUT_U8 (msg, RTA_PREF, obj->ip6_route.rt_pref);
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
|
@@ -3873,6 +3873,16 @@ _ip_route_scope_inv_get_normalized (const NMPlatformIP4Route *route)
|
|||||||
return route->scope_inv;
|
return route->scope_inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint8
|
||||||
|
_route_pref_normalize (guint8 pref)
|
||||||
|
{
|
||||||
|
/* for kernel (and ICMPv6) pref can only have one of 3 values. Normalize. */
|
||||||
|
return NM_IN_SET (pref, NM_ICMPV6_ROUTER_PREF_LOW,
|
||||||
|
NM_ICMPV6_ROUTER_PREF_HIGH)
|
||||||
|
? pref
|
||||||
|
: NM_ICMPV6_ROUTER_PREF_MEDIUM;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_platform_ip_route_normalize:
|
* nm_platform_ip_route_normalize:
|
||||||
* @addr_family: AF_INET or AF_INET6
|
* @addr_family: AF_INET or AF_INET6
|
||||||
@@ -5053,6 +5063,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||||||
char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN], s_pref_src[INET6_ADDRSTRLEN];
|
char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN], s_pref_src[INET6_ADDRSTRLEN];
|
||||||
char s_src_all[INET6_ADDRSTRLEN + 40], s_src[INET6_ADDRSTRLEN];
|
char s_src_all[INET6_ADDRSTRLEN + 40], s_src[INET6_ADDRSTRLEN];
|
||||||
char str_table[30];
|
char str_table[30];
|
||||||
|
char str_pref[40];
|
||||||
|
char str_pref2[30];
|
||||||
char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50];
|
char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50];
|
||||||
char str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32];
|
char str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32];
|
||||||
|
|
||||||
@@ -5085,6 +5097,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||||||
"%s" /* initcwnd */
|
"%s" /* initcwnd */
|
||||||
"%s" /* initrwnd */
|
"%s" /* initrwnd */
|
||||||
"%s" /* mtu */
|
"%s" /* mtu */
|
||||||
|
"%s" /* pref */
|
||||||
"",
|
"",
|
||||||
route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "",
|
route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "",
|
||||||
s_network,
|
s_network,
|
||||||
@@ -5104,7 +5117,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||||||
route->cwnd || route->lock_cwnd ? nm_sprintf_buf (str_cwnd, " cwnd %s%"G_GUINT32_FORMAT, route->lock_cwnd ? "lock " : "", route->cwnd) : "",
|
route->cwnd || route->lock_cwnd ? nm_sprintf_buf (str_cwnd, " cwnd %s%"G_GUINT32_FORMAT, route->lock_cwnd ? "lock " : "", route->cwnd) : "",
|
||||||
route->initcwnd || route->lock_initcwnd ? nm_sprintf_buf (str_initcwnd, " initcwnd %s%"G_GUINT32_FORMAT, route->lock_initcwnd ? "lock " : "", route->initcwnd) : "",
|
route->initcwnd || route->lock_initcwnd ? nm_sprintf_buf (str_initcwnd, " initcwnd %s%"G_GUINT32_FORMAT, route->lock_initcwnd ? "lock " : "", route->initcwnd) : "",
|
||||||
route->initrwnd || route->lock_initrwnd ? nm_sprintf_buf (str_initrwnd, " initrwnd %s%"G_GUINT32_FORMAT, route->lock_initrwnd ? "lock " : "", route->initrwnd) : "",
|
route->initrwnd || route->lock_initrwnd ? nm_sprintf_buf (str_initrwnd, " initrwnd %s%"G_GUINT32_FORMAT, route->lock_initrwnd ? "lock " : "", route->initrwnd) : "",
|
||||||
route->mtu || route->lock_mtu ? nm_sprintf_buf (str_mtu, " mtu %s%"G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", route->mtu) : "");
|
route->mtu || route->lock_mtu ? nm_sprintf_buf (str_mtu, " mtu %s%"G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", route->mtu) : "",
|
||||||
|
route->rt_pref ? nm_sprintf_buf (str_pref, " pref %s", nm_icmpv6_router_pref_to_string (route->rt_pref, str_pref2, sizeof (str_pref2))) : "");
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@@ -5730,6 +5744,10 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT
|
|||||||
h = NM_HASH_COMBINE (h, obj->initcwnd);
|
h = NM_HASH_COMBINE (h, obj->initcwnd);
|
||||||
h = NM_HASH_COMBINE (h, obj->initrwnd);
|
h = NM_HASH_COMBINE (h, obj->initrwnd);
|
||||||
h = NM_HASH_COMBINE (h, obj->mtu);
|
h = NM_HASH_COMBINE (h, obj->mtu);
|
||||||
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
||||||
|
h = NM_HASH_COMBINE (h, _route_pref_normalize (obj->rt_pref));
|
||||||
|
else
|
||||||
|
h = NM_HASH_COMBINE (h, obj->rt_pref);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5796,6 +5814,10 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
|
|||||||
NM_CMP_FIELD (a, b, initcwnd);
|
NM_CMP_FIELD (a, b, initcwnd);
|
||||||
NM_CMP_FIELD (a, b, initrwnd);
|
NM_CMP_FIELD (a, b, initrwnd);
|
||||||
NM_CMP_FIELD (a, b, mtu);
|
NM_CMP_FIELD (a, b, mtu);
|
||||||
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
||||||
|
NM_CMP_DIRECT (_route_pref_normalize (a->rt_pref), _route_pref_normalize (b->rt_pref));
|
||||||
|
else
|
||||||
|
NM_CMP_FIELD (a, b, rt_pref);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -517,6 +517,12 @@ struct _NMPlatformIP6Route {
|
|||||||
*/
|
*/
|
||||||
struct in6_addr src;
|
struct in6_addr src;
|
||||||
guint8 src_plen;
|
guint8 src_plen;
|
||||||
|
|
||||||
|
/* RTA_PREF router preference.
|
||||||
|
*
|
||||||
|
* The type is guint8 to keep the struct size small. But the values are compatible with
|
||||||
|
* the NMIcmpv6RouterPref enum. */
|
||||||
|
guint8 rt_pref;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
Reference in New Issue
Block a user