mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-02 15:50:13 +01:00
platform: add support for blackhole,unreachable,prohibit route type
(cherry picked from commit 92f51c6b43)
This commit is contained in:
parent
bd08f8e81c
commit
a2030c01ce
3 changed files with 108 additions and 8 deletions
|
|
@ -1886,6 +1886,64 @@ again:
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_blackhole(gconstpointer test_data)
|
||||
{
|
||||
int TEST_IDX = GPOINTER_TO_INT(test_data);
|
||||
const int addr_family = (TEST_IDX == 1) ? AF_INET : AF_INET6;
|
||||
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
NMDedupMultiIter iter;
|
||||
const NMPObject *obj;
|
||||
NMPObject obj_stack;
|
||||
NMPlatformIPXRoute rr = {};
|
||||
int r = -1;
|
||||
int i;
|
||||
|
||||
if (IS_IPv4) {
|
||||
rr.r4 = (const NMPlatformIP4Route){
|
||||
.type_coerced = nmtst_rand_select(RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT),
|
||||
};
|
||||
} else {
|
||||
rr.r6 = (const NMPlatformIP6Route){
|
||||
.type_coerced = nmtst_rand_select(RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT),
|
||||
.metric = 1000,
|
||||
};
|
||||
}
|
||||
|
||||
nm_platform_ip_route_normalize(addr_family, &rr.rx);
|
||||
|
||||
if (IS_IPv4)
|
||||
r = nm_platform_ip4_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_APPEND, &rr.r4);
|
||||
else
|
||||
r = nm_platform_ip6_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_APPEND, &rr.r6);
|
||||
|
||||
g_assert_cmpint(r, ==, 0);
|
||||
|
||||
nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), &rr);
|
||||
|
||||
obj = nm_platform_lookup_obj(NM_PLATFORM_GET, NMP_CACHE_ID_TYPE_OBJECT_TYPE, &obj_stack);
|
||||
|
||||
_LOGT(">>> adding %s",
|
||||
nmp_object_to_string(&obj_stack, NMP_OBJECT_TO_STRING_ALL, g_alloca(1000), 1000));
|
||||
_LOGT(">>> found %s",
|
||||
nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_ALL, g_alloca(1000), 1000));
|
||||
|
||||
g_assert(obj);
|
||||
|
||||
head_entry = nm_platform_lookup_object(NM_PLATFORM_GET, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), 0);
|
||||
g_assert(head_entry);
|
||||
g_assert_cmpint(head_entry->len, ==, 1);
|
||||
i = 0;
|
||||
nm_dedup_multi_iter_for_each (&iter, head_entry) {
|
||||
i++;
|
||||
g_assert(iter.current->obj == obj);
|
||||
}
|
||||
g_assert_cmpint(i, ==, 1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
|
||||
|
||||
void
|
||||
|
|
@ -1923,4 +1981,8 @@ _nmtstp_setup_tests(void)
|
|||
add_test_func_data("/route/rule/3", test_rule, GINT_TO_POINTER(3));
|
||||
add_test_func_data("/route/rule/4", test_rule, GINT_TO_POINTER(4));
|
||||
}
|
||||
if (nmtstp_is_root_test()) {
|
||||
add_test_func_data("/route/blackhole/1", test_blackhole, GINT_TO_POINTER(1));
|
||||
add_test_func_data("/route/blackhole/2", test_blackhole, GINT_TO_POINTER(2));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3423,7 +3423,12 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
|
|||
else
|
||||
return NULL;
|
||||
|
||||
if (!NM_IN_SET(rtm->rtm_type, RTN_UNICAST, RTN_LOCAL))
|
||||
if (!NM_IN_SET(rtm->rtm_type,
|
||||
RTN_UNICAST,
|
||||
RTN_LOCAL,
|
||||
RTN_BLACKHOLE,
|
||||
RTN_UNREACHABLE,
|
||||
RTN_PROHIBIT))
|
||||
return NULL;
|
||||
|
||||
if (nlmsg_parse_arr(nlh, sizeof(struct rtmsg), tb, policy) < 0)
|
||||
|
|
@ -3497,16 +3502,45 @@ rta_multipath_done:;
|
|||
/* If no nexthops have been provided via RTA_MULTIPATH
|
||||
* we add it as regular nexthop to maintain backwards
|
||||
* compatibility */
|
||||
nh.ifindex = ifindex;
|
||||
nh.gateway = gateway;
|
||||
nh.ifindex = ifindex;
|
||||
nh.gateway = gateway;
|
||||
nh.is_present = TRUE;
|
||||
} else {
|
||||
/* Kernel supports new style nexthop configuration,
|
||||
* verify that it is a duplicate and ignore old-style nexthop. */
|
||||
if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0)
|
||||
return NULL;
|
||||
}
|
||||
} else if (!nh.is_present)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nm_platform_route_type_is_nodev(rtm->rtm_type)) {
|
||||
/* These routes are special. They don't have an device/ifindex.
|
||||
*
|
||||
* Well, actually, for IPv6 kernel will always say that the device is
|
||||
* 1 (lo). Of course it does!! */
|
||||
if (nh.is_present) {
|
||||
if (IS_IPv4) {
|
||||
if (nh.ifindex != 0 || nh.gateway.addr4 != 0) {
|
||||
/* we only accept kernel to notify about the ifindex/gateway, if it
|
||||
* is zero. This is only to be a bit forgiving, but we really don't
|
||||
* know how to handle such routes that have an ifindex. */
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (!NM_IN_SET(nh.ifindex, 0, 1) || !IN6_IS_ADDR_UNSPECIFIED(&nh.gateway.addr6)) {
|
||||
/* We allow an ifindex of 1 (will be normalized to zero). Otherwise,
|
||||
* we don't expect a device/next hop. */
|
||||
return NULL;
|
||||
}
|
||||
nh.ifindex = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!nh.is_present) {
|
||||
/* a "normal" route needs a device. This is not the route we are looking for. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -386,7 +386,11 @@ _idx_obj_part(const DedupMultiIdxType *idx_type,
|
|||
nm_hash_update_val(h, obj_a);
|
||||
return 0;
|
||||
}
|
||||
nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0);
|
||||
nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0
|
||||
|| (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex == 0
|
||||
&& NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a),
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE)));
|
||||
if (obj_b) {
|
||||
return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b)
|
||||
&& NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex
|
||||
|
|
@ -401,14 +405,14 @@ _idx_obj_part(const DedupMultiIdxType *idx_type,
|
|||
case NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID:
|
||||
obj_type = NMP_OBJECT_GET_TYPE(obj_a);
|
||||
if (!NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)
|
||||
|| NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex <= 0) {
|
||||
|| NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex < 0) {
|
||||
if (h)
|
||||
nm_hash_update_val(h, obj_a);
|
||||
return 0;
|
||||
}
|
||||
if (obj_b) {
|
||||
return obj_type == NMP_OBJECT_GET_TYPE(obj_b)
|
||||
&& NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex > 0
|
||||
&& NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex >= 0
|
||||
&& (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
|
||||
? (nm_platform_ip4_route_cmp(&obj_a->ip4_route,
|
||||
&obj_b->ip4_route,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue