Alexandr Nedvedicky

Friday Aug 10, 2007

IPF Tuneables

IPF Tuneables

This is the first of iregular posts discussing some topics related to IPF. I can promise I'll update this blog any time I'll find something new, but I can't promise it will happen often and regularly. The posts are going to introduce some not so well known facts about IPF. Feel free to ask in comments below, I'll try to answer them. You can also suggest a topic for next post there. Please don't report your problems with IPF, requests for features and so on here. For that purpose you can use majordomo@coombs.anu.edu.au mailing list, or ask SUN, in case you have a support contract. Please consider this place is trying to provide hints and advanced howtos to IPF users.

At this post I'm going to provide some overview of IPF tuneables. So what are these tuneables? They are nothing less than ordinary variables residing in IPF kernel module. User may alter them by command line utility ipf(1M)to fine tune performance parameters of IPF. The IPF manual page for ipf(1M) just recognizes those variables exist.

     -T optionlist

         Allows run-time changing of IPFilter  kernel  variables.
         To  allow  for changing, some variables require IPFilter
         to be in a disabled  state  (-D),  others  do  not.  The
         optionlist parameter is a comma-separated list of tuning

         list

             Retrieve a list of  all  variables  in  the  kernel,
             their maximum, minimum, and current value.


         single variable name

             Retrieve its current value.


         variable name with a following assignment

             To set a new value.

Just type ipf -T list to retrieve a list of variables to tune. The output may differ ipf version to ipf version. The command output should be same for all 4.1.xx IPFs. In ipf(1M) you may read that some variables require to disable to IPF to tune them. To find out, which needs IPF disabled one has to look into sources. Don't worry, I know you are network administrator, not programmer, so let me describe the piece of code for you.

There is an array lcl_ipf_tuneables declared. All tuneable variables you get listed by ipf -T list can be found in this array. You can assume tuneable variables live here at runtime.

Every tuneable variable is described by a C structure ipftuneable_t. Let's breake down the structure to its members. We see it contains:

  • ipft_una - pointer to memory, where given variable resides (altering variable means altering data at this address),
  • ipft_name - variable name, it is printed out when variables are listed, it also serves as a key to look up value for given variable,
  • ipft_min - minimal value,
  • ipft_max - max value, both serve for sanity check of user's input from command ipf(1M),
  • ipft_sz - size of variable (how many bytes of memory is occupied starting at place where ipft_una points to),
  • ipft_flags - flags, I'm going to describe them later, since they are the only reason I'm introducing bits and pieces of IPF sources here,
  • ipft_next - pointer to next variable in array.

At this moment I'm going to describe the initialization of complex data in C. If you are familiar with this, just skip it. The piece of code below intializes (assigns initial values) to variable tune of ipftuneable_t type. Since programmers talk in code speak to each other, they usually say they initializing instance of structure ipftuneable_t. The instance's name is tune.

ipftuneable_t	tune = { { NULL }, "arbitrary_name", 0, 10, 0, 0 }

The initial values for members of structure ipftuneable_t are enclosed between { and }. There are initial values are delimited by commas (,) in between {}. It starts with member ipft_una, which is pointer to another complex type, therefore it is enclosed also in pair of curly brackets. Next one is initial value for ipft_name member. The last initial value in list is value for ipft_flags, member ipft_next is left uninitialized.

The explanation of array initialization is pretty straightforward now. Array is also complex type. Suppose we introduce an array of three integers:

	int 3dVector[] = { 1, 2, 3 };
There are three elements in array of integer type set to initial value. Nothing changes much for array of structures. You declare an array variable:
	ipftuneable_t lcl_ipf_tuneables[];
initializes:
	 ipftuneable_t lcl_ipf_tuneables[] = {};
you must of course initialize every element in array,
	 ipftuneable_t lcl_ipf_tuneables[] = { { { NULL }, "arbitrary_name", 0, 10, 0, 0 } };
At this moment you know enough to read code.

Just look to the initial value of last member of every array element. You can spot there are altering those values:

  • 0,
  • IPFT_WRDISABLED,
  • IPFT_RDONLY,
0 there means there are no constraints for given tuneable variable. You can alter that variable without disabling IPF.

IPFT_WRDISABLED flag value means, you must disable IPF first to alter variable. To change such variable you usually do something like that:
	# ipf -D
	# ipf -T fr_tcptimeout = 49343
	# ipf -E
Sometimes you don't want to lose entries from your NAT table (state table). Therefore you would probably want to use ipfs(1M) command to preserve such runtime data when disabling IPF to tune variable. The command sequence then would look as follows:
	# ipfs -W
	# ipf -D
	# ipf -T fr_tcptimeout = 49343
	# ipf -E
	# ipfs -R
The ipfs -W dumps NAT table and state table to file on disk, while ipfs -R loads content of previously stored file to back to kernel, once IPF is enabled. Implicit file /var/db/ipf/ipnat.ipf is used for NAT table, file /var/db/ipf/ipstate.ipf is used for state table. You may override those files, check ipfs(1M) manpage.

The first post provided introduction to IPF tuneables variables. The most valuable thing offered to the reader is a pointer where to find out information regarding which variable is read only, which requires IPF to be disabled when you need to alter them and which can be changed without any constraints. I intentionally did not create list or some table with overview of those variables, as such those variables are often subject of change.

I'm going to write about IPF table size tuning in my next post.

Comments:

Thank you for sharing,

What is the maximum size of 'ipf_nattable_max' what you achive

I can't reach more that 550000,

If set ipf_nattable_max to be more that 550000, on freebsd 6.2 I got kernel panic.

nebula ~# ipnat -s
mapped in 4152060 out 4677411
added 1220433 expired 0
no memory 126657 bad nat 1772
inuse 496057
rules 1051
wilds 0

Posted by Todor Dragnev on April 04, 2008 at 09:33 AM CEST #

ipf_nattable_max is hard limit chosen
by user.

the physical table size is determined as
a product of ipf_nattable_sz * ipf_nat_maxbucket

that's the maximum of entries, which can fit into table.

so in case of inequity:
ipf_nattable_sz * ipf_nat_maxbucket < ipf_nattable_max

the ipf_nattable_max is overriden by the product of table size, maxbucket.
that's the content of intended next part...

Posted by SashaN on June 03, 2008 at 12:44 PM CEST #

It was a very nice idea! Just wanna say thank you for the information you have shared. Just continue writing this kind of post. I will be your loyal reader. Thanks again.

Posted by links of london jewellery on November 25, 2009 at 03:57 AM CET #

Post a Comment:
  • HTML Syntax: NOT allowed

Calendar

Feeds

Search

Links

Navigation

Referrers