2012-10-10 2 views
2

리눅스에서 가능한 한 as close to real-time 시스템에서 작업 중이며 특정 패킷을 받자 마자 TCP 패킷에 약 600-800 바이트를 보내야합니다.linux에서 NDIS 필터의 아날로그는 무엇입니까?

지연 시간을 최대한 줄이기 위해 수신 패킷을 사용자 공간과 응용 프로그램에 전달하는 대신 커널에서 직접 전송하기를 원합니다.

윈도우에 있다면 NDIS 필터를 작성하여 전송할 패킷과 일치하는 매개 변수를 캐싱하여 수신 된 패킷을 점검하고 일치시 사전 캐쉬 된 패킷을 수신 된 패킷을 상위 계층까지 전달하지 않고 네트워크에 전달할 수있다.

그럼 내 질문은 리눅스에서 NDIS 필터의 가장 유사한 유사점은 무엇입니까?

netfilter에 대한 정보를 읽었으며 아마도 그 정보를 사용하는 것이지만 가능한 최선의 방법인지는 알 수 없습니다.

가능한 최저 대기 시간을 달성하기 위해 내가 할 수있는 다른 조치는 무엇입니까?

내 현재 순수 사용자 공간 코드는 2.6.3x 커널에서 Ubuntu 10.04를 실행하는 Intel Xeon 3.7GHz 프로세서에서 약 80-100 마이크로 초를 제공합니다.

답변

1

Linux 커널에서 BPF (Berkeley packet filter)라는 비슷한 메커니즘이 있습니다. 응용 프로그램에서 BPF 필터를 커널에 등록하십시오. 필터와 일치하는 패킷은 캡처되어 등록 된 후크 기능으로 전달됩니다.

아래는 인터넷에서 발견 한 exmpale 코드입니다. (https://gist.github.com/939154) 기본적으로 BPF 필터로 바인딩을 열고 바인딩을 선택하고 패킷을 수신하기 위해이 FD를 선택해야합니다. ; set_filter (int fd) { struct bpf_program fcode = {0};

/* dump ssh packets only */ 
struct bpf_insn insns[] = { 
    BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), 
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10), 
    BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), 
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8), 
    BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), 
    BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0), 
    BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), 
    BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), 
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 2, 0), 
    BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16), 
    BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 0, 1), 
    BPF_STMT(BPF_RET+BPF_K, (u_int)-1), 
    BPF_STMT(BPF_RET+BPF_K, 0), 
}; 


/* Set the filter */ 
fcode.bf_len = sizeof(insns)/sizeof(struct bpf_insn); 
fcode.bf_insns = &insns[0]; 

if(ioctl(fd, BIOCSETF, &fcode) < 0) 
    return -1; 

return 0; 

}

bpf_inst는 terrbiel 보인다. 그러나 수동으로 작성하지 않아도됩니다. tcp-dump를 사용하여이 스크립트를 자동 생성 할 수 있습니다. 예를 들어

:

sudo tcpdump 'tcp[13]=18' -i eth0 -dd 
{ 0x28, 0, 0, 0x0000000c }, 
{ 0x15, 0, 8, 0x00000800 }, 
{ 0x30, 0, 0, 0x00000017 }, 
{ 0x15, 0, 6, 0x00000006 }, 
{ 0x28, 0, 0, 0x00000014 }, 
{ 0x45, 4, 0, 0x00001fff }, 
{ 0xb1, 0, 0, 0x0000000e }, 
{ 0x50, 0, 0, 0x0000001b }, 
{ 0x15, 0, 1, 0x00000012 }, 
{ 0x6, 0, 0, 0x00000060 }, 
{ 0x6, 0, 0, 0x00000000 }, 
+0

여전히 bpf 장치를 읽고 패킷을 다시 써야하므로 사용자 공간 및 점프대로 점프합니다. 그러나 이것이 벤치 마크에서 벗어나기 전에. Linux 시스템 호출은 Windows보다 더 빠른 경우가 많습니다. –

2

당신은 사용자 공간이 그들을 탈수 할 수 있도록 사용자 공간 또는 NFQUEUE 밖으로 패킷을 복사 할 iptables 대상 NFLOG를 사용할 수 있습니다. 이 상호 작용은 netlink 이상 발생하지만 및 libnetfilter_queue과 같은 라이브러리를 사용할 수 있습니다.