Hello all,
As a followup of sorts to my previous posts, "Error building 2.6.10
kernel with ip_vs_nfct patch - does anyone else get this?", I figured
out what the problem was, and with some advice from Julian Anastasov,
was successful getting kernels compiled with the ip_vs_nfct patch.
This was the error message I would get previously, at the modules stage
of the kernel build:
----------------------------------------------------------
CC [M] net/ipv4/ipvs/ip_vs_proto_ah.o
CC [M] net/ipv4/ipvs/ip_vs_nfct.o
net/ipv4/ipvs/ip_vs_nfct.c: In function `ip_vs_nfct_conn_drop':
include/linux/netfilter_ipv4/ip_conntrack.h:248: sorry, unimplemented:
inlining failed in call to 'ip_conntrack_put': function body not available
net/ipv4/ipvs/ip_vs_nfct.c:385: sorry, unimplemented: called from here
make[3]: *** [net/ipv4/ipvs/ip_vs_nfct.o] Error 1
make[2]: *** [net/ipv4/ipvs] Error 2
----------------------------------------------------------
The system in question is Fedora Core 3, which sports version 3.4.2 of
the GNU C compiler (and everything in the release is built with it).
The kernel source I was using is the kernel-2.6.10-1.741_FC3.src.rpm. I
had added the ip_vs_nfct and nat patches to the kernel build spec file,
inserted the "CONFIG_IP_VS_NFCT=y" kernel config option line between the
"CONFIG_IP_VS_FTP=m" and "CONFIG_IPV6=m" lines of each kernel arch/type
*.config file, and built the kernel.
As it turns out, others have seen problems compiling code which contain
external inline functions with GCC 3.4.2, not just people trying to use
ip_vs_nfct. I found one such instance where the user documented that by
removing "inline" from the function declaration, they were able to
compile successfully.
Since ip_conntrack_put is declared and exported as an inline-type
function in include/linux/netfilter_ipv4/ip_conntrack.h, this seems to
cause a problem for ip_vs_nfct making use of the function. I asked
Julian what he thought about this idea, and he suggested that "inline"
may need to be removed from ip_conntrack_put's declaration in
net/ipv4/netfilter/ip_conntrack_core.c also, since this is where the
function is exported. Armed with this idea, I modified both
ip_conntrack.h and ip_conntrack_core.c to remove "inline" from the
function, and created a patch which I then added to the .spec and kernel
build.
The kernel compiled successfully and ran. My firewall script worked,
and ip_vs_nfct did its job. Unfortunately, I discovered several uptime
hours later when the box kernel panicked that there is a known spinlock
problem in the 2.6.10 kernel - somewhere in the filesystem/block device
drivers code. I say known because comments exist in later iterations of
the 2.6.10 kernel spec changelog which indicate that steps were taken to
increase the verbosity of output when this specific kernel panic
occurs. I do not know if it is an issue with the upstream 2.6.10
sources or not, but at least I knew it wasn't because of ip_vs_nfct.
At any rate, I have been successful building 2.6.9 FC3 kernels with
Julian's 2.6.9 ip_vs_nfct patches, and not seeing the spinlock "not
syncing" kernel panics I saw building with any Fedora Core 3 2.6.10
kernel .src.rpm sources I tried building with. I've been up for 3 days
now on the box running this kernel, and it is functioning exactly as
desired. ...which also means it's gonna be time to update my keepalived
Stateful Firewall/LVS Director HOW-TO document soon...
Specifically, I used the 2.6.9-1.681_FC3 .src.rpm file, including
Julian's two patches (ip_vs_nfct and also the nat patch) and the one
shown below to remove "inline" from the ip_conntrack_put function.
If anyone else is interested in building kernels using Julian's patches
and you have GCC 3.4.2 (or newer, I'm sure...) you may be interested in
this small patch to remove "inline" from ip_conntrack.h and
ip_conntrack_core.c. I'll attach it to this post, and also post the
text of it here:
----------------------------------------------------------
diff -urN ../linux-2.6.10/include/linux/netfilter_ipv4/ip_conntrack.h
./include/linux/netfilter_ipv4/ip_conntrack.h
---
../linux-2.6.10/include/linux/netfilter_ipv4/ip_conntrack.h 2004-12-24
16:35:28.000000000 -0500
+++ ./include/linux/netfilter_ipv4/ip_conntrack.h 2005-02-07
06:48:57.260570933 -0500
@@ -245,7 +245,9 @@
}
/* decrement reference count on a conntrack */
-extern inline void ip_conntrack_put(struct ip_conntrack *ct);
+/* vince: try this without inline:
+extern inline void ip_conntrack_put(struct ip_conntrack *ct); */
+extern void ip_conntrack_put(struct ip_conntrack *ct);
/* find unconfirmed expectation based on tuple */
struct ip_conntrack_expect *
diff -urN ../linux-2.6.10/net/ipv4/netfilter/ip_conntrack_core.c
./net/ipv4/netfilter/ip_conntrack_core.c
--- ../linux-2.6.10/net/ipv4/netfilter/ip_conntrack_core.c 2004-12-24
16:33:47.000000000 -0500
+++ ./net/ipv4/netfilter/ip_conntrack_core.c 2005-02-07
06:48:16.702522768 -0500
@@ -77,7 +77,9 @@
DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
-inline void
+/* vince: try this without inline:
+inline void */
+void
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
----------------------------------------------------------
If anyone else cares to comment on whether removing "inline" from
either/both of these places is good/bad, or what performance impact this
may have, please do tell. But it is working well for me so far.
Good luck everyone.
Vince
diff -urN ../linux-2.6.10/include/linux/netfilter_ipv4/ip_conntrack.h
./include/linux/netfilter_ipv4/ip_conntrack.h
--- ../linux-2.6.10/include/linux/netfilter_ipv4/ip_conntrack.h 2004-12-24
16:35:28.000000000 -0500
+++ ./include/linux/netfilter_ipv4/ip_conntrack.h 2005-02-07
06:48:57.260570933 -0500
@@ -245,7 +245,9 @@
}
/* decrement reference count on a conntrack */
-extern inline void ip_conntrack_put(struct ip_conntrack *ct);
+/* vince: try this without inline:
+extern inline void ip_conntrack_put(struct ip_conntrack *ct); */
+extern void ip_conntrack_put(struct ip_conntrack *ct);
/* find unconfirmed expectation based on tuple */
struct ip_conntrack_expect *
diff -urN ../linux-2.6.10/net/ipv4/netfilter/ip_conntrack_core.c
./net/ipv4/netfilter/ip_conntrack_core.c
--- ../linux-2.6.10/net/ipv4/netfilter/ip_conntrack_core.c 2004-12-24
16:33:47.000000000 -0500
+++ ./net/ipv4/netfilter/ip_conntrack_core.c 2005-02-07 06:48:16.702522768
-0500
@@ -77,7 +77,9 @@
DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
-inline void
+/* vince: try this without inline:
+inline void */
+void
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
|