Byeo

P4: Programming Protocol-Independent Packet Processors 본문

프로그래밍 (Programming)/논문 (Paper)

P4: Programming Protocol-Independent Packet Processors

BKlee 2023. 10. 23. 21:34
반응형

 해당 포스트는 SIgcomm' 14 CCR https://www.sigcomm.org/sites/default/files/ccr/papers/2014/July/0000000-0000004.pdf 를 번역해서 정리한 글입니다.

 

 

초록

P4는 packet 처리 장치를 위한 protocol 비의존적 프로그래밍 언어이다. P4는 OpenFlow와 같은 SDN control protocol과 결합하여 동작한다. 현재의 형태는 OpenFlow가 packet header의 필요 부분을 명시함으로써 동작한다. 하지만 field의 개수가 12개에서 41개로 늘어났고, 이러한 방식은 복잡도를 증가시키나 유연성은 그대로인 문제가 있다. 이 논문에서는 P4를 제안하며, OpenFlow가 어떻게 발전해야할지 제안한다. P4는 세 가지 목표를 갖는다: (1) Reconfigurability in the field: 스위치에 packet 처리 방법이 이미 배포되어 있어도, 프로그래머는 이를 변경할 수 있어야 한다. (2) Protocol independence: 스위치는 어떠한 네트워크 프로토콜에도 묶이면 (제한되면) 안된다. (3) Target independence: 프로그래머는 packet 처리 기능을 하드웨어의 구성과 상관없이 표현할 수 있어야 한다.

 

1. 서론

 Software-Defined Network (SDN)은 네트워크에 대해 프로그래밍을 통한 방식의 제어를 운영자에게 제공한다. SDN에서는 control plane이 물리적으로 forwarding plane (data plane)과 구분되어 있으며, 하나의 control plane이 여러개의 forwarding palne을 제어한다. Forwarding device은 다양한 방식으로 프로그래밍 될 수 있는데 비해, OpenFlow와 같이 상용-오픈-vendor 무관한 인터페이스는 control plane이 다양한 hardware와 software 형상을 갖는 forwarding device를 제어가 가능토록 한다.

 OpenFlow는 처음에 단일 table의 12개의 간단한 field로부터 출발하여, 현재는 수많은 field와 여러 tables를 갖는 구조로 발전하였다. 

 그러나 새로운 header field의 등장은 멈출 기미가 없다. 예를 들어, data-center network와 같은 경우에는 새로운 packet encapsulation protocol (e.g., NVGRE, VXLAN, STT)등을 도입하고 있다. 그래서 반복적으로 OpenFlow의 지원 field를 확장하는 것 보다는, packet header를 matching하고 parsing 하는 데 유연한 방식으로 할 수 있도록 지원하는 새로운 스위치가 논의되어야 한다고 저자들은 주장했다. 이러한 범용적이고 확장가능한 접근 방식은 오늘날의 OpenFlow 1.x 표준보다 간단하고, 우아하며, 미래 지향적이라고 이야기한다.

 최근 칩 디자인은 terabit 속도에서의 custom ASIC에서도 유연함을 얻을 수 있다는 것을 보였다. 그러나 이러한 새로운 세대의 스위치를 프로그래밍하는 것은 쉽지는 않다. 각각의 칩은 각자의 low-level interface를 갖고 있기 때문. 이 논문에서는 P4 (higher-level language for Programming Protocol-independent Packet Processors) 를 소개한다. Figure 1은 packet이 어떻게 처리되어야 할지 알려주도록 스위치를 설정하기 위한 P4와 기존의 fixed function switch에서 사용되던 API (e.g., OpenFlow) 사이의 관계를 보여준다. P4는 network programming에 대한 추상 레벨을 끌어올림과 동시에, 컨트롤러와 스위치 사이에 일반적인 인터페이스를 제공한다. 그래서 미래의 OpenFlow는 controller가 스위치에게 고정적인 기능에 제한되어 설정하는 방식을 넘어서, 어떻게 동작해야 할지 지시할 수 있으리라 저자들은 생각한다. 가장 핵심적인 챌린지는, 수많은 하드웨어-소프트웨어를 아우를 수 있는 표현력과 쉬운 구현 사이에서 적절한 "sweet spot"을 찾는 것.

 

 P4의 목표는 다음과 같다.

  •  Reconfigurability: 컨트롤러는 packet 파싱과 처리를 재정의할 수 있어야 한다.
  •  Protocol independence: 스위치는 어떠한 packet의 포맷에도 묶여있으면 안된다. 대신, 컨트롤러는 (1) header field를 추출해내기 위한 parcket parser와 (2) 해당 header들에 대한 match & action의 집합을 명시해야 한다.
  •  Target independence: C언어 프로그래머가 밑에 있는 CPU를 몰라도 되는 것처럼, 컨트롤러 프로그래머가 밑에 있는 스위치를 알 필요가 없어야 한다. 대신, 컴파일러가 스위치의 기능 범위를 고려하여 P4를 스위치가 이해할 수 있는 프로그램으로 바꿔주어야 한다. (target-independent description P4 to target-dependent program)

관련 연구

  • OpenFlow Primitive Set: OpenFlow forwarding 모델의 추상화를 제안했으나, 컴파일러에 대한 내용이 적음
  • Kangaroo: programmable parsing 제안
  • Protocol oblivious forwarding: protocol 묶이지 않는 forwarding을 제안했으나, network processors에 주로 타겟함
  • ONF의 OpenFlow forwarding abstractions: 스위치의 matching capability를 표현하기 위한 table typing pattern 제안
  • NOSIX: 유연한 match+action table을 제안한다는 점이 논문의 목표와 유사하나, independence 고려하지 않음
  • Click: flexible software packet processing를 지원하지만, 프로그램을 다양한 하드웨어 스위치에 매핑시켜주지 않음 

 

2. Abstract Forwarding Model

 Figure 2는 대략적인 모델을 나타낸다. 스위치는 프로그래머블 parser와 여러 match+action으로 이어지는 단계들을 이용해 packet을 전달한다. 우리 모델은 OpenFlow로부터 파생하여 3가지 일반화를 진행하였다. 1. OpenFlow는 고정된 parser를 가정하지만, 우리의 모델은 새로운 packet header를 정의할 수 있도록 programmable parser를 지원한다. 2. OpenFlow는 match+action의 단계가 일렬화 되어있지만, 우리의 모델은 병렬적으로 존재할 수 있다. 3. 우리의 모델에서의 action은 프로토콜 비의존적인 방법으로 구성이 가능하다.

 

 우리의 모델은 다양한 forwarding 장비 (Ethernet switch, load balancer, router)와 다양한 기술 (ASIC, NPU, reconfigurable switch, software switch, FPGA)에서 어떻게 packet을 처리할 것인지에 대해서 일반화를 시도하였다. 이는 우리로 하여금, packet들이 어떻게 처리될 지 표현하기 위한 공통 언어 (P4)를 고안하도록 하였다. 그래서 프로그래머는 target과 독립적인 프로그램을 개발할 수 있게 되었으며, 이 프로그램은 컴파일러가 다양한 forwarding 장비-상대적으로 느린 software 스위치부터 ASIC-based switch까지 아울러서 매핑시켜줄 수 있도록 하였다.

 

 Forwarding model은 두 가지 작업으로 제어된다. Configure / Populate.
Configure: configure는 parser 프로그램을 실행, match+acition 단계들의 순서를 설정, 그리고 각 단계마다 처리될 header field를 명시한다. Configuiration은 어떤 프로토콜이 지원되는지, 어떻게 스위치가 packet을 처리할지 결정한다.

Populate: Configur 과정에서 지정된 match+action table에 entries를 추가 및 제거하는 작업을 수행한다. Population은 계속 packet에 적용될 정책을 결정하는 역할도 수행한다.

 

 이 논문에서는 configuration와 population이 구분되는 단계로 가정한다. 스위치는 configuration동안 packet을 처리할 필요가 없다. 그러나, 우리는 구현이 downtime없이 업그레이드가 가능하도록 부분 혹은 full reconfiguration 시간동안 packet이 처리될 수 있도록 할 계획이다. 

 분명하게, ASIC switch에서는 configuration 단계가 닥 의미없다. 컴파일러의 역할은 단순히 P4를 지원하는지만 검사하는 것. 

 

 도착한 packet들은 가장 먼저 parser에 의해 처리된다. packet body는 별도의 공간에 저장되며, matching에서 사용할 수 없다. Parser는 header에서 field를 인식하고 추출해내며, 이에 따라 switch에서 처리가능한 protocol을 정의할 수 있게 된다. 우선 우리의 구조에서는 protocol header가 어떤 것들이 있다고 가정하지는 않고, 오로지 parser의 프로그램이 protocol을 정의, 어떤 field를 이용해 처리할 것인지 등을 결정할 수 있다.

 

 추출된 packet header field는 그 다음으로 match+action table에 진입한다. 이 table은 ingress와 egress로 나뉜다 (Figure 2 참고). 둘다 packet header를 수정할 수 있으면서, ingress는 egress port를 결정하고 packet이 어느 queue에 위치 해야하는지 결정하는 작업도 수행한다. Ingress processing에 근거하여 packet이 전달/복제/drop/flow control이 수행된다. Egress는 인스턴스 단위로 packet header 수정을 수행한다 (multicast copy). Action table은 frame 단위의 상태를 추적할 수 있다.

 

 Packet은 단계 사이에서 packet header와 동일하게 고려되고 처리되는 추가적인 정보 (metadata)를 전달할 수 있다 (OpenFlow metadata와 동일해보인다.). Metadata의 예제로는 ingerss port, queue, timestamp, vni 등이 있다. Qdisc (Queueing discipline)은 OpenFlow와 동일한 방법으로 처리된다. Action primitives는 프로그래머가 기존에 존재하던, 혹은 새로운 congestion control 프로토콜을 구현할 수 있도록 한다. 예를 들어, 프로그래머가 원하는 상황에서 스위치가 ECN 비트를 마킹하게 한다거나, match+action table을 이용해 새로운 CC 기법을 구현하는 등이 가능하다.

 

3. 프로그래밍 언어

 이 논문에서는 P4 프로그래밍 언어를 제안한다. Parser를 표현하기 위해서는 프로그래머가 packet header들이 어떻게 처리될 지 표현할 수 있어야 한다. 예를 들어, TTL field 감소, packet header에 새 터널 추가, checksum 재계산 등의 작업 등이 있을 것이다. 이는 P4 언어가 header field를 처리하는데 앞서, header type의 선언과 기본 action set들을 사용하도록 만드는데 동기를 부여한다. 

 

 C++로 스위치의 모듈을 작성할 수 있는 Click을 사용할 수도 있을 것이다. Click은 매우 표현력이 좋고, Kernel내의 CPU가 packet을 어떻게 처리할지 표현하느데 매우 적절하다. 하지만 우리는 dedicated hardware에서 parse-match-action 파이프라인을 표현할 수 있는 언어가 필요하고, 이러한 부분에서 Click은 제약이 충분하지 않게 되어있다. 추가로, Click은 controller-switch 구조를 위해 디자인된 것이 아니고, 따라서 프로그래머가 match+action table을 표현하는 것을 허용하지 않는다. 마지막으로, Click은 병렬 처리를 방해하는 dependency를 추론하는데 어려움이 있다.

 

 Packet 처리 언어는 프로그래머가 header fields간에 어떠한 dependency라도 표현할 수 있어야 한다. Dependency는 어떤 table들이 병렬적으로 실행될 수 있는지 없는지 결정한다. 예를 들어, IP routing table과 ARP table은 둘 사이에 data 의존성이 존재하여 병렬적으로 처리되어야 한다. Dependency는 Table Dependency Graphs (TDGs)를 분석하여 알아낼 수 있다. 이 그래프는 field의 input, action, 그리고 table간의 control flow를 나타낸다. Figure 3은 L2/L3 스위치에서의 TDG 예제를 보여준다. TDG node는 match+action table을 의미하며, dependency 분석을 통해 각 table이 파이프라인에서 어디에 위치해야할 지 알아낼 수 있다. 다만, TDG는 프로그래머가 TDG에 쉽게 접근할 수는 없다. 대부분의 프로그래머는 packet 처리를 구상하는데 그래프보다는 명령형 구조를 이용하는 경향이 있기 때문.

 

 이러한 점은 두 단계의 컴파일 절차를 제안하도록 이끌었다. 가장 높은 레벨에서는 프로그래머가 packet 처리 프로그램을 표현하는데 control flow를 나타내는 명령형 언어인 P4를 사용한다. 그 아래에서는 컴파일러가 P4 표현을 TDG로 변환한다. 그리고 이 TDG는 dependency를 분석하고, TDG를 target 스위치에 매핑한다. P4는 P4 프로그램을 TDG로 변환하기 쉽도록 디자인되었다. 요약하여, P4는 범용적인 Click (dependency 추론과 hardware 매핑을 어렵게 만듦)과 유연하지 않은 OpenFlow 1.0 (protocol processing 재설정이 불가능함) 사이에서의 "sweet spot"이라고 볼 수 있을 것이다.

 

반응형
Comments