The rough experience of compiling Linux-2.6.32 on the ipset-6.23 kernel, linux2.6.32
New version of ipset
Last week, I received a message from the Netfilter email list when I waited for a call from the children's hospital to see a doctor. I listed the new features of the latest version of ipset 6.23, many of which are exactly what I need now, in particular, the timeout and skbinfo parameters are supported. For more information, see manual:
Timeout
All set types supports the optional timeout parameter when creating a set and adding entries. The value of the timeout
Parameter for the create command means the default timeout value (in seconds) for new entries. If a set is created
Timeout support, then the same timeout option can be used to specify non-default timeout values when adding entries. Zero
Timeout value means the entry is added permanent to the set. The timeout value of already added elements can be changed
By readding the element using the-exist option. Example:
Ipset create test hash: ip timeout 300
Ipset add test 192.168.0.1 timeout 60
Ipset-exist add test 192.168.0.1 time out 600
...
Skbinfo, skbmark, skbprio, skbqueue
All set types support the optional skbinfo extension. This extension allow to store the metainfo (firewall mark, tc class
And hardware queue) with every entry and map it to packets by usage of SET netfilter target with -- map-set option. skb identifier \
Mark option format: MARK or MARK/MASK, where MARK and MASK are 32bit hex numbers with 0x prefix. If only mark is speci ‐
Fied mask 0 xffffffff are used. skbprio option has tc class format: MAJOR: MINOR, where major and minor numbers are hex
Without 0x prefix. skbqueue option is just decimal number.
Ipset create foo hash: ip skbinfo
Ipset add foo skbmark 0x1111/0 xff00ffff skbprio skbqueue 10
...
Nomatch
The hash set types which can store net type of data (I. e. hash: * net *) support the optional nomatch option when adding
Entries. When matching elements in the set, entries marked as nomatch are skipped as if those were not added to the set,
Which makes possible to build up sets with exceptions. See the example at hash type hash: net below.
When elements are tested by ipset, the nomatch flags are taken into account. If one wants to test the existence of
Element marked with nomatch in a set, then the flag must be specified too.
...
Compile
In short, compared with the old version 4.5, there are indeed a lot of new things added, so you can't wait to download, compile, and try out. In general, these steps are routine, it will not encounter any major difficulties, especially after reading its README:
0. You need the source tree of your kernel (version> = 2.6.32)
And it have to be configured with ip6tables support enabled,
Modules compiled. For kernel versions <2.6.39 please apply
The netlink. patch against your kernel tree, which adds
New subsystem identifier for ipset.
My kernel is 2.6.32. Although it is old, there is no way. However, since 2.6.32 is supported, you can rest assured that besides README, the website also explicitly states that 2.6.32 kernel is supported:
For the new branch
Linux kernel source code (version> = 2.6.32)
Source of ipset: The ipset-6.23.tar.bz2 (md5sum)
So we started the routine work:
Tar xjvf ipset-6.23.tar.bz2
Cd ipset-6.23
./Configure
The report says no netlink. patch is provided for the kernel, but this is not a problem, but at this point, I raised a question:
Question: I only updated the header file. Why do I have to patch the kernel source code tree?
I felt that this action was not regular. In order not to rely on the source code tree, I typed the patch into the kernel header file 2.6.32 required for compilation, so configure passed smoothly, but encountered another problem, the prompt is that I have not installed libmnl. Because it is a clean environment, I downloaded the libmnl source code of the new version on the Netfilter website and routinely installed libmnl. This step is not mandatory for me. For me, how can I avoid installing libmnl for Netfilter every day...
Next is make, pass, then make modules, report a lot of errors, and then I feel that this ipset-6.23 TMD does not support 2.6.32, all the instructions are TMD in nonsense! The following file is reported as an error:
Ipset-6.23/kernel/net/netfilter/xt_set.c
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ match_v0_checkentry ':
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 99: error: 'const struct xt_mtchk_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 108: error: 'const struct xt_mtchk_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ match_v0_destroy ':
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 123: error: 'const struct xt_mtdtor_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ match_v1_checkentry ':
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 148: error: 'const struct xt_mtchk_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 157: error: 'const struct xt_mtchk_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ match_v1_destroy ':
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 169: error: 'const struct xt_mtdtor_param 'has no member named 'net'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ target_v0 ':
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: 231: error: 'const struct xt_match_param 'has no member named 'targinfo'
/Usr/src/ipset-6.23/kernel/net/netfilter/xt_set.c: In function 'set _ target_v0_checkentry ':
I found the following macro definition in this source file:
#ifdef HAVE_CHECKENTRY_BOOL#define CHECK_OK 1#define CHECK_FAIL(err) 0#define CONST const#define FTYPE bool#define XT_PAR_NET(par) NULL#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */#define CHECK_OK 0#define CHECK_FAIL(err) (err)#define CONST#define FTYPE int#define XT_PAR_NET(par) (par)->net#endif
Obviously, according to the annotation, I should define HAVE_CHECKENTRY_BOOL, but the macro definition should be automated and should not be manually intervened. In the configure file, I found the following definition statement:
if test -f $ksourcedir/net/netfilter/xt_state.c && \ $GREP -q 'bool state_mt_check' $ksourcedir/net/netfilter/xt_state.c; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5$as_echo "yes" >&6; } HAVE_CHECKENTRY_BOOL=defineelse { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5$as_echo "no" >&6; } HAVE_CHECKENTRY_BOOL=undeffi
Note:
$ Ksourcedir/net/netfilter/xt_state.cI was so angry with this evil statement that the source code file was specified to find the type of the return value of the match check callback function in this file. Can't the author tell me through the kernel version number? Isn't the return value specification of match check fixed for a fixed kernel version? Can the following calls change for the 2.6.32 kernel? :
if (par->target->checkentry != NULL && !par->target->checkentry(par)) return -EINVAL;
I'm angry, but I can't force open-source software to do anything, just like Bill. as Gates once said, non-paid programmers cannot write first-class software, which I believe a little bit. Well, I have specified a source code file to let the configure process define the evil HAVE_CHECKENTRY_BOOL macro. It is worth noting that apart from that macro, another macro, HAVE_XT_TARGET_PARAM, plays the same role to adapt to different kernel versions. Its role is to define it as xt_target_param in earlier kernel versions without defining the xt_action_param struct, convert to xt_match_param when necessary. After defining these two macros, xt_set is compiled, but the ipset kernel module itself reports an error, and the ipset kernel module itself is more important than xt_set, you need to know that xt_set is only a module used when interacting with iptables. Even if it cannot be adapted, it is not difficult to write one by yourself. However, if you want to write the kernel module of ipset itself, that is equivalent to implementing ipset-6.23 itself... fortunately, there are not many new errors this time:
CC [M]/usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.o
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: In function 'call _ ad ':
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: 1444: error: 'size _ MAX 'undeclared (first use in this function)
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: 1444: error: (Each undeclared identifier is reported only once
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: 1444: error: for each function it appears in .)
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: 1444: warning: type defaults to 'int' in declaration of '_ min1'
/Usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.c: 1444: warning: comparison of distinct pointer types lacks a cast
Make [4]: **** [/usr/src/ipset-6.23/kernel/net/netfilter/ipset/ip_set_core.o] Error 1
It is said that SIZE_MAX is not defined. This constant is available in kernel Versions later than 3.5. 2.6.32 cannot be compiled unless manually defined. Although it is not difficult to define it manually, but the more I think that the ipset-6.23 of the compilation documentation and support version of the description documentation is not responsible for nonsense, it is simply nonsense !! I found another document, which details the fact that I can still tell:
2 Supported Configurations
* Iptables> = 1.4.3
* Kernel-source> = 2.6.29
For ipset-6 you need:
* Libmnl
* Linux kernel> = 2.6.35
At least and the comments in the ipset-6.23 source code can be right, in addition to this is also in nonsense.
This fact is so disgusting! After I define SIZE_MAX, the compilation will pass smoothly. Although there are some type conversion warnings, it is no big deal to ignore them. So I think in order to make the documents that come with ipset-6.23 better serve the public, it is necessary to make a real patch, in fact I did, I want to do the following:
1. Compile the ipset-6.23 only depends on the kernel header file instead of the source code;
2. Relying on the kernel version to adapt to the data structure and macro definition, rather than finding feature values in the kernel source code.
Since my goal is only to compile successfully on the 2.6.32 kernel, I did not test 2.6.33/34/35/36 and 3.0/1/2/3/4/5/6/7/8... however, I believe that kernel versions above 3.5 can be compiled successfully. The ipset-6.23 package may not be tested in earlier versions, such as 2.6.32 kernel, and the work and subsequent corrections may have been left for me, 2.6.32 may not be used by many people, so it is a matter of course not to provide full access support. I did not blame the author and package owner for anything, maybe it was a little impulsive during the correction process, so I want to clarify here.
This reminds people of the term fashion. This is a word that was born when the extensive industrialization reached its peak at the end of the 19th century. It is widely believed that progress is inevitable and the latest is the best, the speed of changes is faster, and the way to maintain fashion is to stand at the forefront of the trend. This concept has been widely accepted and inherited until Linux 3. X Kernel era... if you still use the 2.6.9 kernel and find a major bug, no one cares about you. The surfers standing at the forefront of the trend will say: the world is improving, why not try kernel 3.17 ?!
Directly go to the ipset-6.23 directory, execute patch-p1 <../ipset-6.23.patch, and the content of the ipset-6.23.patch is as follows:
diff -Nur ipset-6.23/kernel/include/linux/netfilter/ipset/ip_set.h ipset-6.23.new/kernel/include/linux/netfilter/ipset/ip_set.h--- ipset-6.23/kernel/include/linux/netfilter/ipset/ip_set.h 2014-09-23 19:18:34.000000000 +0800+++ ipset-6.23.new/kernel/include/linux/netfilter/ipset/ip_set.h 2014-11-13 16:27:15.000000000 +0800@@ -26,6 +26,9 @@ #define IP_SET_MODULE_DESC(a, b, c) \ _IP_SET_MODULE_DESC(a, __stringify(b), __stringify(c)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)+#define SIZE_MAX (~(size_t)0)+#endif /* Set features */ enum ip_set_feature { IPSET_TYPE_IP_FLAG = 0,diff -Nur ipset-6.23/kernel/net/netfilter/xt_set.c ipset-6.23.new/kernel/net/netfilter/xt_set.c--- ipset-6.23/kernel/net/netfilter/xt_set.c 2014-09-23 19:18:34.000000000 +0800+++ ipset-6.23.new/kernel/net/netfilter/xt_set.c 2014-11-13 16:26:50.000000000 +0800@@ -28,12 +28,18 @@ MODULE_ALIAS("ipt_SET"); MODULE_ALIAS("ip6t_SET"); -#ifdef HAVE_CHECKENTRY_BOOL+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) #define CHECK_OK 1 #define CHECK_FAIL(err) 0 #define CONST const #define FTYPE bool+/* Only confirm version 2.6.32 :) */+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32)+/* netns is not supported completly */+#define XT_PAR_NET(par) (&init_net)+#else #define XT_PAR_NET(par) NULL+#endif #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */ #define CHECK_OK 0 #define CHECK_FAIL(err) (err)@@ -217,7 +223,7 @@ /* Revision 0 interface: backward compatible with netfilter/iptables */ -#ifdef HAVE_XT_TARGET_PARAM+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) #undef xt_action_param #define xt_action_param xt_target_param #define CAST_TO_MATCH (const struct xt_match_param *)
With this patch, you can directly compile the ipset-6.23 package on the 2.6.32 kernel.
Compile Note: 1. The HAVE_CHECKENTRY_BOOL macro on the namespace ipset-6.23 defines XT_PAR_NET as NULL, And the XT_PAR_NET macro retrieves the net struct:
struct net { ... struct net_generic *gen;}
It is worth noting that the gen field:
struct net_generic { unsigned int len; struct rcu_head rcu; void *ptr[0];};
Let's take a look at its annotations:
/* * Generic net pointers are to be used by modules to put some private * stuff on the struct net without explicit struct net modification * * The rules are simple: * 1. register the ops with register_pernet_gen_device to get the id * of your private pointer; * 2. call net_assign_generic() to put the private data on the struct * net (most preferably this should be done in the ->init callback * of the ops registered); * 3. do not change this pointer while the net is alive; * 4. do not try to have any private reference on the net_generic object. * * After accomplishing all of the above, the private pointer can be * accessed with the net_generic() call. */
Ipset is to put its own data in the gen field. If the net macro HAVE_CHECKENTRY_BOOL is set to NULL, it will not be saved. Why? Can it be used even after compilation? In fact, the value does not determine whether the net is null:
static inline struct ip_set_net *ip_set_pernet(struct net *net){ return net_generic(net, ip_set_net_id);}
This will cause the panic to crash. Therefore, the original code cannot be used when the HAVE_CHECKENTRY_BOOL macro is defined. Net is empty. If it is determined, the kernel will not crash, but no data is obtained. If it is not determined, the kernel will crash. Therefore, this Code itself can be said to be wrong!
We know that the 2.6.32 kernel may not support the net namespace well, but init_net exists in any case, so I defined XT_PAR_NET as & init_net.
2. Should I submit a patch? I am afraid of being scolded, and I don't want to swear, So I handed it over to a friend from afar. In my opinion, many people who make mistakes are confused and can start the war with a single phrase. Only programmers cannot afford it. Nothing else. Anyway, I looked at the README operation and wrote> = 2.6.32 above. However, I just couldn't compile it. The method in confiure is really disgusting. It is wrong !!! It's just TMD !!!