P4全称Programming Protocol-Independent Packet Processors,是Nick McKeown和他的团队在2014年提出的一种用于编程与协议无关的数据包处理器的高级语言。P4有三大特征:协议无关性、目标无关性、可重构性。快速实现网络新协议,缩短传统网络设备的研发周期,是P4的重要驱动力之一。本文依据IETF于2017年9月13日公布的最新的IPv10草案,用P4实现支持IPv10协议的交换机,并搭建实验环境来验证IPv10的特性。本文只是通过P4实现IPv10协议为例,说明P4实现网络新协议的路径方法。IPv10本身的价值或前景,不在本文的判断中。
一、背景
自IPv6协议由互联网工程任务组IETF于1998年开发,至今已19年,但到目前为止还没有全面的迁移,导致互联网分为两部分,IPv4仍然占据互联网流量的主导地位。谷歌在2017年4月统计互联网的流量IPv4占85%,IPv6只占15%。因此,对于IPv4和IPv6共存的解决方案的需求成为迁移过程中的一个重要问题,IPv4全面迁移到IPv6也并非轻而易举。
下面列举了几个相关的解决方案:
1.IPv4 / IPv6双协议栈:让计算机同时使用IPv4和IPv6地址,共享IPv4和IPv6,但该解决方案不允许使用IPv4协议的主机与使用IPv6协议的主机相互通信。 此外,在IPv4地址空间耗尽之后,新的Internet主机将无法使用IPv4 / IPv6双栈。
2.隧道技术:允许使用IPv6协议的主机之间通过基于IPv4的网络进行通信,但仍然不允许IPv4主机与IPv6主机相互通信。
3.NAT-PT:允许使用IPv6协议的主机与使用IPv4协议的主机进行通信,并使用主机名,在通信过程中通过DNS获取地址;但该解决方案效率不高,因为它不允许直接使用IP地址进行通信,还需要大量的源、目IP地址转换,使解决方案变得复杂。此外,它的改进版本NAT64在通信过程中采用了DNS64[5]技术,也需要大量的协议转换和静态配置。
二、IPv10介绍
IPv10目前是IETF草案,在2017年9月13日发布了最新版本草案,声称用一个非常简单和有效的方法解决了使用IPv6协议的主机与使用IPv4协议的主机之间相互通信的问题,当主机间直接使用IP地址进行通信时,以及当使用IPv10协议的主机之间使用主机名进行通信时,无需进行协议转换,并且在通信过程中不需要DNS进行地址解析。IPv10协议通过在IP数据报报头中包含IPv4和IPv6地址,支持使用IPv6协议的主机与使用IPv4协议的主机之间进行通信,其报文格式如图一和图二所示。
图一:IPV10的数据包头
图二:IPv10数据包的源目地址
图三:基于IPv10协议,支持使用IPv6协议的主机与使用IPv4的主机之间进行通信
图三中,主机PC-1只有IPv6地址,而主机PC-2只有IPv4地址,两者均都支持IPv10。当主机PC-1往主机PC-2发送数据包时,主机PC-1使用IPv10协议,并在IPv10数据首部的目的地址中填入IPv4的地址。
三、 支持IPv10的P4交换机
图四:P4交换机处理IPv10数据报的流程图
原理说明:
当基于IPv10协议的数据报文进入P4交换机时,解析器解析目的地址的后48位是否全为零:如果全为零,则进行IPv4的地址解析;如果不全为零,则进行IPv6的地址解析。不同的解析方式对应于不同的匹配-动作阶段。流水线处理之后,将IPv10数据报进行封装,并进行转发。
关键代码:
Shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
header ipv10_t { //定义IPv10的前面字段 bit<4> version; bit<8> traffic_class; bit<20> flow_label; bit<16> payload_length; bit<8> next_header; bit<8> hop_limit; ip6Addr_t srcAddr; }
header ipv6_addr_t{ //目的地址为IPv6类型时 ip6Addr_t dstAddr; }
header ipv4_addr_t{ //目的地址为IPv4类型时 ip4Addr_t dstAddr; bit<48> mac; bit<48> zero; } //通过判断目的地址后48位是否全为0,走不同的解析器 state parse_ipv10 { packet.extract(hdr.ipv10); transition select(packet.lookahead<ipv4_addr_t>().zero){ 0: parse_ipv4_addr; default: parse_ipv6_addr; } } |
四、实验验证
实验通过P4-16语言描述交换机对IPv10数据报的处理流程,实验拓扑由一台P4交换机s1和两台主机h1,h2组成。在h1主机终端上通过scapy[8]将IPv6的数据包改造为IPv10的数据包经过s1发送给h2,h2收到数据包后将展示收到数据包的内容。
首先,需要git
Shell
1 |
$ git clone https://github.com/deepYY/ipv10_p4.git |
然后进入制定目录创建P4交换机
Shell
1 2 |
$ cd ipv10_p4 $ ./run.sh |
图五:创建拓扑
创建成如图的拓扑:
图六:拓扑图
然后开启两个主机h1,h2的终端
Shell
1 |
$ mininet > xterm h1 h2 |
在h2的终端上
Shell
1 |
$ ./receive.py |
在h1的终端上
先发送h2的ipv4地址数据包
Shell
1 |
$ ./send_ipv4_addr.py 10.0.2.10 ‘P4 is cool ’ |
在发送h1的ipv6地址数据包
Shell
1 |
$ ./send_ipv6_addr.py fe80::5678 ‘P4is cool’ |
h1主机查看信息:
图七:h1终端发送数据包
h2主机查看信息:
图八:h2接受到数据包