实验要求

  • 在本次实验中,目的是编写一个P4程序,使主机能够监控网络中所有链路的使用情况
  • 本练习基于基本的IPv4转发练习,因此请确保在尝试此练习之前完成此练习(basic.p4)
  • 具体来说,我们将修改基本P4程序以处理源路由探测包,以便它能够在每个跳处获取出口链路利用率,并将其传递给主机以进行监控。

实验内容

Step1:设计包头

1.为了获取包经过了多少跳,定义了一个包头 probe_t

header probe_t {bit<8> hop_cnt;
}

2.在每一跳的过程中,收集我们想要的信息,比如交换机的端口号,进出时间等

header probe_data_t {bit<1>    bos;bit<7>    swid;bit<8>    port;bit<32>   byte_cnt;time_t    last_time;time_t    cur_time;
}

3.指定交换机应该将这个探测包发往哪里,保证了探测包的确定性转发路径

header probe_fwd_t {bit<8>   egress_spec;
}

包头的总体结构如下,但是实际的包头结构要么是ipv4包要么是探测包

struct headers {ethernet_t              ethernet;ipv4_t                  ipv4;probe_t                 probe;probe_data_t[MAX_HOPS]  probe_data;probe_fwd_t[MAX_HOPS]   probe_fwd;
}

Step2: 设计两个寄存器

`byte_cnt_reg` :统计自最后一个探测数据包从端口发送出去以来从每个端口发送出去的字节数。

`last_time_reg`:存储上一个探测包从端口出去的最后时间

Step3: 对照实验

先把没有完善的p4代码编译并载入交换机创建mininet运行一下,我打开同一个主机的两个终端,一个发送数据包,一个接收数据包,至于数据包的发送原理,就是简单的python网络编程提及的东西,我在以后放在java网络编程一块讲。

可以看到,接收端收到的域都是0,并没有提现任何信息,这是因为我的监测模块还没实现

Step4: 控制面逻辑

控制面逻辑的json主要包含4个元素,分别是p4目标,也就是底层实现,以及p4info,这是p4文件编译后生成的信息文件,还有bmv2_json指的是p4文件编译后的json,最后一个是table_entires,描述了table里面每一个键值对,注意到,和以往不同的是,这里有Egress控制流的表了(swid)

{"target": "bmv2","p4info": "build/link_monitor.p4.p4info.txt","bmv2_json": "build/link_monitor.json","table_entries": [{"table": "MyEgress.swid","default_action": true,"action_name": "MyEgress.set_swid","action_params": {"swid": 2}},{"table": "MyIngress.ipv4_lpm","default_action": true,"action_name": "MyIngress.drop","action_params": { }},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.1.1", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "08:00:00:00:03:00","port": 4}},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.2.2", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "08:00:00:00:04:00","port": 3}},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.3.3", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "08:00:00:00:03:33","port": 1}},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.4.4", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "08:00:00:00:04:44","port": 2}}]
}

Step5:数据平面逻辑设计(解析器)

解析器设计,我们先要解析这些包,在设计解析器逻辑的时候,可以看出: