Привет.
Появилась задача переслать полученный пакет обратно в сеть. Из-за того, что это нужно делать максимально быстро(важно быстродействие), было принято решение делать это через модуль ядра.
Для этого пишу функцию, которая вызывается при получении каждого пакета и регистрирую ее в различные обработчики.
В качестве примера брал код отсюда: http://stackoverflow.com/questions/10107367/kernel-module-to-ethernet-packet-... 
А так же писал свою реализацию: 
//PROTOTYPES/////////////////////////////////////////////////////////////
void* kmemcpy(void*, const void*, ssize_t len);
unsigned int ip_packets_hook(uint hooknum, struct sk_buff* skb,
							 const struct net_device* in,
							 const struct net_device* out,
							 int (*ofkn)(struct sk_buff*));
void get_net_dev();
//GLOBALS///////////////////////////////////////////////////////////////
static struct nf_hook_ops butcher_netfilter_hook;
struct net_device *dev;
int ifindex = NULL;
static struct socket *s;
int tx_len;
struct sockaddr_ll socket_address;
spinlock_t *mr_lock;
unsigned long flags;
//INIT//////////////////////////////////////////////////////////////////
static int __init init(void)
{
    printk(KERN_ALERT "module init");
    // structure for NetFilter hook
    butcher_netfilter_hook.hook     = ip_packets_hook;
    butcher_netfilter_hook.owner    = THIS_MODULE;
    butcher_netfilter_hook.pf       = PF_INET;
    butcher_netfilter_hook.hooknum  = NF_INET_PRE_ROUTING;
    butcher_netfilter_hook.priority = NF_IP_PRI_FIRST;
    nf_register_hook(&butcher_netfilter_hook);
    return 0;
}
//EXIT//////////////////////////////////////////////////////////////////
static void __exit exit(void)
{
    nf_unregister_hook(&butcher_netfilter_hook);
    printk(KERN_ALERT "module exit");
}
////////////////////////////////////////////////////////////////////////
module_init(init);
module_exit(exit);
////////////////////////////////////////////////////////////////////////
//CORE//////////////////////////////////////////////////////////////////
unsigned int ip_packets_hook(uint hooknum, struct sk_buff* skb,
							 const struct net_device* in,
							 const struct net_device* out,
							 int (*ofkn)(struct sk_buff*))
{
    printk(KERN_ALERT "whook");
    struct iphdr* ip;
	struct tcphdr* tcp;
    struct sk_buff *my_skb = 0;
    my_skb = kmalloc(sizeof(struct sk_buff), GFP_KERNEL);
    if(!my_skb)
    {
        printk(KERN_ALERT "no malloc");
        return NF_DROP;
    }
    else
    {
        printk(KERN_ALERT "malloc done");
    }
    memcpy(my_skb, skb, sizeof(struct sk_buff));
    // CHECKS IF It's an IP packet
    printk(KERN_ALERT "after kmemcpy %d %d %d %d\n", my_skb->protocol, skb->protocol, my_skb->tail, skb->tail);
    if (my_skb->protocol == htons(ETH_P_IP))
    {
        // get IP-header
        printk(KERN_ALERT "ip proto\n");
        ip = (struct iphdr*)skb_network_header(my_skb);
        if (ip->version == 4 && ip->protocol == IPPROTO_ICMP)
        {
            printk(KERN_ALERT "icmp proto\n");
            unsigned char srcaddr[6];
            struct ethhdr *eth = eth_hdr(my_skb);
            printk(KERN_ALERT "way before sending");
            my_skb->dev = in;
            my_skb->pkt_type = PACKET_OTHERHOST;
            memcpy(srcaddr, eth->h_source, ETH_ALEN);
            memcpy(eth->h_source, eth->h_dest, ETH_ALEN);
            memcpy(eth->h_dest, srcaddr, ETH_ALEN);
            printk(KERN_ALERT "before sending");
                if(dev_queue_xmit(my_skb) == NET_XMIT_SUCCESS)
                {
                    printk(KERN_ALERT "success");
                }
                else
                {
                    printk(KERN_ALERT "phail");
                }
//            kfree_skb(skb);
//            kfree_skb(my_skb);
              dev_queue_xmit(skb); 
        }
    }
    return NF_ACCEPT;
}
void* kmemcpy(void* dst, const void* src, ssize_t len)
{
    char* pdst = (char*)dst;
    char* psrc = (char*)src;
    int i;
    for(i = 0; i < len; i++)
    {
        *pdst++ = *psrc++;
    }
    return dst;
}
void get_net_dev(void)
{
    read_lock(&dev_base_lock);
    for_each_netdev(&init_net, dev) {
    if (!strcmp(dev->name,"eth0")){
        ifindex = dev->ifindex;
    //    printk(KERN_INFO "mtu: %d", ifp->mtu);
        break;
        }
    }
    read_unlock(&dev_base_lock);
}
Проблемы две: постоянно ловлю панику ядра и мои пакеты не уходят в сеть(мониторю вайршарками на обеих машинах).

