...
출처 | 왜 | 내용 | 배운 점 및 기억해야할 점 | 비고 |
---|---|---|---|---|
과학데이터교육 텍스트데이터분석 | 충북대 현장실습 직무교육 | 텍스트 데이터 분석 모델 평가 및 구현하기, 토픽별 필요 단어 분류, 긍정 및 부정 감성분석 사전 제작, 데이터 예측을 위한 머신러닝 기법 | 11차시까지 수강 |
23/02/16
- 참고사항
-
- 동영상 참고
출처 | 왜 | 내용 | 배운 점 및 기억해야할 점 | 비고 |
---|---|---|---|---|
과학데이터교육 텍스트데이터분석 | 충북대 현장실습 직무교육 |
배운 것 및 기억해야할 것
P4 튜토리얼 basic forwarding 예제
...
코드 블럭 | ||
---|---|---|
| ||
[01:22:43.726] [bmv2] [W] [thread 3131] [P4Runtime] p4::tmp::P4DeviceConfig is deprecated [01:22:43.728] [bmv2] [D] [thread 3131] Set default default entry for table 'MyIngress.ipv4_lpm': NoAction - [01:22:43.728] [bmv2] [D] [thread 3131] Set default default entry for table 'MyIngress.myTunnel_exact': MyIngress.drop - [01:22:43.730] [bmv2] [D] [thread 3131] simple_switch target has been notified of a config swap [01:22:43.738] [bmv2] [D] [thread 3135] Entry 0 added to table 'MyIngress.ipv4_lpm' [01:22:43.738] [bmv2] [D] [thread 3135] Dumping entry 0 Match key: * hdr.ipv4.dstAddr : LPM 0a000202/32 Action entry: MyIngress.myTunnel_ingress - 64, [01:22:43.741] [bmv2] [D] [thread 3131] Entry 0 added to table 'MyIngress.myTunnel_exact' [01:22:43.741] [bmv2] [D] [thread 3131] Dumping entry 0 Match key: * hdr.myTunnel.dst_id : EXACT 00c8 Action entry: MyIngress.myTunnel_egress - 80000000111,1, /** s1에 ingress rule과 egress rule을 추가**/ [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Processing packet received on port 1 [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser 'parser': start [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser 'parser' entering state 'start' [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Extracting header 'ethernet' [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser state 'start': key is 0800 [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Bytes parsed: 14 [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser 'parser' entering state 'parse_ipv4' [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Extracting header 'ipv4' [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser state 'parse_ipv4' has no switch, going to default next state [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Bytes parsed: 34 [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Parser 'parser': end [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Pipeline 'ingress': start [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(169) Condition "hdr.ipv4.isValid() && !hdr.myTunnel.isValid()" (node_2) is true [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Applying table 'MyIngress.ipv4_lpm' [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Looking up key: * hdr.ipv4.dstAddr : 0a000202 [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Table 'MyIngress.ipv4_lpm': hit with handle 0 //테이블에 항목이 추가되어 h2의 ipAddr와 hit [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Dumping entry 0 Match key: * hdr.ipv4.dstAddr : LPM 0a000202/32 Action entry: MyIngress.myTunnel_ingress - 64, [01:23:34.105] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Action entry is MyIngress.myTunnel_ingress - 64, //hit한 항목의 action인 myTunnel_ingress를 실행한다. [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Action MyIngress.myTunnel_ingress [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(122) Primitive hdr.myTunnel.setValid() [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(123) Primitive hdr.myTunnel.dst_id = dst_id [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(124) Primitive hdr.myTunnel.proto_id = hdr.ethernet.etherType [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(5) Primitive 0x1212; ... [01:23:34.105] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(126) Primitive (bit<32>) hdr.myTunnel.dst_id [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(126) Primitive ingressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id) [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Updated counter 'MyIngress.ingressTunnelCounter' at index 100 [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(174) Condition "hdr.myTunnel.isValid()" (node_4) is true [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Applying table 'MyIngress.myTunnel_exact' [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Looking up key: * hdr.myTunnel.dst_id : 0064 [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Table 'MyIngress.myTunnel_exact': miss //아직 tunnel의 전달 규칙 테이블이 추가되지 않았기 때문에 miss [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Action entry is MyIngress.drop - [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] Action MyIngress.drop [01:23:34.106] [bmv2] [T] [thread 3033] [57.0] [cxt 0] advanced_tunnel.p4(111) Primitive mark_to_drop(standard_metadata) [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Pipeline 'ingress': end [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Egress port is 511 [01:23:34.106] [bmv2] [D] [thread 3033] [57.0] [cxt 0] Dropping packet at the end of ingress |
아직 tunnel 테이블에 항목을 패킷 전달 규칙을 추가하지 않았기 때문에 s1에 패킷이 들어가기만 하고 나오지 않은것을 확인할 수 있다. 전달되지 않은것을 확인할 수 있다.
이후에 제대로 된 mycontroller.py로 테이블을 채워 넣고 h1 ping -c1 h2를 실행했을 때
코드 블럭 | ||
---|---|---|
| ||
[02:02:54.048] [bmv2] [W] [thread 3663] [P4Runtime] p4::tmp::P4DeviceConfig is deprecated
[02:02:54.050] [bmv2] [D] [thread 3663] Set default default entry for table 'MyIngress.ipv4_lpm': NoAction -
[02:02:54.050] [bmv2] [D] [thread 3663] Set default default entry for table 'MyIngress.myTunnel_exact': MyIngress.drop -
[02:02:54.052] [bmv2] [D] [thread 3663] simple_switch target has been notified of a config swap
[02:02:54.059] [bmv2] [D] [thread 3667] Entry 0 added to table 'MyIngress.ipv4_lpm'
[02:02:54.059] [bmv2] [D] [thread 3667] Dumping entry 0
Match key:
* hdr.ipv4.dstAddr : LPM 0a000202/32
Action entry: MyIngress.myTunnel_ingress - 64,
[02:02:54.060] [bmv2] [D] [thread 3663] Entry 0 added to table 'MyIngress.myTunnel_exact' // 패킷 전달 규칙까지 테이블에 추가
[02:02:54.060] [bmv2] [D] [thread 3663] Dumping entry 0
Match key:
* hdr.myTunnel.dst_id : EXACT 0064
Action entry: MyIngress.myTunnel_forward - 2,
[02:02:54.065] [bmv2] [D] [thread 3667] Entry 1 added to table 'MyIngress.myTunnel_exact'
[02:02:54.065] [bmv2] [D] [thread 3667] Dumping entry 1
Match key:
* hdr.myTunnel.dst_id : EXACT 00c8
Action entry: MyIngress.myTunnel_egress - 80000000111,1,
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Processing packet received on port 1
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser 'parser': start
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser 'parser' entering state 'start'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Extracting header 'ethernet'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser state 'start': key is 0800
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Bytes parsed: 14
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser 'parser' entering state 'parse_ipv4'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Extracting header 'ipv4'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser state 'parse_ipv4' has no switch, going to default next state
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Bytes parsed: 34
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Parser 'parser': end
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Pipeline 'ingress': start
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(169) Condition "hdr.ipv4.isValid() && !hdr.myTunnel.isValid()" (node_2) is true
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Applying table 'MyIngress.ipv4_lpm'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Looking up key:
* hdr.ipv4.dstAddr : 0a000202
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Table 'MyIngress.ipv4_lpm': hit with handle 0
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Dumping entry 0
Match key:
* hdr.ipv4.dstAddr : LPM 0a000202/32
Action entry: MyIngress.myTunnel_ingress - 64,
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Action entry is MyIngress.myTunnel_ingress - 64,
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Action MyIngress.myTunnel_ingress
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(122) Primitive hdr.myTunnel.setValid()
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(123) Primitive hdr.myTunnel.dst_id = dst_id
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(124) Primitive hdr.myTunnel.proto_id = hdr.ethernet.etherType
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(5) Primitive 0x1212; ...
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(126) Primitive (bit<32>) hdr.myTunnel.dst_id
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(126) Primitive ingressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id)
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Updated counter 'MyIngress.ingressTunnelCounter' at index 100
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(174) Condition "hdr.myTunnel.isValid()" (node_4) is true
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Applying table 'MyIngress.myTunnel_exact'
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Looking up key:
* hdr.myTunnel.dst_id : 0064
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Table 'MyIngress.myTunnel_exact': hit with handle 0 // 터널을 통한 패킷 전송 규칙도 hit
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Dumping entry 0
Match key:
* hdr.myTunnel.dst_id : EXACT 0064
Action entry: MyIngress.myTunnel_forward - 2,
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Action entry is MyIngress.myTunnel_forward - 2,
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] Action MyIngress.myTunnel_forward
[02:03:13.197] [bmv2] [T] [thread 3602] [33.0] [cxt 0] advanced_tunnel.p4(130) Primitive standard_metadata.egress_spec = port
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Pipeline 'ingress': end
[02:03:13.197] [bmv2] [D] [thread 3602] [33.0] [cxt 0] Egress port is 2
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Pipeline 'egress': start
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Pipeline 'egress': end
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Deparser 'deparser': start
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Updating checksum 'cksum'
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Deparsing header 'ethernet'
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Deparsing header 'myTunnel'
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Deparsing header 'ipv4'
[02:03:13.197] [bmv2] [D] [thread 3605] [33.0] [cxt 0] Deparser 'deparser': end
[02:03:13.198] [bmv2] [D] [thread 3607] [33.0] [cxt 0] Transmitting packet of size 102 out of port 2 //정상적으로 s1의 port2로 패킷 전달 |
코드 블럭 | ||
---|---|---|
| ||
[02:02:54.054] [bmv2] [W] [thread 3666] [P4Runtime] p4::tmp::P4DeviceConfig is deprecated
[02:02:54.056] [bmv2] [D] [thread 3666] Set default default entry for table 'MyIngress.ipv4_lpm': NoAction -
[02:02:54.056] [bmv2] [D] [thread 3666] Set default default entry for table 'MyIngress.myTunnel_exact': MyIngress.drop -
[02:02:54.057] [bmv2] [D] [thread 3666] simple_switch target has been notified of a config swap
[02:02:54.062] [bmv2] [D] [thread 3672] Entry 0 added to table 'MyIngress.myTunnel_exact'
[02:02:54.062] [bmv2] [D] [thread 3672] Dumping entry 0
Match key:
* hdr.myTunnel.dst_id : EXACT 0064
Action entry: MyIngress.myTunnel_egress - 80000000222,1,
[02:02:54.063] [bmv2] [D] [thread 3666] Entry 0 added to table 'MyIngress.ipv4_lpm'
[02:02:54.063] [bmv2] [D] [thread 3666] Dumping entry 0
Match key:
* hdr.ipv4.dstAddr : LPM 0a000101/32
Action entry: MyIngress.myTunnel_ingress - c8,
[02:02:54.064] [bmv2] [D] [thread 3672] Entry 1 added to table 'MyIngress.myTunnel_exact'
[02:02:54.064] [bmv2] [D] [thread 3672] Dumping entry 1
Match key:
* hdr.myTunnel.dst_id : EXACT 00c8
Action entry: MyIngress.myTunnel_forward - 2,
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Processing packet received on port 2//s1에서 보낸 패킷을 s2의 port 2로 받았다.
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser 'parser': start
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser 'parser' entering state 'start'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Extracting header 'ethernet'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser state 'start': key is 1212
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Bytes parsed: 14
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser 'parser' entering state 'parse_myTunnel'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Extracting header 'myTunnel'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser state 'parse_myTunnel': key is 0800
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Bytes parsed: 18
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser 'parser' entering state 'parse_ipv4'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Extracting header 'ipv4'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser state 'parse_ipv4' has no switch, going to default next state
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Bytes parsed: 38
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Parser 'parser': end
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Pipeline 'ingress': start
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(169) Condition "hdr.ipv4.isValid() && !hdr.myTunnel.isValid()" (node_2) is false
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(174) Condition "hdr.myTunnel.isValid()" (node_4) is true
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Applying table 'MyIngress.myTunnel_exact'
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Looking up key:
* hdr.myTunnel.dst_id : 0064
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Table 'MyIngress.myTunnel_exact': hit with handle 0
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Dumping entry 0
Match key:
* hdr.myTunnel.dst_id : EXACT 0064
Action entry: MyIngress.myTunnel_egress - 80000000222,1,
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Action entry is MyIngress.myTunnel_egress - 80000000222,1,
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Action MyIngress.myTunnel_egress
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(134) Primitive standard_metadata.egress_spec = port
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(135) Primitive hdr.ethernet.dstAddr = dstAddr
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(136) Primitive hdr.ethernet.etherType = hdr.myTunnel.proto_id
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(137) Primitive hdr.myTunnel.setInvalid()
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(138) Primitive (bit<32>) hdr.myTunnel.dst_id
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] advanced_tunnel.p4(138) Primitive egressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id)
[02:03:13.198] [bmv2] [T] [thread 3620] [26.0] [cxt 0] Updated counter 'MyIngress.egressTunnelCounter' at index 100
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Pipeline 'ingress': end
[02:03:13.198] [bmv2] [D] [thread 3620] [26.0] [cxt 0] Egress port is 1
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Pipeline 'egress': start
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Pipeline 'egress': end
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Deparser 'deparser': start
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Updating checksum 'cksum'
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Deparsing header 'ethernet'
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Deparsing header 'ipv4'
[02:03:13.198] [bmv2] [D] [thread 3622] [26.0] [cxt 0] Deparser 'deparser': end
[02:03:13.198] [bmv2] [D] [thread 3625] [26.0] [cxt 0] Transmitting packet of size 98 out of port 1 //정상적으로 h2가 연결되어 있는 port 1로 패킷을 전달 |
코드 블럭 | ||
---|---|---|
| ||
#!/usr/bin/env python3
import argparse
import os
import sys
from time import sleep
import grpc
# Import P4Runtime lib from parent utils dir
# Probably there's a better way of doing this.
sys.path.append(
os.path.join(os.path.dirname(os.path.abspath(__file__)),
'../../utils/'))
import p4runtime_lib.bmv2
import p4runtime_lib.helper
from p4runtime_lib.switch import ShutdownAllSwitchConnections
SWITCH_TO_HOST_PORT = 1
SWITCH_TO_SWITCH_PORT = 2
def writeTunnelRules(p4info_helper, ingress_sw, egress_sw, tunnel_id,
dst_eth_addr, dst_ip_addr):
"""
Installs three rules:
1) An tunnel ingress rule on the ingress switch in the ipv4_lpm table that
encapsulates traffic into a tunnel with the specified ID
2) A transit rule on the ingress switch that forwards traffic based on
the specified ID
3) An tunnel egress rule on the egress switch that decapsulates traffic
with the specified ID and sends it to the host
:param p4info_helper: the P4Info helper
:param ingress_sw: the ingress switch connection
:param egress_sw: the egress switch connection
:param tunnel_id: the specified tunnel ID
:param dst_eth_addr: the destination Ethernet address to write in the
egress rule
:param dst_ip_addr: the destination IP to match in the ingress rule
"""
# 1) Tunnel Ingress Rule -> 패킷이 스위치에 들어올 때의 규칙을 ipv4 테이블에 설정한다. 즉, s1에 들어오는 각각의 패킷의 ipv4Addr에 맞는 action을 지정한다. 여기서는 패킷이 이동할 터널의 id를 myTunnel_ingress action에 전달한다.
table_entry = p4info_helper.buildTableEntry(
table_name="MyIngress.ipv4_lpm",
match_fields={
"hdr.ipv4.dstAddr": (dst_ip_addr, 32)
},
action_name="MyIngress.myTunnel_ingress",
action_params={
"dst_id": tunnel_id,
})
ingress_sw.WriteTableEntry(table_entry)
print("Installed ingress tunnel rule on %s" % ingress_sw.name)
# 2) Tunnel Transit Rule
# The rule will need to be added to the myTunnel_exact table and match on
# the tunnel ID (hdr.myTunnel.dst_id). Traffic will need to be forwarded
# using the myTunnel_forward action on the port connected to the next switch.
#
# For our simple topology, switch 1 and switch 2 are connected using a
# link attached to port 2 on both switches. We have defined a variable at
# the top of the file, SWITCH_TO_SWITCH_PORT, that you can use as the output
# port for this action.
#
# We will only need a transit rule on the ingress switch because we are
# using a simple topology. In general, you'll need on transit rule for
# each switch in the path (except the last switch, which has the egress rule),
# and you will need to select the port dynamically for each switch based on
# your topology.
# TODO build the transit rule
# TODO install the transit rule on the ingress switch
table_entry = p4info_helper.buildTableEntry( #tunnel 테이블에 규칙을 추가한다. 여기서는 tunnel헤더의 tunnel_id를 보고 패킷이 전송될 port를 지정해준다.
table_name="MyIngress.myTunnel_exact",
match_fields={
"hdr.myTunnel.dst_id": tunnel_id
},
action_name="MyIngress.myTunnel_forward",
action_params={
"port": SWITCH_TO_SWITCH_PORT
})
ingress_sw.WriteTableEntry(table_entry)
print("Installed transit tunnel rule on %s" % ingress_sw.name)
# 3) Tunnel Egress Rule
# For our simple topology, the host will always be located on the
# SWITCH_TO_HOST_PORT (port 1).
# In general, you will need to keep track of which port the host is
# connected to.
table_entry = p4info_helper.buildTableEntry( # tunnel을 모두 통과하고 호스트로 패킷을 전달할 때 tunnel 헤더의 tunnel_id에 따른 목적지 호스트의 ipAddr과 연결된 port를 지정해준다.
table_name="MyIngress.myTunnel_exact",
match_fields={
"hdr.myTunnel.dst_id": tunnel_id
},
action_name="MyIngress.myTunnel_egress",
action_params={
"dstAddr": dst_eth_addr,
"port": SWITCH_TO_HOST_PORT
})
egress_sw.WriteTableEntry(table_entry)
print("Installed egress tunnel rule on %s" % egress_sw.name)
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
# TODO For extra credit, you can use the p4info_helper to translate
# the IDs in the entry to names
table_name = p4info_helper.get_tables_name(entry.table_id)
print('%s: ' % table_name, end=' ')
for m in entry.match:
print(p4info_helper.get_match_field_name(table_name, m.field_id), end=' ')
print('%r' % (p4info_helper.get_match_field_value(m),), end=' ')
action = entry.action.action
action_name = p4info_helper.get_actions_name(action.action_id)
print('->', action_name, end=' ')
for p in action.params:
print(p4info_helper.get_action_param_name(action_name, p.param_id), end=' ')
print('%r' % p.value, end=' ')
print()
def printCounter(p4info_helper, sw, counter_name, index):
"""
Reads the specified counter at the specified index from the switch. In our
program, the index is the tunnel ID. If the index is 0, it will return all
values from the counter.
:param p4info_helper: the P4Info helper
:param sw: the switch connection
:param counter_name: the name of the counter from the P4 program
:param index: the counter index (in our case, the tunnel ID)
"""
for response in sw.ReadCounters(p4info_helper.get_counters_id(counter_name), index):
for entity in response.entities:
counter = entity.counter_entry
print("%s %s %d: %d packets (%d bytes)" % (
sw.name, counter_name, index,
counter.data.packet_count, counter.data.byte_count
))
def printGrpcError(e):
print("gRPC Error:", e.details(), end=' ')
status_code = e.code()
print("(%s)" % status_code.name, end=' ')
traceback = sys.exc_info()[2]
print("[%s:%d]" % (traceback.tb_frame.f_code.co_filename, traceback.tb_lineno))
def main(p4info_file_path, bmv2_file_path):
# Instantiate a P4Runtime helper from the p4info file
p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_file_path)
try:
# Create a switch connection object for s1 and s2;
# this is backed by a P4Runtime gRPC connection.
# Also, dump all P4Runtime messages sent to switch to given txt files.
s1 = p4runtime_lib.bmv2.Bmv2SwitchConnection(
name='s1',
address='127.0.0.1:50051',
device_id=0,
proto_dump_file='logs/s1-p4runtime-requests.txt')
s2 = p4runtime_lib.bmv2.Bmv2SwitchConnection(
name='s2',
address='127.0.0.1:50052',
device_id=1,
proto_dump_file='logs/s2-p4runtime-requests.txt')
# Send master arbitration update message to establish this controller as
# master (required by P4Runtime before performing any other write operation)
s1.MasterArbitrationUpdate()
s2.MasterArbitrationUpdate()
# Install the P4 program on the switches
s1.SetForwardingPipelineConfig(p4info=p4info_helper.p4info,
bmv2_json_file_path=bmv2_file_path)
print("Installed P4 Program using SetForwardingPipelineConfig on s1")
s2.SetForwardingPipelineConfig(p4info=p4info_helper.p4info,
bmv2_json_file_path=bmv2_file_path)
print("Installed P4 Program using SetForwardingPipelineConfig on s2")
# Write the rules that tunnel traffic from h1 to h2
writeTunnelRules(p4info_helper, ingress_sw=s1, egress_sw=s2, tunnel_id=100,
dst_eth_addr="08:00:00:00:02:22", dst_ip_addr="10.0.2.2")
# Write the rules that tunnel traffic from h2 to h1
writeTunnelRules(p4info_helper, ingress_sw=s2, egress_sw=s1, tunnel_id=200,
dst_eth_addr="08:00:00:00:01:11", dst_ip_addr="10.0.1.1")
# TODO Uncomment the following two lines to read table entries from s1 and s2
readTableRules(p4info_helper, s1)
readTableRules(p4info_helper, s2)
# Print the tunnel counters every 2 seconds
while True:
sleep(2)
print('\n----- Reading tunnel counters -----')
printCounter(p4info_helper, s1, "MyIngress.ingressTunnelCounter", 100)
printCounter(p4info_helper, s2, "MyIngress.egressTunnelCounter", 100)
printCounter(p4info_helper, s2, "MyIngress.ingressTunnelCounter", 200)
printCounter(p4info_helper, s1, "MyIngress.egressTunnelCounter", 200)
except KeyboardInterrupt:
print(" Shutting down.")
except grpc.RpcError as e:
printGrpcError(e)
ShutdownAllSwitchConnections()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='P4Runtime Controller')
parser.add_argument('--p4info', help='p4info proto in text format from p4c',
type=str, action="store", required=False,
default='./build/advanced_tunnel.p4.p4info.txt')
parser.add_argument('--bmv2-json', help='BMv2 JSON file from p4c',
type=str, action="store", required=False,
default='./build/advanced_tunnel.json')
args = parser.parse_args()
if not os.path.exists(args.p4info):
parser.print_help()
print("\np4info file not found: %s\nHave you run 'make'?" % args.p4info)
parser.exit(1)
if not os.path.exists(args.bmv2_json):
parser.print_help()
print("\nBMv2 JSON file not found: %s\nHave you run 'make'?" % args.bmv2_json)
parser.exit(1)
main(args.p4info, args.bmv2_json) |