近期遇到一个IPv6的NAT问题,在解决了之后总想写一点形而上的东西,什么是正确的,什么是错误的,什么合理,什么不合理,无关文档,无关代码,甚至无关技术,仅仅随便聊聊。昨天下班的路上整理了一下思路,周末了,写一点吧。
如果一个报文过大却不能分片的时候,比方说携带了DF标志的IPv4报文和所有的IPv6报文,转发设备会给数据的始发站回送一则ICMP消息,意思是你这报文太大了,请缩小数据重新发。
对于IPv4的情况,我们不用太在乎这种ICMP消息,因为IPv4网络中,IP报文本身只要没有DF标记,就是可以任意分片的,即便携带了DF标记,我们也有足够的经验去对应,但是对于IPv6的情况,事情就变得复杂了,特别是中间链路存在NAT设备的情况下。
IPv6报文除了始发站之外,全程不能分片,因此如果遭遇了MTU小于报文大小的设备,就必须保证该设备回送的ICMP too big消息可以正确到达始发站。在标准的逐跳IPv6网络上,这没有什么问题,因为无论沿着哪条路径,ICMP消息只要到达始发站就万事大吉。然而,如果原始报文中间经过NAT设备,那么就必须严格保证回送的ICMP消息经过同一个NAT设备才行,而这个条件在真实网络中,不采用特殊手段是不能保证的,特别是ECMP情形下。
我们来看一个来自Linux内核nf_conntrack代码注释里的case:
下图展示了该case和NAT联动的各种情况:
为了让ICMP too big消息经过同一NAT设备到达始发站,我们不得不采取一些手段让ICMP too big消息和原始数据流做绑定,执行同一个Load Balance策略(比如ECMP的情况),显然这会引入很多额外的工作量,是的,这非常令人沮丧。
嗟夫!
IPv6还要NAT么,这是为什么?
显然,IPv6并不存在地址不够用的问题,显然,IPv6可以携带安全头保证安全,显然,IPv6可以Random hostID来隐藏主机,显然,IPv6根本就不需要NAT。
IPv4一开始也是干干净净的,NAT并不包含在一开始的设计中,这种后来引入的技术是为了解决IPv4固有的一些问题的,然而为什么,为什么还要把IPv4的这个遗瘤带到IPv6的新时代。继承一个错误的东西,对于IPv6而言,毫无意义!
去除了NAT,IPv6完全靠路由全网互联互通,这正是互联网一开始的初衷,然而,更激进一点地说,即便是没有NAT的IPv6,还是不如IPv4!
IPv6可能是另一个错误!
NAT是为了解决IPv4的问题的,IPv6也是。NAT解决了IPv4的部分问题,IPv6则宣称它解决了IPv4的所有问题,然而悲哀的是,人们在对新技术的狂欢过后,很难去想象背后的代价,为了解决IPv4的问题,引入的代价。
是为每一粒沙子分配一个IP地址重要,还是节省一度电重要?
IPv6需要更多的空间被存储和传输,同时128位的IPv6地址将让大多数的IPv4路由查找算法下课,同时最长前缀匹配算法却没有本质的变化,这需要更多的能量来平滑这个过度,设计更加复杂的算法,虽然层次化的地址分配有效降低了IPv6路由表的规模,然而也只是降低而已。
本质上,IPv6之于IPv4和64位处理器之于32位处理器一样,只是希望大力出奇迹,然而背后的代价却是各种支撑设施的质变,我还是举那个老例子,600米的摩天大楼很容易建造,然而1200米的摩天大楼却很难,因为支撑系统的复杂度会指数级上升,不要怕蚂蚁变成人这么大,因为它自己就会把自己压垮。
可能一开始IPv4用同一个地址空间的IP地址同时标识终端和网络本身就不妥,明明是两个层次却非要挤在一个地址空间,最终会发现,终端数量是越来越多,而网络中间节点其实并没有对应量级的扩张,近40年来,我们的终端数量增加到了几十亿,可是路由器的增长却远低几个数量级,二者并不需要同等的可扩展性。终端和网络并不是一回事,把它们放在同一个地址空间的同一个地址中,可能并不是最简单的。
其实我一直觉得,LISP(Locator Identity Separation)协议的设计思想非常不错,嗯,应该这就是最简单的吧。
好了,这里不适合引入LISP的话题,所以也就结束了吧,说好的,这只是一篇形而上的随笔,无关技术细节,所以也就是无所谓对于不对了,技术细节的东西我也不会写在这里。
浙江温州皮鞋湿,下雨进水不会胖。
来源:oschina
链接:https://my.oschina.net/u/4319574/blog/4816918