Whole document tree
    

Whole document tree

Linux netfilter Hacking HOWTO: Netfilter Hooks for Tunnel Writers Next Previous Contents

6. Netfilter Hooks for Tunnel Writers

Authors of tunnel (or encapsulation) drivers should follow two simple rules for the 2.4 kernel (as do the drivers inside the kernel, like net/ipv4/ipip.c):

  • Release skb->nfct if you're going to make the packet unrecognisable (ie. decapsulating/encapsulating). You don't need to do this if you unwrap it into a *new* skb, but if you're going to do it in place, you must do this.

    Otherwise: the NAT code will use the old connection tracking information to mangle the packet, with bad consequences.

  • Make sure the encapsulated packets go through the LOCAL_OUT hook, and decapsulated packets go through the PRE_ROUTING hook (most tunnels use ip_rcv(), which does this for you).

    Otherwise: the user will not be able to filter as they expect to with tunnels.

The canonical way to do the first is to insert code like the following before you wrap or unwrap the packet:

        /* 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

Usually, all you need to do for the second, is to find where the newly encapsulated packet goes into "ip_send()", and replace it with something like:

        /* Send "new" packet from local host */
        NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ip_send);

Following these rules means that the person setting up the packet filtering rules on the tunnel box will see something like the following sequence for a packet being tunnelled:

  1. FORWARD hook: normal packet (from eth0 -> tunl0)
  2. LOCAL_OUT hook: encapsulated packet (to eth1).

And for the reply packet:

  1. LOCAL_IN hook: encapsulated reply packet (from eth1)
  2. FORWARD hook: reply packet (from eth1 -> eth0).


Next Previous Contents