From bc1ad5fdcdff10be1c87364413d13cd47f76f4ea Mon Sep 17 00:00:00 2001 From: Oliver Kurz Date: Sun, 12 Jul 2020 21:17:41 +0200 Subject: [PATCH] Make local VM host IPs '10.0.2.2' configurable Related progress issue: https://progress.opensuse.org/issues/68851 --- doc/backend_vars.asciidoc | 1 + doc/networking.md | 20 +++++++++++++------- os-autoinst-openvswitch | 28 +++++++++++++++++----------- t/03-testapi.t | 2 ++ testapi.pm | 4 ++-- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/doc/backend_vars.asciidoc b/doc/backend_vars.asciidoc index db6fe323..0eabe0c7 100644 --- a/doc/backend_vars.asciidoc +++ b/doc/backend_vars.asciidoc @@ -107,6 +107,7 @@ QEMUVGA;see qemu -device ?;cirrus;VGA device to use with VM QEMU_COMPRESS_QCOW2;boolean;1;compress qcow2 images intended for upload QEMU_IMG_CREATE_TRIES;integer;3;Define number of tries for qemu-img commands QEMU_HUGE_PAGES_PATH;string;undef;Define a path to use huge pages (e.g. /dev/hugepages/) +QEMU_HOST_IP;string;10.0.2.2;The VM host IP used in usermode networking. Set `NICTYPE=user` and NICTYPE_USER_OPTIONS accordingly to match following https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29 QEMU_MAX_MIGRATION_TIME;integer;240;Maximum time in seconds a migration to file may take for example for snapshot creation before being forcefully aborted. QEMU_NO_FDC_SET;boolean;0;Don't disable the floppy drive. QEMU_NO_KVM;boolean;0;Don't use KVM acceleration. diff --git a/doc/networking.md b/doc/networking.md index fcc332d0..0a123586 100644 --- a/doc/networking.md +++ b/doc/networking.md @@ -13,13 +13,19 @@ limitation - only TCP and UDP are supported. However no additional configuration If options for "user" mode are required, they can be set in NICTYPE_USER_OPTIONS variable. ## TAP device support -When advanced configurations, routing or better performance is required, NICTYPE can be set to -"tap". In this case, preconfigured TAP device on host system is used as VM network device. -Which TAP device is used depends on TAPDEV variable which is automatically set to "tap" + worker id - 1, -i.e. worker1 uses tap0, worker 6 uses tap5. This mode requires the system administrator to create -a TAP device for each running worker and to manually prepare any routing or bridging before "tap" -networking can be used. TAP devices need to be created with proper permissions so VMs can access -them, e.g. "tunctl -u _openqa-worker -p -t tap0". + +When advanced configurations, routing or better performance is required, +NICTYPE can be set to "tap". In this case, preconfigured TAP device on host +system is used as VM network device. Which TAP device is used depends on +TAPDEV variable which is automatically set to "tap" + worker id - 1, i.e. +worker1 uses tap0, worker 6 uses tap5. This mode requires the system +administrator to create a TAP device for each running worker and to manually +prepare any routing or bridging before "tap" networking can be used. TAP +devices need to be created with proper permissions so VMs can access them, +e.g. "tunctl -u _openqa-worker -p -t tap0". + +Some configuration can also be configured by environment variables as defined +in the script `os-autoinst-openvswitch`. ## Multiple network devices To create multiple network devices, one can set multiple, comma-separated MAC addresses diff --git a/os-autoinst-openvswitch b/os-autoinst-openvswitch index f7f98762..d251e802 100755 --- a/os-autoinst-openvswitch +++ b/os-autoinst-openvswitch @@ -41,16 +41,22 @@ sub init_switch { die "can't parse bridge local port MAC" unless $self->{MAC}; die "can't parse bridge local port IP" unless $self->{IP}; + my $local_ip = $ENV{OS_AUTOINST_BRIDGE_LOCAL_IP} // '10.0.2.2'; + my $netmask = $ENV{OS_AUTOINST_BRIDGE_NETMASK} // 15; + my $rewrite_target = $ENV{OS_AUTOINST_BRIDGE_REWRITE_TARGET} // '10.1.0.0'; + # we also need a hex-converted form of the rewrite target, thanks + # https://www.perlmonks.org/?node_id=704295 + my $rewrite_target_hex = unpack('H*', pack('C*', split ('\.', $rewrite_target))); # the VM have unique MAC that differs in the last 16 bits (see /usr/lib/os-autoinst/backend/qemu.pm) # the IP can conflict across vlans - # to allow connection from VM to host os-autoinst (10.0.2.2), we have to do some IP translation - # we use simple scheme: + # to allow connection from VM to host os-autoinst ($local_ip), we have to do some IP translation + # we use simple scheme, e.g.: # MAC 52:54:00:12:XX:YY -> IP 10.1.XX.YY - # br0 has IP 10.0.2.2 and netmask /15 that covers 10.0.0.0 and 10.1.0.0 ranges + # br0 has IP $local_ip and netmask $netmask. E.g. '/15' covers 10.0.2.2 and 10.1.0.0 ranges # this should be also configured permanently in /etc/sysconfig/network - die "bridge local port IP is expected to be 10.0.2.2/15" unless $self->{IP} eq '10.0.2.2/15'; + die "bridge local port IP is expected to be $local_ip/$netmask" unless $self->{IP} eq "$local_ip/$netmask"; # openflow rules don't survive reboot so they must be installed on each startup for my $rule ( @@ -64,23 +70,23 @@ sub init_switch { # reply packets from local port are handled by learned rules in table 1 'table=0,priority=1,in_port=LOCAL,actions=resubmit(,1)', - # arp 10.0.2.2 - learn rule for handling replies, rewrite ARP sender IP to 10.1.x.x range and send to local + # arp e.g. 10.0.2.2 - learn rule for handling replies, rewrite ARP sender IP to e.g. 10.1.x.x range and send to local # the learned rule rewrites ARP target to the original IP and sends the packet to the original port - 'table=0,priority=100,dl_type=0x0806,nw_dst=10.0.2.2,actions=' . # + "table=0,priority=100,dl_type=0x0806,nw_dst=$local_ip,actions=" . # 'learn(table=1,priority=100,in_port=LOCAL,dl_type=0x0806,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],output:NXM_OF_IN_PORT[]),' . # - 'load:0xa010000->NXM_OF_ARP_SPA[],move:NXM_OF_ETH_SRC[0..15]->NXM_OF_ARP_SPA[0..15],' . # + "load:0x$rewrite_target_hex->NXM_OF_ARP_SPA[],move:NXM_OF_ETH_SRC[0..$netmask]->NXM_OF_ARP_SPA[0..$netmask]," . # 'local', - # tcp to $self->{MAC} syn - learn rule for handling replies, rewrite source IP to 10.1.x.x range and send to local + # tcp to $self->{MAC} syn - learn rule for handling replies, rewrite source IP to e.g. 10.1.x.x range and send to local # the learned rule rewrites DST to the original IP and sends the packet to the original port "table=0,priority=100,dl_type=0x0800,tcp_flags=+syn-ack,dl_dst=$self->{MAC},actions=" . # 'learn(table=1,priority=100,in_port=LOCAL,dl_type=0x0800,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],output:NXM_OF_IN_PORT[]),' . # - 'mod_nw_src:10.1.0.0,move:NXM_OF_ETH_SRC[0..15]->NXM_OF_IP_SRC[0..15],' . # + "mod_nw_src:$rewrite_target,move:NXM_OF_ETH_SRC[0..$netmask]->NXM_OF_IP_SRC[0..$netmask]," . # 'local', - # tcp to $self->{MAC} other - rewrite source IP to 10.1.x.x range and send to local + # tcp to $self->{MAC} other - rewrite source IP to e.g. 10.1.x.x range and send to local "table=0,priority=99,dl_type=0x0800,dl_dst=$self->{MAC},actions=" . # - 'mod_nw_src:10.1.0.0,move:NXM_OF_ETH_SRC[0..15]->NXM_OF_IP_SRC[0..15],local', + "mod_nw_src:$rewrite_target,move:NXM_OF_ETH_SRC[0..$netmask]->NXM_OF_IP_SRC[0..$netmask],local", ) { system('ovs-ofctl', 'add-flow', $self->{BRIDGE}, $rule); diff --git a/t/03-testapi.t b/t/03-testapi.t index 205c5098..d53aa125 100755 --- a/t/03-testapi.t +++ b/t/03-testapi.t @@ -677,6 +677,8 @@ subtest 'autoinst_url' => sub { is(autoinst_url('foo'), 'http://my_worker_host:1/foo', 'autoinst_url returns reasonable URL based on WORKER_HOSTNAME'); $bmwqemu::vars{BACKEND} = 'qemu'; is(autoinst_url('foo'), 'http://10.0.2.2:1/foo', 'autoinst_url returns static IP for qemu'); + $bmwqemu::vars{QEMU_HOST_IP} = '192.168.42.1'; + is(autoinst_url('foo'), 'http://192.168.42.1:1/foo', 'autoinst_url returns configured static IP'); $bmwqemu::vars{AUTOINST_URL_HOSTNAME} = 'localhost'; is(autoinst_url('foo'), 'http://localhost:1/foo', 'we can configure the hostname that autoinst_url returns'); }; diff --git a/testapi.pm b/testapi.pm index c7551650..ed94bd58 100755 --- a/testapi.pm +++ b/testapi.pm @@ -2012,10 +2012,10 @@ sub diag { =for stopwords kvm VM Return VM's host IP - in a kvm instance you reach the VM's host under 10.0.2.2 + in a kvm instance you reach the VM's host under default 10.0.2.2 =cut sub host_ip { - return check_var('BACKEND', 'qemu') ? '10.0.2.2' : get_required_var('WORKER_HOSTNAME'); + return check_var('BACKEND', 'qemu') ? get_var('QEMU_HOST_IP', '10.0.2.2') : get_required_var('WORKER_HOSTNAME'); } =head2 autoinst_url -- 2.28.0.rc1