iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0

若是想要了解 SDN OpenFlow 以及 P4 請不要吝嗇點擊喜歡或是訂閱我喔!(訂閱又不收費XD)
未來有機會也可以跟大家分享我當網管的辛酸血淚史,可以讓人解決問題時可以參考我的文章。

話不多說,我們就累狗!!/images/emoticon/emoticon05.gif

再我們程式撰寫方面我們可以將SWITCH,切割成下列幾個小種類

  • PARSER
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;
    }

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

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);
    }
}
  • INGRESS
control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {

    counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) ingressTunnelCounter;
    counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) egressTunnelCounter;

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

    action myTunnel_ingress(bit<16> dst_id) {
        hdr.myTunnel.setValid();
        hdr.myTunnel.dst_id = dst_id;
        hdr.myTunnel.proto_id = hdr.ethernet.etherType;
        hdr.ethernet.etherType = TYPE_MYTUNNEL;
        ingressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);
    }

    action myTunnel_forward(egressSpec_t port) {
        standard_metadata.egress_spec = port;
    }

    action myTunnel_egress(macAddr_t dstAddr, egressSpec_t port) {
        standard_metadata.egress_spec = port;
        hdr.ethernet.dstAddr = dstAddr;
        hdr.ethernet.etherType = hdr.myTunnel.proto_id;
        hdr.myTunnel.setInvalid();
        egressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);
    }

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

    table myTunnel_exact {
        key = {
            hdr.myTunnel.dst_id: exact;
        }
        actions = {
            myTunnel_forward;
            myTunnel_egress;
            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 all tunneled packets.
            myTunnel_exact.apply();
        }
    }
}
  • ENGRESS
control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
    apply {  }
}
  • DEPARSER
control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
        packet.emit(hdr.myTunnel);
        packet.emit(hdr.ipv4);
    }
}

那 P4RUNTIME是甚麼呢?

  • P4runtime就是 Control Plane 和 Data Plane 之間的溝通流程!
  • 我們的目標就是不透過 switch 內部的 CLI 傳達指令 我們就由 controller直接的下指令下來!

這邊就與 OpenFlow 協定類似 透過 install flow table來決定 routing 方式
我們透過 controller install flow entries 來達到轉發的目的

def readTableRules(p4info_helper, sw):
    """
    Reads the table entries from all tables on the switch.

    :param p4info_helper: the P4Info helper
    :param sw: the switch connection
    """
    print '\n----- Reading tables rules for %s -----' % sw.name
    for response in sw.ReadTableEntries():
        for entity in response.entities:
            entry = entity.table_entry
            #
            #
            print entry
            print '-----'

那我們就必須了解 readTable Rules 怎麼做 一樣當成習題!
我們明天再一起講解!

在此付上我的 Reference,我將會以簡短白話的方式來講解 P4 這套語言,若是你/妳不嫌棄可以訂閱我的發文
每天就根據我自己了解的程度來做發文的動作,如果自己對於 P4也有興趣可以先來預習,那我們明天見!
Reference :
P4_turtorial
[(http://docs.google.com/presentation/d/1zliBqsS8IOD4nQUboRRmF_19poeLLDLadD5zLzrTkVc/edit#slide=id.g37fca2850e_6_1802)]


上一篇
[Day9] P4 Basic Tunnel 制定 Forwarding Rules(2)
下一篇
[DAY11] P4RUNTIME 解析(2)
系列文
A survey between OpenFlow Protocol and P4 in Software Defined Network(SDN)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言