VPP API 계층 레퍼런스

clib · vlib · vnet · VCL · TLS · offload로 이어지는 VPP API 계층 구조와 각 계층의 책임을 한 장의 지도로 정리합니다.

선행 문서: 이 페이지는 기초와 아키텍처의 벡터 패킷 처리·그래프 노드 개념을 전제로 합니다. 내부 구현 카테고리의 다른 페이지와 함께 읽어 주세요.

VPP의 소스 트리에는 기능이 비슷해 보이는 접두사(clib_, vlib_, vnet_, session_, vppcom_, tls_, vnet_crypto_)가 여러 개 섞여 있어서 처음 접하면 어느 계층의 API를 써야 할지 판단하기 어렵습니다. 이 절은 각 접두사가 어느 계층의 책임을 지고, 어떤 핵심 자료형(Type)과 함수가 있으며, 플러그인과 애플리케이션이 각각 어디에서 시작해야 하는지를 정리합니다. 아래 SVG는 전체 계층을 단 한 장에 펼쳐 본 지도(Map)입니다.

VPP API 계층 스택 — 어느 접두사가 어느 층에 속하는가 ① 애플리케이션 / 호스트 스택 API 유저 프로세스가 VPP를 "소켓처럼" 쓰는 경로. 공유 메모리 기반, syscall 없음. vppcom_* (VCL) vls_* (VLS 잠금) LD_PRELOAD (소켓 hook) Binary API / VAPI stats segment (read-only) ② 세션 / 전송 계층 API (호스트 스택 코어) TCP/UDP/TLS/QUIC 트랜스포트 엔진과 세션 핸들 관리. 플러그인과 VCL이 둘 다 여기로 모임. session_* (app/session) tcp_* / udp_* tls_* (openssl/mbedtls/picotls) quic_* (quicly 기반) svm_fifo_* (공유 FIFO) ③ vnet — 네트워크 의미(Network Semantics) 계층 인터페이스, L2/L3 스택, FIB, ACL, IPsec, 암호화 프레임워크 등 "네트워크 장비다운" 추상화. vnet_sw_interface_* ip4_fib_* / ip6_fib_* adj_* (인접성) ipsec_sa_* / esp_* vnet_crypto_* acl_* classify_* (N-tuple) feature_arc / VNET_FEATURE_INIT dpo_* (데이터 평면 오브젝트) fib_path_* vnet_hw_interface_* (드라이버 정책) ④ vlib — 벡터 처리 런타임 (Vector Library) 그래프 노드, 버퍼, 메인 루프, 프로세스 노드, 트레이스, CLI. 모든 노드가 반드시 이 계층 위에서 움직임. vlib_main_t / vm vlib_buffer_t / 풀 VLIB_REGISTER_NODE vlib_get_next_frame vlib_worker_thread_barrier_sync vlib_process_* (프로세스 노드) vlib_cli_register_* vlib_add_trace vlib_node_increment_counter vlib_frame_queue_* (핸드오프) ⑤ clib / vppinfra — 기반 자료구조 & 원자성/동기화 메모리 · 벡터 · 풀 · 해시 · 원자 · 락 · 시간 · 포맷. 표준 libc를 대체하는 범용 유틸리티. clib_mem / mheap vec_* (동적 배열) pool_* (인덱스 풀) clib_bihash clib_atomic_* clib_spinlock / rwlock ⑥ 디바이스 · 오프로드 계층 DPDK PMD / rte_* rdma / mlx5 af_xdp / xsk_* cryptodev (QAT) ipsecmb / AES-NI memif / vhost-user

이 지도를 사용하는 기본 원칙은 단순합니다. 아래 계층은 위 계층의 언어를 모른다는 것입니다. 예를 들어 clib_bihash는 자기가 FIB를 저장하는지 ACL을 저장하는지 알지 못하고, vlib는 패킷이 TLS인지 IPsec인지 구분하지 않으며, vnet은 애플리케이션 세션이 어떤 소켓 API를 통해 접근하는지 신경 쓰지 않습니다. 이 단방향 의존성 덕분에 VPP는 플러그인으로 기능을 갈아 끼워도 하부가 흔들리지 않습니다.

각 계층의 책임과 대표 API

계층주요 디렉터리대표 자료형대표 API언제 직접 호출하는가
⑤ clib/vppinfra src/vppinfra/ u8 * 벡터, pool_t, clib_bihash_*_t clib_mem_alloc, vec_add1, pool_get, clib_bihash_add_del, clib_atomic_fetch_add, clib_spinlock_lock 플러그인 내부 자료구조, 집계 카운터, 해시 기반 세션/플로우 테이블을 손수 만들 때
④ vlib src/vlib/ vlib_main_t, vlib_buffer_t, vlib_node_registration_t, vlib_frame_t VLIB_REGISTER_NODE, vlib_get_buffer, vlib_get_next_frame, vlib_validate_buffer_enqueue_*, vlib_process_wait_for_event, vlib_worker_thread_barrier_sync 새 그래프 노드를 작성하거나 CLI/프로세스 노드를 등록할 때 — 플러그인 개발의 기본 언어
③ vnet src/vnet/ vnet_main_t, vnet_hw_interface_t, ip4_fib_t, ipsec_sa_t, vnet_crypto_op_t vnet_sw_interface_set_flags, fib_table_entry_path_add, ipsec_sa_add_and_lock, vnet_feature_enable_disable, vnet_crypto_process_ops 인터페이스, 라우팅, ACL, IPsec, 암호화(Encryption)처럼 "네트워크 장비다운" 기능을 붙일 때
② session / transport src/vnet/session/, tcp/, tls/, quic/ session_t, app_worker_t, tls_ctx_t, svm_fifo_t session_alloc_for_connection, tcp_connection_alloc, tls_init_ctx, svm_fifo_enqueue TCP/TLS/QUIC 엔진을 확장하거나 새 트랜스포트를 플러그인으로 추가할 때. 일반 플러그인은 거의 직접 만지지 않음
① 애플리케이션 / VCL src/vcl/ vppcom_endpt_t, vls_handle_t, vppcom_cert_key_pair_t vppcom_app_create, vppcom_session_create, vppcom_session_connect, vppcom_epoll_wait, vppcom_add_cert_key_pair 유저 프로세스가 VPP 호스트 스택을 "소켓처럼" 사용하고자 할 때 (대부분의 애플리케이션 개발 경로)
⑥ 오프로드 DPDK · cryptodev · ipsecmb rte_mbuf, rte_crypto_op, rte_cryptodev_* rte_eth_rx_burst, rte_cryptodev_enqueue_burst, rte_cryptodev_dequeue_burst, IPsec-MB의 IMB_AES_GCM_ENC_* 드라이버 또는 vnet_crypto 백엔드를 직접 작성할 때 — 일반적으로 플러그인은 vnet_crypto_*를 통해 간접 사용

하나의 요청이 계층을 어떻게 관통하는가

추상 개념을 구체화하기 위해, HTTPS 요청이 들어와서 IPsec 터널로 재전송되는 극단적인 경로를 따라가 봅니다. 이 한 줄의 플로우가 위 여섯 계층을 모두 건드립니다.

  1. ⑥ DPDK PMD가 NIC 링에서 rte_mbuf를 가져와 VPP의 vlib_buffer_t로 감쌉니다.
  2. ④ vlibdpdk-input 노드가 프레임을 만들고, 벡터 단위로 다음 노드에 넘깁니다.
  3. ③ vnetethernet-input → ip4-input → ip4-lookupip4_fib_tadj_*를 사용해 FIB 룩업을 수행합니다.
  4. ② sessiontcp-established가 TCP 상태 머신을 돌리고, TLS 세션이면 tls_* → svm_fifo_* 경로로 복호화(Decryption)된 평문을 RX FIFO에 적재합니다.
  5. ① VCL 애플리케이션이 vppcom_session_read로 평문을 읽고, 검사/변형 후 vppcom_session_write로 다른 세션에 씁니다.
  6. 반대 방향으로 내려오는 패킷은 다시 ③ vnetesp-encrypt⑤ clibclib_atomic_fetch_addipsec_sa_t.seq를 증가시키고, vnet_crypto_process_ops를 호출합니다.
  7. ⑥ cryptodev(QAT)가 실제 AES-GCM 연산을 수행하고, 완료된 버퍼가 ④ vlib의 TX 경로로 돌아옵니다.
읽기 순서 가이드: 처음 VPP를 익힐 때는 이 지도의 ④ vlib → ⑤ clib → ③ vnet → ② session → ① VCL 순서가 이해도가 가장 빠릅니다. vlib는 "어떻게 움직이는가"를, clib는 "어떤 자료구조가 가용한가"를, vnet은 "네트워크 의미가 어떻게 붙는가"를, session/VCL은 "커널 소켓을 어떻게 흉내 내는가"를 설명합니다. ⑥ 오프로드는 필요할 때만 파고들어도 됩니다.

접두사만 보고 계층을 판별하는 법

실전에서는 헤더 파일명과 함수 접두사만 보고도 어느 계층에서 호출해야 하는지 거의 판단할 수 있습니다.

자주 하는 혼동: clib_*vlib_*는 이름이 비슷해 보이지만, clib_*컨텍스트가 없는 순수 유틸리티이고 vlib_*는 반드시 런타임 컨텍스트(vm)를 요구합니다. 예를 들어 clib_mem_alloc은 어디서든 부를 수 있지만 vlib_get_buffer(vm, bi)vm 없이 호출되면 세그폴트합니다. 이 차이가 플러그인 초기화 함수에서 가장 자주 틀리는 지점입니다.