Can i use dev_queue_xmit()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We wrote a KernelModule for fetching internet packets through certain 
interface, and reforwarding them through another interface of our choice 
based on IP-address,Port values of packet.
 
This module is working fine for less rate of traffic(< 200 Mbps) , But 
same module is dropping some of the packets(4 lakhs out of 10 lakhs)  for 
highier speeds(> 200Mbps).Function  *dev_queue_xmit()* in the kernel 
module, is returning NET_XMIT_DROP for dropped packets.This is due to 
the function call *q->enqueue(skb,q)* in dev_queue_xmit().What might be 
the reason for that return value.

Is it the problem with s/w or h/w ? We are using Linux-2.4 and Gigabyte 
Eth cards.And we are genrating traffic by resending same packet for many 
times.How can we figure out the location of problem. 

We are attaching our module file.

I will be very thankful to your help.
Thanks in advance,
K.AnanthaKiran
#define MODULE
#define __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <asm-i386/types.h>


/* This is the structure we shall use to register our function */

static struct nf_hook_ops nfho; /* Initialisation routine */

int hook_func(unsigned int hooknum,
	      struct sk_buff **skbuff,
	      const struct net_device *in,
	      const struct net_device *out,
	     int (*okfn)(struct sk_buff *))
{
	struct sk_buff* skb=*skbuff;
	struct iphdr *iph;
	struct tcphdr *th;
	struct ethhdr *ether;
	unsigned char ea1[7] = {0x00,0x07,0xe9,0x24,0x71,0x15};
	unsigned int devno;
	static int cnt[3];
	struct net_device *dev;
	
	u32  saddr,daddr; 
	u16  source,dest; 
	
	/*
	 *  Checking whether skb and IP_Header are not null
	 */
	
	 if (!skb ) 		return NF_ACCEPT;
         if (!(skb->nh.iph)) 	return NF_ACCEPT;

	if(strcmp(in->name,"eth0") != 0)
		return NF_ACCEPT;
	/*
	 * Checking whether Packet is from Ethernet device or not
	 * Doubt: What is the better place to put it ! 
	 */

	if(skb->dev->type!=ARPHRD_ETHER)
		return NF_ACCEPT;
	
	iph = skb->nh.iph;

	/*
	 * Checking whether packet is TCP or UDP packet 
	 *  otherwise ignore it 
	 */

	if ( iph -> protocol != IPPROTO_TCP && iph -> protocol != IPPROTO_UDP )
		return NF_ACCEPT;

	th = (struct tcphdr *) (skb->data + (skb->nh.iph->ihl * 4) ) ;
	
	// Getting source and destination ip addresses from ip header
	saddr = iph->saddr;
	daddr = iph->daddr;

	// Getting source and destination ports from TCP header
	source = th->source;
	dest   = th->dest;

	// Computing Hash 

	devno = (saddr + daddr + source + dest) % 2;


	// Starting address of ethernet frame


	if((ether = (struct ethhdr *)skb->mac.ethernet)== NULL) 
		return NF_ACCEPT;
	
	// Selecting device 
	switch(devno)
	{
		case 0: 
			if( (dev = dev_get_by_name("eth1")) == NULL)
				return NF_ACCEPT;
			memcpy(ether->h_source,dev->dev_addr,ETH_ALEN);
			break;

		case 1:
			if( (dev = dev_get_by_name("eth2")) == NULL)
				return NF_ACCEPT;
			memcpy(ether->h_source,dev->dev_addr,ETH_ALEN);
			break;

		case 2:
			if( (dev = dev_get_by_name("eth1")) == NULL)
				return NF_ACCEPT;
			memcpy(ether->h_source,dev->dev_addr,ETH_ALEN);
			break;

	}

	//Setting Destination as ea1
	memcpy(ether->h_dest,ea1,ETH_ALEN);

	skb->data = (unsigned char *)skb->mac.ethernet;
	skb->len += ETH_HLEN; 
	
	// Setting it as outgoing packet
	skb->pkt_type=PACKET_OUTGOING;

	// changing the dev to output device we need
	skb->dev = dev;

	// Transmitting the packet
	if((cnt[2]=dev_queue_xmit(skb))==NET_XMIT_SUCCESS) 
		cnt[0]++;
	else
		if(cnt[2] != 1)
		printk("%d ",cnt[2]);
	cnt[1]++;
	if((cnt[1]%100000)==0) printk("%d %d\n",cnt[0],cnt[1]);

	return NF_STOLEN;

}
int init_module()
{
	/* Fill in our hook structure */
	nfho.hook     = (nf_hookfn *)hook_func;

	/* Handler function */
	nfho.hooknum  = NF_IP_PRE_ROUTING; /* First hook for IPv4 */
	nfho.pf       = PF_INET;
	nfho.priority = NF_IP_PRI_FIRST;   /* Make our function first */
          
	nf_register_hook(&nfho);

	return 0;
}
          
/* Cleanup routine */
void cleanup_module()
{
	nf_unregister_hook(&nfho);
}



























[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux