mirror of https://github.com/containers/podman.git
Merge pull request #20494 from edsantiago/systest_subnet_check
CI: systest: safer random_rfc1918_subnet
This commit is contained in:
commit
c3fae01368
|
@ -126,11 +126,13 @@ function random_rfc1918_subnet() {
|
|||
local retries=1024
|
||||
|
||||
while [ "$retries" -gt 0 ];do
|
||||
local cidr=172.$(( 16 + $RANDOM % 16 )).$(( $RANDOM & 255 ))
|
||||
# 172.16.0.0 -> 172.31.255.255
|
||||
local n1=172
|
||||
local n2=$(( 16 + $RANDOM & 15 ))
|
||||
local n3=$(( $RANDOM & 255 ))
|
||||
|
||||
in_use=$(ip route list | grep -F $cidr)
|
||||
if [ -z "$in_use" ]; then
|
||||
echo "$cidr"
|
||||
if ! subnet_in_use $n1 $n2 $n3; then
|
||||
echo "$n1.$n2.$n3"
|
||||
return
|
||||
fi
|
||||
|
||||
|
@ -140,6 +142,69 @@ function random_rfc1918_subnet() {
|
|||
die "Could not find a random not-in-use rfc1918 subnet"
|
||||
}
|
||||
|
||||
# subnet_in_use() - true if subnet already routed on host
|
||||
function subnet_in_use() {
|
||||
local subnet_script=${PODMAN_TMPDIR-/var/tmp}/subnet-in-use
|
||||
rm -f $subnet_script
|
||||
|
||||
# This would be a nightmare to do in bash. ipcalc, ipcalc-ng, sipcalc
|
||||
# would be nice but are unavailable some environments (cough RHEL).
|
||||
# Likewise python/perl netmask modules. So, use bare-bones perl.
|
||||
cat >$subnet_script <<"EOF"
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# 3 octets, in binary: 172.16.x -> 1010 1100 0000 1000 xxxx xxxx ...
|
||||
my $subnet_to_check = sprintf("%08b%08b%08b", @ARGV);
|
||||
|
||||
my $found = 0;
|
||||
|
||||
# Input is "ip route list", one or more lines like '10.0.0.0/8 via ...'
|
||||
while (<STDIN>) {
|
||||
# Only interested in x.x.x.x/n lines
|
||||
if (m!^([\d.]+)/(\d+)!) {
|
||||
my ($ip, $bits) = ($1, $2);
|
||||
|
||||
# Our caller has /24 granularity, so treat /30 on host as /24.
|
||||
$bits = 24 if $bits > 24;
|
||||
|
||||
# Temporary: entire subnet as binary string. 4 octets, split,
|
||||
# then represented as a 32-bit binary string.
|
||||
my $net = sprintf("%08b%08b%08b%08b", split(/\./, $ip));
|
||||
|
||||
# Now truncate those 32 bits down to the route's netmask size.
|
||||
# This is the actual subnet range in use on the host.
|
||||
my $net_truncated = sprintf("%.*s", $bits, $net);
|
||||
|
||||
# Desired subnet is in use if it matches a host route prefix
|
||||
# print STDERR "--- $subnet_to_check in $net_truncated (@ARGV in $ip/$bits)\n";
|
||||
$found = 1 if $subnet_to_check =~ /^$net_truncated/;
|
||||
}
|
||||
}
|
||||
|
||||
# Convert to shell exit status (0 = success)
|
||||
exit !$found;
|
||||
EOF
|
||||
|
||||
chmod 755 $subnet_script
|
||||
|
||||
# This runs 'ip route list', converts x.x.x.x/n to its binary prefix,
|
||||
# then checks if our desired subnet matches that prefix (i.e. is in
|
||||
# that range). Existing routes with size greater than 24 are
|
||||
# normalized to /24 because that's the granularity of our
|
||||
# random_rfc1918_subnet code.
|
||||
#
|
||||
# Contrived examples:
|
||||
# 127.0.0.0/1 -> 0
|
||||
# 128.0.0.0/1 -> 1
|
||||
# 10.0.0.0/8 -> 00001010
|
||||
#
|
||||
# I'm so sorry for the ugliness.
|
||||
ip route list | $subnet_script $*
|
||||
}
|
||||
|
||||
# ipv4_get_route_default() - Print first default IPv4 route reported by netlink
|
||||
# $1: Optional output of 'ip -j -4 route show' from a different context
|
||||
function ipv4_get_route_default() {
|
||||
|
|
|
@ -18,6 +18,10 @@ die() {
|
|||
testnum=0
|
||||
rc=0
|
||||
|
||||
# Possibly used by the code we're testing
|
||||
PODMAN_TMPDIR=$(mktemp -d --tmpdir=${TMPDIR:-/tmp} podman_helper_tests.XXXXXX)
|
||||
trap 'rm -rf $PODMAN_TMPDIR' 0
|
||||
|
||||
###############################################################################
|
||||
# BEGIN test the parse_table helper
|
||||
|
||||
|
@ -242,6 +246,42 @@ done < <(parse_table "$table")
|
|||
|
||||
# END ipv6_to_procfs
|
||||
###############################################################################
|
||||
# BEGIN subnet_in_use ... because that's complicated
|
||||
|
||||
# Override ip command
|
||||
function ip() {
|
||||
echo "default foo"
|
||||
echo "192.168.0.0/16"
|
||||
echo "172.17.2.3/30"
|
||||
echo "172.128.0.0/9"
|
||||
}
|
||||
|
||||
# x.y.z | result (1 = in use, 0 = not in use - opposite of exit code)
|
||||
table="
|
||||
172 | 0 | 0 | 0
|
||||
172 | 0 | 255 | 0
|
||||
172 | 1 | 1 | 0
|
||||
172 | 1 | 2 | 0
|
||||
172 | 1 | 3 | 0
|
||||
172 | 17 | 1 | 0
|
||||
172 | 17 | 2 | 1
|
||||
172 | 17 | 3 | 0
|
||||
172 | 127 | 0 | 0
|
||||
172 | 128 | 0 | 1
|
||||
172 | 255 | 2 | 1
|
||||
192 | 168 | 1 | 1
|
||||
"
|
||||
|
||||
while read n1 n2 n3 expect; do
|
||||
subnet_in_use $n1 $n2 $n3
|
||||
actual=$?
|
||||
check_result "$((1 - $actual))" "$expect" "subnet_in_use $n1.$n2.$n3"
|
||||
done < <(parse_table "$table")
|
||||
|
||||
unset -f ip
|
||||
|
||||
# END subnet_in_use
|
||||
###############################################################################
|
||||
# BEGIN check_assert
|
||||
#
|
||||
# This is way, way more complicated than it should be. The purpose is
|
||||
|
|
Loading…
Reference in New Issue