...
전공교육 | 개발실습 | 부서교육 | 부서업무지원 | 기타 | |
---|---|---|---|---|---|
P | 과학데이터교육 일 3.2시간 이상 수강 | p4 tutorial실습 | |||
D | ECN 실습, QoS 실습, Firewall 실습, Link monitoring 실습 | ||||
C | |||||
A |
일일회고
23/02/20
- Fact : ECN, QoS, Firewall을 실습해보고 코드를 이해했다.
- Feelings : 글로만 배웠던 것들을 코딩을 통해 구현해 보니 신기했다.
- Finding : QoS가 무엇인지 처음 알게 되었고 Firewall에 블룸 필터의 개념을 확실히 알게 되었다.
- Future Action Plan : Link Monitoring 실습, P4 튜토리얼 내용 총 정리
- Feedbacks :
23/02/21
- Fact :
- Feelings :
- Finding :
- Future Action Plan :
- Feedbacks :
Memo
23/02/20
- 참고사항
- 동영상 참고
출처 | 왜 | 내용 | 배운 점 및 기억해야할 점 | 비고 |
---|---|---|---|---|
과학데이터교육 인공지능 | 충북대 현장실습 직무교육 | 다양한 에이전트 아키텍처, 상태공간과 탐색문제1,2, 다양한 탐색 문제와 탐색 전략 |
23/02/21
- 참고사항
- -
- 동영상 참고
출처 | 왜 | 내용 | 배운 점 및 기억해야할 점 | 비고 |
---|---|---|---|---|
과학데이터교육 인공지능 | 충북대 현장실습 직무교육 |
배운 것 및 기억해야할 것
P4 튜토리얼 Explicit Congestion Notification(ECN)의 이해
...
h1과 h2는 통신이 되며 h1에서 h3로는 통신이 되지만 h3에서 h1로는 통신이 되지 않는다.
P4 튜토리얼 Explicit Congestion Notification(ECN)의 이해
사전조건
probe 패킷이라는 경로 상의 스위치 정보 및 패킷 이동 경로에 대한 정보를 담는 헤더를 추가하여 토폴로지의 모든 스위치를 순회해본다.
코드 리뷰
코드 블럭 |
---|
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>
const bit<16> TYPE_IPV4 = 0x800;
const bit<16> TYPE_PROBE = 0x812;
#define MAX_HOPS 10
#define MAX_PORTS 8
/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/
typedef bit<9> egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;
typedef bit<48> time_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;
}
// Top-level probe header, indicates how many hops this probe
// packet has traversed so far.
header probe_t {
bit<8> hop_cnt;
}
// The data added to the probe by each switch at each hop.
header probe_data_t {
bit<1> bos;
bit<7> swid;
bit<8> port;
bit<32> byte_cnt;
time_t last_time;
time_t cur_time;
}
// Indicates the egress port the switch should send this probe
// packet out of. There is one of these headers for each hop.
header probe_fwd_t {
bit<8> egress_spec;
}
struct parser_metadata_t {
bit<8> remaining;
}
struct metadata {
bit<8> egress_spec;
parser_metadata_t parser_metadata;
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
probe_t probe;
probe_data_t[MAX_HOPS] probe_data;
probe_fwd_t[MAX_HOPS] probe_fwd;
}
/*************************************************************************
*********************** 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;
}
// 이더넷 헤더에서 ipv4 패킷인지 프로브 패킷인지 구분해서 헤더를 추출한다.
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
TYPE_IPV4: parse_ipv4;
TYPE_PROBE: parse_probe;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition accept;
}
//프로브 패킷이라면 probe 헤더에서 hop_cnt필드로 지나온 hop의 개수를 저장한다.
state parse_probe {
packet.extract(hdr.probe);
meta.parser_metadata.remaining = hdr.probe.hop_cnt + 1;
transition select(hdr.probe.hop_cnt) {
0: parse_probe_fwd;
default: parse_probe_data;
}
}
//지나온 홉에 개수에 따라 probe_data 헤더를 추출한다. probe_data의 bos가 1 즉, 마지막 probe_data까지 추출했다면 probe_fwd를 추출한다.
state parse_probe_data {
packet.extract(hdr.probe_data.next);
transition select(hdr.probe_data.last.bos) {
1: parse_probe_fwd;
default: parse_probe_data;
}
}
//probe_fwd를 추출한다. probe_fwd는 이 패킷이 지나갈 경로를 나타내는 헤더이다. 현재 지나온 hop의 개수에 맞게 다음 경로(port)를 추출하는 것이다.
state parse_probe_fwd {
packet.extract(hdr.probe_fwd.next);
meta.parser_metadata.remaining = meta.parser_metadata.remaining - 1;
// extract the forwarding data
meta.egress_spec = hdr.probe_fwd.last.egress_spec;
transition select(meta.parser_metadata.remaining) {
0: accept;
default: parse_probe_fwd;
}
}
}
/*************************************************************************
************ 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();
}
else if (hdr.probe.isValid()) {
//다음 경로(port)를 설정한다.
standard_metadata.egress_spec = (bit<9>)meta.egress_spec;
//지나온 hop의 개수를 증가시킨다.
hdr.probe.hop_cnt = hdr.probe.hop_cnt + 1;
}
}
}
/*************************************************************************
**************** 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) {
// count the number of bytes seen since the last probe
register<bit<32>>(MAX_PORTS) byte_cnt_reg;
// remember the time of the last probe
register<time_t>(MAX_PORTS) last_time_reg;
action set_swid(bit<7> swid) {
hdr.probe_data[0].swid = swid;
}
table swid {
actions = {
set_swid;
NoAction;
}
default_action = NoAction();
}
apply {
bit<32> byte_cnt;
bit<32> new_byte_cnt;
time_t last_time;
time_t cur_time = standard_metadata.egress_global_timestamp;
// increment byte cnt for this packet's port
byte_cnt_reg.read(byte_cnt, (bit<32>)standard_metadata.egress_port);
byte_cnt = byte_cnt + standard_metadata.packet_length;
// reset the byte count when a probe packet passes through
new_byte_cnt = (hdr.probe.isValid()) ? 0 : byte_cnt;
byte_cnt_reg.write((bit<32>)standard_metadata.egress_port, new_byte_cnt);
if (hdr.probe.isValid()) {
// fill out probe fields
hdr.probe_data.push_front(1);
hdr.probe_data[0].setValid();
if (hdr.probe.hop_cnt == 1) {
hdr.probe_data[0].bos = 1;
}
else {
hdr.probe_data[0].bos = 0;
}
// set switch ID field
swid.apply();
hdr.probe_data[0].port = (bit<8>)standard_metadata.egress_port;
hdr.probe_data[0].byte_cnt = byte_cnt;
// read / update the last_time_reg
last_time_reg.read(last_time, (bit<32>)standard_metadata.egress_port);
last_time_reg.write((bit<32>)standard_metadata.egress_port, cur_time);
hdr.probe_data[0].last_time = last_time;
hdr.probe_data[0].cur_time = cur_time;
}
}
}
/*************************************************************************
************* 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.probe);
packet.emit(hdr.probe_data);
packet.emit(hdr.probe_fwd);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
|
실행결과
코드 블럭 |
---|
#!/usr/bin/env python3
import sys
import time
from probe_hdrs import *
def main():
probe_pkt = Ether(dst='ff:ff:ff:ff:ff:ff', src=get_if_hwaddr('eth0')) / \ #패킷을 보내기전에 경로를 설정해줬다.
Probe(hop_cnt=0) / \
ProbeFwd(egress_spec=4) / \
ProbeFwd(egress_spec=1) / \
ProbeFwd(egress_spec=4) / \
ProbeFwd(egress_spec=1) / \
ProbeFwd(egress_spec=3) / \
ProbeFwd(egress_spec=2) / \
ProbeFwd(egress_spec=3) / \
ProbeFwd(egress_spec=2) / \
ProbeFwd(egress_spec=1)
while True:
try:
sendp(probe_pkt, iface='eth0')
time.sleep(1)
except KeyboardInterrupt:
sys.exit()
if __name__ == '__main__':
main() |
위의 코드로 패킷의 경로를 설정한 후에 h1에서 실행을 하면 저 경로로 패킷이 갔다가 다시 h1로 돌아오는 것을 알 수 있다. 이때 h1에서 돌아온 패킷을 검사하는 ./receive.py를 실행하면 위 사진과 같은 결과를 볼 수 있다.
첫 줄부터 보면 s1의 port1을 통해 패킷이 나온 것을 확인 할 수 있으며 마지막 프로브 패킷이 포트에서 전송된 이후 s1의 port1에서 전송된 바이트 수를 알 수 있다.
맨 밑줄이 프로브 패킷의 첫 시작이므로 윗 줄로 갈수록 각 포트에서 전송된 바이트가 점점 증가하는 것을 볼 수 있다.