A logic like this might work:

%post daemon-config-network
if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml 
; then
    # Function to convert IP/CIDR to start and end integer bounds
    # Handles both explicit CIDR (e.g., 192.168.64.0/18) and implicit single IPs
    get_ip_bounds() {
        local ip_cidr="$1"
        local ip="${ip_cidr%%/*}"
        local mask="${ip_cidr#*/}"

        # Fallback to /32 if no mask is provided
        [ "$mask" = "$ip_cidr" ] && mask=32

        # Parse IP octets
        IFS=. read -r o1 o2 o3 o4 <<EOF
$ip
EOF
        # Calculate 32-bit integer for the base IP
        local ip_num=$(( (o1 << 24) | (o2 << 16) | (o3 << 8) | o4 ))

        # Calculate netmask bitmask
        local mask_num=$(( 0xFFFFFFFF << (32 - mask) ))

        # Output network start and end integers
        echo "$(( ip_num & mask_num )) $(( ip_num | (~mask_num & 0xFFFFFFFF) ))"
    }

    # Internal helper to verify if two subnets overlap
    check_overlap() {
        local sub1_start=$1 sub1_end=$2 sub2_start=$3 sub2_end=$4
        # Overlap happens if start1 <= end2 AND end1 >= start2
        if [ $sub1_start -le $sub2_end ] && [ $sub1_end -le $sub2_start ]; then
            return 0 # Overlap found
        fi
        return 1 # No overlap
    }

    orig_sub=122
    sub=${orig_sub}

    # Get active system routes
    existing_routes=$(ip route show | cut -d' ' -f1)

    # Loop through possible replacements until one doesn't overlap with ANY 
system route
    for try_sub in $(seq 122 254); do
        # Generate target bounds for 192.168.${try_sub}.0/24
        read -r target_start target_end <<EOF
$(get_ip_bounds "192.168.${try_sub}.0/24")
EOF

        conflict=0
        # Check against every route currently active on the host
        while read -r route; do
            [ -z "$route" ] && continue

            # Skip default routes or complex targets that aren't numeric IPs
            case "$route" in
                default|[*a-zA-Z]*) continue ;;
            esac

            read -r route_start route_end <<EOF
$(get_ip_bounds "$route")
EOF

            # Check overlap math
            if [ $target_start -le $route_end ] && [ $target_end -ge 
$route_start ]; then
                conflict=1
                break
            fi
        done <<EOF
$existing_routes
EOF

        # If no conflict found for this subnet, select it and stop searching
        if [ $conflict -eq 0 ]; then
            sub=${try_sub}
            break
        fi
    done

    # Apply configuration with the safe subnet choice
    sed -e "s/${orig_sub}/${sub}/g" \
         < %{_datadir}/libvirt/networks/default.xml \
         > %{_sysconfdir}/libvirt/qemu/networks/default.xml
    ln -s ../default.xml 
%{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml
    chmod 0600 %{_sysconfdir}/libvirt/qemu/networks/default.xml
fi

** Summary changed:

- libvirt-daemon-config-network.postrm.in does not check if subnet 
192.168.122.0/24 is already used
+ libvirt-daemon-config-network.postinst.in does not check if subnet 
192.168.122.0/24 is already used

** Description changed:

- In our packaging libvirt-daemon-config-network.postrm.in blindly copies
- default.xml to /etc/libvirt/qemu/networks/default.xml.
+ In our packaging libvirt-daemon-config-network.postinst.in blindly
+ copies default.xml to /etc/libvirt/qemu/networks/default.xml.
  
  This leads to conflicts when installing libvirt in a VM that was
  launched by libvirt.
  
  Upstream libvirt.spec.in is a bit more refined:
  
  In daemon-config-network it checks if there is a route involving 
192.168.122.0/24.
  If yes, it looks for an unused subnet 192.168.?.0/24.
  At least the developer understood the problem. But the solution is bad.
  E.g. a subnet already in use could be 192.168.64.0/18 which comprises 
192.168.122.0/24.

** Changed in: libvirt (Ubuntu)
   Importance: Undecided => Low

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2164823

Title:
  libvirt-daemon-config-network.postinst.in does not check if subnet
  192.168.122.0/24 is already used

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/2164823/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to