如何确定下一个可用的网络接口名称和 IP 范围?

如何确定下一个可用的网络接口名称和 IP 范围?

我正在开发一个可以在主机上创建 TUN/TAP 接口的应用程序。我可以使用以下方法创建这样的接口:

sudo ip tuntap add tap0 mode tap

现在的问题是,tap0这里是硬编码的。它应该是动态的。

当我创建下一个点击设备时,它应该是tap1等等。

现在,当我继续为设备提供范围时,我可以手动执行以下操作:

sudo ip addr add 172.16.0.1/24 dev tap0

现在当我创建tap1时,我不想重叠ip。

有没有什么简单的方法来管理这些tap设备?

答案1

#!/bin/bash
i=0;
while [ $i -ne 5 ]
do
  sudo ip tuntap add tap$i mode tap &>/dev/null
  if [[ $? -eq 0 ]]; then
   echo "$i"
   exit 0
  fi
  i=$(($i+1))
done
exit 1

尝试 tun0 到 tun4,创建第一个空闲接口并返回编号

答案2

对于下一个可用的点击设备,您可以使用以下功能:

function nextTapDevice() {
    counter=-1
    while [ $? -eq 0 ]; do
        counter=$(($counter+1))
        ip link show tap$counter &> /dev/null 
    done

    echo tap$counter
}

nextTapDevice

它的运行原理与 @stony 描述的相同,但它会一直运行直到ip link show抛出错误。这意味着没有指定的设备tap$counter可用。该设备名称将是下一个可用的设备名称。


对于下一个可用的 IP 范围,您首先需要遵守策略或 IP 范围。确保此 IP 范围不会与其他应用程序(例如 Docker 等)冲突。

对于我的用例,我决定使用172.16.0.0/16.我将把最后一个八位字节分配给每个虚拟机(我正在使用的应用程序)。我可以运行 256 个虚拟机。

我将重用nextTapDevice上面编写的函数的修改版本。tap$counter我将只返回计数器,而不是在上面的函数中返回。

这是其余的代码:

function nextTapDevice() {
    counter=-1
    while [ $? -eq 0 ]; do
        counter=$(($counter+1))
        ip link show tap$counter &> /dev/null 
    done

    echo $counter
}

# nextTapDevice

function nextIPRange() {
    for ((i=0; i<$(nextTapDevice);++i)); do
        output=$(ip -br addr show tap$i | awk '{print $3}')
    done
    echo $output | awk -F. '{ print $1"."$2"."$3+1"."$4 }'
}

nextIPRange

缺点:即使在 256 之后,第三个八位字节也会继续递增。如果您的用例超过该点,您可能需要实施额外的检查。

答案3

只是为了好玩,这里有一个 FreeBSD 解决方案,基于 tunN 将使用本地 IP 172.16.N.1 和远程 IP 10.172.N.1 的假设:

#!/usr/bin/env bash

# what's the base name of the network interface?  NO SPACES!
devBase='tun'

# Maximum of N interfaces, numbered 0 .. N-1   NO HIGHER THAN 256!
N=256

# what's the printf spec of the tun's local address?  NO SPACES!
ipLocal='172.16.%d.1'

# what's the printf spec of the tun's remote address?  NO SPACES!
ipRemote='10.172.%d.1'

nextTun() {
# $1 is the device base name

  result="$(jot -w "${1}%d" $N 0 | grep -vxFf <(ifconfig -l | grep -ow "${1}[0-9]\+") | head -1)"
  if [[ -n "$result" ]]
  then
    printf '%s\n' "$result"
  else
    exit $?
  fi
}

if tun="$(nextTun $devBase)"
then
        devN=${tun#$devBase}
        printf 'Creating %s ...\n' "$tun"
        ipl=$(printf $ipLocal  $devN)
        ipr=$(printf $ipRemote $devN)
        ifcfg="$(printf 'sudo ifconfig %s create %s %s' "$tun" $ipl $ipr )"
        sudo $ifcfg || {
                printf '"%s" failed.\n' $tun
                exit 2
        }
else
        printf 'No %s devices available.\n' "$devBase"
        exit 1
fi

这声明了一个接受基本接口名称的函数nextTun,例如tun.它会快速列出可能的设备jot列表,删除所有已在使用的设备,并获取第一个(最低的)可用设备。如果没有可用的设备,则该函数不返回任何结果,并返回非零退出代码。Ntuntuntuntun

主要代码测试是否成功nextTun。如果找到,则它会构造必要的ifconfig语法来创建具有适当本地和远程 IP 的tun设备编号。devN一旦语法被构建,它就会被传递sudo到执行。如果nextTun指示分配可用设备失败tun,则该代码指示没有更多设备可用,并返回非零退出代码。

相关内容