我有一个连接了三个接口的树莓派,eth0
我想要实现的是通过所有接口都有到互联网的路由,但到目前为止仅wlan0
获得一条路由。ppp0
eth0
ppp0
这是route -n
和的输出ip route show
(现在没有可用的 ppp0 接口,但我知道它可以工作)
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.39
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.243
/etc/dhcp/dhclient-exit-hooks.d/
我编写了一个脚本,一旦接口从 dhcp 获得报价,就会触发该脚本。
#!/bin/bash
calculateCIDR() {
nbits=0
IFS=.
for dec in $1 ; do
case $dec in
255) let nbits+=8;;
254) let nbits+=7;;
252) let nbits+=6;;
248) let nbits+=5;;
240) let nbits+=4;;
224) let nbits+=3;;
192) let nbits+=2;;
128) let nbits+=1;;
0);;
*)
echo "Error calulating CIDR exiting.";
exit 1
;;
esac
done
echo $nbits
}
calculateSubnet() {
IFS=. read -r i1 i2 i3 i4 <<< $1
IFS=. read -r m1 m2 m3 m4 <<< $2
echo "$((i1 & m1)).$((i2 & m2)).$((i3 & m3)).$((i4 & m4))"
}
# check if all parameters are there
# expected parameters
# $1 = iface
# $2 = ip
# $3 = mask
# $4 = gateway
if [ $# -ne 4 ]
then
echo "Illegal number of arguments"
exit 2
fi
# assign variables
IFACE=$1
IP=$2
MASK=$3
GATEWAY=$4
# extract inface number and calculate table number
case $IFACE in
eth*)
TABLEID=$(( 10 + `echo $IFACE | grep -o -E '[0-9]+'`))
METRIC=0
;;
wlan*)
TABLEID=$(( 30 + `echo $IFACE | grep -o -E '[0-9]+'`))
METRIC=$(( 50 + `echo $IFACE | grep -o -E '[0-9]+'`))
;;
ppp*)
TABLEID=$(( 90 + `echo $IFACE | grep -o -E '[0-9]+'`))
METRIC=$(( 100 + `echo $IFACE | grep -o -E '[0-9]+'`))
;;
*)
echo "Bad interface exiting"
exit 1
;;
esac
# create new table for interface only if not existing there already
grep -q -F "$TABLEID $IFACE" /etc/iproute2/rt_tables || echo "$TABLEID $IFACE" >> /etc/iproute2/rt_tables
# remove previous rules
while ip rule delete table $IFACE 2>/dev/null; do true; done
# flush previous table
ip route flush table $IFACE
# calculate CIDR from
CIDR=$(calculateCIDR $MASK)
# calculate subnet address
SUBNET=$(calculateSubnet $IP $MASK)
# create route for local network
ip route add $SUBNET/$CIDR dev $IFACE src $IP metric $METRIC table $IFACE
# create route for internet
ip route add default via $GATEWAY dev $IFACE metric $METRIC table $IFACE
# set rules for the interface
ip rule add from $IP/32 table $IFACE
ip rule add to $IP/32 table $IFACE
# done
exit 0
这个相同的脚本用于网络设置提供的所有接口,wlan0 永远不会获得到互联网的路由,这意味着我无法使用它来 ping 本地网络之外的任何内容。有人知道为什么吗?我已经没有主意了。
答案1
第一:始终使用ip(8)
命令代替。route
是 Linux 命令之一这是弃用的方式。基本上,Linux 路由是从其他操作系统移植的,不能与 Linux 路由表方案一起使用(它只显示主表)。
main
路由表始终是隐式的。在匹配需要路由的内容之前main
,local
内核还会查看表(基本上所有广播、本地地址和环回都在那里)。这就是为什么每个接口上都不能有默认路由,因为在表上路由时,main
只有一个默认路由会优先于其他默认路由。看看你有什么桌子ip rule list
。
配置基本冗余需要执行的操作是:
- 创建 2 条规则(例如
link01
“link02”)及其路由表 - 将表中的默认路由保留为空
main
。 - 创建一条到表的默认路由
link01
,另一条到 的默认路由link02
。 - 为这些表创建规则或
iptables
在匹配每个表时创建规则 - 为 Wifi 和电缆连接创建单独的网络 IP 范围。
您当前的设置面临一个问题:您在同一个网关和同一个表(main
)上重复默认路由到不同的接口(在尝试第二次添加默认路由时可能会遇到“路由已存在”错误) 。这永远不会发生。 arp 应该如何处理同时在 2 个接口上发布的相同 IP?
替代解决方案:
如果您想要一些冗余,例如主动备份解决方案,而不必更改我上面列出的项目,你可以使用绑定接口配置为模式 1,将eth0
和wlan0
作为奴隶。这是一个Debian 示例因此/etc/network/interfaces
你必须适应你的发行版:
# Slaves
auto eth0
iface eth0 inet manual
bond-master bond0
bond-primary eth0
bond-mode active-backup
auto wlan0
iface wlan0 inet manual
wpa-conf /etc/network/wpa.conf
bond-master bond0
bond-primary eth0
bond-mode active-backup
# Master
auto bond0
iface bond0 inet dhcp
bond-slaves none
bond-primary eth0
bond-mode active-backup
bond-miimon 100
这样,您将通过电缆和 WiFi 进行连接,并拥有两者的“统一”IP 地址。
如果您有一个能够执行 LACP(IEEE 802.3ad)的中/高端网络交换机,您可以进行同时使用两条电缆/连接的链路聚合(bond
Linux 的模式将为 4)。