30, 31 or 32 —— 那些令人费解的网络前缀

warning: 这篇文章距离上次修改已过395天,其中的内容可能已经有所变动。

故事的起源和笔者最近的一份作业有关

这件事实际上可能没那么复杂

但就是.....很反直觉

info:如果您是从某位学生所上交的实验报告中找到并进入本文的,嗯,没错,这就是我写的

背景

站长最近考上了大学,就读于计算机网络专业,平时的专业课作业自然是和网络专业有关的。

最近一份的作业是要我们规划一个子网,也就是给定了一个/24地址块情况下,让我们规划好WAN地址,LAN地址,以及ISP内部的LAN地址。根据某位老师的说法,这份作业题还是从思科的培训资料上摘下来的,那想必也是身价不小了(

这份作业中有这么一条题目,首先是给定一个拓扑图:


然后给出一些IP的划分规定,让你根据这个规定规划子网。其中就有这么规定:

第 5 个子网为现有的 WAN,采用点到点链路。
第 6 个子网为将来的 WAN,采用点到点链路;
第 7 个子网为将来的 WAN,采用点到点链路。

这三个都直接连接到路由器上,也就是说需要给这个网络以及接口分配IP。分配IP问题不大,问题大是如何分配网络及其子网掩码?

从网上一查,得到了三个截然不同的结果:/30,/31,/32

标准的/30

首先回顾一下以太网环境下的IP地址组成规范。一般来说是,在指定的地址块里面,主机位全0的是网络号,主机位全1的是广播地址,剩下的是主机地址。假设一个地址块10.0.0.0/24,可以得知网络号10.0.0.0,广播地址10.0.0.255,剩下的是主机地址。我们日常说的可用地址就是指的主机地址。

现在考虑这么一个问题,网络前缀『最小可用』是多少?网上能查到的回答基本上都是/30,也就是说,假设一个地址块10.0.0.0/30,可得:

  • 网络号:10.0.0.0
  • 广播地址:10.0.0.3
  • 可用地址:10.0.0.1,10.0.0.2

两个可用的主机地址,很好。如果办过运营商专线的朋友可能了解过这一点,运营商把设备接进来你的机房之后,如果指明的是/30的网络前缀,会给你四个IP地址,但是不要想太好,你能用的IP一般来说只有一个。因为网络号和广播地址和网关一人占一个地址,4-3=1,剩下的才是你的

『不能用吗?』的/31

现在我们『突破』一下这个限制,把网络前缀提到/31,会怎么样?

很多人一看这个就大喊,博主你说瞎话误人子弟啊,/31只有一个广播地址和一个网络号,没有空间给主机地址,没意义啊!

确实是这样的,但是我们不妨大胆一点,把思路放宽一些:『广播地址和网络号』是人为规定的东西。既然大家都是人为规定,那么我可不可以规定这两个地址不是广播地址和网络号,而是就是两个主机地址呢?

没错,这就是题图中的RFC3021所规定的东西。

RFC3021的标题是《Using 31-Bit Prefixes on IPv4 Point-to-Point Links》(在IPv4点对点链路中的使用31位网络前缀),发布于2000年的12月,距今已有23年,可以说,已经成为了事实上的标准。

3021尝试解决的是点对点链路(下文简称PtPL)占用IP太多的问题,正如前文所言,我们平常会假设一个二层网络就是以太网,那么『最低可用前缀』就是/30,但是/30要吃掉4个IPv4地址,怎么看怎么浪费。而在PtPL中,只有两方(所以得名点对点)在通讯,不像传统以太网那样是点对多点的,更加没有子网的概念,只要扔到线路上的东西是一定会是发给对方的,因此传统以太网中的广播地址和网络号就显得有点多余了。

/31网络前缀就解决了这个问题,让一个『块』当中只有两个地址,双方各一个,你叫Alice我叫Bob,大家都认识对方,可以互相通讯。细心的读者可能已经发现了,这个东西和传统的以太网并不是很兼容,因此3021中特别规定:

  A third option is to use host addresses on both ends of a point-to-
  point link.  This option provides the same address space savings as
  using a 31-bit subnet mask, but may only be used in links using PPP
  encapsulation [RFC1332].

第三种选择是在点对点链路的两端使用主机地址。/31前缀提供的可用地址空间(与/30)大小相同,但更加节省(实际占用空间),但只能在使用 PPP 封装[RFC1332]的链路中使用。

RFC1332定义了在PPP链路上建立IP链路(IPCP)的实现,由于和本文关系不大就不贴出来了,感兴趣的不妨阅读一下。

因此不难发现,在IP over PPP链路上使用/31的子网掩码是没问题的。观察作业题目给出的图不难发现,连接两个路由器(R1-ISP和R2-Central)的线是红色闪电状的,这在思科的模拟软件中正好代表了串口,串口之上跑的一般就是PPP协议,因此我们可以放心地给这两个路由器的这两个接口分配/31的地址,对应于作业,可以自己选一个,那就是192.168.23.2/31192.168.23.3/31

小小的题外话

如果两台路由器不是用PPP,而是用以太网互联,此时用/31会怎么样呢?

在eNSP中新建如下拓扑


然后给两个路由器相连的接口分配相应的地址

[AR1-GigabitEthernet0/0/0]ip address 10.0.0.2 31
Warning: Please be cautious when using the IP address 
with 31-bit mask on non-P2P interfaces.
[AR2-GigabitEthernet0/0/0]ip address 10.0.0.3 31
Warning: Please be cautious when using the IP address 
with 31-bit mask on non-P2P interfaces.

路由器(此时可以视为是两个主机)给出提示:在非点对点链路上使用/31前缀要小心

但是小心归小心,暂时先不管,我们不妨Ping一下看看通不通

[AR1]ping 10.0.0.3
  PING 10.0.0.3: 56  data bytes, press CTRL_C to break
    Reply from 10.0.0.3: bytes=56 Sequence=1 ttl=255 time=80 ms
    Reply from 10.0.0.3: bytes=56 Sequence=2 ttl=255 time=30 ms
    Reply from 10.0.0.3: bytes=56 Sequence=3 ttl=255 time=20 ms
    Reply from 10.0.0.3: bytes=56 Sequence=4 ttl=255 time=20 ms
    Reply from 10.0.0.3: bytes=56 Sequence=5 ttl=255 time=30 ms

  --- 10.0.0.3 ping statistics ---
    5 packet(s) transmitted
    5 packet(s) received
    0.00% packet loss
    round-trip min/avg/max = 20/36/80 ms

很明显是通的,证明我们的配置没有问题,/31确实可以用。

但是机器不是傻子,为什么刚刚会警告我们呢?道理很简单:上面的拓扑虽然说用的是以太网,但是在物理意义上确实是点到点的,用/31没啥毛病。但如果是传统的网络拓扑(比如,交换机下连接了若干台主机),此时用/31就有可能会出现莫名其妙的行为(也就是俗称的未定义行为)。在3021中也指明了这一点:

The intent of this document is to discuss the applicability and operation of 31-bit prefixes on point-to-point links.  The effects (if any) on other types of interfaces are not considered.

本文档的目的是讨论/31前缀在点对点链路上的适用性和操作。对于其他类型的接口的影响(如果有)并不考虑在内

这种情况下最好还是不要去尝试了,当然试试无所谓,但别上生产,毕竟影响程度从网络不通到抽卡全歪都有可能发生,没人会给你担保未定义行为所造成的后果。

『网关竟是我自己』的/32

打开你家的路由器后台界面,切换到接口选项卡,有概率会发现:


你没看错,PPPoE拨号之后机器设定了一个/32的网络前缀,有些路由器还可能会显示此时的网关地址就是你拿到的IP地址

那么好,现在又有人问了,网关地址和自己的地址一样,那还怎么上网呢,数据不是都发给自己了嘛?

一般情况来说,是的,而且很多资料都会规定/32网络前缀只用于loopback接口。

但是能写进本文的都不太一般,还记得开头说过什么吗?这里的东西都很反直觉。事实上是,平时拨号上网所使用的PPPoE协议架构中,只有你有IP地址

没错,现在我们没有网关,没有其他别的什么乱七八糟的东西,只有你。运营商那边帮你接进网络的东西,不叫网关,叫BRAS(宽带远程接入系统),作用很类似网关,但不能简单的等同于网关。

为了简单理解起见,我们将互联网抽象成一条总线。假设这么一个情况,从你家的电脑里面拉出了一根线,接到这根总线上,此时你的电脑是要配置IP地址,这没问题。但是你需不需要给这根线(以及接入总线的那个插头)配置IP地址呢?很显然并不必,它只是一根线。

PPP在此处就是起到了这根线的作用,本质上可以理解为你的电脑成为了远端BRAS的一个虚端口。因为是PPP,所以在这根线上只有你的电脑和BRAS,没有第三方了,你的电脑发出的任何数据,只要不是发给本机,都会从这个接口发走,而且发出去的数据一定会被对方接收,不可能发到其他第三方手上。所以此时网关地址是多少,有关系吗?没有。反正各种数据都要从这个接口出去,区不区分网关其实没啥。

另一方面,此时你发给BRAS的数据都会被转发到互联网上,你并不是在和BRAS本身通讯,或者说,你就是BARS的一部分,所以BRAS连接你的那个端口也不需要配置(通常意义上的)IP地址,只需要配置好静态路由,当电脑告诉他,我想去哪里,他就会帮你转到那里。

上面讨论的是PPP,实际用的是PPPoE。既然在(over)人家以太网的地盘上,多多少少就要听他的话。以太网是需要MAC地址来通讯的,平时我们怎么获得对端的MAC地址?用ARP协议,对吧?但是PPPoE不怎么干,他在握手阶段就首先通过二层广播方式寻找PPPoE服务器的位置,服务器收到广播包之后会按以太网规范在回复的时候带上自己的MAC地址,这样本地就知道了PPPoE服务器的地址,可以直接进行通讯了。

观察以上过程可以发现,IP完全没有插手,这也就是上面所说『只有你有IP地址』的含义。所以在PPPoE链路上可以放心的用/32网络前缀。

那么电脑怎么知道网络数据从这个接口出呢?平时我们是用路由表的,现在我们还用路由表。路由表中一个重要的参数就是『下一跳地址』,也就是网关地址。在本文所述的PPPoE环境中,因为没有网关,所以网关地址也可以随便写,但不能不写,毕竟得用来装装样子,让电脑可以自动生成一条路由,告诉IP协议栈,所有的数据都从这个接口发出。

一般来说,这条路由是

0.0.0.0 ==> x.x.x.x

x.x.x.x就是你所配置的网关地址,但是正如上面所说,电脑不是傻子,当电脑看到这个IP对应的接口是一个PPPoE接口的时候,它会自动帮你把数据包封装成PPPoE然后扔出去。换句话说,这个网关地址可以理解为『在路由表上唯一地标识这个接口的标识符』,标志符是什么没关系,只要合法并且能够塞进路由表里面就行,因此,为了简便起见,设置成和本机IP一样就行了。

写在最后

实验报告末尾有一个『实验心得』的填空区。往常的话,笔者一般会实际地写一些问题,或者没有的话就写个无。写完本文之后,倒是觉得,我可以把它作为心得之一提交上去了。

深山踏红叶,耳畔闻鹿鸣,感谢您的阅读。

(全文完)

none
最后修改于:2023年10月23日 14:34

添加新评论