zoukankan      html  css  js  c++  java
  • 2019 SDN上机第7次作业

    1.补充并运行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) {
                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();
        }
        
        apply {
            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 {
            packet.emit(hdr.ethernet);
            packet.emit(hdr.ipv4);
        }
    }
    
    /*************************************************************************
    ***********************  S W I T C H  *******************************
    *************************************************************************/
    
    V1Switch(
    MyParser(),
    MyVerifyChecksum(),
    MyIngress(),
    MyEgress(),
    MyComputeChecksum(),
    MyDeparser()
    ) main;
    
    

    接着打开终端,进入basic文件夹,输入make run编译运行
    img
    img

    在mininet界面进行ping通测试,
    如果都连通,证明代码补充成功
    img

    2.补充并运行支持基本隧道协议的basic_tunnel代码

    任务是定义新的头部类型并修改交换机部分的代码,从而将消息封装进IP数据包并让目标端口使用新的头部类型

    补充后代码如下:

    /* -*- P4_16 -*- */
    #include <core.p4>
    #include <v1model.p4>
    
    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;
    }
    
    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 */
    }
    
    struct headers {
        ethernet_t   ethernet;
        myTunnel_t   myTunnel;
        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) {
                TYPE_MYTUNNEL: parse_myTunnel;
                TYPE_IPV4: parse_ipv4;
                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();
        }
        
        action myTunnel_forward(egressSpec_t port) {
            standard_metadata.egress_spec = port;
        }
    
        table myTunnel_exact {
            key = {
                hdr.myTunnel.dst_id: exact;
            }
            actions = {
                myTunnel_forward;
                drop;
            }
            size = 1024;
            default_action = drop();
        }
    
        apply {
            if (hdr.ipv4.isValid() && !hdr.myTunnel.isValid()) {
                // Process only non-tunneled IPv4 packets
                ipv4_lpm.apply();
            }
    
            if (hdr.myTunnel.isValid()) {
                // process tunneled packets
                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);
            packet.emit(hdr.myTunnel);
            packet.emit(hdr.ipv4);
        }
    }
    
    /*************************************************************************
    ***********************  S W I T C H  *******************************
    *************************************************************************/
    
    V1Switch(
    MyParser(),
    MyVerifyChecksum(),
    MyIngress(),
    MyEgress(),
    MyComputeChecksum(),
    MyDeparser()
    ) main;
    
    

    接着打开终端,进入basic_tunnel文件夹,输入make run编译运行,并进行pingall连接测试:
    img

    img

    在mininet命令提示符界面输入

    xterm h1 h2 h3 
    

    来模拟终端

    img

    img

    img

    先在主机2的xterm界面输入

    ./receive.py
    

    启动服务器

    img

    接着在主机3的xterm界面输入

    ./send.py 10.0.2.2 "lsj nb"
    

    发送信息
    img

    检查主机2的xterm界面,可以看到已经接收到了信息

    img

    接着在主机3的xterm界面更改dst_id,再次发送信息

    ./send.py 10.0.1.1 "lsj realy nb" --dst_id 2
    

    img

    检查主机2的xterm界面,可以看到本应该发到主机1的信息,因为dst_id的修改,发到了主机2(IP地址变更为了主机1的地址)。
    img

    接着在主机3的xterm界面修改IP地址,再一次发送信息

    ./send.py 10.0.2.2 "lsj realy nb" --dst_id 2
    

    检查主机2的xterm界面,可以看到已经接收到了信息,IP地址又变更为了主机2的地址,这是因为交换机不再使用IP头部数据来定位,而是用数据包中的隧道头部数据来定位。

    3.对P4的认识和体会

    P4(Programming Protocol-Independent Packet Processors)是一种数据面的高级编程语言。它可以克服OpenFlow的局限。通过P4语言,我们可以定义我们想要的数据面。进而再通过南向协议添加流表项。 P4凭借其优异的抽象能力以及灵活性,将网络的可编程性下压到了数据平面,让数据包的解析和转发流程也能通过编程控制,为实现SDN的终极目标提供了有力支撑。

  • 相关阅读:
    Linux查看物理CPU个数、核数、逻辑CPU个数
    epoll、cpoll、xpoll
    Curl命令简介
    ps:分钟级监控服务内存变化情况
    linux系统/var/log目录下的信息详解
    pthread_create、pthread_join
    【转载】nginx中gzip的各项配置以及配置参数的意思详解
    linux——Nginx——反向代理服务器
    点击复制文本 ctrl+v粘贴
    npm源切换
  • 原文地址:https://www.cnblogs.com/gs-23/p/12026223.html
Copyright © 2011-2022 走看看