diff -ruN ipvsadm-1.21.orig/Makefile ipvsadm-1.21.new/Makefile
--- ipvsadm-1.21.orig/Makefile	Thu Jul 11 23:26:44 2002
+++ ipvsadm-1.21.new/Makefile	Mon Jul 29 20:54:38 2002
@@ -2,7 +2,7 @@
 #      ipvsadm - IP Virtual Server ADMinistration program
 #                for IPVS NetFilter Module in kernel 2.4
 #
-#      Version: $Id: Makefile,v 1.19 2002/07/11 14:26:44 wensong Exp $
+#      Version: $Id: Makefile,v 1.4 2002/07/12 01:59:35 simon Exp $
 #
 #      Authors: Wensong Zhang <wensong@linux-vs.org>
 #               Peter Kese <peter.kese@ijs.si>
@@ -22,24 +22,36 @@
 #                     :   Added autodetection of libpot
 #                     :   Added BUILD_ROOT support
 #      Wensong        :   Changed the OBJS according to detection
+#      Horms          :   Build recursively
+#                     :   Dist done in place
+#                     :   Install sysconfig file as appropriate
+#                     :   Distcheck tries to build from dist tar ball
+#                     :   Distclean cleans the tree rather than building it
+#                     :   Destination directories can be configured
+#                     :   using environment variables
+#                     :   Include net/ip_vs.h in dest tar ball
 #
 
 NAME	= ipvsadm
 VERSION	= $(shell cat VERSION)
-RELEASE	= 1
+RELEASE	= 1.um.1
 SCHEDULERS = "$(shell cat SCHEDULERS)"
 PROGROOT = $(shell basename `pwd`)
 
-CC	= gcc
-CFLAGS	= -Wall -Wunused -Wstrict-prototypes -g -O2
-SBIN    = $(BUILD_ROOT)/sbin
-MANDIR	= usr/man
-MAN	= $(BUILD_ROOT)/$(MANDIR)/man8
-INIT    = $(BUILD_ROOT)/etc/rc.d/init.d
-MKDIR   = mkdir
-INSTALL = install
-INCLUDE = -I/usr/src/linux/include -I.. -I.
-STATIC_LIBS = libipvs/libipvs.a
+CC	    = gcc
+INCLUDE     = -I/usr/src/linux/include -I. -I./net -I..
+CFLAGS	    = -Wall -Wunused -Wstrict-prototypes -g -O2 $(INCLUDE)
+SBINDIR     = /sbin
+SBIN_DIR    = $(BUILD_ROOT)/$(SBINDIR)
+MANDIR      = /usr/man
+MAN_DIR	    = $(BUILD_ROOT)/$(MANDIR)/man8
+INITDIR     = /etc/init.d
+INIT_DIR    = $(BUILD_ROOT)/$(INITDIR)
+SYSCONFIGDIR  = /etc/sysconfig
+SYSCONFIG_DIR = $(BUILD_ROOT)/$(SYSCONFIGDIR)
+MKDIR       = mkdir
+INSTALL     = install
+
 
 
 #####################################
@@ -64,51 +76,89 @@
 POPT_DEFINE = -DHAVE_POPT
 endif
 
-OBJS = ipvsadm.o config_stream.o dynamic_array.o
+SRC = $(wildcard *.c)
+HDR = $(wildcard *.h)
+MAN = $(wildcard *.8)
+SBIN_SCRIPT = ipvsadm-restore ipvsadm-save 
+BIN = ipvsadm
+OBJS = $(SRC:.c=.o)
+SPEC_IN = ipvsadm.spec.in
+SPEC = $(SPEC_IN:.in=)
 LIBS = $(POPT_LIB)
 DEFINES = -DVERSION=\"$(VERSION)\" -DSCHEDULERS=\"$(SCHEDULERS)\" \
 	  $(POPT_DEFINE) $(IP_VS_H_DEFINE)
+EXTRA_DIST= Makefile README SCHEDULERS VERSION ipvsadm.c ipvsadm.sh \
+ipvsadm.sysconfig
+DIST = $(SRC) $(HDR) $(MAN) $(SBIN_SCRIPT) $(SPEC) $(SPEC_IN) $(EXTRA_DIST)
+STATIC_LIBS = libipvs/libipvs.a
+SUBDIRS     = debian libipvs
 
-.PHONY = all clean install dist distclean rpm rpms
+.PHONY = all clean install dist distclean distclean-1 distcheck \
+rpm rpms deb debs
 
-all:            ipvsadm
+all:            subdir-all $(BIN)
 
-ipvsadm:	$(OBJS) $(STATIC_LIBS)
-		$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+subdir-all:
+		for i in $(SUBDIRS); do \
+			make -C $$i all; \
+		done
+
+$(BIN):		$(OBJS)
+		$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(STATIC_LIBS)
 
 install:        ipvsadm
-		if [ ! -d $(SBIN) ]; then $(MKDIR) -p $(SBIN); fi
-		$(INSTALL) -m 0755 -s ipvsadm $(SBIN)
-		$(INSTALL) -m 0755 ipvsadm-save $(SBIN)
-		$(INSTALL) -m 0755 ipvsadm-restore $(SBIN)
-		[ -d $(MAN) ] || $(MKDIR) -p $(MAN)
-		$(INSTALL) -m 0644 ipvsadm.8 $(MAN)
-		$(INSTALL) -m 0644 ipvsadm-save.8 $(MAN)
-		$(INSTALL) -m 0644 ipvsadm-restore.8 $(MAN)
-		if [ -d $(INIT) ]; then \
-		  $(INSTALL) -m 0755 ipvsadm.sh $(INIT)/ipvsadm; \
+		if [ ! -d $(SBIN_DIR) ]; then $(MKDIR) -p $(SBIN_DIR); fi
+		for i in $(SBIN_SCRIPT) $(BIN); do\
+			$(INSTALL) -m 0755 -s $$i $(SBIN_DIR);\
+		done
+		if [ ! -d $(MAN_DIR) ]; then $(MKDIR) -p $(MAN_DIR); fi
+		for i in $(MAN); do\
+			$(INSTALL) -m 644 $$i $(MAN_DIR);\
+		done
+		if [ -d $(INIT_DIR) ]; then \
+			$(INSTALL) -m 0755 ipvsadm.sh $(INIT_DIR)/ipvsadm; \
+		fi
+		if [ -d $(SYSCONFIG_DIR) ]; then \
+			$(INSTALL) -m 0644 ipvsadm.sysconfig \
+		  		$(SYSCONFIG_DIR)/ipvsadm;\
 		fi
+		for i in $(SUBDIRS); do \
+			make -C $$i install; \
+		done
 
 clean:
-		rm -f ipvsadm $(NAME).spec $(NAME)-$(VERSION).tar.gz
-		rm -rf debian/tmp
-		find . -name '*.[ao]' -o -name "*~" -o -name "*.orig" \
-		  -o -name "*.rej" -o -name core | xargs rm -f
-
-distclean:	clean
-
-dist:		distclean
-		sed -e "s/@@VERSION@@/$(VERSION)/g" \
-		    -e "s/@@RELEASE@@/$(RELEASE)/g" \
-		    < ipvsadm.spec.in > ipvsadm.spec
-		rm -f $(NAME)-$(VERSION)
-		ln -s . $(NAME)-$(VERSION)
-		tar czvf $(NAME)-$(VERSION).tar.gz			\
-		    --exclude CVS					\
-		    --exclude $(NAME)-$(VERSION)/$(NAME)-$(VERSION)	\
-		    --exclude $(NAME)-$(VERSION).tar.gz			\
-		    $(NAME)-$(VERSION)/*
-		rm -f $(NAME)-$(VERSION)
+		rm -f $(BIN) $(NAME).spec $(NAME)-$(VERSION).tar.gz
+		rm -f *.[ao] *~ *.orig *.rej core
+		for i in $(SUBDIRS); do \
+			make -C $$i clean; \
+		done
+
+distclean-1:
+		rm -rf "$(NAME)-$(VERSION)/" "$(NAME)-$(VERSION).tar" \
+		"$(NAME)-$(VERSION).tar.gz"
+
+distclean: 	distclean-1 clean
+
+dist: 		distclean-1 $(SPEC)
+		mkdir "$(NAME)-$(VERSION)/"
+		cp $(DIST) "$(NAME)-$(VERSION)/"
+		mkdir "$(NAME)-$(VERSION)/net/"
+		cp ../ip_vs.h "$(NAME)-$(VERSION)/net/"
+		for i in $(SUBDIRS); do \
+			DISTDIR="../$(NAME)-$(VERSION)/$$i" make -C $$i dist; \
+		done
+		tar -cf "$(NAME)-$(VERSION).tar" "$(NAME)-$(VERSION)/"
+		gzip --best "$(NAME)-$(VERSION).tar"
+		rm -rf "$(NAME)-$(VERSION)/"
+
+distcheck: 	dist
+		tar -zxf "$(NAME)-$(VERSION).tar.gz"
+		( cd "$(NAME)-$(VERSION)";\
+			BUILD_ROOT="`pwd`/.done/" make distclean all install)
+		rm -r "$(NAME)-$(VERSION)/"
+		@echo "#######################################################"
+		@echo "# $(NAME)-$(VERSION).tar.gz is ready for distribution"
+		@echo "#######################################################"
 
 rpm:		rpms
 
@@ -122,7 +172,10 @@
 debs:
 		dpkg-buildpackage
 
-%.o:	%.c
-		$(CC) $(CFLAGS) $(INCLUDE) $(DEFINES) -o $@ -c $<
+%.o:		%.c
+		$(CC) $(CFLAGS) $(DEFINES) -o $@ -c $<
 
-include $(shell echo */Makefile)
+%.spec:		%.spec.in
+		sed -e "s/@@VERSION@@/$(VERSION)/g" \
+		    -e "s/@@RELEASE@@/$(RELEASE)/g" \
+		    < $< > $@
diff -ruN ipvsadm-1.21.orig/README ipvsadm-1.21.new/README
--- ipvsadm-1.21.orig/README	Thu Jan 24 23:23:51 2002
+++ ipvsadm-1.21.new/README	Mon Jul 29 20:54:38 2002
@@ -28,7 +28,8 @@
 	/usr/man/man8/ipvsadm.8
 	/usr/man/man8/ipvsadm-save.8
 	/usr/man/man8/ipvsadm-restore.8
-	/etc/rc.d/init.d/ipvsadm
+	/etc/init.d/ipvsadm
+	/etc/sysconfig/ipvsadm
 This will be done automatically when calling
 	make install
 in the source directory.
diff -ruN ipvsadm-1.21.orig/debian/Makefile ipvsadm-1.21.new/debian/Makefile
--- ipvsadm-1.21.orig/debian/Makefile	Thu Jan  1 09:00:00 1970
+++ ipvsadm-1.21.new/debian/Makefile	Mon Jul 29 20:54:39 2002
@@ -0,0 +1,34 @@
+#      ipvsadm - IP Virtual Server ADMinistration program
+#                for IPVS NetFilter Module in kernel 2.4
+#
+#      Version: $Id: Makefile,v 1.1 2002/07/10 06:42:59 simon Exp $
+#
+#      Authors: Wensong Zhang <wensong@linux-vs.org>
+#               Peter Kese <peter.kese@ijs.si>
+#
+#      This file:
+#
+#      ChangeLog
+#
+#      Horms          :   Created
+
+EXTRA_DIST = Makefile changelog control copyright ipvsadm.dirs ipvsadm.files \
+rules
+DIST = $(EXTRA_DIST)
+
+.PHONY = all clean install dist distclean rpm rpms
+
+all:
+
+install:
+
+clean:
+		rm -f *.[ao] *~ *.orig *.rej core
+		rm -f *.substvars *.debhelper files
+		rm -r -f ipvsadm tmp
+
+distclean:	clean
+
+dist:	
+		mkdir "$(DISTDIR)/"
+		cp $(DIST) "$(DISTDIR)/"
diff -ruN ipvsadm-1.21.orig/ipvsadm-restore ipvsadm-1.21.new/ipvsadm-restore
--- ipvsadm-1.21.orig/ipvsadm-restore	Mon Mar 19 00:01:45 2001
+++ ipvsadm-1.21.new/ipvsadm-restore	Mon Jul 29 20:54:38 2002
@@ -4,7 +4,7 @@
 #      A very simple wrapper to restore IPVS rules
 #      Inspired by ipchains-save.
 #
-#      Version: $Id: ipvsadm-restore,v 1.2 2001/03/18 15:01:45 wensong Exp $
+#      Version: $Id: ipvsadm-restore,v 1.1.1.1 2002/07/10 05:34:36 simon Exp $
 #
 #      Script Author: Horms <horms@vergenet.net>
 #
diff -ruN ipvsadm-1.21.orig/ipvsadm-restore.8 ipvsadm-1.21.new/ipvsadm-restore.8
--- ipvsadm-1.21.orig/ipvsadm-restore.8	Thu Mar 22 21:57:46 2001
+++ ipvsadm-1.21.new/ipvsadm-restore.8	Mon Jul 29 20:54:38 2002
@@ -2,7 +2,7 @@
 .\"     ipvsadm-restore(8) manual page
 .\"     Inspired by ipchains-restore
 .\"
-.\"	$Id: ipvsadm-restore.8,v 1.1 2001/03/22 12:57:46 wensong Exp $	
+.\"	$Id: ipvsadm-restore.8,v 1.1.1.1 2002/07/10 05:34:36 simon Exp $	
 .\"
 .\"     Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
 .\"
diff -ruN ipvsadm-1.21.orig/ipvsadm-save ipvsadm-1.21.new/ipvsadm-save
--- ipvsadm-1.21.orig/ipvsadm-save	Thu Mar 22 21:57:46 2001
+++ ipvsadm-1.21.new/ipvsadm-save	Mon Jul 29 20:54:38 2002
@@ -4,7 +4,7 @@
 #      A very simple wrapper to save IPVS rules
 #      Inspired by ipchains-save.
 #
-#      Version: $Id: ipvsadm-save,v 1.3 2001/03/22 12:57:46 wensong Exp $
+#      Version: $Id: ipvsadm-save,v 1.1.1.1 2002/07/10 05:34:36 simon Exp $
 #
 #      Script Author: Horms <horms@vergenet.net>
 #
diff -ruN ipvsadm-1.21.orig/ipvsadm-save.8 ipvsadm-1.21.new/ipvsadm-save.8
--- ipvsadm-1.21.orig/ipvsadm-save.8	Thu Mar 22 21:57:46 2001
+++ ipvsadm-1.21.new/ipvsadm-save.8	Mon Jul 29 20:54:38 2002
@@ -2,7 +2,7 @@
 .\"     ipvsadm-save(8) manual page
 .\"     Inspired by ipchains-save
 .\"
-.\"	$Id: ipvsadm-save.8,v 1.1 2001/03/22 12:57:46 wensong Exp $	
+.\"	$Id: ipvsadm-save.8,v 1.1.1.1 2002/07/10 05:34:36 simon Exp $	
 .\"
 .\"     Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
 .\"
diff -ruN ipvsadm-1.21.orig/ipvsadm.8 ipvsadm-1.21.new/ipvsadm.8
--- ipvsadm-1.21.orig/ipvsadm.8	Thu Jul 11 23:26:44 2002
+++ ipvsadm-1.21.new/ipvsadm.8	Mon Jul 29 20:54:38 2002
@@ -1,7 +1,7 @@
 .\"
 .\"     ipvsadm(8) manual page
 .\"
-.\"	$Id: ipvsadm.8,v 1.14 2002/07/11 14:26:44 wensong Exp $
+.\"	$Id: ipvsadm.8,v 1.3 2002/07/12 01:46:20 simon Exp $
 .\"
 .\"     Authors: Mike Wangsmo <wanger@redhat.com>
 .\"              Wensong Zhang <wensong@linux.com>
@@ -13,7 +13,9 @@
 .\"       Wensong Zhang    :  Added a short note about the defense strategies
 .\"       Horms            :  Tidy up some of the description and the
 .\"                           grammar in the -f and sysctl sections
-.\"       Wensong Zhang    :  --set option description taken from ipchains(8)
+.\"       Wensong Zhang    :  -set option description taken from ipchains(8)
+.\"       Horms            :  Document synchronisation daemon's proc
+.\"                           entries.
 .\"
 .\"     This program is free software; you can redistribute it and/or modify
 .\"     it under the terms of the GNU General Public License as published by
@@ -154,19 +156,43 @@
 the current timeout value of the  corresponding  entry  is preserved.
 .TP
 .B --start-daemon \fIstate\fP
-Start the connection synchronization daemon. The \fIstate\fP is to
+Start the connection synchronisation daemon. The \fIstate\fP is to
 indicate that the daemon is started as \fImaster\fP or \fIbackup\fP. The
-connection synchronization daemon is implemented inside the Linux
-kernel. The master daemon running at the primary load balancer
+connection synchronisation daemon is implemented inside the Linux
+kernel. The master daemon running on the primary load balancer
 multicasts changes of connections periodically, and the backup daemon
-running at the backup load balancers receives multicast message and
-creates corresponding connections. Then, in case the primary load
-balancer fails, a backup load balancer will takeover, and it has state
-of almost all connections, so that almost all established connections
+running on the backup load balancers receives multicast message and
+creates corresponding connections. Then, if the primary load
+balancer fails and backup load balancer takes oever, it has the state
+of almost all connections. Thus, almost all established connections
 can continue to access the service.
+.sp
+There are 3 proc enties that effect the behaviour of the
+synchronisation daemon. In the case of each of
+these proc entries, values outside of the valid ranges given
+will be rounded up or down as neccessary.
+.sp
+/proc/sys/net/ipv4/vs/sync_msg_max_size sets the maximum size of messages
+sent by the synchronisation daemon in bytes. The default is 1228 and the
+useful range is 52 through to 6172.
+.sp
+/proc/sys/net/ipv4/vs/sync_frequency sets syncrhonisation frequency \-
+the how often a connection is
+synchronised in terms of the number of packets received.  The default is 50
+and the useful range is 1 through to 2147483648.
+.sp
+/proc/sys/net/ipv4/vs/sync_threshold sets the synchronisation threshold \-
+the minmum number of packets a connection needs to receive before it will
+be synchronised.  The default is 3 and the useful range is from 0 up to the
+synchronisation frequency. Once this threshold is passed the connection
+will be syncronised each time the number of packets, modulus the
+synchronisation frequency equals the threshold.  For example, using the
+default frequency of 50 and the default threshold of 3,
+syncronisation will occur on once the 3rd packet is recieved, and every
+50th packet from then onwards.
 .TP
 .B --stop-daemon
-Stop the connection synchronization daemon.
+Stop the connection synchronisation daemon.
 .TP
 \fB-h, --help\fR
 Display a description of the command syntax.
@@ -457,6 +483,10 @@
 .br
 .I /proc/sys/net/ipv4/vs/secure_tcp
 .br
+.I /proc/sys/net/ipv4/vs/sync_msg_max_size
+.br
+.I /proc/sys/net/ipv4/vs/sync_threshold
+.br
 .I /proc/sys/net/ipv4/vs/timeout_close
 .br
 .I /proc/sys/net/ipv4/vs/timeout_closewait
@@ -488,5 +518,5 @@
 	  Peter Kese <peter.kese@ijs.si>
 man page - Mike Wangsmo <wanger@redhat.com>
 	   Wensong Zhang <wensong@linuxvirtualserver.org>
-	   Horms <horms@valinux.com>
+	   Horms <horms@vergenet.net>
 .fi
diff -ruN ipvsadm-1.21.orig/ipvsadm.c ipvsadm-1.21.new/ipvsadm.c
--- ipvsadm-1.21.orig/ipvsadm.c	Thu Jul 11 23:26:44 2002
+++ ipvsadm-1.21.new/ipvsadm.c	Mon Jul 29 20:54:38 2002
@@ -2,7 +2,7 @@
  *      ipvsadm - IP Virtual Server ADMinistration program
  *                for IPVS NetFilter Module in kernel 2.4
  *
- *      Version: $Id: ipvsadm.c,v 1.19 2002/07/11 14:26:44 wensong Exp $
+ *      Version: $Id: ipvsadm.c,v 1.1.1.2 2002/07/12 01:07:52 simon Exp $
  *
  *      Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
  *               Peter Kese <peter.kese@ijs.si>
diff -ruN ipvsadm-1.21.orig/ipvsadm.sh ipvsadm-1.21.new/ipvsadm.sh
--- ipvsadm-1.21.orig/ipvsadm.sh	Thu Jul 11 23:26:44 2002
+++ ipvsadm-1.21.new/ipvsadm.sh	Mon Jul 29 20:54:38 2002
@@ -28,9 +28,9 @@
 fi
 
 # Use the funtions provided by Red Hat or use our own
-if [ -f /etc/rc.d/init.d/functions ]
+if [ -f /etc/init.d/functions ]
 then
-  . /etc/rc.d/init.d/functions
+  . /etc/init.d/functions
 else
   function action {
     echo "$1"
diff -ruN ipvsadm-1.21.orig/ipvsadm.spec ipvsadm-1.21.new/ipvsadm.spec
--- ipvsadm-1.21.orig/ipvsadm.spec	Thu Aug  1 09:52:03 2002
+++ ipvsadm-1.21.new/ipvsadm.spec	Mon Jul 29 20:54:38 2002
@@ -3,11 +3,11 @@
 Summary: Utility to administer the Linux Virtual Server
 Name: ipvsadm
 Version: 1.21
-Release: 1
+Release: 1.um.1
 Copyright: GNU General Public Licence
 URL: http://www.LinuxVirtualServer.org/
 Group: Applications/System
-Source0: http://www.LinuxVirtualServer.org/software/ipvsadm-%{version}.tar.gz
+Source0: http://www.LinuxVirtualServer.org/software/%{name}-%{version}.tar.gz
 BuildRoot: /var/tmp/%name-%{PACKAGE_VERSION}-root
 Docdir: %{prefix}/doc
 Provides: %{name}-%{version}
@@ -28,14 +28,17 @@
 
 %install
 rm -rf $RPM_BUILD_ROOT
-mkdir -p ${RPM_BUILD_ROOT}/{sbin,%{_mandir}/man8,etc/rc.d/init.d}
-make install BUILD_ROOT=${RPM_BUILD_ROOT} MANDIR=%{_mandir}
+mkdir -p ${RPM_BUILD_ROOT}/{sbin,%{_mandir}/man8,etc/{init.d,sysconfig}}
+make install BUILD_ROOT=${RPM_BUILD_ROOT} MANDIR=%{_mandir} \
+	SBINDIR=/sbin INITDIR=%{_sysconfdir}/init.d \
+	SYSCONFIGDIR=%{_sysconfdir}/sysconfig
 
 
 %files
 %defattr(-,root,root)
 %doc README
-%config /etc/rc.d/init.d/ipvsadm
+%config /etc/init.d/ipvsadm
+%config /etc/sysconfig/ipvsadm
 /sbin/ipvsadm*
 %{_mandir}/man8/ipvsadm*
 
@@ -52,6 +55,10 @@
 
 
 %changelog
+* Fri Jun 5 2002 Horms <horms@vergenet.net>
+- Include /etc/sysconfig/ipvsadm in RPM
+- Install init script into /etc/init.d instead of /etc/init.d/rc.d
+
 * Thu Dec 16 2001 Wensong Zhang <wensong@linuxvirtualserver.org>
 - Changed to install ipvsadm man pages according to the %{_mandir}
 
diff -ruN ipvsadm-1.21.orig/ipvsadm.spec.in ipvsadm-1.21.new/ipvsadm.spec.in
--- ipvsadm-1.21.orig/ipvsadm.spec.in	Thu Jul 11 23:26:44 2002
+++ ipvsadm-1.21.new/ipvsadm.spec.in	Mon Jul 29 20:54:38 2002
@@ -7,7 +7,7 @@
 Copyright: GNU General Public Licence
 URL: http://www.LinuxVirtualServer.org/
 Group: Applications/System
-Source0: http://www.LinuxVirtualServer.org/software/ipvsadm-%{version}.tar.gz
+Source0: http://www.LinuxVirtualServer.org/software/%{name}-%{version}.tar.gz
 BuildRoot: /var/tmp/%name-%{PACKAGE_VERSION}-root
 Docdir: %{prefix}/doc
 Provides: %{name}-%{version}
@@ -28,14 +28,17 @@
 
 %install
 rm -rf $RPM_BUILD_ROOT
-mkdir -p ${RPM_BUILD_ROOT}/{sbin,%{_mandir}/man8,etc/rc.d/init.d}
-make install BUILD_ROOT=${RPM_BUILD_ROOT} MANDIR=%{_mandir}
+mkdir -p ${RPM_BUILD_ROOT}/{sbin,%{_mandir}/man8,etc/{init.d,sysconfig}}
+make install BUILD_ROOT=${RPM_BUILD_ROOT} MANDIR=%{_mandir} \
+	SBINDIR=/sbin INITDIR=%{_sysconfdir}/init.d \
+	SYSCONFIGDIR=%{_sysconfdir}/sysconfig
 
 
 %files
 %defattr(-,root,root)
 %doc README
-%config /etc/rc.d/init.d/ipvsadm
+%config /etc/init.d/ipvsadm
+%config /etc/sysconfig/ipvsadm
 /sbin/ipvsadm*
 %{_mandir}/man8/ipvsadm*
 
@@ -52,6 +55,10 @@
 
 
 %changelog
+* Fri Jun 5 2002 Horms <horms@vergenet.net>
+- Include /etc/sysconfig/ipvsadm in RPM
+- Install init script into /etc/init.d instead of /etc/init.d/rc.d
+
 * Thu Dec 16 2001 Wensong Zhang <wensong@linuxvirtualserver.org>
 - Changed to install ipvsadm man pages according to the %{_mandir}
 
diff -ruN ipvsadm-1.21.orig/ipvsadm.sysconfig ipvsadm-1.21.new/ipvsadm.sysconfig
--- ipvsadm-1.21.orig/ipvsadm.sysconfig	Thu Jan  1 09:00:00 1970
+++ ipvsadm-1.21.new/ipvsadm.sysconfig	Mon Jul 29 20:54:38 2002
@@ -0,0 +1,7 @@
+######################################################################
+# /etc/sysconfig/ipvsadm
+#
+# To populate this file configure your LVS virtual services and
+# then run /etc/init.d/ipvsadm save
+######################################################################
+
diff -ruN ipvsadm-1.21.orig/libipvs/Makefile ipvsadm-1.21.new/libipvs/Makefile
--- ipvsadm-1.21.orig/libipvs/Makefile	Wed Sep 19 00:42:54 2001
+++ ipvsadm-1.21.new/libipvs/Makefile	Mon Jul 29 20:54:39 2002
@@ -1,2 +1,47 @@
+#      ipvsadm - IP Virtual Server ADMinistration program
+#                for IPVS NetFilter Module in kernel 2.4
+#
+#      Version: $Id: Makefile,v 1.2 2002/07/10 06:41:28 simon Exp $
+#
+#      Authors: Wensong Zhang <wensong@linux-vs.org>
+#               Peter Kese <peter.kese@ijs.si>
+#
+#      This file:
+#
+#      ChangeLog
+#
+#      Horms          :   Added this file
 
-libipvs/libipvs.a: libipvs/libipvs.a(libipvs/libipvs.o)
+CC          = gcc
+INCLUDE     = -I/usr/src/linux/include -I.. -I../net -I../..
+CFLAGS      = -Wall -Wunused -Wstrict-prototypes -g -O2 $(INCLUDE)
+
+SRC = $(wildcard *.c)
+HDR = $(wildcard *.h)
+OBJ = $(SRC:.c=.o)
+STATIC_LIB = libipvs.a
+EXTRA_DIST = Makefile
+DIST = $(EXTRA_DIST) $(SRC) $(HDR)
+
+.PHONY = all clean install dist distclean rpm rpms
+
+all: 		$(STATIC_LIB)
+
+$(STATIC_LIB):	$(OBJ)
+	ar rv $(STATIC_LIB) $(OBJ)
+
+install:
+
+clean:
+		rm -f *.[ao] *~ *.orig *.rej core
+
+distclean:	clean
+
+dist:	
+		mkdir "$(DISTDIR)/"
+		cp $(DIST) "$(DISTDIR)/"
+
+libipvs.a: 	libipvs.o
+
+%.o:		%.c
+		$(CC) $(CFLAGS) $(DEFINES) -o $@ -c $<
diff -ruN ipvsadm-1.21.orig/libipvs/libipvs.c ipvsadm-1.21.new/libipvs/libipvs.c
--- ipvsadm-1.21.orig/libipvs/libipvs.c	Fri Nov 23 23:34:17 2001
+++ ipvsadm-1.21.new/libipvs/libipvs.c	Mon Jul 29 20:54:39 2002
@@ -1,7 +1,7 @@
 /*
  * libipvs:	Library for manipulating IPVS through [gs]etsockopt
  *
- * Version:     $Id: libipvs.c,v 1.4 2001/11/23 14:34:17 wensong Exp $
+ * Version:     $Id: libipvs.c,v 1.1.1.1 2002/07/10 05:34:36 simon Exp $
  *
  * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
  *
diff -ruN ipvsadm-1.21.orig/libipvs/libipvs.h ipvsadm-1.21.new/libipvs/libipvs.h
--- ipvsadm-1.21.orig/libipvs/libipvs.h	Tue Jul  9 23:41:19 2002
+++ ipvsadm-1.21.new/libipvs/libipvs.h	Mon Jul 29 20:54:39 2002
@@ -1,7 +1,7 @@
 /*
  * libipvs.h:	header file for the library ipvs
  *
- * Version:	$Id: libipvs.h,v 1.3 2002/07/09 14:41:19 wensong Exp $
+ * Version:	$Id: libipvs.h,v 1.1.1.2 2002/07/12 01:07:52 simon Exp $
  *
  * Authors:	Wensong Zhang <wensong@linuxvirtualserver.org>
  *
diff -ruN ipvsadm-1.21.orig/net/ip_vs.h ipvsadm-1.21.new/net/ip_vs.h
--- ipvsadm-1.21.orig/net/ip_vs.h	Thu Jan  1 09:00:00 1970
+++ ipvsadm-1.21.new/net/ip_vs.h	Mon Jul 29 20:54:39 2002
@@ -0,0 +1,1095 @@
+/*
+ *      IP Virtual Server
+ *      data structure and functionality definitions
+ */
+
+#ifndef _IP_VS_H
+#define _IP_VS_H
+
+#include <asm/types.h>          /* For __uXX types */
+
+#define IP_VS_VERSION_CODE            0x010004
+#define NVERSION(version)                       \
+	(version >> 16) & 0xFF,                 \
+	(version >> 8) & 0xFF,                  \
+	version & 0xFF
+
+/*
+ *      Virtual Service Flags
+ */
+#define IP_VS_SVC_F_PERSISTENT        0x0001    /* persistent port */
+#define IP_VS_SVC_F_HASHED            0x0002    /* hashed entry */
+
+/*
+ *      Destination Server Flags
+ */
+#define IP_VS_DEST_F_AVAILABLE        0x0001    /* Available tag */
+
+/*
+ *      IPVS sync daemon states
+ */
+#define IP_VS_STATE_NONE    0           /* daemon is stopped */
+#define IP_VS_STATE_MASTER  1           /* started as master */
+#define IP_VS_STATE_BACKUP  2           /* started as backup */
+
+/*
+ *      IPVS socket options
+ */
+#define IP_VS_BASE_CTL		(64+1024+64)		/* base */
+
+#define IP_VS_SO_SET_NONE	IP_VS_BASE_CTL	        /* just peek */
+#define IP_VS_SO_SET_INSERT	(IP_VS_BASE_CTL+1)
+#define IP_VS_SO_SET_ADD	(IP_VS_BASE_CTL+2)
+#define IP_VS_SO_SET_EDIT	(IP_VS_BASE_CTL+3)
+#define IP_VS_SO_SET_DEL	(IP_VS_BASE_CTL+4)
+#define IP_VS_SO_SET_FLUSH	(IP_VS_BASE_CTL+5)
+#define IP_VS_SO_SET_LIST	(IP_VS_BASE_CTL+6)
+#define IP_VS_SO_SET_ADDDEST	(IP_VS_BASE_CTL+7)
+#define IP_VS_SO_SET_DELDEST	(IP_VS_BASE_CTL+8)
+#define IP_VS_SO_SET_EDITDEST	(IP_VS_BASE_CTL+9)
+#define IP_VS_SO_SET_TIMEOUTS	(IP_VS_BASE_CTL+10)
+#define IP_VS_SO_SET_STARTDAEMON (IP_VS_BASE_CTL+11)
+#define IP_VS_SO_SET_STOPDAEMON (IP_VS_BASE_CTL+12)
+#define IP_VS_SO_SET_RESTORE    (IP_VS_BASE_CTL+13)
+#define IP_VS_SO_SET_SAVE       (IP_VS_BASE_CTL+14)
+#define IP_VS_SO_SET_ZERO	(IP_VS_BASE_CTL+15)
+#define IP_VS_SO_SET_MAX	IP_VS_SO_SET_ZERO
+
+#define IP_VS_SO_GET_VERSION	IP_VS_BASE_CTL
+#define IP_VS_SO_GET_INFO	(IP_VS_BASE_CTL+1)
+#define IP_VS_SO_GET_SERVICES	(IP_VS_BASE_CTL+2)
+#define IP_VS_SO_GET_SERVICE	(IP_VS_BASE_CTL+3)
+#define IP_VS_SO_GET_DESTS	(IP_VS_BASE_CTL+4)
+#define IP_VS_SO_GET_DEST	(IP_VS_BASE_CTL+5)	/* not used now */
+#define IP_VS_SO_GET_TIMEOUTS	(IP_VS_BASE_CTL+6)
+#define IP_VS_SO_GET_DAEMON	(IP_VS_BASE_CTL+7)
+#define IP_VS_SO_GET_MAX	IP_VS_SO_GET_DAEMON
+
+
+/*
+ *      IPVS Connection Flags
+ */
+#define IP_VS_CONN_F_FWD_MASK         0x0007    /* mask for the fwd methods */
+#define IP_VS_CONN_F_MASQ	      0x0000    /* masquerading */
+#define IP_VS_CONN_F_LOCALNODE	      0x0001    /* local node */
+#define IP_VS_CONN_F_TUNNEL	      0x0002    /* tunneling */
+#define IP_VS_CONN_F_DROUTE           0x0003    /* direct routing */
+#define IP_VS_CONN_F_BYPASS           0x0004    /* cache bypass */
+#define IP_VS_CONN_F_HASHED	      0x0040	/* hashed entry */
+#define IP_VS_CONN_F_NOOUTPUT         0x0080    /* no output packets */
+#define IP_VS_CONN_F_INACTIVE         0x0100    /* not established */
+#define IP_VS_CONN_F_OUT_SEQ          0x0200    /* must do output seq adjust */
+#define IP_VS_CONN_F_IN_SEQ           0x0400    /* must do input seq adjust */
+#define IP_VS_CONN_F_SEQ_MASK         0x0600    /* in/out sequence mask */
+#define IP_VS_CONN_F_NO_CPORT         0x0800    /* no client port set yet */
+
+/* Move it to better place one day, for now keep it unique */
+#define NFC_IPVS_PROPERTY	0x10000
+
+#define IP_VS_SCHEDNAME_MAXLEN         16
+#define IP_VS_IFNAME_MAXLEN            16
+
+struct ip_vs_rule_user {
+	/* global options */
+	int             tcp_timeout;    /* timeout values */
+	int             tcp_fin_timeout;
+	int             udp_timeout;
+	int             state;          /* sync daemon state */
+	char            mcast_ifn[IP_VS_IFNAME_MAXLEN];
+					/* multicast interface name */
+
+	/* virtual service options */
+	u_int16_t	protocol;
+	u_int32_t	vaddr;          /* virtual address */
+	u_int16_t	vport;
+	u_int32_t       vfwmark;        /* firwall mark of virtual service*/
+	char            sched_name[IP_VS_SCHEDNAME_MAXLEN];
+	unsigned	vs_flags;       /* virtual service flags */
+	unsigned        timeout;        /* persistent timeout in ticks */
+	u_int32_t	netmask;        /* persistent netmask */
+
+	/* destination specific options */
+	u_int32_t	daddr;          /* destination address */
+	u_int16_t	dport;
+	unsigned        conn_flags;     /* destination flags */
+	int             weight;         /* destination weight */
+};
+
+
+/*
+ *	IPVS statistics object (for user space)
+ */
+struct ip_vs_stats_user
+{
+	__u32                   conns;          /* connections scheduled */
+	__u32                   inpkts;         /* incoming packets */
+	__u32                   outpkts;        /* outgoing packets */
+	__u64                   inbytes;        /* incoming bytes */
+	__u64                   outbytes;       /* outgoing bytes */
+
+	__u32			cps;		/* current connection rate */
+	__u32			inpps;		/* current in packet rate */
+	__u32			outpps;		/* current out packet rate */
+	__u32			inbps;		/* current in byte rate */
+	__u32			outbps;		/* current out byte rate */
+};
+
+
+/* The argument to IP_VS_SO_GET_INFO */
+struct ip_vs_getinfo {
+	/* version number */
+	unsigned int	version;
+
+	/* size of connection hash table */
+	unsigned int	size;
+
+	/* number of virtual services */
+	unsigned int	num_services;
+};
+
+/* The argument to IP_VS_SO_GET_SERVICE */
+struct ip_vs_service_user {
+	/* which service: user fills this in */
+	u_int16_t	protocol;
+	u_int32_t	addr;           /* virtual address */
+	u_int16_t	port;
+	u_int32_t       fwmark;         /* firwall mark of virtual service */
+
+	/* service options */
+	char            sched_name[IP_VS_SCHEDNAME_MAXLEN];
+	unsigned	flags;          /* virtual service flags */
+	unsigned        timeout;        /* persistent timeout in ticks */
+	u_int32_t	netmask;        /* persistent netmask */
+
+	/* number of real servers */
+	unsigned int    num_dests;
+
+	/* statistics */
+	struct ip_vs_stats_user stats;
+};
+
+struct ip_vs_dest_user {
+	u_int32_t	addr;           /* destination address */
+	u_int16_t	port;
+	unsigned	flags;		/* destination flags */
+	int		weight;         /* destination weight */
+	u_int32_t	activeconns;	/* active connections */
+	u_int32_t	inactconns;	/* inactive connections */
+
+	/* statistics */
+	struct ip_vs_stats_user stats;
+};
+
+/* The argument to IP_VS_SO_GET_DESTS */
+struct ip_vs_get_dests {
+	/* which service: user fills this in */
+	u_int16_t	protocol;
+	u_int32_t	addr;           /* virtual address */
+	u_int16_t	port;
+	u_int32_t       fwmark;         /* firwall mark of virtual service */
+
+	/* number of real servers */
+	unsigned int    num_dests;
+
+	/* the real servers */
+	struct ip_vs_dest_user entrytable[0];
+};
+
+/* The argument to IP_VS_SO_GET_SERVICES */
+struct ip_vs_get_services {
+	/* number of virtual services */
+	unsigned int num_services;
+
+	/* service table */
+	struct ip_vs_service_user entrytable[0];
+};
+
+/* The argument to IP_VS_SO_GET_TIMEOUTS */
+struct ip_vs_timeout_user {
+	int             tcp_timeout;
+	int             tcp_fin_timeout;
+	int             udp_timeout;
+};
+
+/* The argument to IP_VS_SO_GET_DAEMON */
+struct ip_vs_daemon_user {
+	int	state;				/* sync daemon state */
+	char	mcast_ifn[IP_VS_IFNAME_MAXLEN];	/* multicast interface name */
+};
+
+
+/*
+ *      IPVS State Values
+ */
+enum {
+	IP_VS_S_NONE = 0,
+	IP_VS_S_ESTABLISHED,
+	IP_VS_S_SYN_SENT,
+	IP_VS_S_SYN_RECV,
+	IP_VS_S_FIN_WAIT,
+	IP_VS_S_TIME_WAIT,
+	IP_VS_S_CLOSE,
+	IP_VS_S_CLOSE_WAIT,
+	IP_VS_S_LAST_ACK,
+	IP_VS_S_LISTEN,
+	IP_VS_S_SYNACK,
+	IP_VS_S_UDP,
+	IP_VS_S_ICMP,
+	IP_VS_S_LAST
+};
+
+/*
+ *     IPVS connection entry hash table
+ */
+
+#define VS_STATE_INPUT	        0
+#define VS_STATE_OUTPUT	        4
+#define VS_STATE_INPUT_ONLY	8
+
+/*
+ *	Delta sequence info structure
+ *	Each ip_vs_conn has 2 (output AND input seq. changes).
+ *      Only used in the VS/NAT.
+ */
+struct ip_vs_seq {
+	__u32           init_seq;       /* Add delta from this seq */
+	__u32           delta;          /* Delta in sequence numbers */
+	__u32           previous_delta; /* Delta in sequence numbers
+					   before last resized pkt */
+};
+
+
+/*
+ *	IPVS sync connection entry
+ */
+struct ip_vs_sync_conn {
+	__u8			reserved;
+
+	/* Protocol, addresses and port numbers */
+	__u8			protocol;       /* Which protocol (TCP/UDP) */
+	__u16			cport;
+	__u16                   vport;
+	__u16                   dport;
+	__u32                   caddr;          /* client address */
+	__u32                   vaddr;          /* virtual address */
+	__u32                   daddr;          /* destination address */
+
+	/* Flags and state transition */
+	__u16                   flags;          /* status flags */
+	__u16                   state;          /* state info */
+
+	/* The sequence options start here */
+};
+
+struct ip_vs_sync_conn_options {
+	struct ip_vs_seq        in_seq;         /* incoming seq. struct */
+	struct ip_vs_seq        out_seq;        /* outgoing seq. struct */
+};
+
+#define IP_VS_SYNC_CONN_TIMEOUT (3*60*HZ)
+#define IP_VS_SYNC_SIMPLE_CONN_SIZE  (sizeof(struct ip_vs_sync_conn))
+#define IP_VS_SYNC_FULL_CONN_SIZE  \
+(sizeof(struct ip_vs_sync_conn) + sizeof(struct ip_vs_sync_conn_options))
+
+
+/*
+  The master mulitcasts messages to the backup load balancers in the
+  following format.
+
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |  Count Conns  |   Reserved    |            Size               |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                                                               |
+      |                    IPVS Sync Connection (1)                   |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                            .                                  |
+      |                            .                                  |
+      |                            .                                  |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                                                               |
+      |                    IPVS Sync Connection (n)                   |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+struct ip_vs_sync_mesg {
+	__u8                    nr_conns;
+	__u8                    reserved;
+	__u16                   size;
+
+	/* ip_vs_sync_conn entries start here */
+};
+
+
+/* Trailing  sizeof(struct ip_vs_sync_conn_options) is to allow 
+ * the full connection count to be used by allowing a bit of extra
+ * space, just in case the last connection is FULL_CONN_SIZE
+ * instead of SIMPLE_CONN_SIZE */
+
+/* At the very least the message needs to hold one message */
+#define IP_VS_SYNC_MESG_MAX_SIZE_MIN \
+	(IP_VS_SYNC_SIMPLE_CONN_SIZE + sizeof(struct ip_vs_sync_mesg) \
+	 + sizeof(struct ip_vs_sync_conn_options))
+
+/* At most, 256 messages can be carried. This is because
+ * the nr_conns element in the ip_vs_sync_mesg structure
+ * is an unsigned 8bit integer, and thus has a valid range
+ * of 0 - 255. Beyond that a wraparound will occur. */
+#define IP_VS_SYNC_MESG_MAX_SIZE_MAX \
+	(255 * IP_VS_SYNC_SIMPLE_CONN_SIZE + sizeof(struct ip_vs_sync_mesg) \
+	 + sizeof(struct ip_vs_sync_conn_options))
+
+/* By default, send 50 connections per message. This fits niceley
+ * into a 1500 MTU packet */
+#define IP_VS_SYNC_MESG_MAX_SIZE_DEFAULT \
+	(50 * IP_VS_SYNC_SIMPLE_CONN_SIZE + sizeof(struct ip_vs_sync_mesg) \
+	 + sizeof(struct ip_vs_sync_conn_options))
+
+#define IP_VS_SYNC_MESG_MAX_SIZE \
+	((sysctl_ip_vs_sync_msg_max_size > IP_VS_SYNC_MESG_MAX_SIZE_MAX) ? \
+	IP_VS_SYNC_MESG_MAX_SIZE_MAX: \
+	((sysctl_ip_vs_sync_msg_max_size < IP_VS_SYNC_MESG_MAX_SIZE_MIN) ? \
+	 IP_VS_SYNC_MESG_MAX_SIZE_MIN : sysctl_ip_vs_sync_msg_max_size))
+
+
+#define IP_VS_SYNC_FREQUENCY_DEFAULT 50
+#define IP_VS_SYNC_FREQUENCY \
+	((sysctl_ip_vs_sync_frequency < 1) ? 1 : sysctl_ip_vs_sync_frequency)
+
+#define IP_VS_SYNC_THRESHOLD_DEFAULT 3     
+#define IP_VS_SYNC_THRESHOLD \
+	((sysctl_ip_vs_sync_threshold < 0) ? 0 : \
+	 (sysctl_ip_vs_sync_threshold >= IP_VS_SYNC_FREQUENCY) ? \
+	 IP_VS_SYNC_FREQUENCY - 1 : sysctl_ip_vs_sync_threshold) 
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/list.h>                 /* for struct list_head */
+#include <linux/spinlock.h>             /* for struct rwlock_t */
+#include <linux/skbuff.h>               /* for struct sk_buff */
+#include <linux/ip.h>                   /* for struct iphdr */
+#include <asm/atomic.h>                 /* for struct atomic_t */
+#include <linux/netdevice.h>		/* for struct neighbour; */
+/* 2.4.7 #include <net/dst.h>*/			/* for struct dst_entry */
+#include <net/route.h>			/* for ip_route_output */
+#include <net/tcp.h>
+#include <net/udp.h>
+
+
+#ifdef CONFIG_IP_VS_DEBUG
+extern int ip_vs_get_debug_level(void);
+#define IP_VS_DBG(level, msg...)			\
+    do {						\
+	    if (level <= ip_vs_get_debug_level())	\
+		    printk(KERN_DEBUG "IPVS: " msg);	\
+    } while (0)
+#define IP_VS_DBG_RL(msg...)				\
+    do {						\
+	    if (net_ratelimit())			\
+		    printk(KERN_DEBUG "IPVS: " msg);	\
+    } while (0)
+#else	/* NO DEBUGGING at ALL */
+#define IP_VS_DBG(level, msg...)  do {} while (0)
+#define IP_VS_DBG_RL(msg...)  do {} while (0)
+#endif
+
+#define IP_VS_BUG() BUG()
+#define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg)
+#define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg)
+#define IP_VS_WARNING(msg...) \
+	printk(KERN_WARNING "IPVS: " msg)
+#define IP_VS_ERR_RL(msg...)				\
+    do {						\
+	    if (net_ratelimit())			\
+		    printk(KERN_ERR "IPVS: " msg);	\
+    } while (0)
+
+#ifdef CONFIG_IP_VS_DEBUG
+#define EnterFunction(level)						\
+    do {								\
+	    if (level <= ip_vs_get_debug_level())			\
+		    printk(KERN_DEBUG "Enter: %s, %s line %i\n",	\
+			   __FUNCTION__, __FILE__, __LINE__);		\
+    } while (0)
+#define LeaveFunction(level)                                            \
+    do {                                                                \
+	    if (level <= ip_vs_get_debug_level())                       \
+			printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \
+			       __FUNCTION__, __FILE__, __LINE__);       \
+    } while (0)
+#else
+#define EnterFunction(level)   do {} while (0)
+#define LeaveFunction(level)   do {} while (0)
+#endif
+
+
+/*
+ *      The port number of FTP service (in network order).
+ */
+#define FTPPORT  __constant_htons(21)
+#define FTPDATA  __constant_htons(20)
+
+
+/*
+ *      IPVS sysctl variables under the /proc/sys/net/ipv4/vs/
+ */
+#define NET_IPV4_VS              21
+
+enum {
+	NET_IPV4_VS_DEBUG_LEVEL=1,
+	NET_IPV4_VS_AMEMTHRESH=2,
+	NET_IPV4_VS_AMDROPRATE=3,
+	NET_IPV4_VS_DROP_ENTRY=4,
+	NET_IPV4_VS_DROP_PACKET=5,
+	NET_IPV4_VS_SECURE_TCP=6,
+	NET_IPV4_VS_TO_ES=7,
+	NET_IPV4_VS_TO_SS=8,
+	NET_IPV4_VS_TO_SR=9,
+	NET_IPV4_VS_TO_FW=10,
+	NET_IPV4_VS_TO_TW=11,
+	NET_IPV4_VS_TO_CL=12,
+	NET_IPV4_VS_TO_CW=13,
+	NET_IPV4_VS_TO_LA=14,
+	NET_IPV4_VS_TO_LI=15,
+	NET_IPV4_VS_TO_SA=16,
+	NET_IPV4_VS_TO_UDP=17,
+	NET_IPV4_VS_TO_ICMP=18,
+	NET_IPV4_VS_LBLC_EXPIRE=19,
+	NET_IPV4_VS_LBLCR_EXPIRE=20,
+	NET_IPV4_VS_CACHE_BYPASS=22,
+	NET_IPV4_VS_EXPIRE_NODEST_CONN=23,
+	NET_IPV4_VS_SYNC_THRESHOLD=24,
+	NET_IPV4_VS_SYNC_FREQUENCY=25,
+	NET_IPV4_VS_SYNC_MSG_MAX_SIZE=26,
+	NET_IPV4_VS_NAT_ICMP_SEND=27,
+	NET_IPV4_VS_LAST
+};
+
+
+struct ip_vs_timeout_table {
+	atomic_t refcnt;
+	int scale;
+	int timeout[IP_VS_S_LAST+1];
+};
+
+
+/*
+ *	Transport protocol header
+ */
+union ip_vs_tphdr {
+	unsigned char *raw;
+	struct udphdr *uh;
+	struct tcphdr *th;
+	struct icmphdr *icmph;
+	__u16 *portp;
+};
+
+
+/*
+ *	IPVS statistics object
+ */
+struct ip_vs_stats
+{
+	__u32                   conns;          /* connections scheduled */
+	__u32                   inpkts;         /* incoming packets */
+	__u32                   outpkts;        /* outgoing packets */
+	__u64                   inbytes;        /* incoming bytes */
+	__u64                   outbytes;       /* outgoing bytes */
+
+	__u32			cps;		/* current connection rate */
+	__u32			inpps;		/* current in packet rate */
+	__u32			outpps;		/* current out packet rate */
+	__u32			inbps;		/* current in byte rate */
+	__u32			outbps;		/* current out byte rate */
+
+	spinlock_t              lock;           /* spin lock */
+};
+
+
+/*
+ *	IP_VS structure allocated for each dynamically scheduled connection
+ */
+struct ip_vs_conn {
+	struct list_head        c_list;         /* hashed list heads */
+
+	/* Protocol, addresses and port numbers */
+	__u32                   caddr;          /* client address */
+	__u32                   vaddr;          /* virtual address */
+	__u32                   daddr;          /* destination address */
+	__u16                   cport;
+	__u16                   vport;
+	__u16                   dport;
+	__u16                   protocol;       /* Which protocol (TCP/UDP) */
+
+	/* counter and timer */
+	atomic_t		refcnt;		/* reference count */
+	struct timer_list	timer;		/* Expiration timer */
+	volatile unsigned long	timeout;	/* timeout */
+	struct ip_vs_timeout_table *timeout_table;
+
+	/* Flags and state transition */
+	spinlock_t              lock;           /* lock for state transition */
+	volatile __u16          flags;          /* status flags */
+	volatile __u16          state;          /* state info */
+
+	/* Control members */
+	struct ip_vs_conn       *control;       /* Master control connection */
+	atomic_t                n_control;      /* Number of controlled ones */
+	struct ip_vs_dest       *dest;          /* real server */
+	atomic_t                in_pkts;        /* incoming packet counter */
+
+	/* packet transmitter for different forwarding methods */
+	int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp);
+
+	/* Note: we can group the following members into a structure,
+	   in order to save more space, and the following members are
+	   only used in VS/NAT anyway */
+	struct ip_vs_app        *app;           /* bound ip_vs_app object */
+	void                    *app_data;      /* Application private data */
+	struct ip_vs_seq        in_seq;         /* incoming seq. struct */
+	struct ip_vs_seq        out_seq;        /* outgoing seq. struct */
+};
+
+
+/*
+ *	The information about the virtual service offered to the net
+ *	and the forwarding entries
+ */
+struct ip_vs_service {
+	struct list_head	s_list;   /* for normal service table */
+	struct list_head	f_list;   /* for fwmark-based service table */
+	atomic_t		refcnt;   /* reference counter */
+	atomic_t		usecnt;   /* use counter */
+
+	__u16			protocol; /* which protocol (TCP/UDP) */
+	__u32			addr;	  /* IP address for virtual service */
+	__u16			port;	  /* port number for the service */
+	__u32                   fwmark;   /* firewall mark of the service */
+	unsigned		flags;	  /* service status flags */
+	unsigned		timeout;  /* persistent timeout in ticks */
+	__u32			netmask;  /* grouping granularity */
+
+	struct list_head	destinations;  /* real server d-linked list */
+	__u32			num_dests;     /* number of servers */
+	struct ip_vs_stats      stats;         /* statistics for the service */
+
+	/* for scheduling */
+	struct ip_vs_scheduler	*scheduler;    /* bound scheduler object */
+	rwlock_t		sched_lock;    /* lock sched_data */
+	void			*sched_data;   /* scheduler application data */
+};
+
+
+/*
+ *	The real server destination forwarding entry
+ *	with ip address, port number, and so on.
+ */
+struct ip_vs_dest {
+	struct list_head	n_list;   /* for the dests in the service */
+	struct list_head	d_list;   /* for table with all the dests */
+
+	__u32			addr;	  /* IP address of real server */
+	__u16			port;	  /* port number of the service */
+	unsigned		flags;	  /* dest status flags */
+	atomic_t		weight;	  /* server weight */
+	atomic_t		conn_flags;	/* flags to copy to conn */
+	atomic_t		activeconns;	/* active connections */
+	atomic_t		inactconns;     /* inactive connections */
+	atomic_t		refcnt;	        /* reference counter */
+	struct ip_vs_stats      stats;          /* statistics */
+
+	/* for destination cache */
+	spinlock_t		dst_lock;	/* lock dst_cache */
+	struct dst_entry	*dst_cache;	/* destination cache entry */
+	u32			dst_rtos;	/* RT_TOS(tos) for dst */
+
+	/* for virtual service */
+	struct ip_vs_service    *svc;     /* service that it belongs to */
+	__u16			protocol; /* which protocol (TCP/UDP) */
+	__u32			vaddr;	  /* IP address for virtual service */
+	__u16			vport;	  /* port number for the service */
+	__u32                   vfwmark;  /* firewall mark of the service */
+};
+
+
+/*
+ *	The scheduler object
+ */
+struct ip_vs_scheduler {
+	struct list_head        n_list;   /* d-linked list head */
+	char			*name;    /* scheduler name */
+	atomic_t                refcnt;   /* reference counter */
+	struct module           *module;  /* THIS_MODULE/NULL */
+
+	/* scheduler initializing service */
+	int (*init_service)(struct ip_vs_service *svc);
+	/* scheduling service finish */
+	int (*done_service)(struct ip_vs_service *svc);
+	/* scheduler updating service */
+	int (*update_service)(struct ip_vs_service *svc);
+
+	/* selecting a server from the given service */
+	struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc,
+				       struct iphdr *iph);
+};
+
+
+/*
+ *	The application module object
+ */
+struct ip_vs_app
+{
+	struct list_head        n_list;   /* d-linked list head */
+	char                    *name;    /* name of application module */
+	unsigned                type;     /* type = proto<<16 | port
+					     (host byte order)*/
+	struct module		*module;  /* THIS_MODULE/NULL */
+
+	/* ip_vs_app initializer */
+	int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *);
+	/* ip_vs_app finish */
+	int (*done_conn)(struct ip_vs_app *, struct ip_vs_conn *);
+	/* output hook */
+	int (*pkt_out)(struct ip_vs_app *,
+		       struct ip_vs_conn *, struct sk_buff *);
+	/* input hook */
+	int (*pkt_in)(struct ip_vs_app *,
+		      struct ip_vs_conn *, struct sk_buff *);
+};
+
+
+/*
+ *      IPVS core functions
+ *      (from ip_vs_core.c)
+ */
+extern const char *ip_vs_proto_name(unsigned proto);
+extern unsigned int check_for_ip_vs_out(struct sk_buff **skb_p,
+					int (*okfn)(struct sk_buff *));
+
+
+/*
+ *     ip_vs_conn handling functions
+ *     (from ip_vs_conn.c)
+ */
+
+/*
+ *     IPVS connection entry hash table
+ */
+#ifndef CONFIG_IP_VS_TAB_BITS
+#define CONFIG_IP_VS_TAB_BITS   12
+#endif
+/* make sure that IP_VS_CONN_TAB_BITS is located in [8, 20] */
+#if CONFIG_IP_VS_TAB_BITS < 8
+#define IP_VS_CONN_TAB_BITS	8
+#endif
+#if CONFIG_IP_VS_TAB_BITS > 20
+#define IP_VS_CONN_TAB_BITS	20
+#endif
+#if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20
+#define IP_VS_CONN_TAB_BITS	CONFIG_IP_VS_TAB_BITS
+#endif
+#define IP_VS_CONN_TAB_SIZE     (1 << IP_VS_CONN_TAB_BITS)
+#define IP_VS_CONN_TAB_MASK     (IP_VS_CONN_TAB_SIZE - 1)
+
+extern struct ip_vs_timeout_table vs_timeout_table;
+extern struct ip_vs_timeout_table vs_timeout_table_dos;
+
+extern struct ip_vs_conn *ip_vs_conn_in_get
+(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+extern struct ip_vs_conn *ip_vs_conn_out_get
+(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
+
+/* put back the conn without restarting its timer */
+static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
+{
+	atomic_dec(&cp->refcnt);
+}
+extern void ip_vs_conn_put(struct ip_vs_conn *cp);
+
+extern struct ip_vs_conn *
+ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
+	       __u32 daddr, __u16 dport, unsigned flags,
+	       struct ip_vs_dest *dest);
+extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
+
+extern const char * ip_vs_state_name(int state);
+extern int ip_vs_set_state(struct ip_vs_conn *cp, int state_off,
+			   struct iphdr *iph, void *tp);
+extern int ip_vs_conn_listen(struct ip_vs_conn *cp);
+extern int ip_vs_check_template(struct ip_vs_conn *ct);
+extern void ip_vs_secure_tcp_set(int on);
+extern void ip_vs_random_dropentry(void);
+extern int ip_vs_conn_init(void);
+extern void ip_vs_conn_cleanup(void);
+
+static inline void ip_vs_control_del(struct ip_vs_conn *cp)
+{
+	struct ip_vs_conn *ctl_cp = cp->control;
+	if (!ctl_cp) {
+		IP_VS_ERR("request control DEL for uncontrolled: "
+			  "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
+			  NIPQUAD(cp->caddr),ntohs(cp->cport),
+			  NIPQUAD(cp->vaddr),ntohs(cp->vport));
+		return;
+	}
+
+	IP_VS_DBG(7, "DELeting control for: "
+		  "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
+		  NIPQUAD(cp->caddr),ntohs(cp->cport),
+		  NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport));
+
+	cp->control = NULL;
+	if (atomic_read(&ctl_cp->n_control) == 0) {
+		IP_VS_ERR("BUG control DEL with n=0 : "
+			  "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
+			  NIPQUAD(cp->caddr),ntohs(cp->cport),
+			  NIPQUAD(cp->vaddr),ntohs(cp->vport));
+		return;
+	}
+	atomic_dec(&ctl_cp->n_control);
+}
+
+static inline void
+ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
+{
+	if (cp->control) {
+		IP_VS_ERR("request control ADD for already controlled: "
+			  "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
+			  NIPQUAD(cp->caddr),ntohs(cp->cport),
+			  NIPQUAD(cp->vaddr),ntohs(cp->vport));
+		ip_vs_control_del(cp);
+	}
+
+	IP_VS_DBG(7, "ADDing control for: "
+		  "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
+		  NIPQUAD(cp->caddr),ntohs(cp->cport),
+		  NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport));
+
+	cp->control = ctl_cp;
+	atomic_inc(&ctl_cp->n_control);
+}
+
+
+/*
+ *      IPVS application functions
+ *      (from ip_vs_app.c)
+ */
+#define IP_VS_APP_MAX_PORTS  8
+extern int register_ip_vs_app(struct ip_vs_app *mapp,
+			      unsigned short proto, __u16 port);
+extern int unregister_ip_vs_app(struct ip_vs_app *mapp);
+extern struct ip_vs_app * ip_vs_bind_app(struct ip_vs_conn *cp);
+extern int ip_vs_unbind_app(struct ip_vs_conn *cp);
+extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb);
+extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb);
+extern int ip_vs_skb_replace(struct sk_buff *skb, int pri,
+			     char *o_buf, int o_len, char *n_buf, int n_len);
+extern int ip_vs_app_init(void);
+extern void ip_vs_app_cleanup(void);
+
+
+/*
+ *      Registering/unregistering scheduler functions
+ *      (from ip_vs_sched.c)
+ */
+extern int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
+extern int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
+extern int ip_vs_bind_scheduler(struct ip_vs_service *svc,
+				struct ip_vs_scheduler *scheduler);
+extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc);
+extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
+extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
+
+
+/*
+ *      IPVS control data and functions
+ *      (from ip_vs_ctl.c)
+ */
+extern int sysctl_ip_vs_cache_bypass;
+extern int sysctl_ip_vs_expire_nodest_conn;
+extern int sysctl_ip_vs_sync_threshold;
+extern int sysctl_ip_vs_sync_frequency;
+extern int sysctl_ip_vs_sync_msg_max_size;
+extern int sysctl_ip_vs_nat_icmp_send;
+extern atomic_t ip_vs_dropentry;
+extern struct ip_vs_stats ip_vs_stats;
+
+extern struct ip_vs_service *ip_vs_service_get(__u32 fwmark,
+					       __u16 protocol,
+					       __u32 vaddr, __u16 vport);
+static inline void ip_vs_service_put(struct ip_vs_service *svc)
+{
+	atomic_dec(&svc->usecnt);
+}
+
+extern struct ip_vs_dest *
+ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
+extern void update_defense_level(void);
+extern void ip_vs_random_dropentry(void);
+extern int ip_vs_control_init(void);
+extern void ip_vs_control_cleanup(void);
+
+
+/*
+ *      IPVS sync daemon data and function prototypes
+ *      (from ip_vs_sync.c)
+ */
+extern volatile int ip_vs_sync_state;
+extern char ip_vs_mcast_ifn[IP_VS_IFNAME_MAXLEN];
+extern int start_sync_thread(int state, char *mcast_ifn);
+extern int stop_sync_thread(void);
+extern int dump_sync_thread(void);
+extern void ip_vs_sync_conn(struct ip_vs_conn *cp);
+extern void ip_vs_process_message(const char *buffer, const size_t buflen);
+
+
+/*
+ *      IPVS rate estimator prototypes (from ip_vs_est.c)
+ */
+extern int ip_vs_new_estimator(struct ip_vs_stats *stats);
+extern void ip_vs_kill_estimator(struct ip_vs_stats *stats);
+extern void ip_vs_zero_estimator(struct ip_vs_stats *stats);
+
+
+/*
+ *	This is a simple mechanism to ignore packets when
+ *	we are loaded. Just set ip_vs_drop_rate to 'n' and
+ *	we start to drop 1/rate of the packets
+ */
+extern int ip_vs_drop_rate;
+extern int ip_vs_drop_counter;
+
+static __inline__ int ip_vs_todrop(void)
+{
+	if (!ip_vs_drop_rate) return 0;
+	if (--ip_vs_drop_counter > 0) return 0;
+	ip_vs_drop_counter = ip_vs_drop_rate;
+	return 1;
+}
+
+
+/*
+ *      Slow timer functions for IPVS
+ *      (from ip_vs_timer.c)
+ */
+extern void add_sltimer(struct timer_list * timer);
+extern int  del_sltimer(struct timer_list * timer);
+extern void mod_sltimer(struct timer_list *timer, unsigned long expires);
+extern void ip_vs_sltimer_init(void);
+extern void ip_vs_sltimer_cleanup(void);
+
+
+/*
+ *      ip_vs_fwd_tag returns the forwarding tag of the connection
+ */
+#define IP_VS_FWD_METHOD(cp)  (cp->flags & IP_VS_CONN_F_FWD_MASK)
+
+extern __inline__ char ip_vs_fwd_tag(struct ip_vs_conn *cp)
+{
+	char fwd;
+
+	switch (IP_VS_FWD_METHOD(cp)) {
+	case IP_VS_CONN_F_MASQ:
+		fwd = 'M'; break;
+	case IP_VS_CONN_F_LOCALNODE:
+		fwd = 'L'; break;
+	case IP_VS_CONN_F_TUNNEL:
+		fwd = 'T'; break;
+	case IP_VS_CONN_F_DROUTE:
+		fwd = 'R'; break;
+	case IP_VS_CONN_F_BYPASS:
+		fwd = 'B'; break;
+	default:
+		fwd = '?'; break;
+	}
+	return fwd;
+}
+
+
+/*
+ *	transport layer header checking
+ */
+extern inline int ip_vs_header_check(struct sk_buff *skb, int proto, int ihl)
+{
+	int len;
+
+	switch (proto) {
+	case IPPROTO_TCP:
+		len = ihl + sizeof(struct tcphdr);
+		/* we don't care about TCP options */
+		break;
+	case IPPROTO_UDP:
+		len = ihl + sizeof(struct udphdr);
+		break;
+	default:
+		len = 0;
+	}
+
+	/* guarantee protocol header available in skb data area */
+	if (!pskb_may_pull(skb, len))
+		return -1;
+	else
+		return 0;
+}
+
+
+/*
+ *      Destination cache
+ */
+static inline void
+__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst)
+{
+	struct dst_entry *old_dst;
+
+	old_dst = dest->dst_cache;
+	dest->dst_cache = dst;
+	dest->dst_rtos = rtos;
+	dst_release(old_dst);
+}
+
+static inline void
+__ip_vs_dst_reset(struct ip_vs_dest *dest)
+{
+	struct dst_entry *old_dst;
+
+	old_dst = dest->dst_cache;
+	dest->dst_cache = NULL;
+	dst_release(old_dst);
+}
+
+static inline struct dst_entry *
+__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie)
+{
+	struct dst_entry *dst = dest->dst_cache;
+
+	if (!dst)
+		return NULL;
+	if ((dst->obsolete || rtos != dest->dst_rtos) &&
+	    dst->ops->check(dst, cookie) == NULL) {
+		dest->dst_cache = 0;
+		return NULL;
+	}
+	dst_hold(dst);
+	return dst;
+}
+
+static inline struct rtable *
+__ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
+{
+	struct rtable *rt;			/* Route to the other host */
+	struct ip_vs_dest *dest = cp->dest;
+
+	if (dest) {
+		spin_lock(&dest->dst_lock);
+		if (!(rt = (struct rtable *)
+		      __ip_vs_dst_check(dest, rtos, 0))) {
+			if (ip_route_output(&rt, dest->addr, 0, rtos, 0)) {
+				spin_unlock(&dest->dst_lock);
+				IP_VS_DBG_RL("ip_route_output error, "
+					     "dest: %u.%u.%u.%u\n",
+					     NIPQUAD(dest->addr));
+				return NULL;
+			}
+			__ip_vs_dst_set(dest, rtos, dst_clone(&rt->u.dst));
+			IP_VS_DBG(10, "new dst %u.%u.%u.%u, refcnt=%d, rtos=%X\n",
+				  NIPQUAD(dest->addr),
+				  atomic_read(&rt->u.dst.__refcnt), rtos);
+		}
+		spin_unlock(&dest->dst_lock);
+	} else {
+		if (ip_route_output(&rt, cp->daddr, 0, rtos, 0)) {
+			IP_VS_DBG_RL("ip_route_output error, dest: "
+				     "%u.%u.%u.%u\n", NIPQUAD(cp->daddr));
+			return NULL;
+		}
+	}
+
+	return rt;
+}
+
+static inline u16 ip_vs_check_diff(u32 old, u32 new, u16 oldsum)
+{
+	u32 diff[2] = { old, new };
+
+	return csum_fold(csum_partial((char *) diff, sizeof(diff),
+				      oldsum ^ 0xFFFF));
+}
+
+static inline void ip_vs_fast_check_update(union ip_vs_tphdr *h,
+	u32 oldip, u32 newip, u16 oldport, u16 newport, u8 protocol)
+{
+	u16 *checkp;
+
+	if (protocol == IPPROTO_TCP)
+		checkp = &h->th->check;
+	else
+		checkp = &h->uh->check;
+	*checkp = ip_vs_check_diff(~oldip, newip,
+		ip_vs_check_diff(oldport ^ 0xFFFF, newport, *checkp));
+	if (!*checkp && protocol == IPPROTO_UDP)
+		*checkp = 0xFFFF;
+}
+
+static inline int
+ip_vs_skb_cow(struct sk_buff *skb, unsigned int headroom,
+	      struct iphdr **iph_p, unsigned char **t_p)
+{
+	int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb);
+
+	if (delta < 0)
+		delta = 0;
+
+	if (delta ||skb_cloned(skb)) {
+		if (pskb_expand_head(skb, (delta+15)&~15, 0, GFP_ATOMIC))
+			return -ENOMEM;
+
+		/* skb data changed, update pointers */
+		*iph_p = skb->nh.iph;
+		*t_p = (char*) (*iph_p) + (*iph_p)->ihl * 4;
+	}
+	return 0;
+}
+
+typedef int ip_vs_sync_table_send_handler_t(struct socket *sock,
+		const char *buffer, const size_t length, void **data);
+typedef int ip_vs_sync_table_recv_loop_handler_t(struct socket *sock,
+		void **data);
+typedef struct sk_buff *ip_vs_sync_table_recv_ready_handler_t(
+		struct socket *sock, void **data);
+typedef struct socket *ip_vs_sync_table_open_handler_t(void **data);
+typedef int ip_vs_sync_table_close_handler_t(struct socket *sock, void **data);
+typedef int ip_vs_sync_table_done_handler_t(struct socket *sock, void **data);
+
+typedef struct {
+	ip_vs_sync_table_send_handler_t       *send;
+	ip_vs_sync_table_recv_loop_handler_t  *recv_loop;
+	ip_vs_sync_table_open_handler_t       *open_send;
+	ip_vs_sync_table_open_handler_t       *open_recv;
+	ip_vs_sync_table_close_handler_t      *close_send;
+	ip_vs_sync_table_close_handler_t      *close_recv;
+	ip_vs_sync_table_done_handler_t       *done;
+	void *data;
+	int state;
+	spinlock_t lock;
+} ip_vs_sync_table_t;
+
+int __init ip_vs_sync_init(void);
+int __exit ip_vs_sync_cleanup(void);
+int ip_vs_sync_table_register(ip_vs_sync_table_send_handler_t *send,
+		ip_vs_sync_table_recv_loop_handler_t *recv_loop,
+		ip_vs_sync_table_open_handler_t *open_send,
+		ip_vs_sync_table_open_handler_t *open_recv,
+		ip_vs_sync_table_close_handler_t *close_send,
+		ip_vs_sync_table_close_handler_t *close_recv,
+		ip_vs_sync_table_done_handler_t *done,
+		void *data);
+
+void ip_vs_sync_table_register_default(void);
+void ip_vs_sync_table_unregister(void);
+
+void ip_vs_conn_dump_to_sync(void);
+#endif /* __KERNEL__ */
+
+#endif	/* _IP_VS_H */
