Re: [Q] Adding a rule to a table, match->check_entry() behavior
Ugg, third time :-) Wasn't think clearly. You need to put this reference counter INSIDE the allocated memory. Since iptables will run checkentry() on one peace of memory (the new one) and destroy() on another (the old one). Set the reference counter to 1 after allocating the memory first time checkentry() is runned. There :-) 2002-04-09 05:29:57+0200, Joakim Axelsson <[EMAIL PROTECTED]> -> > 2002-04-09 03:31:22+0200, Joakim Axelsson <[EMAIL PROTECTED]> -> > > [snip problem] > > I hate answering my own mails :-) But, I talked to Martin Josefsson and he > told me that my observatiosn was correct. So how did I solve this problem. I > think it can be nice for anyone else runing into this problem: > > Typically we initiate some memory in checkentry(). However we only do this > if userspace has set this point to NULL. This will mean that when changing > the table the match data struct will go from kernelspace to userspace and > back unchanged, including the pointer. When checkentry is being runned again > it simple skips the init since it knows that it has already been initiated. > The problem is now destroy(), how do we know when we got an actually > destory() (our rule is remove) or just a destroy() because we changed > another rule and thuse "reloaded" this rule. Well use a reference counter to > help your pointer. Set the pointer to NULL and the reference counter to 0 > when first "building" the match in userspace. First time we ever run > checkentry() in kernel we set the pointer to non NULL and the reference > counter to 1. Every second time checkentry() is being runned (pointer is non > NULL) on us we increase the reference count by 1. Every time destroy() is > being runned we start by decreasing the reference count by 1. If we hit 0 we > know that we are actually being deleted and we should deallocate the memory > we used. > > Happy match/target writing with this tip :-) > > I still can't find the doc for how to write a match/target tho? Maybe this > tip should be there? If not already. > > -- > /Gozem A.K.A. Joakim Axelsson -- /Gozem A.K.A. Joakim Axelsson
Re: [Q] Adding a rule to a table, match->check_entry() behavior
2002-04-09 03:31:22+0200, Joakim Axelsson <[EMAIL PROTECTED]> -> [snip problem] I hate answering my own mails :-) But, I talked to Martin Josefsson and he told me that my observatiosn was correct. So how did I solve this problem. I think it can be nice for anyone else runing into this problem: Typically we initiate some memory in checkentry(). However we only do this if userspace has set this point to NULL. This will mean that when changing the table the match data struct will go from kernelspace to userspace and back unchanged, including the pointer. When checkentry is being runned again it simple skips the init since it knows that it has already been initiated. The problem is now destroy(), how do we know when we got an actually destory() (our rule is remove) or just a destroy() because we changed another rule and thuse "reloaded" this rule. Well use a reference counter to help your pointer. Set the pointer to NULL and the reference counter to 0 when first "building" the match in userspace. First time we ever run checkentry() in kernel we set the pointer to non NULL and the reference counter to 1. Every second time checkentry() is being runned (pointer is non NULL) on us we increase the reference count by 1. Every time destroy() is being runned we start by decreasing the reference count by 1. If we hit 0 we know that we are actually being deleted and we should deallocate the memory we used. Happy match/target writing with this tip :-) I still can't find the doc for how to write a match/target tho? Maybe this tip should be there? If not already. -- /Gozem A.K.A. Joakim Axelsson
[Q] Adding a rule to a table, match->check_entry() behavior
As i'm almost finished with my new match (superlimit). I ran into some strange things. It seams that each time I add a new rule to a table the entire table is reloaded. Because match->checkentry() for my new match is being runned once for each existing rule in the table and once for the new rule coming. And after than match->destroy() is called for each of the already existing rules. The only conclusion i have for this is that we are actually replacing the entrie table, not just adding a new rule. This must be a problem having it this way. My new match will loose all of its state when someone adds a rule, and I can for sure say that people do not expect the behavior to be like that. Is it really a need to replace the entire table, can't we modify the existing one by being smart. It will save alot of resources (if the table is long and having many complicated and/or memory-heavy matches/targets). And we will not loose any state of the matches/target. In my example with superlimit (which is mush more flexable than the existing limit) i can limit on say 5G/day (packets or bytes). Loosing that state after a half a day is something you don't want, and something a user won't expect after changing another rule. Maybe im geting it all wrong here, but atleast thats what i could get out of the source when I read it. Second, I can't find any documentation on match nor target how they should be written (what all the arguments for the function are, etc.). I think I have read some somewhere, has it been lost? I might have forgotten to set any flag that this behavior of my new match isn't wanted. That nfcache is one thing that i'm not sure of. Third, a question about SMP. I can see that in the old limit code there is a uggly hack for soliving a SMP-problem. It seams as far as i can tell from what problem the code tries to work around is that match->checkentry() is being runned once per CPU. Sniped from ipt_limit.c: ---8<--- checkentry() { struct ipt_rateinfo *r = matchinfo; ... /* For SMP, we only want to use one set of counters. */ r->master = r; } match() { struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; ... } ---8< Meaning that every of the number copies we might get of this entry (?) the last one setting r->master is the one we are working with. Is this correct? Thanks! Keep the work up! -- /Gozem A.K.A. Joakim Axelsson