...
- 참고사항
- 패킷의 이해 https://blog.naver.com/sujunghan726/220315439853 → Ethernet 패킷과 IPv4패킷의 이해
bmv2 소프트웨어 스위치에 구현된 V1Model 아키텍처 https://github.com/p4lang/p4c/blob/main/p4include/v1model.p4 → 독립형 또는 Mininet에서 P4 소프트웨어 스위치를 실행하기 위한 시뮬레이션 환경인 mv2에 구현된 소프트웨어 스위치
- 동영상 참고
출처 | 왜 | 내용 | 배운 점 및 기억해야할 점 | 비고 |
---|---|---|---|---|
과학데이터교육 텍스트데이터분석 | 충북대 현장실습 직무교육 | 문장 의미 분석, 단어 빈도 및 연관성 수치 계산, 텍스트 데이터 분석 프로세스 기획, 텍스트 데이터 분석 기법 | 7차시까지 수강 |
배운 것 및 기억해야할 것
P4 튜토리얼 basic forwarding 예제
코드 블럭 | ||
---|---|---|
| ||
/* -*- 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.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;
|
basic forwading의 pod-topo 내의 sX-runtime.json 파일의 설정에 따른 패킷의 이동경로
https://github.com/p4lang/tutorials/tree/master/exercises/basic/pod-topo 의 sX-runtime.json은 스위치의 테이블 역할을 설정한다.
스위치의 테이블 내에 매치되는 목적지(ipAddr)의 다음 경로를 저장하고 있는다. 튜토리얼에 설정된 테이블에 따라 h1 호스트에서 h4로의 경로는 아래와 같다.