배경
1Gbps를 초과하는 네트워크 인터페이스 처리량을 얻기 위해 PF_RING를 사용하려고 시도했습니다. 예제 코드인 pfsend를 사용하고 zero-copy 모드로 데이터 전송을 설정했지만, pfring_open 오류가 발생했습니다: [No such device] (pf_ring not loaded or interface zc:p2p1 is down ?). 이 오류를 해결하기 위한 진단 및 문제 해결 과정을 기술합니다.
사용한 버전은 PF_RING 8.6.1이며, GitHub - ntop/PF_RING: High-speed packet processing framework에서 다운로드할 수 있습니다.
드라이버 로딩
PF_RING-8.6.1/drivers/intel/ixgbe/ixgbe-5.19.6-zc 디렉토리에 load_driver.sh 스크립트가 있습니다. 이 스크립트를 실행하여 드라이버를 로드할 수 있습니다. 실행 시 다음과 같은 경고 메시지가 나타납니다:
Warning: 512 hugepages available, 1024 requested.
이 오류는 큰 페이지 메모리(hugepages)가 부족하기 때문에 발생합니다. 다음 명령어로 큰 페이지 메모리를 조정할 수 있습니다:
echo 1024> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
여기서 1024는 실제 시스템의 메모리 상황에 맞게 조절해야 합니다. 조정 후 다시 load_driver.sh를 실행하면 스크립트가 정상적으로 실행됩니다.
pfsend 실행
위 명령을 실행한 후, pfsend를 사용하여 pcap 패킷을 전송했습니다. 그러다 다음과 같은 오류가 발생했습니다:
pfring_open error [Invalid argument] (pf_ring not loaded or interface zc:p2p1 is down ?)
이 오류 키워드로 검색한 결과 GitHub의 이슈(https://github.com/ntop/PF_RING/issues/541)를 찾았습니다. 이 이슈는 해결된 상태였으며, pf_pfringcfg --list-interfaces 명령어로 네트워크 인터페이스 설정을 확인할 수 있다는 내용이 있었습니다. 해당 명령어는 PF_RING-8.6.1/package/usr/bin/pf_ringcfg 경로에 있었습니다. 실행 결과는 다음과 같았습니다:
기존 시스템에 있던 p2p1, p2p2 인터페이스가 목록에 없는 것을 확인했습니다. 드라이버 호환성 문제로 판단하여 다른 드라이버를 시도하기로 결정했습니다. PF_RING-8.6.1/drivers/intel 디렉토리에는 igb, ixgbe, e1000e, i40e, ice, ixgbevf 등의 드라이버가 있습니다. 이번에는 igb 드라이버를 사용해 보기로 했습니다.
cd PF_RING-8.6.1/drivers/intel/igb/igb-5.14.16-zc/src
sh load_driver.sh
실행 시 다음과 같은 오류가 발생했습니다:
이 오류는 이전에 ixgbe 드라이버가 로드되어 있기 때문입니다. 먼저 ixgbe를 언로드한 후 스크립트를 실행해야 합니다.
rmmod ixgbe
sh load_driver.sh
위 명령을 실행한 후, pfsend를 다시 실행했지만 여전히 동일한 오류가 발생했습니다.
다음으로 i40e 드라이버를 시도해 보았습니다:
igb 드라이버를 로드했을 때와 유사한 과정을 거쳤습니다. 중복 과정은 생략하고 다음과 같이 실행했습니다.
rmmod igb
cd ~/PF_RING-8.6.1/drivers/intel/i40e/i40e-2.17.4-zc/src/
sh load_driver.sh
스크립트가 성공적으로 실행된 후, zero-copy 모드로 pfsend를 다시 실행했습니다:
이번에는 정상적으로 패킷 전송이 성공했습니다. 라이선스가 없어 5분간의 전송 제한이 있지만, 문제는 해결된 상태입니다.
이제 pf_ringcfg 명령어로 각 네트워크 인터페이스의 드라이버 상태를 확인합니다:
./pf_ringcfg --list-interfaces
결과는 다음과 같았습니다:
Name: p2p1 Driver: i40e RSS: 1 [Running ZC]
Name: p2p2 Driver: i40e RSS: 1 [Running ZC]
Name: p3p1 Driver: i40e RSS: 1 [Running ZC]
Name: p3p2 Driver: i40e RSS: 1 [Running ZC]
Name: vboxnet0 Driver: vboxnet RSS: 1 [Linux Driver]
Name: em4 Driver: tg3 RSS: 1 [Linux Driver]
Name: em1 Driver: tg3 RSS: 1 [Linux Driver]
Name: em3 Driver: tg3 RSS: 1 [Linux Driver]
Name: em2 Driver: tg3 RSS: 1 [Linux Driver]
이로써 문제가 해결되었습니다.
고찰
이 문제 해결 과정은 특별한 기술보다는 여러 네트워크 드라이버를 시도하는 과정이었습니다. 다행히 시도해야 할 드라이버가 많지 않아 문제를 빠르게 해결할 수 있었습니다. 만약 새로운 네트워크 장치(새로운 NIC)를 다루게 된다면, 사전에 해당 장치의 드라이버 정보를 파악한다면 더 효율적으로 문제를 해결할 수 있을 것입니다.