From 697b9864df221703e405bc8ef805336aba4dbc39 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Mar 2019 08:53:31 +0100 Subject: [PATCH] platform/tests: adjust probabilities for generating randomized rules The routing-rule tests generate a number of routing rules and tries to add and delete them. For that, _rule_create_random() sets random fields of the rule. Note that especially interesting are rules that leave most fields unset (at zero), because they trigger kernel issues rh#1686075 and rh#1685816. But a rule has many fields, so in order to generate rules that have most fields unset, we need to use low probabilities when rolling the dice for setting a field. Otherwise, most rules end up with several fields set and don't reproduce the kernel issue (especially the test failed to hit rh#1686075). --- src/platform/tests/test-route.c | 185 ++++++++++++++++---------------- 1 file changed, 90 insertions(+), 95 deletions(-) diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 6e01b0b067..995da9ff21 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -1067,6 +1067,28 @@ _platform_has_routing_rule (NMPlatform *platform, return o; } +static guint32 +_rr_rand_choose_u32 (guint32 p) +{ + /* mostly, we just return zero. We want that each rule only has few + * fields set -- having most fields at zero. */ + if ((p % 10000u) < 7500u) + return 0; + + /* give 0xFFFFFFFFu extra probability. */ + if ((p % 10000u) < 8250u) + return 0xFFFFFFFFu; + + /* choose a small number. */ + if ((p % 10000u) < 9125u) + return (~p) % 10; + + /* finally, full random number. */ + return ~p; +} + +#define _rr_rand_choose_u8(p) ((guint8) _rr_rand_choose_u32 ((p))) + static const NMPObject * _rule_create_random (NMPlatform *platform) { @@ -1095,81 +1117,74 @@ _rule_create_random (NMPlatform *platform) addr_size = nm_utils_addr_family_to_size (rr->addr_family); - p = nmtst_get_rand_int () % 1000u; - if (p < 250) - rr->priority = 10000 + (p / 50); + p = nmtst_get_rand_int (); + if ((p % 1000u) < 50) + rr->priority = 10000 + ((~p) % 20u); - p = nmtst_get_rand_int () % 1000u; - if (p < 60) - nm_sprintf_buf (rr->iifname, "t-iif-%u", p / 20); - else if (p < 120) + p = nmtst_get_rand_int (); + if ((p % 1000u) < 40) + nm_sprintf_buf (rr->iifname, "t-iif-%u", (~p) % 20); + else if ((p % 1000u) < 80) nm_sprintf_buf (rr->iifname, "%s", DEVICE_NAME); - p = nmtst_get_rand_int () % 1000u; - if (p < 60) - nm_sprintf_buf (rr->oifname, "t-oif-%d", p / 20); - else if (p < 120) + p = nmtst_get_rand_int (); + if ((p % 1000u) < 40) + nm_sprintf_buf (rr->oifname, "t-oif-%d", (~p) % 20); + else if ((p % 1000u) < 80) nm_sprintf_buf (rr->oifname, "%s", DEVICE_NAME); - p = nmtst_get_rand_int () % 1000u; - if (p < 60) - nm_sprintf_buf (rr->iifname, "t-iif-%d", p / 20); - else if (p < 120) - nm_sprintf_buf (rr->iifname, "%s", DEVICE_NAME); - for (i = 0; i < 2; i++) { NMIPAddr *p_addr = i ? &rr->src : &rr->dst; guint8 *p_len = i ? &rr->src_len : &rr->dst_len; - p = nmtst_get_rand_int () % 1000u; - if (p < 300) { + p = nmtst_get_rand_int (); + if ((p % 1000u) < 100) { /* if we set src_len/dst_len to zero, the src/dst is actually ignored. * * For fuzzying, still set the address. It shall have no further effect. * */ - *p_len = p % (addr_size * 8 + 1); - p = nmtst_get_rand_int () % 750; - if (p <= 255) { + *p_len = (~p) % (addr_size * 8 + 1); + p = nmtst_get_rand_int (); + if ((p % 3u) == 0) { if (rr->addr_family == AF_INET) - p_addr->addr4 = nmtst_inet4_from_string (nm_sprintf_buf (saddr, "192.192.5.%u", p)); + p_addr->addr4 = nmtst_inet4_from_string (nm_sprintf_buf (saddr, "192.192.5.%u", (~p) % 256u)); else - p_addr->addr6 = *nmtst_inet6_from_string (nm_sprintf_buf (saddr, "1:2:3:4::f:%02x", p)); - } else if (p <= 512) + p_addr->addr6 = *nmtst_inet6_from_string (nm_sprintf_buf (saddr, "1:2:3:4::f:%02x", (~p) % 256u)); + } else if ((p % 3u) == 1) nmtst_rand_buf (NULL, p_addr, addr_size); } } - p = nmtst_get_rand_int () % 1000u; - if (p < 50) - rr->tun_id = 10000 + p; + p = nmtst_get_rand_int (); + if ((p % 1000u) < 50) + rr->tun_id = 10000 + ((~p) % 20); again_action: - p = nmtst_get_rand_int () % 1000u; - if (p < 300) + p = nmtst_get_rand_int (); + if ((p % 1000u) < 500) rr->action = FR_ACT_UNSPEC; - else if (p < 700) - rr->action = p % 12; + else if ((p % 1000u) < 750) + rr->action = (~p) % 12u; else - rr->action = p % 0xFF; + rr->action = (~p) % 0x100u; + + rr->priority = _rr_rand_choose_u32 (nmtst_get_rand_int ()); - rr->priority = nmtst_rand_select (0, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ()); if ( rr->action == FR_ACT_GOTO && rr->priority == G_MAXINT32) goto again_action; -again_goto_target: - rr->goto_target = nmtst_rand_select (0, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int (), - rr->priority + 1); + p = nmtst_get_rand_int (); + if ((p % 10000u) < 100) + rr->goto_target = rr->priority + 1; + else + rr->goto_target = _rr_rand_choose_u32 (nmtst_get_rand_int ()); if ( rr->action == FR_ACT_GOTO && rr->goto_target <= rr->priority) - goto again_goto_target; + goto again_action; - p = nmtst_get_rand_int () % 1000u; - if (p < 50) { + p = nmtst_get_rand_int (); + if ((p % 1000u) < 25) { if (_rule_check_kernel_support (platform, FRA_L3MDEV)) { rr->l3mdev = TRUE; rr->table = RT_TABLE_UNSPEC; @@ -1178,78 +1193,58 @@ again_goto_target: again_table: if (!rr->l3mdev) { - rr->table = nmtst_rand_select (RT_TABLE_UNSPEC, - RT_TABLE_MAIN, - 10000 + nmtst_get_rand_int () % 10); + p = nmtst_get_rand_int (); + if ((p % 1000u) < 700) + rr->table = RT_TABLE_UNSPEC; + else if ((p % 1000u) < 850) + rr->table = RT_TABLE_MAIN; + else + rr->table = 10000 + ((~p) % 10); if ( rr->action == FR_ACT_TO_TBL && rr->table == RT_TABLE_UNSPEC) goto again_table; } - rr->fwmark = nmtst_rand_select (0, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ()); - rr->fwmask = nmtst_rand_select (0u, - 0xFFFFFFFFu, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ()); + rr->fwmark = _rr_rand_choose_u32 (nmtst_get_rand_int ()); + rr->fwmask = _rr_rand_choose_u32 (nmtst_get_rand_int ()); - rr->flow = nmtst_rand_select (0u, - 0xFFFFFFFFu, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ()); + rr->flow = _rr_rand_choose_u32 (nmtst_get_rand_int ()); - if (_rule_check_kernel_support (platform, FRA_PROTOCOL)) { - rr->protocol = nmtst_rand_select (0u, - 255u, - nmtst_get_rand_int () % 256); - } + if (_rule_check_kernel_support (platform, FRA_PROTOCOL)) + rr->protocol = _rr_rand_choose_u8 (nmtst_get_rand_int ()); #define IPTOS_TOS_MASK 0x1E again_tos: - rr->tos = nmtst_rand_select (0u, - 255u, - nmtst_get_rand_int () % 256); + rr->tos = _rr_rand_choose_u8 (nmtst_get_rand_int ()); if ( rr->addr_family == AF_INET && rr->tos & ~IPTOS_TOS_MASK) goto again_tos; - if (_rule_check_kernel_support (platform, FRA_IP_PROTO)) { - rr->ip_proto = nmtst_rand_select (0u, - 255u, - nmtst_get_rand_int () % 256); - } + if (_rule_check_kernel_support (platform, FRA_IP_PROTO)) + rr->ip_proto = _rr_rand_choose_u8 (nmtst_get_rand_int ()); - if (_rule_check_kernel_support (platform, FRA_SUPPRESS_PREFIXLEN)) { - rr->suppress_prefixlen_inverse = ~((guint32) nmtst_rand_select (0u, - 0xFFFFFFFFu, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ())); - } + if (_rule_check_kernel_support (platform, FRA_SUPPRESS_PREFIXLEN)) + rr->suppress_prefixlen_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_int ()); - if (_rule_check_kernel_support (platform, FRA_SUPPRESS_IFGROUP)) { - rr->suppress_ifgroup_inverse = ~((guint32) nmtst_rand_select (0u, - 0xFFFFFFFFu, - nmtst_get_rand_int () % 100, - nmtst_get_rand_int ())); + if (_rule_check_kernel_support (platform, FRA_SUPPRESS_IFGROUP)) + rr->suppress_ifgroup_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_int ()); + + if (_rule_check_kernel_support (platform, FRA_UID_RANGE)) { + p = nmtst_get_rand_int (); + rr->uid_range_has = (p % 10000u) < 200; } again_uid_range: - p = nmtst_get_rand_int () % 1000u; - if (p < 100) { - if (_rule_check_kernel_support (platform, FRA_UID_RANGE)) - rr->uid_range_has = TRUE; - } - rr->uid_range.start = nmtst_rand_select (0u, uids.uid, uids.euid); rr->uid_range.end = nmtst_rand_select (0u, uids.uid, uids.euid); - if (rr->uid_range.end < rr->uid_range.start) - NMTST_SWAP (rr->uid_range.start, rr->uid_range.end); - - if ( rr->uid_range.start == ((guint32) -1) - || rr->uid_range.end == ((guint32) -1)) - goto again_uid_range; + if (rr->uid_range_has) { + if (rr->uid_range.end < rr->uid_range.start) + NMTST_SWAP (rr->uid_range.start, rr->uid_range.end); + if ( rr->uid_range.start == ((guint32) -1) + || rr->uid_range.end == ((guint32) -1)) + goto again_uid_range; + } for (i = 0; i < 2; i++) { NMFibRulePortRange *range = i ? &rr->sport_range : &rr->dport_range; @@ -1259,7 +1254,7 @@ again_uid_range: continue; p = nmtst_get_rand_int (); - if ((p % 1000u) < 100) { + if ((p % 10000u) < 300) { while (range->start == 0) { p = p ^ nmtst_get_rand_int (); range->start = nmtst_rand_select (1u, 0xFFFEu, ((p ) % 0xFFFEu) + 1);