Les auteurs de drivers de tunnels (ou encapsulation) devraient
suivre deux règles simples avec les noyaux 2.4 (comme le font les
drivers qui sont déjà dans le noyau comme net/ipv4/ipip.c) :
Relâchez le skb->nfct si vous allez rendre le paquet
inreconnaissable (par exemple décapsulation/encapsulation). Vous
n'avez pas besoin de faire ça si vous déroulez le nouveau paquet
dans un *nouveau* skb, mais si vous voulez le faire dans le même,
alors il faut relâcher.
Sinon : le code de NAT va utiliser les anciennes informations de
suivit de connexion pour modifier le paquet, ce qui aura de
mauvaises conséquences.
Faites en sorte que le paquet encapsulé va par le hook
LOCAL_OUT, et que le paquet décapsulé passe par le PRE_ROUTING hook
(la plupart des tunnels utilisent ip_rcv(), qui fait déjà ça pour
vous)
Sinon : L'utilisateur ne sera pas capable de filtrer les paquets
avec votre tunnel comme ils l'entendent.
La forme canonique pour mettre en place le premier conseil est
d'insérer du code comme celui qui suit, avant de dérouler le paquet
:
/* Dire a netfilter que ce paquet n'est plus le même
que celui d'avant! */
#ifdef CONFIG_NETFILTER
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
D'habitude, tout ce que vous avez à faire pour le second, est de
trouver où le paquet nouvellement encapsulé va avec "ip_send()", et
de remplacer ça avec quelque-chose comme :
/* Envoie le "nouveau" paquet à partir de localhost */
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, ip_send);
Suivre ces règles veut dire que la personne qui met en place une
règles de filtrage sur la machine qui tunnelle verra la séquence
suivante pour un paquet qui est tunellé :
FORWARD hook : le paquet normal (eth0 -> tunl0)
LOCAL_OUT hook : le paquet encapsulé (vers eth1)
Et pour le paquet réponse :
LOCAL_IN hook : paquet réponse encapsulé (en provenance de
eth1)