PF_RING 은 네트웍 디바이스에서 수신한 패킷을 user space로 빠르게 전달할 수 있는 패킷 캡쳐를 위한 소켓이다. 이를 사용하면 pcap 라이브러리의 성능을 크게 향상시킬 수 있다.
참고 사이트 : http://www.ntop.org/PF_RING.html
참고 논문 : http://luca.ntop.org/Ring.pdf
PF_RING 소켓의 아키텍쳐는 다음 그림과 같다.
수정 후 해당 스크립트를 실행하면 kernel.org 에서 스크립트에 수정한 버젼에 맞는 커널 소스를 다운로드 후 다운로드 받은 커널에 PF_RING 패치를 적용하고 해당 커널 버젼에 맞는 패치 파일을 생성하는 일련의 과정을 수행한다. 모든 작업이 끝나면 workspace 라는 디렉토리가 생기며 그 안에 리눅스 원본 소스, 패치가 적용된 소스, 압축된 패치 파일 등이 생긴다. 패치된 소스의 커널 옵션을 수정하여 커널 컴파일 후 생성된 커널 이미지를 사용하여도 좋고, 현재 시스템의 커널 소스가 있다면 커널 소스에 생성된 패치를 적용한 후 커널을 새로 컴파일해도 상관없다. 패치를 적용한 커널에서 다음 옵션을 반드시 설정한다.
커널 컴파일 후 시스템의 커널을 생성된 커널로 바꾸고 시스템을 재시작한다. 여기까지하면 커널은 준비가 끝났으며 pcap 라이브러리를 새로 설치하는 작업이 남았다. 먼저 PF_RING 소켓을 사용한 pcap 라이브러리를 만들기 위해서 필요한 libpfring 라이브러리를 만든다. 라이브러리를 컴파일하기 전에 먼저 /usr/include/linux/ring.h 파일이 있는지 확인하고 없으면 다음과 같이 심볼릭 링크를 만들어 include 디렉토리를 수정한다. 커널은 /usr/src/linux 에 위치한다고 가정한다.
상기와 같이 커널 소스 내의 include 디렉토리를 심볼릭 링크를 걸어서 사용해도 괜찮고, 또는 커널 소스 안에 있는 ring.h 파일을 /usr/include/linux 디렉토리에 다음과 같이 복사하여 사용하여도 무방하다.
ring.h 파일을 /usr/include/linux 디렉토리에 위치시킨 후 libpfring 라이브러리를 컴파일한다. libpfring 라이브러리의 소스 디렉토리 위치는 다음과 같다.
참고 사이트 : http://www.ntop.org/PF_RING.html
참고 논문 : http://luca.ntop.org/Ring.pdf
PF_RING 소켓의 아키텍쳐는 다음 그림과 같다.
논문에서는 리눅스 커널 2.6.1 에 NAPI 드라이버를 사용하였을 경우 PF_RING 을 사용하지 않았을 경우와 사용하였을 경우의 성능을 비교하고 있는데, 64 byte 패킷을 사용하여 테스트 하였을 때 전자는 2.5%의 캡쳐율을 보이지만 후자의 경우 75.7%의 캡쳐율을 보인다. 또한 1500 byte 패킷을 사용하였을 때, 전자는 34.3%, 후자는 92.9%의 캡쳐율을 보인다. 단순히 수치로만 비교하더라도 꽤 큰 성능 향상을 기대할 수 있다.
PF_RING 을 사용하기 위한 과정은 다음과 같다.
먼저 소스 파일을 다운로드 받는다. 소스 파일은 CVS를 사용하여 다운로드 받을 수 있다
다운로드 받은 소스 파일안의 'mkpatch.sh' 스크립트 파일을 현재 사용중인 리눅스 커널 버젼에 맞추어 수정한다.
먼저 소스 파일을 다운로드 받는다. 소스 파일은 CVS를 사용하여 다운로드 받을 수 있다
export CVSROOT=:pserver:anonymous@cvs.ntop.org:/export/home/ntop
cvs login (패스워드는 'ntop' 을 입력한다.)
cvs co PF_RING
cvs login (패스워드는 'ntop' 을 입력한다.)
cvs co PF_RING
다운로드 받은 소스 파일안의 'mkpatch.sh' 스크립트 파일을 현재 사용중인 리눅스 커널 버젼에 맞추어 수정한다.
22 PATCH=ring3
23 PREFIX=linux
24 # or
25 #PREFIX=kernel-source
26 # kernel identifiers.
27 VERSION=2
28 PATCHLEVEL=6
29 SUBLEVEL=16.1
30 KERNEL_VERSION=$VERSION.$PATCHLEVEL.$SUBLEVEL
31 EXTRAVERSION=-1-686-smp-$PATCH
수정 후 해당 스크립트를 실행하면 kernel.org 에서 스크립트에 수정한 버젼에 맞는 커널 소스를 다운로드 후 다운로드 받은 커널에 PF_RING 패치를 적용하고 해당 커널 버젼에 맞는 패치 파일을 생성하는 일련의 과정을 수행한다. 모든 작업이 끝나면 workspace 라는 디렉토리가 생기며 그 안에 리눅스 원본 소스, 패치가 적용된 소스, 압축된 패치 파일 등이 생긴다. 패치된 소스의 커널 옵션을 수정하여 커널 컴파일 후 생성된 커널 이미지를 사용하여도 좋고, 현재 시스템의 커널 소스가 있다면 커널 소스에 생성된 패치를 적용한 후 커널을 새로 컴파일해도 상관없다. 패치를 적용한 커널에서 다음 옵션을 반드시 설정한다.
Kernel 2.4 : Networking options --> Socket Filtering --> PF_RING
Kernel 2.6 : Networking --> Networking options --> PF_RING sockets
Kernel 2.6 : Networking --> Networking options --> PF_RING sockets
커널 컴파일 후 시스템의 커널을 생성된 커널로 바꾸고 시스템을 재시작한다. 여기까지하면 커널은 준비가 끝났으며 pcap 라이브러리를 새로 설치하는 작업이 남았다. 먼저 PF_RING 소켓을 사용한 pcap 라이브러리를 만들기 위해서 필요한 libpfring 라이브러리를 만든다. 라이브러리를 컴파일하기 전에 먼저 /usr/include/linux/ring.h 파일이 있는지 확인하고 없으면 다음과 같이 심볼릭 링크를 만들어 include 디렉토리를 수정한다. 커널은 /usr/src/linux 에 위치한다고 가정한다.
mv /usr/include/linux /usr/include/linux_org
ln -s /usr/src/linux/include/linux /usr/include/linux
ln -s /usr/src/linux/include/linux /usr/include/linux
상기와 같이 커널 소스 내의 include 디렉토리를 심볼릭 링크를 걸어서 사용해도 괜찮고, 또는 커널 소스 안에 있는 ring.h 파일을 /usr/include/linux 디렉토리에 다음과 같이 복사하여 사용하여도 무방하다.
cp /usr/src/linux/include/linux/ring.h /usr/include/linux
ring.h 파일을 /usr/include/linux 디렉토리에 위치시킨 후 libpfring 라이브러리를 컴파일한다. libpfring 라이브러리의 소스 디렉토리 위치는 다음과 같다.
PF_RING/userland/libpfring
다운로드 받은 pcap 라이브러리 소스의 압축을 풀고 configure 를 실행하여 Makefile 을 생성한 후 Makefile 의 다음 내용을 수정한다. 압축을 푼 pcap 라이브러리 소스 디렉토리의 위치는 PF_RING/userland/libpcap-0.9.4 라고 가정한다.
pcap 라이브러리가 PF_RING 소켓을 사용하도록 pcap 라이브러리 소스파일을 수정한다.
make 를 사용하여 pcap 라이브러리를 컴파일 하고 설치한다.
예제 소스를 사용하여 실제 동작을 확인할 수 있다. 예제 소스는 패킷을 캡쳐하여 통계를 보여주는 pcount 라는 프로그램이다. 소스의 위치는 다음과 같다.
프로그램을 컴파일 후 실행시키고 ctrl-c 를 눌러 종료시키면 캡쳐 통계를 볼 수 있다. dmesg 를 사용하여 다음과 비슷한 커널 메세지를 확인할 수 있다면 pcap 라이브러리가 PF_RING 소켓을 이용하여 동작하고 있는 것이다.
위의 과정을 거쳐 생성한 pcap 라이브러리는 PF_RING 을 사용할 수 있는 환경에서는 PF_RING 을 사용하여 동작하고 그렇지 않을 경우에는 기본 bpf 를 사용하여 동작하기 때문에 시스템 커널이 바뀌어도 어플리케이션을 새로 컴파일할 필요는 없다. 해당 내용은 pcap-linux.c 소스 파일의 pcap_open_live() 함수의 소스를 살펴보면 확인할 수 있다.
44 CC = gcc
45 CCOPT = -O2
46 INCLS = -I. -I../libpfring
47 DEFS = -DHAVE_CONFIG_H -D_U_="__attribute__((unused))"
48 LIBS = ../libpfring/libpfring.a
49 DYEXT = so
45 CCOPT = -O2
46 INCLS = -I. -I../libpfring
47 DEFS = -DHAVE_CONFIG_H -D_U_="__attribute__((unused))"
48 LIBS = ../libpfring/libpfring.a
49 DYEXT = so
pcap 라이브러리가 PF_RING 소켓을 사용하도록 pcap 라이브러리 소스파일을 수정한다.
cp ../libpcap-0.9.4-ring/pcap-int.h ./ -f
cp ../libpcap-0.9.4-ring/pcap-linux.c ./ -f
cp ../libpcap-0.9.4-ring/pcap-linux.c ./ -f
make 를 사용하여 pcap 라이브러리를 컴파일 하고 설치한다.
make && make install
예제 소스를 사용하여 실제 동작을 확인할 수 있다. 예제 소스는 패킷을 캡쳐하여 통계를 보여주는 pcount 라는 프로그램이다. 소스의 위치는 다음과 같다.
PF_RING/userland/pcount
프로그램을 컴파일 후 실행시키고 ctrl-c 를 눌러 종료시키면 캡쳐 통계를 볼 수 있다. dmesg 를 사용하여 다음과 비슷한 커널 메세지를 확인할 수 있다면 pcap 라이브러리가 PF_RING 소켓을 이용하여 동작하고 있는 것이다.
...
RING: succesfully allocated 1024 KB [tot_mem=598076][order=8]
RING: allocated 7181 slots [slot_len=146][tot_mem=1048576]
...
RING: succesfully allocated 1024 KB [tot_mem=598076][order=8]
RING: allocated 7181 slots [slot_len=146][tot_mem=1048576]
...
위의 과정을 거쳐 생성한 pcap 라이브러리는 PF_RING 을 사용할 수 있는 환경에서는 PF_RING 을 사용하여 동작하고 그렇지 않을 경우에는 기본 bpf 를 사용하여 동작하기 때문에 시스템 커널이 바뀌어도 어플리케이션을 새로 컴파일할 필요는 없다. 해당 내용은 pcap-linux.c 소스 파일의 pcap_open_live() 함수의 소스를 살펴보면 확인할 수 있다.
출처 : http://blog.naver.com/semigifn?Redirect=Log&logNo=10019148926
'Fundamental > Algorithm' 카테고리의 다른 글
PF-RING을 사용한 Packet Capture Rate 향상 (0) | 2014.03.19 |
---|
댓글