Tunnel 드라이버 제작자들은 2.4 커널에 대해서는 다음에 보이는 단순한 두개의 규칙을 따르기 바란다.
패킷을 인식할 수 없도록 하려면 skb->nfct를 릴리즈 해야한다(즉, decapsulating/encapsulating). 만일 패킷을 *new* skb로 감싸지 않으려면 릴리즈를 하지 않아도 되지만, 적절한 곳에서 수행하고자 한다면, 반드시 릴리즈 해야 한다.
그렇지 않은 경우는, NAT 코드는 패킷을 맹글하기 위해 과거의 connection tracking 정보를 이용할 것이고, 이로 인해 순서가 엉망이 될 것이다.
encapsulated 패킷은 반드시 LOCAL_OUT 훅을 통과하도록 해야하며, decapsulated 패킷은 PRE_ROUTING 훅을 통과해야만 한다. 이를 수행하기 위해 대부분의 tunnel은 ip_rcv()를 사용한다.
그렇지 않은 경우는, 사용자들이 tunnel을 이용하여 원하는 대로 필터링할 수 없을 것이다.
첫 번째를 수행하는 표준 방법은 패킷을 wrap하거나 unwrap하기 전에 다음과 유사한 코드를 삽입하는 것이다.
/* Tell the netfilter framework that this packet is not the same as the one before! */ #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); skb->nfct = NULL; #ifdef CONFIG_NETFILTER_DEBUG skb->nf_debug = 0; #endif #endif |
두 번째를 수행하기 위해 필요로 하는 것은 새로이 encapsulated된 패킷이 ``ip_send()''로 들어가는 위치를 찾아내고, 이를 다음과 같은 것으로 대체하는 것이다.
/* Send "new" packet from local host */ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ip_send); |
다음에 보인 룰이 의미하는 것은 tunnel 박스에 패킷 필터링 룰을 적용하고자 하는 사람이 tunnel 되고 있는 패킷에 대해 다음과 같은 절차를 보게 될 것이다.
FORWARD hook : normal packet (from eth0 -> tunl0)
LOCAL_OUT hook : encapsulated packet (to eth1)
LOCAL_IN hook: encapsulated reply packet (from eth1)
FORWARD hook: reply packet (from eth1 -> eth0).