2019 SDN上机第7 次作业

basic补充`/* -- P4_16 -- */

include <core.p4>
include <v1model.p4>

const bit<16> TYPE_IPV4 = 0x800;

/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/

typedef 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 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 {
​ /* empty */
}

struct headers {
​ ethernet_t ethernet;
​ ipv4_t ipv4;
}

/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/

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) {
​ 0x0800: parse_ipv4;
​ default: accept;
​ }
​ }
​ state parse_ipv4{
​ packet.extract(hdr.ipv4); //解析数据报文头部
​ transition accept;
​ }
}

/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/

control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
​ apply { }
}

/*************************************************************************
************** I N G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyIngress(inout headers hdr,
​ inout metadata meta,
​ inout standard_metadata_t standard_metadata) {
​ action drop() {
​ mark_to_drop(standard_metadata);
​ }

​ action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
​ /* TODO: fill out code in action body /
​ hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
​ hdr.ethernet.dstAddr = dstAddr;
​ standard_metadata.egress_spec = port;
​ hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
​ }

​ table ipv4_lpm {
​ key = {
​ hdr.ipv4.dstAddr: lpm;
​ }
​ actions = {
​ ipv4_forward;
​ drop;
​ NoAction;
​ }
​ size = 1024;
​ default_action = NoAction();
​ }

​ apply {
​ /
TODO: fix ingress control logic
* - ipv4_lpm should be applied only when IPv4 header is valid
​ */
if(hdr.ipv4.isValid())
​ ipv4_lpm.apply();
}
}

/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyEgress(inout headers hdr,
​ inout metadata meta,
​ inout standard_metadata_t standard_metadata) {
​ apply { }
}

/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/

control MyComputeChecksum(inout headers hdr, inout metadata meta) {
​ apply {
​ update_checksum(
​ hdr.ipv4.isValid(),
​ { hdr.ipv4.version,
​ hdr.ipv4.ihl,
​ hdr.ipv4.diffserv,
​ hdr.ipv4.totalLen,
​ hdr.ipv4.identification,
​ hdr.ipv4.flags,
​ hdr.ipv4.fragOffset,
​ hdr.ipv4.ttl,
​ hdr.ipv4.protocol,
​ hdr.ipv4.srcAddr,
​ hdr.ipv4.dstAddr },
​ hdr.ipv4.hdrChecksum,
​ HashAlgorithm.csum16);
​ }
}

/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
​ apply {
​ /* TODO: add deparser logic */
​ packet.emit(hdr.ethernet);
​ packet.emit(hdr.ipv4);
​ }
}

/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/

V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;

make run运行结果: ![img](https://img2018.cnblogs.com/blog/1330691/201912/1330691-20191211193425206-62249920.png) ![img](https://img2018.cnblogs.com/blog/1330691/201912/1330691-20191211193449092-1071231128.png) 测试是否连通: ![img](https://img2018.cnblogs.com/blog/1330691/201912/1330691-20191211193641901-2128774931.png)basic_tunnel补充/* -- P4_16 -- */

include <core.p4>
include <v1model.p4>

// NOTE: new type added here
const bit<16> TYPE_MYTUNNEL = 0x1212;
const bit<16> TYPE_IPV4 = 0x800;

/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/

typedef 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;
}

// NOTE: added new header type
header myTunnel_t {
​ bit<16> proto_id;
​ bit<16> dst_id;
}

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 {
​ /* empty */
}

// NOTE: Added new header type to headers struct
struct headers {
​ ethernet_t ethernet;
​ myTunnel_t myTunnel;
​ ipv4_t ipv4;
}

/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/

// TODO: Update the parser to parse the myTunnel header as well
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_IPV4 : parse_ipv4;
​ TYPE_MYTUNNEL: parse_myTunnel;
​ default : accept;
​ }
​ }
​ state parse_myTunnel{
​ packet.extract(hdr.myTunnel);
​ transition select(hdr.myTunnel.proto_id) {
​ TYPE_IPV4: parse_ipv4;
​ default: accept;
​ }
​ }

​ state parse_ipv4 {
​ packet.extract(hdr.ipv4);
​ transition accept;
​ }

}

/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/

control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
​ apply { }
}

/*************************************************************************
************** I N G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyIngress(inout headers hdr,
​ inout metadata meta,
​ inout standard_metadata_t standard_metadata) {
​ action drop() {
​ mark_to_drop(standard_metadata);
​ }

​ action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
​ standard_metadata.egress_spec = port;
​ hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
​ hdr.ethernet.dstAddr = dstAddr;
​ hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
​ }

​ table ipv4_lpm {
​ key = {
​ hdr.ipv4.dstAddr: lpm;
​ }
​ actions = {
​ ipv4_forward;
​ drop;
​ NoAction;
​ }
​ size = 1024;
​ default_action = drop();
​ }

​ // TODO: declare a new action: myTunnel_forward(egressSpec_t port)
​ action myTunnel_forward(egressSpec_t port) {
​ standard_metadata.egress_spec = port;
​ }

​ // TODO: declare a new table: myTunnel_exact
​ // TODO: also remember to add table entries!
​ table myTunnel_exact {
​ key = {
​ hdr.myTunnel.dst_id: exact;
​ }
​ actions = {
​ myTunnel_forward;
​ drop;
​ }
​ size = 1024;
​ default_action = drop();
​ }

​ apply {
​ // TODO: Update control flow

​ if (hdr.ipv4.isValid()&&!hdr.myTunnel.isValid()) {
​ ipv4_lpm.apply();
​ }
​ if (hdr.myTunnel.isValid()) {
​ myTunnel_exact.apply();
​ }
​ }
}

/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyEgress(inout headers hdr,
​ inout metadata meta,
​ inout standard_metadata_t standard_metadata) {
​ apply { }
}

/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/

control MyComputeChecksum(inout headers hdr, inout metadata meta) {
​ apply {
​ update_checksum(
​ hdr.ipv4.isValid(),
​ { hdr.ipv4.version,
​ hdr.ipv4.ihl,
​ hdr.ipv4.diffserv,
​ hdr.ipv4.totalLen,
​ hdr.ipv4.identification,
​ hdr.ipv4.flags,
​ hdr.ipv4.fragOffset,
​ hdr.ipv4.ttl,
​ hdr.ipv4.protocol,
​ hdr.ipv4.srcAddr,
​ hdr.ipv4.dstAddr },
​ hdr.ipv4.hdrChecksum,
​ HashAlgorithm.csum16);
​ }
}

/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
​ apply {
​ packet.emit(hdr.ethernet);
​ // TODO: emit myTunnel header as well
​ packet.emit(hdr.myTunnel);
​ packet.emit(hdr.ipv4);
​ }
}

/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/

V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
`make run运行:
img
img
使用ip解析发送信息:
img
使用通道发送信息:
img
向不同主机发送信息:
img
认识和体会:利用p4进行配置,极大地增加了灵活性,非常方便。可以不更换硬件,就进行报文的动态修改。