# ipvs: IP Virtual Server Module for the NetFilter framework

# uncomment the following line for debugging
DEBUGFLAGS	= -DCONFIG_IP_VS_DEBUG

# need to specify the path of kernel source
KERNELSOURCE	= /usr/src/linux


KERNELRELEASE	= $(shell echo -e "\#include <linux/version.h>\nUTS_RELEASE" \
		    > conftest.c &&					     \
		    gcc -E -I$(KERNELSOURCE)/include conftest.c | tail -1    \
		    | cut -d '"' -f 2 && rm -f conftest.c)

KERNELSYMS	= /boot/System.map-$(KERNELRELEASE)

ARCH		= $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
		  -e s/arm.*/arm/ -e s/sa110/arm/)


# If System.map exists, run depmod.  This deliberately does not have a
# dependency on System.map since that would run the dependency tree on
# vmlinux.  This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write.  However the
# boot script depmod is the master version.
ifeq "$(strip $(INSTALL_MOD_PATH))" ""
depmod_opts     :=
else
depmod_opts     := -b $(INSTALL_MOD_PATH) -r
endif


# include the kernel config file
include $(KERNELSOURCE)/.config

check_gcc	= $(shell if gcc $(1) -S -o /dev/null -xc /dev/null > 	  \
		  /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)

i386_CFLAGS	= -pipe
i386_CFLAGS	+= $(call check_gcc,-mpreferred-stack-boundary=2,)

# processor-related compiling options
cflags-$(CONFIG_M386)		+= -march=i386
cflags-$(CONFIG_M486)		+= -march=i486
cflags-$(CONFIG_M586)		+= -march=i586
cflags-$(CONFIG_M586TSC)	+= -march=i586
cflags-$(CONFIG_M586MMX)	+= $(call check_gcc,-march=pentium-mmx,-march=i586)
cflags-$(CONFIG_M686)		+= -march=i686
cflags-$(CONFIG_MPENTIUMIII)	+= $(call check_gcc,-march=pentium3,-march=i686)
cflags-$(CONFIG_MPENTIUM4)	+= $(call check_gcc,-march=pentium4,-march=i686)
cflags-$(CONFIG_MK6)		+= $(call check_gcc,-march=k6,-march=i586)
cflags-$(CONFIG_MK7)		+= $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4)
cflags-$(CONFIG_MCRUSOE)	+= -march=i686 -malign-functions=0 -malign-jumps=0 -malign-loops=0
cflags-$(CONFIG_MWINCHIPC6)	+= $(call check_gcc,-march=winchip-c6,-march=i586)
cflags-$(CONFIG_MWINCHIP2)	+= $(call check_gcc,-march=winchip2,-march=i586)
cflags-$(CONFIG_MWINCHIP3D)	+= -march=i586
cflags-$(CONFIG_MCYRIXIII)	+= $(call check_gcc,-march=c3,-march=i486) -malign-functions=0 -malign-jumps=0 -malign-loops=0

i386_CFLAGS	+= $(cflags-y) -I$(KERNELSOURCE)/arch/i386/mach-generic
i386_LDFLAGS	= -m elf_i386
ARCH_CFLAGS	= $($(ARCH)_CFLAGS)


comma		:= ,
MODNAME		= $(subst $(comma),_,$(subst -,_,$(*F)))
BASENAME_FLAGS	= -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
depfile		= $(subst $(comma),_,$(@D)/.$(@F).d)
NOSTDINC_FLAGS	= -nostdinc -iwithprefix include
EXPORT_FLAGS	= -DEXPORT_SYMTAB

EXPORT_OBJS	:= ip_vs_core.o ip_vs_app.o
$(EXPORT_OBJS)	: export_flags := $(EXPORT_FLAGS)

# As per the Linux Kernel's Makefile:
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots.  This is not defined in the
# makefile but the arguement can be passed to make if needed.

MODLIB		= $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/kernel/net/ipv4/ipvs/

CC		= gcc
CFLAGS		= -Wp,-MD,$(depfile) -D__KERNEL__ -I$(KERNELSOURCE)/include \
		  -Wall -Wstrict-prototypes -Wno-trigraphs -O2		    \
		  -fno-strict-aliasing -fno-common -fomit-frame-pointer	    \
		  $(ARCH_CFLAGS) $(NOSTDINC_FLAGS) -DMODULE		    \
		  $(BASENAME_FLAGS) $(export_flags) $(DEBUGFLAGS)
LDFLAGS		= $($(ARCH)_LDFLAGS)

CORE		= ip_vs.o
CORE_OBJS	= ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o	   \
		  ip_vs_xmit.o ip_vs_timer.o ip_vs_app.o ip_vs_sync.o	   \
		  ip_vs_est.o ip_vs_proto.o ip_vs_proto_tcp.o		   \
		  ip_vs_proto_udp.o ip_vs_proto_icmp.o ip_vs_proto_ahesp.o
SCHEDULERS	= ip_vs_lc.o ip_vs_rr.o ip_vs_wlc.o ip_vs_wrr.o		\
		  ip_vs_lblc.o ip_vs_lblcr.o ip_vs_dh.o ip_vs_sh.o
APPMODS		= ip_vs_ftp.o
TARGETS		= $(CORE:.o=.ko) $(SCHEDULERS:.o=.ko) $(APPMODS:.o=.ko)

include $(KERNELSOURCE)/scripts/Makefile.lib


all:
		@echo "Tired to keep changing the Makefile with the Makefile changes of"
		@echo "the Linux kernel 2.5.xx. Currently, you need install the ipvs source"
		@echo "code to the kernel source code, in order to build ipvs."
		@echo "See the README at the upper directory for more information."

$(CORE:.o=.ko):	%.ko : $(CORE_OBJS)
		$(LD) $(LDFLAGS) -r -o $@ $^

$(CORE_OBJS):	%.o : %.c
		$(CC) $(CFLAGS) -DKBUILD_MODNAME=ip_vs -c -o $@ $<

$(SCHEDULERS):	%.o : %.c
		$(CC) $(CFLAGS) -DKBUILD_MODNAME=$(MODNAME) -c -o $@ $<

$(APPMODS):	%.o : %.c
		$(CC) $(CFLAGS) -DKBUILD_MODNAME=$(MODNAME) -c -o $@ $<

$(SCHEDULERS:.o=.ko): %.ko :%.o
		$(LD) $(LDFLAGS) -r -o $@ $^

$(APPMODS:.o=.ko): %.ko :%.o
		$(LD) $(LDFLAGS) -r -o $@ $^

install:	ip_vs.ko
		-rmmod ip_vs
		insmod ip_vs.ko
		lsmod

modules_install: $(TARGETS)
		if [ ! -d "$(MODLIB)" ]; then mkdir -p "$(MODLIB)"; fi
		install -m 600 -c -s $(TARGETS) "$(MODLIB)"
		depmod -ae -F $(KERNELSYMS) $(depmod_opts) $(KERNELRELEASE)

modules_uninstall:
		(cd "$(MODLIB)"; rm -f $(TARGETS))
		rmdir "$(MODLIB)"

clean:
		rm -f $(TARGETS) *.o *~ *.bak *.orig *.rej

distclean:	clean
		make -C ipvsadm distclean
		rm -f TAGS tags
