* proposal of xt_physdev's patch to limit traffic
@ 2010-10-21 10:27 ahmed amamou
2010-10-21 10:47 ` Gianni Tedesco
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: ahmed amamou @ 2010-10-21 10:27 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 1024 bytes --]
Good morning every Body
I'm new in modules programming and I've made a patch to limit packet traffic in bridge(patch is joined with the mail).
In order to limit the traffic, i used the netback limitation method to count traffic with skb->len for each vif to stop traffic, as i can't put down vif, i change the hotdrop flag to 1 (change was based on xt_physdev of dom 0 2.6.18.8 so in the patch will find it 1 but it's easy to change the patch to recent dom 0 version by just changing *hotdrop=1; to *par->hotdrop=true;)
The problem that i have is that when i reach traffic limit (30mb/s by defaut and can be changed via proc EX: "echo vif1.0 312500,50000' >/proc/changeRXrate know that doing it via proc is the worst way but i don't know any other way to do it any suggestion will be welcome ) and begin drop traffic fell terribly and became 10mb/s
will be really thankful if anybody could help me with suggestions and advices in order to solve this problem
Sincerly
Ahmed AMAMOU
[-- Attachment #1.2: Type: text/html, Size: 1280 bytes --]
[-- Attachment #2: xt_physdev_diff --]
[-- Type: application/octet-stream, Size: 10846 bytes --]
*** xt_physdev_old.c 2010-10-18 10:53:54.000000000 +0200
--- xt_physdev.c 2010-10-21 11:17:47.000000000 +0200
***************
*** 14,21 ****
--- 14,31 ----
#include <linux/netfilter/xt_physdev.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge.h>
+ #include <linux/string.h>
+
+ #include <linux/slab.h> /* For kmalloc() */
+ #include <linux/timer.h>
+ #include <linux/sched.h>
+ #include <linux/proc_fs.h>
+ #include <linux/vmalloc.h>
#define MATCH 1
#define NOMATCH 0
+ #ifndef ULONG_MAX
+ #define ULONG_MAX (~0UL)
+ #endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
***************
*** 23,28 ****
--- 33,316 ----
MODULE_ALIAS("ipt_physdev");
MODULE_ALIAS("ip6t_physdev");
+ #define DEFAULT_CREDIT_BYTES 187500
+ #define DEFAULT_CREDIT_USEC 50000
+ #define PROC_ENTRY_FILENAME "changeRXrate"
+ #define INTERFACENAMESIZE 10
+ #define LONGSIZE 64
+ #define PROCFS_MAX_SIZE 1024
+
+ struct interface_limit{
+ char name[IFNAMSIZ];
+ unsigned long credit_bytes;
+ unsigned long credit_usec;
+ unsigned long remaining_credit;
+ unsigned long credit_timeout;
+ struct interface_limit *next;
+ };
+
+ static char procfs_buffer[PROCFS_MAX_SIZE];
+ static unsigned long procfs_buffer_size = 0;
+ struct proc_dir_entry *Proc_File;
+ static struct interface_limit* interface_list=NULL;
+
+
+ /**
+ mystrtoul convert char to unsigned long
+ @param str
+ @return unsigned long
+ **/
+ unsigned long
+ mystrtoul(char *str )
+ {
+ unsigned long res;
+ unsigned long mul;
+ char *ptr;
+ mul = 1;
+ res=0;
+ for(ptr = str + strlen(str) - 1; ptr >= str; ptr--){
+ if(*ptr < '0' || *ptr > '9')
+ return(-1);
+ res += (*ptr - '0') * mul;
+ mul *= 10;
+ }
+ return res;
+ }
+ /**
+ initialise_interface_list initilize the interface_list by adding the first interface
+ @param name first interface name
+ @param credit_byte first interface credit_byte
+ @param credit_usec first interface cedti_usec
+ @return the first added interface
+ **/
+ struct interface_limit*
+ initialize_interface_list(char* name, unsigned long credit_bytes,unsigned long credit_usec)
+ {
+ interface_list=kmalloc(sizeof(struct interface_limit),GFP_KERNEL);
+ sprintf(interface_list->name,"%s",name);
+ if (credit_bytes > 0)
+ interface_list->credit_bytes=credit_bytes;
+ else
+ interface_list->credit_bytes=DEFAULT_CREDIT_BYTES;
+ if (credit_usec > 0)
+ interface_list->credit_usec=credit_usec;
+ else
+ interface_list->credit_usec=DEFAULT_CREDIT_USEC;
+ interface_list->remaining_credit=0;
+ interface_list->credit_timeout=jiffies;
+ interface_list->next=NULL;
+ return interface_list;
+
+ }
+
+ /**
+ add_interface add interface to our interface list
+ @param name added interface name
+ @param credit_byte added interface credit_byte
+ @param credit_usec added interface cedti_usec
+ @return the added interface
+ **/
+ struct interface_limit*
+ add_interface(char* name, unsigned long credit_bytes,unsigned long credit_usec)
+ {
+ struct interface_limit * new_interface=NULL;
+ new_interface=kmalloc(sizeof(struct interface_limit),GFP_KERNEL);
+ sprintf(new_interface->name,"%s",name);
+ if (credit_bytes > 0)
+ new_interface->credit_bytes=credit_bytes;
+ else
+ new_interface->credit_bytes=DEFAULT_CREDIT_BYTES;
+ if (credit_usec > 0)
+ new_interface->credit_usec=credit_usec;
+ else
+ new_interface->credit_usec=DEFAULT_CREDIT_USEC;
+ new_interface->remaining_credit=0;
+ new_interface->credit_timeout=jiffies;
+ new_interface->next=interface_list->next;
+ interface_list->next=new_interface;
+ return new_interface;
+ }
+
+ /**
+ add_interface_credit refill interface credit
+ @param netif network interface that w'll refill with credit byte
+ @return 0 if success
+ **/
+ static int
+ add_interface_credit(struct interface_limit * netif)
+ {
+ unsigned long max_burst, max_credit;
+ max_burst = 3*netif->credit_bytes;
+ max_credit = netif->remaining_credit + netif->credit_bytes;
+ if (max_credit < netif->remaining_credit)
+ max_credit = ULONG_MAX;
+ netif->remaining_credit = min(max_credit, max_burst);
+ //printk(KERN_ALERT "remaining_credit after add: %lu\n",netif->remaining_credit);
+ return 0;
+ }
+
+
+
+ /**
+ find_interface_by_name
+ @param name the name of serached interface
+ @return pointer to the interface
+ **/
+
+ struct interface_limit*
+ find_interface_by_name(char* name)
+ {
+ if (interface_list != NULL){
+ struct interface_limit* nextpos=interface_list->next;
+ if (!(strcmp(interface_list->name,name)))
+ return interface_list;
+ else {
+ while (nextpos !=NULL){
+ if (!(strcmp(nextpos->name,name)))
+ return nextpos;
+ nextpos=nextpos->next;
+ }
+ return add_interface(name,0,0);
+ }
+ } else {
+ return initialize_interface_list(name,0,0);
+ }
+ }
+
+ /**
+ check if the network interface that will recive the paquet is allowed to recive it and check for credit add
+ @param netif_name interface that will check for credit
+ @param Rxrequestsize size of resived paquet to match
+ @return 1 if have enough credit 0 else
+ **/
+
+
+ static int
+ check_remaining_credit(char* netif_name,unsigned long Rxrequestsize)
+ {
+
+ int ret;
+ unsigned long next_credit;
+ unsigned long now;
+ struct interface_limit * netif=NULL;
+ netif=find_interface_by_name(netif_name);
+ ret=0;
+
+ now = jiffies;
+ next_credit =netif->credit_timeout + msecs_to_jiffies(netif->credit_usec / 1000);//next credit satrting time
+
+ //if (time_after_eq(now, next_credit)){ // we started a new slice so w'll have to refill credit
+ if (now >= next_credit){ // we started a new slice so w'll have to refill credit
+ netif->credit_timeout = now;
+ add_interface_credit(netif);
+ //printk(KERN_ALERT "now: %lu next_credit: %lu\n",now,next_credit);
+ }
+ //printk(KERN_ALERT "ifname :%s Rxrequestsize: %lu remaining_credit: %lu\n",netif->name,Rxrequestsize,netif->remaining_credit);
+ if (netif->remaining_credit > Rxrequestsize){
+ //printk(KERN_ALERT "%s match\n",netif->name);
+ netif->remaining_credit -= Rxrequestsize;
+ return 1;
+ } else{
+ //printk(KERN_ALERT "%s no match\n",netif->name);
+ return 0;
+ }
+ return 1;
+ }
+
+
+ int
+ procfile_read(char *buffer,
+ char **buffer_location,
+ off_t offset, int buffer_length, int *eof, void *data)
+ {
+ int l;
+ int len;
+ int i=0;
+ off_t begin = 0;
+
+ if (offset > 0){
+ len = 0;
+ }else{
+ if (interface_list!=NULL)
+ {
+ struct interface_limit* nextpos=interface_list->next;
+ len= sprintf(buffer,"%i ifname=%s bytes=%lu usec=%lu\n",i,interface_list->name,interface_list->credit_bytes,interface_list->credit_usec);
+ i += 1;
+ while (nextpos !=NULL){
+ l=sprintf(buffer+len,"%i ifname=%s bytes=%lu usec=%lu\n",i,nextpos->name,nextpos->credit_bytes,nextpos->credit_usec);
+ len += l;
+ i += 1;
+ nextpos=nextpos->next;
+ if (len+begin > offset+buffer_length)
+ goto done;
+ if (len+begin < offset) {
+ begin += len;
+ len = 0;
+ }
+ }
+ } else {
+ len=sprintf(buffer,"no interface detected for the moment\n");
+ return len;
+
+ }
+ }
+
+ done:
+ if (offset >= len+begin)
+ return 0;
+ *buffer_location = buffer + (offset-begin);
+ return ((buffer_length < begin+len-offset) ? buffer_length : begin+len-offset);
+ }
+
+ int
+ procfile_write(struct file *file, const char *buffer, unsigned long count,
+ void *data)
+ {
+ int i=0;
+ int j=0;
+ char name[INTERFACENAMESIZE];
+ char rate[LONGSIZE];
+ char slice[LONGSIZE];
+ struct interface_limit * tmp_intrface=NULL;
+
+ procfs_buffer_size = count;
+ if (procfs_buffer_size > PROCFS_MAX_SIZE ) {
+ procfs_buffer_size = PROCFS_MAX_SIZE;
+ }
+
+ /* write data to the buffer */
+ if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
+ return -EFAULT;
+ }
+
+ while (procfs_buffer[i]!= ' ' && i< count){
+ name[i]=procfs_buffer[i];
+ i++;
+ }
+ name[i]='\0';
+ i++;
+ while(procfs_buffer[i]!= ',' && i< count){
+ rate[j]=procfs_buffer[i];
+ i++;
+ j++;
+ }
+
+ rate[j]='\0';
+ i++;
+ j=0;
+ while(i< count){
+ slice[j]=procfs_buffer[i];
+ i++;
+ j++;
+ }
+ slice[j-1]='\0';
+ tmp_intrface= find_interface_by_name(name);
+ tmp_intrface->credit_bytes=mystrtoul(rate);
+ tmp_intrface->credit_usec=mystrtoul(slice);
+ return procfs_buffer_size;
+
+ }
+
static int
match(const struct sk_buff *skb,
const struct net_device *in,
***************
*** 90,100 ****
return MATCH;
outdev = nf_bridge->physoutdev ?
nf_bridge->physoutdev->name : nulldevname;
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
ret |= (((const unsigned int *)outdev)[i]
^ ((const unsigned int *)info->physoutdev)[i])
& ((const unsigned int *)info->out_mask)[i];
! }
return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT);
}
--- 378,396 ----
return MATCH;
outdev = nf_bridge->physoutdev ?
nf_bridge->physoutdev->name : nulldevname;
+ /*code modif in match */
+ if (outdev[0]=='v' || outdev[0]=='V'){
+ if (!(check_remaining_credit(outdev,(unsigned long)skb->len))){
+ *hotdrop=1; // *par->hotdrop=true; in recent kernel
+ return NOMATCH;
+ }
+ }
+ /*code modif in match*/
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
ret |= (((const unsigned int *)outdev)[i]
^ ((const unsigned int *)info->physoutdev)[i])
& ((const unsigned int *)info->out_mask)[i];
! }
return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT);
}
***************
*** 150,155 ****
--- 446,465 ----
static int __init xt_physdev_init(void)
{
int ret;
+ Proc_File = create_proc_entry(PROC_ENTRY_FILENAME, 0644, NULL);
+ if (Proc_File == NULL) {
+ remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
+ printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
+ PROC_ENTRY_FILENAME);
+ return -ENOMEM;
+ }
+ Proc_File->write_proc = procfile_write;
+ Proc_File->read_proc = procfile_read;
+ Proc_File->owner = THIS_MODULE;
+ Proc_File->mode = S_IFREG | S_IRUGO;
+ Proc_File->uid = 0;
+ Proc_File->gid = 0;
+ Proc_File->size = 80;
ret = xt_register_match(&physdev_match);
if (ret < 0)
***************
*** 166,171 ****
--- 476,482 ----
{
xt_unregister_match(&physdev_match);
xt_unregister_match(&physdev6_match);
+ remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
}
module_init(xt_physdev_init);
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: proposal of xt_physdev's patch to limit traffic
2010-10-21 10:27 proposal of xt_physdev's patch to limit traffic ahmed amamou
@ 2010-10-21 10:47 ` Gianni Tedesco
2010-10-21 10:52 ` Ian Campbell
2010-10-21 12:38 ` Felix Kuperjans
2 siblings, 0 replies; 4+ messages in thread
From: Gianni Tedesco @ 2010-10-21 10:47 UTC (permalink / raw)
To: ahmed amamou; +Cc: xen-devel@lists.xensource.com
On Thu, 2010-10-21 at 11:27 +0100, ahmed amamou wrote:
> Good morning every Body
>
> I'm new in modules programming and I've made a patch to limit packet
> traffic in bridge(patch is joined with the mail).
>
> In order to limit the traffic, i used the netback limitation method to
> count traffic with skb->len for each vif to stop traffic, as i can't
> put down vif, i change the hotdrop flag to 1 (change was based on
> xt_physdev of dom 0 2.6.18.8 so in the patch will find it 1 but it's
> easy to change the patch to recent dom 0 version by just changing
> *hotdrop=1; to *par->hotdrop=true;)
>
> The problem that i have is that when i reach traffic limit (30mb/s by
> defaut and can be changed via proc EX: "echo vif1.0 312500,50000'
> >/proc/changeRXrate know that doing it via proc is the worst way but i
> don't know any other way to do it any suggestion will be welcome ) and
> begin drop traffic fell terribly and became 10mb/s
>
> will be really thankful if anybody could help me with suggestions and
> advices in order to solve this problem
Isn't this possible with either QoS/tc possibly combined with IMQ
(intermediate queueing device) ?
In either case, I think linux-net is the place to discuss this.
Gianni
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: proposal of xt_physdev's patch to limit traffic
2010-10-21 10:27 proposal of xt_physdev's patch to limit traffic ahmed amamou
2010-10-21 10:47 ` Gianni Tedesco
@ 2010-10-21 10:52 ` Ian Campbell
2010-10-21 12:38 ` Felix Kuperjans
2 siblings, 0 replies; 4+ messages in thread
From: Ian Campbell @ 2010-10-21 10:52 UTC (permalink / raw)
To: ahmed amamou; +Cc: xen-devel@lists.xensource.com
Hi Ahmed,
On Thu, 2010-10-21 at 11:27 +0100, ahmed amamou wrote:
> Good morning every Body
>
> I'm new in modules programming and I've made a patch to limit packet
> traffic in bridge(patch is joined with the mail).
>
> In order to limit the traffic, i used the netback limitation method to
> count traffic with skb->len for each vif to stop traffic, as i can't
> put down vif, i change the hotdrop flag to 1 (change was based on
> xt_physdev of dom 0 2.6.18.8 so in the patch will find it 1 but it's
> easy to change the patch to recent dom 0 version by just changing
> *hotdrop=1; to *par->hotdrop=true;)
>
> The problem that i have is that when i reach traffic limit (30mb/s by
> defaut and can be changed via proc EX: "echo vif1.0 312500,50000'
> >/proc/changeRXrate know that doing it via proc is the worst way but i
> don't know any other way to do it any suggestion will be welcome ) and
> begin drop traffic fell terribly and became 10mb/s
>
> will be really thankful if anybody could help me with suggestions and
> advices in order to solve this problem
There doesn't seem to be anything particularly xen specific about your
patch. I think you will likely find more people able to help on the
netfilter lists (see the MAINTAINERS file).
However I'd first recommend reading Documentation/CodingStyle and
Documentation/SubmittingPatches as well as rebasing to a much newer
kernel than 2.6.18 (which is ancient even by Xen standards). You might
find ./scripts/checkpatch.pl useful as a rough guide to the coding style
fixes.
Ian.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: proposal of xt_physdev's patch to limit traffic
2010-10-21 10:27 proposal of xt_physdev's patch to limit traffic ahmed amamou
2010-10-21 10:47 ` Gianni Tedesco
2010-10-21 10:52 ` Ian Campbell
@ 2010-10-21 12:38 ` Felix Kuperjans
2 siblings, 0 replies; 4+ messages in thread
From: Felix Kuperjans @ 2010-10-21 12:38 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 1723 bytes --]
I think you don't even need any new netfilter patches or features.
Just using "physdev" together with the "quota" match should be
sufficient (maybe it's not in the 2.6.18 kernel, but definitely in
recent or pv_ops kernels).
In addition, I don't think that the netfilter will be interested in a
quota patch to physdev; physdev is meant to match the device a packages
was coming from on a bridge - quotas are definitely the job of the quota
match or QoS, not the physdev match.
Regards,
Felix
Am 21.10.2010 12:27, schrieb ahmed amamou:
> Good morning every Body
>
> I'm new in modules programming and I've made a patch to limit packet
> traffic in bridge(patch is joined with the mail).
>
> In order to limit the traffic, i used the netback limitation method to
> count traffic with skb->len for each vif to stop traffic, as i can't
> put down vif, i change the hotdrop flag to 1 (change was based on
> xt_physdev of dom 0 2.6.18.8 so in the patch will find it 1 but it's
> easy to change the patch to recent dom 0 version by just changing
> *hotdrop=1; to *par->hotdrop=true;)
>
> The problem that i have is that when i reach traffic limit (30mb/s by
> defaut and can be changed via proc EX: "echo vif1.0 312500,50000'
> >/proc/changeRXrate know that doing it via proc is the worst way but i
> don't know any other way to do it any suggestion will be welcome ) and
> begin drop traffic fell terribly and became 10mb/s
>
> will be really thankful if anybody could help me with suggestions and
> advices in order to solve this problem
>
>
> Sincerly
>
> Ahmed AMAMOU
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 2748 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-10-21 12:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-21 10:27 proposal of xt_physdev's patch to limit traffic ahmed amamou
2010-10-21 10:47 ` Gianni Tedesco
2010-10-21 10:52 ` Ian Campbell
2010-10-21 12:38 ` Felix Kuperjans
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.