- Today
- Total
Byeo
5. P4 - ecn 본문
이번 P4 tutorial은 ECN입니다. ECN은 Explicit Congestion Notification의 약자로, switch에서 congestion이 발생했을 때 ECN bit를 set해서 host에게 알려주는 역할을 수행합니다. (DCTCP)
tutorial: https://github.com/p4lang/tutorials/tree/master/exercises/ecn
0. Topology
- switch 1에는 h1과 h11이, switch 2에는 h2와 h22가, 그리고 switch 3에는 h3이 연결되어 있습니다.
- 각 host는 10.0.<switchid>.<hostid>의 IP를 갖고 있습니다.
- h11에서 h22는 iperf를 통해서 많은 양의 traffic을 주고받습니다. 그리고 h1과 h2 사이에서는 낮은 양의 traffic을 주고 받습니다. topology.json에서 s1과 s2 사이에서는 512kbps로 제한하였기 때문에, h2에서는 적절하게 설정된 ECN value를 봐야합니다.
1. Test run
1-1. h1, h11, h2, h22 xterm 열기
mininet> xterm h1 h11 h2 h22
1-2. 각 터미널에 명령어 입력
h2> ./receive.py
h22> iperf -s -u
h1> ./send.py 10.0.2.2 "P4 is cool" 30
h11> iperf -c 10.0.2.22 -t 15 -u
1-3. 결과 확인
결과를 확인해보면 iperf가 최대한의 traffic을 쏘고 있을 텐데에도 불구하고 h2에서는 항상 tos (DiffServ + ECN)이 1인 것을 확인할 수 있습니다.
2. Implementation
이제 ecn.p4를 작업해봅니다.
2-1. ipv4 header split
/*
* TODO: split tos to two fields 6 bit diffserv and 2 bit ecn
*/
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> tos;
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;
}
현재 주어진 skeleton code에는 tos field가 8 bits로 정의되어 있습니다. 이를 6 bits의 diffServ field와 2 bits의 ECN bit로 분리해줍니다.
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> diffServ;
bit<2> ecn;
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;
}
2-2. parser
parser는 건드릴 내용이 딱히 없습니다.
2-3. Ingress Control
ingress control 역시도 건드릴 내용이 없습니다. ipv4_lpm table을 적용해서 ipv4_forward action을 실행합니다.
2-4. Egress Control
/*************************************************************************
**************** 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 {
/*
* TODO:
* - if ecn is 1 or 2
* - compare standard_metadata.enq_qdepth with threshold
* and set hdr.ipv4.ecn to 3 if larger
*/
}
}
Egress control은 standard_metadata.enq_qdepth의 값을 확인하여 특정 값 이상이면 ecn bit를 3으로 전환합니다. 단, ecn이 기존에 1 혹은 2인 경우에만 ECN bit를 지원한다는 뜻이므로 1 또는 2인지 체크해야합니다.
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply {
if (hdr.ipv4.ecn == 1 || hdr.ipv4.ecn == 2) {
if (standard_metadata.enq_qdepth > ECN_THRESHOLD) {
hdr.ipv4.ecn = 3;
}
}
}
}
2-5. Checksum Recalculation
packet의 일부 bit가 바뀌었으므로 checksum을 반드시 재계산해야합니다. 사실 MyComputeChecksum controll에서 이미 해주고 있는데요, field가 바뀌었으므로 코드를 수정해줍니다.
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply {
/* TODO: replace tos with diffserve and ecn */
update_checksum(
hdr.ipv4.isValid(),
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffServ, // <------------
hdr.ipv4.ecn, // <------------
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);
}
}
Result
h1, h11, h2, h22를 동일하게 셋업하고 실행하면 tos가 0x3으로 set된 것을 확인할 수 있습니다!
'프로그래밍 (Programming) > P4' 카테고리의 다른 글
7. P4 - source routing (0) | 2024.07.04 |
---|---|
6. P4 - mri (0) | 2024.06.29 |
4. P4 - P4runtime (0) | 2024.06.25 |
3. P4 - calc (0) | 2024.06.21 |
2. P4 - basic_tunnel (0) | 2024.06.19 |