列出所有路由表

列出所有路由表

我需要知道如何列出所有路由表的 ID。例如,我可以运行:

ip rule add fwmark 2 table 104
ip route add dev eth0 default via 192.168.3.7 table 104

呼吁ip rule list演出:

0:  from all lookup local 
32765:  from all fwmark 0x2 lookup 104 
32766:  from all lookup main 
32767:  from all lookup default

并呼吁大家关注ip route show table 104

default via 192.168.3.7 dev eth0

如果我随后调用ip rule del table 104,则后续调用会ip rule list显示:

0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default

但是,调用ip route show table 104仍然显示:

default via 192.168.3.7 dev eth0

我知道我可以使用 刷新表ip route flush table 104。我希望能够刷新所有不是 、 和 的表localmain因此default我希望能够列出现有表。

我见过有人使用cat /etc/iproute2/rt_tables,但这只会产生:

#
# reserved values
#
255 local
254 main
253 default
0   unspec
#
# local
#
#1  inr.ruhep

我该怎么做才能获取当前存在的所有表名?提前致谢!

答案1

有一种方法可以列出所有表的所有路由条目。ip route show table all

使用一些 shell 管道魔法,您可以提取所有表名和 ID,如下所示:

ip route show table all | grep "table" | sed 's/.*\(table.*\)/\1/g' | awk '{print $2}' | sort | uniq

或者

ip route show table all | grep -Po 'table \K[^\s]+' | sort -u

如果您只关心数字表名称,请添加一些 grep 过滤:

ip route show table all | grep "table" | sed 's/.*\(table.*\)/\1/g' | awk '{print $2}' | sort | uniq | grep -e "[0-9]"

或者

ip route show table all | grep -Po 'table \K[^\s]+' | sort -u | grep -e "[0-9]"

答案2

我该怎么做才能获取当前存在的所有表名?

该文件/etc/iproute2/rt_tables是表的唯一来源名称在系统上。在内部,路由表具有整数标识符。

您的问题的其余部分有点令人困惑。如果某个表未被规则引用,则它实际上被“删除”,因为它对系统的路由没有影响。因此,您可以列出所有积极的路由表如下:

ip rule list | awk '/lookup/ {print $NF}'

查找lookup路由规则中的所有操作并打印目标。

路由表似乎由 64 位整数标识。如果您真的想找到所有具有规则的路由表,即使是对您的系统没有影响的非活动路由表,您也可以简单地从 1 到 2^64 进行循环迭代:

seq 0 $(echo '2 64 ^ p' | dc) | xargs -iTABLE sh -c 'echo === TABLE ===; ip route show table TABLE'

...但是这将需要永远的时间,因为 64 位覆盖了很大的空间。

答案3

(egrep '^\s*[0-9]' /etc/iproute2/rt_tables | awk '{print $2}' | sort -u; ip rule list | awk '/lookup/ {print $NF}' | sort -u; ip route show table all | sed 's/.*\(table.*\)/\1/g' | awk '{if($0 ~ /table/) print $2; else print "main";}' | sort -u) | sort | uniq -c

感谢这个线程引出了这个组合,它显示了当前包含路由、被规则引用和命名的所有路由表,每个有内容、被引用和被命名的表旁边都有一个 3,或者如果三个条件中的一个或两个适用,则有一个 2 或 1。

答案4

这是我根据从此线程收集的信息编写的脚本。它适用于运行 Marshmallow 6.0.1 的旧 Note 5(设置为可轻松复制/粘贴到运行 su 的 adb shell 终端中)

# Tested on Samsung Galaxy Note5 running Android Marshmallow 6.0.1 - needs root and termux app installed
# Must be run as root
# Termux app must be installed so column will work. This first line adds termux to the search path for the current console session - probably not necessary if you are typing all this into the termux app on the device
export PATH=$PATH:/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets; export LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib; \
echo -e "\nRouting table names and where they are present and populated:"; (echo "Table Name,\"ip rule list\",\"ip route show table <name>\",\"/data/misc/net/rt_tables\""; (egrep '^\s*[0-9]' /data/misc/net/rt_tables | awk '{print $2 ",file"}' | sort -u; ip rule list | awk '/lookup/ {print $NF ",rule"}' | sort -u; ip route show table all | sed 's/.*\(table.*\)/\1/g' | awk '{{if($0 ~ /table/) printf $2; else printf "main";}; print ",route"}' | sort -u) | sort | awk 'BEGIN{FS=","} {dnames[$1]=1; if($2=="file"){dfile[$1]=1}; if($2=="rule"){drule[$1]=1}; if($2=="route"){droute[$1]=1};} END {for (name in dnames) {printf name; printf "," ; if(drule[name]==1){printf "rule"}; printf "," ; if(droute[name]==1){printf "route"}; printf "," ; if(dfile[name]==1){printf "file"};print "" }}' |sort )| column -t -s',' -o' | '

输出如下所示:

Routing table names and where they are present and populated:
Table Name     | "ip rule list" | "ip route show table <name>" | "/data/misc/net/rt_tables"
0              |                | route                        | 
1              | rule           | route                        | 
61             | rule           | route                        | 
legacy_network | rule           |                              | file
legacy_system  | rule           | route                        | file
local          | rule           | route                        | file
local_network  | rule           | route                        | file
main           | rule           | route                        | file
rmnet0         | rule           | route                        | file
rmnet1         | rule           | route                        | file

以下是适用于 CentOS 7 的相同脚本:

# Tested on CentOS 7
echo -e "\nRouting table names and where they are present and populated:"; (echo "Table Name,\"ip rule list\",\"ip route show table <name>\",\"/etc/iproute2/rt_tables\""; (egrep '^\s*[0-9]' /etc/iproute2/rt_tables | awk '{print $2 ",file"}' | sort -u; ip rule list | awk '/lookup/ {print $NF ",rule"}' | sort -u; ip route show table all | sed 's/.*\(table.*\)/\1/g' | awk '{{if($0 ~ /table/) printf $2; else printf "main";}; print ",route"}' | sort -u) | sort | awk 'BEGIN{FS=","} {dnames[$1]=1; if($2=="file"){dfile[$1]=1}; if($2=="rule"){drule[$1]=1}; if($2=="route"){droute[$1]=1};} END {for (name in dnames) {printf name; printf "," ; if(drule[name]==1){printf "rule"}; printf "," ; if(droute[name]==1){printf "route"}; printf "," ; if(dfile[name]==1){printf "file"};print "" }}' |sort )| column -t -s',' -o' | '

相关内容