欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

P4语言——source

时间:2023-07-04
练习:源路由

本练习的目的是实现源路由。 使用源路由,源主机引导网络中的每个交换机将数据包发送到特定的端口。 主机在数据包中放置一个输出端口堆栈。 在本例中,我们只是将堆栈放在Ethernet报头之后,并选择一个特殊的etherType来表示。 每个交换机从堆栈中弹出一个项目,并根据指定的端口号转发数据包。

拓扑图代码

{ "hosts": { "h1": {"ip": "10.0.1.1/24", "mac": "08:00:00:00:01:11", "commands":["route add default gw 10.0.1.10 dev eth0", "arp -i eth0 -s 10.0.1.10 08:00:00:00:01:00"]}, "h2": {"ip": "10.0.2.2/24", "mac": "08:00:00:00:02:22", "commands":["route add default gw 10.0.2.20 dev eth0", "arp -i eth0 -s 10.0.2.20 08:00:00:00:02:00"]}, "h3": {"ip": "10.0.3.3/24", "mac": "08:00:00:00:03:33", "commands":["route add default gw 10.0.3.30 dev eth0", "arp -i eth0 -s 10.0.3.30 08:00:00:00:03:00"]} }, "switches": { "s1": { "runtime_json" : "s1-runtime.json" }, "s2": { "runtime_json" : "s2-runtime.json" }, "s3": { "runtime_json" : "s3-runtime.json" } }, "links": [ ["h1", "s1-p1"], ["s1-p2", "s2-p2"], ["s1-p3", "s3-p2"], ["s3-p3", "s2-p3"], ["h2", "s2-p1"], ["h3", "s3-p1"] ]}

p4文件 头部包含链路层协议、源路由协议、ipv4协议源路由协议参数设置源路由下一跳action设置packet包的处理流程逻辑关系封装header出交换机

#include #include const bit<16> TYPE_IPV4 = 0x800;const bit<16> TYPE_SRCROUTING = 0x1234;#define MAX_HOPS 9typedef bit<9> egressSpec_t;typedef bit<48> macAddr_t;typedef bit<32> ip4Addr_t;header ethernet_t { macAddr_t dstAddr; macAddr_t srcAddr; bit<16> etherType;}header srcRoute_t { bit<1> bos;//标记是否是最后一个 bit<15> port;//标记出端口}header ipv4_t { bit<4> version; bit<4> ihl; bit<8> diffserv; bit<16> totalLen; bit<16> identification; bit<3> flags; bit<13> fragOffset; bit<8> ttl; bit<8> protocol; bit<16> hdrChecksum; ip4Addr_t srcAddr; ip4Addr_t dstAddr;}struct metadata { }struct headers { ethernet_t ethernet; srcRoute_t[MAX_HOPS] srcRoutes;//header有多条srcRoutes实现多跳 ipv4_t ipv4;}parser MyParser(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { state start { transition parse_ethernet; } state parse_ethernet { packet.extract(hdr.ethernet); transition select(hdr.ethernet.etherType) { TYPE_SRCROUTING: parse_srcRouting; default: accept; } } state parse_srcRouting { packet.extract(hdr.srcRoutes.next);//包的解封,使用next和extract移动指针 transition select(hdr.srcRoutes.last.bos) {//这是指针的上一层也就是刚刚解封的一层 1: parse_ipv4; default: parse_srcRouting; } } state parse_ipv4 { packet.extract(hdr.ipv4); transition accept; }}control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply { }}control MyIngress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { action drop() { mark_to_drop(standard_metadata); } action srcRoute_nhop() { standard_metadata.egress_spec = (bit<9>)hdr.srcRoutes[0].port;//下一跳端口 hdr.srcRoutes.pop_front(1);//总是删除第一层的srcRoute } action srcRoute_finish() { hdr.ethernet.etherType = TYPE_IPV4;//结束srcRoutes就会全部删除 } action update_ttl(){ hdr.ipv4.ttl = hdr.ipv4.ttl - 1; } apply { if (hdr.srcRoutes[0].isValid()){ if (hdr.srcRoutes[0].bos == 1){//检查是否是最后一跳 srcRoute_finish(); } srcRoute_nhop(); if (hdr.ipv4.isValid()){ update_ttl(); } }else{ drop(); } }}control MyEgress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { apply { }}control MyComputeChecksum(inout headers hdr, inout metadata meta) { apply { }}control MyDeparser(packet_out packet, in headers hdr) { apply { packet.emit(hdr.ethernet); packet.emit(hdr.srcRoutes); packet.emit(hdr.ipv4); }}V1Switch(MyParser(),MyVerifyChecksum(),MyIngress(),MyEgress(),MyComputeChecksum(),MyDeparser()) main;

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。