View file File name : netfilter-hacking-HOWTO-6.html Content :<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.82"> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <TITLE>Linux netfilter Hacking HOWTO: Netfilter Hooks for Tunnel Writers</TITLE> <LINK HREF="netfilter-hacking-HOWTO-7.html" REL=next> <LINK HREF="netfilter-hacking-HOWTO-5.html" REL=previous> <LINK HREF="netfilter-hacking-HOWTO.html#toc6" REL=contents> </HEAD> <BODY> <A HREF="netfilter-hacking-HOWTO-7.html">Next</A> <A HREF="netfilter-hacking-HOWTO-5.html">Previous</A> <A HREF="netfilter-hacking-HOWTO.html#toc6">Contents</A> <HR> <H2><A NAME="s6">6.</A> <A HREF="netfilter-hacking-HOWTO.html#toc6">Netfilter Hooks for Tunnel Writers</A></H2> <P>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):</P> <P> <UL> <LI>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. <P>Otherwise: the NAT code will use the old connection tracking information to mangle the packet, with bad consequences.</P> </LI> <LI>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). <P>Otherwise: the user will not be able to filter as they expect to with tunnels.</P> </LI> </UL> </P> <P>The canonical way to do the first is to insert code like the following before you wrap or unwrap the packet:</P> <P> <BLOCKQUOTE><CODE> <PRE> /* 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 </PRE> </CODE></BLOCKQUOTE> </P> <P>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:</P> <P> <BLOCKQUOTE><CODE> <PRE> /* Send "new" packet from local host */ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ip_send); </PRE> </CODE></BLOCKQUOTE> </P> <P> 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:</P> <P> <OL> <LI> FORWARD hook: normal packet (from eth0 -> tunl0)</LI> <LI> LOCAL_OUT hook: encapsulated packet (to eth1).</LI> </OL> </P> <P>And for the reply packet: <OL> <LI> LOCAL_IN hook: encapsulated reply packet (from eth1)</LI> <LI> FORWARD hook: reply packet (from eth1 -> eth0).</LI> </OL> </P> <HR> <A HREF="netfilter-hacking-HOWTO-7.html">Next</A> <A HREF="netfilter-hacking-HOWTO-5.html">Previous</A> <A HREF="netfilter-hacking-HOWTO.html#toc6">Contents</A> </BODY> </HTML>