버전 비교

  • 이 줄이 추가되었습니다.
  • 이 줄이 삭제되었습니다.
  • 서식이 변경되었습니다.

...


전공교육개발실습부서교육부서업무지원기타
P과학데이터교육 일 3.2시간 이상 수강p4 tutorial실습
우수성과취합 마무리
D텍스트 데이터분석 수강, 인공지능 부분 수강basic forwarding 실습, basic tunnel 실습,P4runtime실습, mri 실습,소스라우트 실습, 부하분산 실습
우수성과 취합 마무리 및 검토
C텍스트 데이터분석 수강, 인공지능 부분 수강basic forwarding 실습, basic tunnel 실습,P4runtime실습, mri 실습,소스라우트 실습, 부하분산 실습 및 이해
우수성과 취합 마무리 및 검토
A




일일회고

23/02/13

  • Fact : P4 실습환경을 구축하고 기본적인 forwarding 을 실습해보았다, 우수성과취합을 진행했다.
  • Feelings : 새로운 언어를 배우는 것은 언제나 어렵지만 c언어와 비슷한 면이 있어서 다행이다.
  • Finding : 네트워크를 효율적으로 관리하는 프로그래밍 언어가 있다는 것을 처음 알았다.
  • Future Action Plan : 우수성과 취합, P4 튜토리얼을 보면서 다음 내용 실습
  • Feedbacks : 

...

  • Fact : P4 튜토리얼의 P4runtime과 mri를 실습해보고 이해하였다.
  • Feelings : 생각보다 경로를 추척하기 위한 mri의 구조가 단순해서 놀랐다.
  • Finding : 첫날에 들었던 INT의 축소된 버전을 해보면서 어떤식으로 경로를 모니터링 할 수 있는지 알았다.
  • Future Action Plan : P4 소스포워딩
  • Feedbacks :

23/02/17

  • Fact :  P4 튜토리얼의 P4sourceroute와 P4 loadbalancing을 실습해보고 이해하였다.
  • Feelings :  어느정도 기본적인 P4 코드를 짤 수 있을 것 같다.
  • Finding :  새로운 소스라우트와 로드밸런싱을 배웠다.
  • Future Action Plan :  P4의 남은 튜토리얼 수행
  • Feedbacks : 

Memo

23/02/13

...

출처

내용

배운 점 및 기억해야할 점

비고

과학데이터교육 텍스트데이터분석충북대 현장실습 직무교육
데이터 시각화, 정형-비정형 데이터 분석 모델 기획, 공공 데이터 분석, 분석 목적 인사이트 도출, 예측 및 데이터 평가텍스트데이터분석 수강 끝

23/02/17

출처

내용

배운 점 및 기억해야할 점

비고

과학데이터교육 인공지능충북대 현장실습 직무교육
인공지능의 소개, 인공지능의 발달사, 에이전트 정의 및 지능형 에이전트, 에이전트 환경과 에이전트 아키텍처4차시까지 수강

...

코드 블럭
linenumberstrue
/* -*- 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;

//ethernet의 기본 헤더 
header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}
//IPv4의 기본 헤더
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  ***********************************
*************************************************************************/
//패킷에서 헤더를 분리
//packet_in packet은 스위치에 들어오는 패킷
//out headers hdr은 패킷에서 분리된 헤더들이 각각 저장될 변수같은것
//start 상태로 시작해서 모든 헤더 분리가 정상적으로 끝난다면 accept 상태로 이동해서 정상종료, 아니라면 ignore 상태로 이동
parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {

	//패킷을 처음으로 전달받아서 시작된 상태
    state start {
		//parse_ethernet으로 상태 이동
        transition parse_ethernet;
    }
    state parse_ethernet {
		//패킷에서 ethernet헤더에 맞게 분리/추출
        packet.extract(hdr.ethernet);
		//패킷에서 분리된 ethernet 헤더에서 etherType 값이 위에서 정의된 TYPE_IPV4 0x800라면 parse_ipv4 상태로 이동, 0x800이 아닌 상태(default)라면 accept상태로 이동 -> 즉 c언어의 switch 같은 문법
        transition select(hdr.ethernet.etherType) {
            TYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }
	
    state parse_ipv4 {
		//패킷에서 추가적으로 ipv4 헤더 분리/추출
        packet.extract(hdr.ipv4);
		//패킷에서 추출 후에 accept 상태로 이동
        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   *******************
*************************************************************************/

//table을 참조하면서 패킷이 다음으로 이동할 경로 설정
control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {
	//table에 match되는 ipv4의 dstAddr이 없다면 패킷을 삭제한다.
    action drop() {
        mark_to_drop(standard_metadata);
    }
	//table에 match되는 ipv4의 dstAddr이 있다면 실행되는 action으로 알맞은 dstAddr와 port를 인수로 전달받는다.
    action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
		//해당 스위치/호스트에서 송신할때 쓰는 포트를 설정
		//standard_metadata는 v1model 아키텍처에 의해 전달받은 구조체이며 패킷의 다양한 정보가 들어있다. 특히 standard_metadata.egress_spec는 패킷이 이동할 출력포트를 지정한다.
         standard_metadata.egress_spec = port;
		//이더넷의 헤더안의 srtAddr과 dstAddr을 알맞게 설정한다.
        hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
        hdr.ethernet.dstAddr = dstAddr;
		//패킷이 이동할 때마다 ipv4의 ttl을 1씩 줄어들게한다.
        hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
    }
	//테이블을 정의한다.
    table ipv4_lpm {
		//테이블의 key와 match되는 방식을 설정한다.
        key = {
            hdr.ipv4.dstAddr: lpm;
        }
		//테이블의 모든 액션을 정의한다.
        actions = {
            ipv4_forward;
            drop;
            NoAction;
        }
        size = 1024;
		//기본 액션을 정의한다.
        default_action = drop();
    }
	//컨트롤 실행
    apply {
		//ipv4가 유효하다면 테이블 매칭을 실행한다.
        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   **************
*************************************************************************/

//ipv4 헤더의 내용이 변경되었으므로 체크섬 값도 그에 맞게 변경
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  *******************************
*************************************************************************/
//v1model의 기본적인 switch 아키텍처
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;

...

코드 블럭
/* -*- 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) {
			//이더넷타입이 새로 만든 타입이라면 parse_myTunnel로 헤더 분리 이더넷타입에 따른 파서를 수행한다.
            TYPE_MYTUNNEL: parse_myTunnel;
            TYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_myTunnel {
		//터널링 헤더 분리
        packet.extract(hdr.myTunnel);
		//이후에 터널링 헤더 안의 proto_id가 ipv4라면 ipv4 헤더도 분리
        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, 터널의 다음 터널이 존재하는목적지 포트를 인수로 받는다
    action myTunnel_forward(egressSpec_t port) {
		//나가는 포트를 설정
        standard_metadata.egress_spec = port;
    }
	//새로운 테이블 설정
    table myTunnel_exact {
        key = {
			//터널링 헤더의 dst_id를 key로 설정하고 구별 방법을 exact로 설정
            hdr.myTunnel.dst_id: exact;
        }
        actions = {
			//알맞는 action 설정
            myTunnel_forward;
            drop;
        }
        size = 1024;
        default_action = drop();
    }

    apply {
		//ipv4헤더가 유효하고 터널링 헤더가 유효하지 않다면 ipv4테이블로 포워딩을 진행한다.
        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;

...

토폴로지의 모든 스위치를 모두 돌아서 h1→h2로 패킷전송이 성공했다.

P4 튜토리얼 Load balancing의 이해

사전 조건

간단한 버전의 Equal-Cost Multipath Forwarding을 기반으로 한 형태의 로드 밸런싱을 구현합니다. 구현할 스위치는 두 개의 테이블을 사용하여 임의로 두 개의 대상 호스트 중 하나로 패킷을 전달합니다. 첫 번째 테이블은 해시 함수(소스 및 대상 IP 주소, IP 프로토콜, 소스 및 대상 TCP 포트로 구성된 5-튜플에 적용됨)를 사용하여 두 호스트 중 하나를 선택합니다. 두 번째 테이블은 계산된 해시 값을 사용하여 선택한 호스트로 패킷을 전달합니다.

튜토리얼 코드 리뷰

코드 블럭
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

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

header ethernet_t {
    bit<48> dstAddr;
    bit<48> 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;
    bit<32> srcAddr;
    bit<32> dstAddr;
}
//tcp 헤더
header tcp_t {
    bit<16> srcPort;
    bit<16> dstPort;
    bit<32> seqNo;
    bit<32> ackNo;
    bit<4>  dataOffset;
    bit<3>  res;
    bit<3>  ecn;
    bit<6>  ctrl;
    bit<16> window;
    bit<16> checksum;
    bit<16> urgentPtr;
}
//ecmp 선택자
struct metadata {
    bit<14> ecmp_select;
}

struct headers {
    ethernet_t ethernet;
    ipv4_t     ipv4;
    tcp_t      tcp;
}

/*************************************************************************
*********************** 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) {
            0x800: parse_ipv4;
            default: accept;
        }
    }
    state parse_ipv4 {
        packet.extract(hdr.ipv4);
        transition select(hdr.ipv4.protocol) {
            6: parse_tcp;
            default: accept;
        }
    }
    state parse_tcp {
        packet.extract(hdr.tcp);
        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 set_ecmp_select(bit<16> ecmp_base, bit<32> ecmp_count) {
		//소스 및 대상 IP 주소, IP 프로토콜, 소스 및 대상 TCP 포트로 해쉬값을 얻고 ecmp_select에 저장한다.
        hash(meta.ecmp_select,
            HashAlgorithm.crc16,
            ecmp_base,
            { hdr.ipv4.srcAddr,
              hdr.ipv4.dstAddr,
              hdr.ipv4.protocol,
              hdr.tcp.srcPort,
              hdr.tcp.dstPort },
            ecmp_count);
    }
    action set_nhop(bit<48> nhop_dmac, bit<32> nhop_ipv4, bit<9> port) {//나갈 포드를 지정한다.
        hdr.ethernet.dstAddr = nhop_dmac;
        hdr.ipv4.dstAddr = nhop_ipv4;
        standard_metadata.egress_spec = port;
        hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
    }
    table ecmp_group {//어떤 ecmp 그룹인지를 판별한다.
        key = {
            hdr.ipv4.dstAddr: lpm;
        }
        actions = {
            drop;
            set_ecmp_select;
        }
        size = 1024;
    }
    table ecmp_nhop {//ecmp그룹에 맞는 목적지, 경로를 지정한다.
        key = {
            meta.ecmp_select: exact;
        }
        actions = {
            drop;
            set_nhop;
        }
        size = 2;
    }
    apply {
        if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
            ecmp_group.apply();
            ecmp_nhop.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) {
	//이더넷의 srcAddr을 수정한다.
    action rewrite_mac(bit<48> smac) {
        hdr.ethernet.srcAddr = smac;
    }
    action drop() {
        mark_to_drop(standard_metadata);
    }
    table send_frame {//나가는 포트에 맞게 이더넷 헤더 수정
        key = {
            standard_metadata.egress_port: exact;
        }
        actions = {
            rewrite_mac;
            drop;
        }
        size = 256;
    }
    apply {
        send_frame.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);
        packet.emit(hdr.tcp);
    }
}

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

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

튜토리얼 실행결과

Image Added

h1에서 자기 자신에게 보낼 패킷을 보내면 패킷의 TCP 헤더에 따라 목적지 호스트가 바뀌는 것을 볼 수 있다.