交叉編譯iproute2網絡管理工具
busybox中自帶的ip命令不支持netns和bridge,於是,參考網文指導,自己移植了一個。
參考: https://blog.csdn.net/u013401853/article/details/71126645
發佈: 2017年05月03日 17:04:58 普朗克常量
-
1)下載源碼
-
官網:
- https://www.kernel.org/pub/linux/utils/net/iproute2/ 版本號 3.1.0 起
- iproute2-3.1.0.tar.bz2 23-Nov-2011 19:11 395K
- iproute2-3.19.0.tar.xz 10-Feb-2015 23:15 444K
- iproute2-4.11.0.tar.xz 01-May-2017 16:33 642K
- iproute2-4.13.0.tar.xz 05-Sep-2017 16:41 655K
- iproute2-4.19.0.tar.gz 23-Oct-2018 17:19 939K
- iproute2-4.20.0.tar.xz 07-Jan-2019 18:28 690K
-
更低版本
-
-
2)解壓,修改Makefile
- 修改Makefille中的CC爲交叉編譯器
CC = /usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc
- 普朗克常量/PS: 因爲我只需要ip命令,所以修改第38行只編譯ip工具 SUBDIRS=ip
- 關於 4.19.0 版本
// 修改 Makefile --- 交叉編譯器 CC = /usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc // 修改config.mk --- 交叉編譯器 AR:=/usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-ar CC:=/usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc // 修改config.mk --- 去除對SELinux和CAP的支持 HAVE_SELINUX:= #LDLIBS += -lselinux #CFLAGS += -DHAVE_SELINUX CFLAGS += -DNEED_STRLCPY HAVE_CAP:= #CFLAGS += -DHAVE_LIBCAP #LDLIBS += -lcap
- 修改Makefille中的CC爲交叉編譯器
-
3)make
make LDFLAGS=-static ## 靜態連接,否則,運行時報缺少.so文件
PS:
- 該make過程不會完全成功,但所需的ip已編譯完成,ip目錄下的ip即爲所需的ip可執行程序
- 下載的4.19 版本要求編譯器有selinux.h、capability.h(gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi不支持),故下載了4.13版本,通過編譯
-
4)編譯錯誤解決
- 由於gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi編譯器的原因,函數setns聲明有衝突,如下:
解決:編輯./include/namespace.h,使用bits/sched.h的聲明In file included from utils.c:36:0: ../include/namespace.h:35:19: error: static declaration of ‘setns’ follows non-static declaration static inline int setns(int fd, int nstype) ^~~~~ In file included from /usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/libc/usr/include/sched.h:43:0, from ../include/namespace.h:4, from utils.c:36: /usr/arm/toolchain/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/libc/usr/include/bits/sched.h:91:12: note: previous declaration of ‘setns’ was here extern int setns (int __fd, int __nstype) __THROW;
#ifndef HAVE_SETNS extern int setns (int __fd, int __nstype) __THROW; /* static inline int setns(int fd, int nstype) { ... } */ #endif /* HAVE_SETNS */
-
libmnl required for error support
lib ## 編譯 iproute2-4.19/lib目錄 libnetlink.c:120:2: warning: #warning "libmnl required for error support" [-Wcpp] #warning "libmnl required for error support"
查看lib/libnetlink.c源碼,如果沒有定義 HAVE_LIBMNL 宏,則有上述警告。可以從官網 http://ftp.netfilter.org/pub/libmnl/ 下載 libmnl 編譯,這裏未作此測試
-
靜態鏈接時,執行
ip link add veth0a type veth peer name veth0b
失敗# 在 CentOS 7 中靜態鏈接,出現同樣問題,側面佐證靜態鏈接不可行; # 在 ./ip/iplink.c 中加入跟蹤代碼,發現問題出在 dlh = BODY = dlopen(NULL, RTLD_LAZY) 時爲(明顯地,必須是動態鏈接)
動態編譯,將libdl.so.2.23拷貝到目標機並ln -s爲libdl.so.2,運行ldd,如下:
/root # ldd ./ip linux-vdso.so.1 (0x7ee1e000) libdl.so.2 => /lib/libdl.so.2 (0x76fa0000) libc.so.6 => /lib/libc.so.6 (0x76eb3000) /lib/ld-linux.so.3 (0x76fb3000)
然後,執行
ip link add veth0a type veth peer name veth0b
成功
- 由於gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi編譯器的原因,函數setns聲明有衝突,如下:
-
5)將ip目錄下的ip程序放進板子看能否運行
直接就能運行
普朗克常量/PS: 以前以爲要下載內核對應的iproute2版本才能正常運行,但我編譯了最新的iiproute版本放進板子一樣可以運行。
# 動態鏈接時,報告缺少.so文件 /root # ./ip --help ./ip: error while loading shared libraries: libdl.so.2: cannot open shared object file: No such file or directory
-
參考: