简介
loopback接口是Linux系统中特殊的虚拟接口,通常不需要对地址和掩码进行特殊设置。由于项目特殊需求,需要使用此网段地址作(127.x.0.0/16)作为设备内部板卡间通信管理地址使用,因此需要对loopback接口的地址和掩码进行修改。本文在Ubuntu系统中进行方案的验证。
loopback接口简介
TCP/IP协议中Lookback接口是一个通过软件实现的虚拟网络接口,它不与任何硬件相关联。
RFC2606中明确指出了loopback地址的标准域名为localhost。在IPv4中,其对应的IP地址一直是127.0.0.1;理论上,整个127 IP段(127.0.0.0~127.255.255.255)的IP地址都为loopback地址,与localhost对应。在IPv6中,localhost对应的IP地址为0:0:0:0:0:0:0:1,一般写作::1。
[root@localhost ~]# ifconfig lo
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
loopback地址和掩码修改
IP协议规定loopback数据包是不允许在网络中传输的,网络网络接口必须丢弃接收到的loopback数据包。要想改变此缺省规则,需要对loopback地址的判断规则进行修改,对内核进行修改和定制:
diff --git a/include/linux/in.h b/include/linux/in.h
index d60122a..32d52db 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -238,7 +238,7 @@ struct sockaddr_in {
/* Address to loopback in software to local host. */
#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
-#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
+#define IN_LOOPBACK(a) ((((long int) (a)) & 0xffff0000) == 0x7f000000)
/* Defines for Multicast INADDR */
#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
@@ -254,7 +254,7 @@ struct sockaddr_in {
static inline bool ipv4_is_loopback(__be32 addr)
{
- return (addr & htonl(0xff000000)) == htonl(0x7f000000);
+ return (addr & htonl(0xffff0000)) == htonl(0x7f000000);
}
static inline bool ipv4_is_multicast(__be32 addr)
在内核的include/linux/in.h中对loopback地址的掩码进行修改,并修改了loopback地址的判断。按照上述修改,仅127.0.0.0-127.0.255.255为loopback地址,其余127.1.0.0-127.255.255.255均可作为正常接口地址使用。
配置修改完需要对内核进行重新编译与安装。新内核启动后,可以对loopback地址掩码进行修改:
[root@localhost ~]# ifconfig lo netmask 255.255.0.0
[root@localhost ~]# ifconfig lo
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4812 errors:0 dropped:0 overruns:0 frame:0
TX packets:4812 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2394109 (2.3 MB) TX bytes:2394109 (2.3 MB)
配置VLAN子接口
添加VLAN子接口需要安装VLAN包:
[root@localhost ~]# apt-get install vlan
在当前的eth1接口上添加vlan11的子接口,并配置127.11.x.x网段地址。
[root@localhost ~]# vconfig add eth1 11
[root@localhost ~]# ifconfig eth1.11 127.11.254.1 netmask 255.255.0.0
[root@localhost ~]# ifconfig vlan11
vlan11 Link encap:Ethernet HWaddr 00:0c:29:22:cf:ac
inet addr:127.11.254.1 Bcast:127.11.255.255 Mask:255.255.0.0
inet6 addr: fe80::20c:29ff:fe22:cfac/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1496 Metric:1
RX packets:246546 errors:0 dropped:0 overruns:0 frame:0
TX packets:933262 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21837553 (21.8 MB) TX bytes:3719833865 (3.7 GB)
在虚拟化环境下,我们可以通过virtual switch来连接两个Linux系统,验证此vlan11接口之间的通信。
接口配置文件
根据上述对loopback接口的修改,最终相关的接口配置文件如下:
[root@localhost ~]# cat /etc/network/interfaces
auto lo
iface lo inet loopback
address 127.0.0.1
netmask 255.255.0.0
network 127.0.0.0
broadcast 127.0.255.255
auto vlan11
iface vlan11 inet static
address 127.11.254.1
netmask 255.255.0.0
network 127.11.0.0
broadcast 127.11.255.255
mtu 1496
vlan_raw_device eth1
进行到这里,系统已经开始支持127.x.x.x/16的接口地址,相关的报文可以通过网口发出。
loopback接口掩码加载问题的规避
在实际测试中,发现系统重启后,loopback地址掩码并不能正常加载,仍为255.0.0.0。这应该是由于NetworkManager加载/etc/network/interfaces配置时,忽略了用户的配置导致。为规避这个问题,可以在/etc/rc.local中对loopback地址的掩码进行配置,在/etc/rc.local中追加下面的语句:
ifconfig lo netmask 255.255.0.0