update initialisation scripts
diff --git a/Makefile b/Makefile
index ac3e9fa..00e377d 100644
--- a/Makefile
+++ b/Makefile
@@ -2,13 +2,15 @@
 
 PROGNAME:=ebtables
 PROGVERSION:=2.0.7
-PROGDATE:=June\ 2005
+PROGDATE:=September\ 2005
 
 # default paths
 LIBDIR:=/usr/lib
 MANDIR:=/usr/local/man
 BINDIR:=/usr/local/sbin
 ETCDIR:=/etc
+INITDIR:=/etc/rc.d/init.d
+SYSCONFIGDIR:=/etc/sysconfig
 DESTDIR:=
 
 # include DESTDIR param
@@ -16,6 +18,8 @@
 override MANDIR:=$(DESTDIR)$(MANDIR)
 override BINDIR:=$(DESTDIR)$(BINDIR)
 override ETCDIR:=$(DESTDIR)$(ETCDIR)
+override INITDIR:=$(DESTDIR)$(INITDIR)
+override SYSCONFIGDIR:=$(DESTDIR)$(SYSCONFIGDIR)
 
 
 CFLAGS:=-Wall -Wunused
@@ -38,7 +42,7 @@
 ETHERTYPESPATH?=$(ETCDIR)
 ETHERTYPESFILE:=$(ETHERTYPESPATH)/ethertypes
 
-PIPE_DIR?=/tmp/$(PROGNAME)-v$(PROGVERSION)
+PIPE_DIR?=$(DESTDIR)/tmp/$(PROGNAME)-v$(PROGVERSION)
 PIPE=$(PIPE_DIR)/ebtablesd_pipe
 EBTD_CMDLINE_MAXLN?=2048
 EBTD_ARGC_MAX?=50
@@ -106,6 +110,20 @@
 .PHONY: daemon
 daemon: ebtablesd ebtablesu
 
+tmp1:=$(shell printf $(BINDIR) | sed 's/\//\\\//g')
+tmp2:=$(shell printf $(SYSCONFIGDIR) | sed 's/\//\\\//g')
+.PHONY: scripts
+scripts: ebtables-save ebtables-restore ebtables.sysv ebtables-config
+	cat ebtables-save | sed 's/__EXEC_PATH__/$(tmp1)/g' > ebtables-save_
+	install -m 0755 -o root -g root ebtables-save_ $(BINDIR)/ebtables-save
+	cat ebtables-restore | sed 's/__EXEC_PATH__/$(tmp1)/g' > ebtables-restore_
+	install -m 0755 -o root -g root ebtables-restore_ $(BINDIR)/ebtables-restore
+	cat ebtables.sysv | sed 's/__EXEC_PATH__/$(tmp1)/g' | sed 's/__SYSCONFIG__/$(tmp2)/g'> ebtables.sysv_
+	install -m 0755 -o root -g root ebtables.sysv_ $(INITDIR)/ebtables
+	cat ebtables-config | sed 's/__SYSCONFIG__/$(tmp1)/g' > ebtables-config_
+	install -m 0600 -o root -g root ebtables-config_ $(SYSCONFIGDIR)/ebtables-config
+	rm -f ebtables-save_ ebtables-restore_ ebtables.sysv_ ebtables-config_
+
 $(MANDIR)/man8/ebtables.8: ebtables.8
 	mkdir -p $(@D)
 	install -m 0644 -o root -g root $< $@
@@ -122,7 +140,7 @@
 	install -m 0755 -o root -g root $(PROGNAME)u $(BINFILE_EBTU)
 
 .PHONY: install
-install: $(MANDIR)/man8/ebtables.8 $(ETHERTYPESFILE) exec
+install: $(MANDIR)/man8/ebtables.8 $(ETHERTYPESFILE) exec scripts
 	mkdir -p $(LIBDIR)
 	install -m 0755 extensions/*.so $(LIBDIR)
 	install -m 0755 *.so $(LIBDIR)
diff --git a/ebtables-config b/ebtables-config
new file mode 100644
index 0000000..0393e63
--- /dev/null
+++ b/ebtables-config
@@ -0,0 +1,37 @@
+# Save (and possibly restore) in text format.
+#   Value: yes|no,  default: yes
+# Save the firewall rules in text format to __SYSCONFIG__/ebtables
+# If EBTABLES_BINARY_FORMAT="no" then restoring the firewall rules
+# is done using this text format.
+EBTABLES_TEXT_FORMAT="yes"
+
+# Save (and restore) in binary format.
+#   Value: yes|no,  default: yes
+# Save (and restore) the firewall rules in binary format to (and from)
+# __SYSCONFIG__/ebtables.<chain>. Enabling this option will make
+# firewall initialisation a lot faster.
+EBTABLES_BINARY_FORMAT="yes"
+
+# Unload modules on restart and stop
+#   Value: yes|no,  default: yes
+# This option has to be 'yes' to get to a sane state for a firewall
+# restart or stop. Only set to 'no' if there are problems unloading netfilter
+# modules.
+EBTABLES_MODULES_UNLOAD="yes"
+
+# Save current firewall rules on stop.
+#   Value: yes|no,  default: no
+# Saves all firewall rules if firewall gets stopped
+# (e.g. on system shutdown).
+EBTABLES_SAVE_ON_STOP="no"
+
+# Save current firewall rules on restart.
+#   Value: yes|no,  default: no
+# Saves all firewall rules if firewall gets restarted.
+EBTABLES_SAVE_ON_RESTART="no"
+
+# Save (and restore) rule counters.
+#   Value: yes|no,  default: no
+# Save rule counters when saving a kernel table to a file and when
+# populating a table in the kernel.
+EBTABLES_SAVE_COUNTER="no"
diff --git a/ebtables-restore b/ebtables-restore
index 171a80c..abe049d 100644
--- a/ebtables-restore
+++ b/ebtables-restore
@@ -6,8 +6,8 @@
 #
 
 use strict;
-my $ebtables = "/sbin/ebtables";
-my $table;
+my $ebtables = "__EXEC_PATH__/ebtables";
+my $table = "";
 my $rc;
 my $line;
 
@@ -16,43 +16,42 @@
 # Creates user chains.
 # ==============================
 sub check_chain {
-	if ($table eq "filter") {
-		if ($_[1] eq "INPUT") { return; }
-		if ($_[1] eq "FORWARD") { return; }
-		if ($_[1] eq "OUTPUT") { return; }
-	}
-	if ($table eq "nat") {
-		if ($_[1] eq "PREROUTING") { return; }
-		if ($_[1] eq "POSTROUTING") { return; }
-		if ($_[1] eq "OUTPUT") { return; }
-	}
-	if ($table eq "broute") {
-		if ($_[1] eq "BROUTING") { return; }
-	}
-	$rc = `$ebtables -t $_[0] -N $_[1]`;
-        unless($? == 0) {print "ERROR: $rc\n"; exit -1};
+    if ($table eq "filter") {
+        if ($_[1] eq "INPUT") { return; }
+        if ($_[1] eq "FORWARD") { return; }
+        if ($_[1] eq "OUTPUT") { return; }
+    }
+    if ($table eq "nat") {
+        if ($_[1] eq "PREROUTING") { return; }
+        if ($_[1] eq "POSTROUTING") { return; }
+        if ($_[1] eq "OUTPUT") { return; }
+    }
+    if ($table eq "broute") {
+        if ($_[1] eq "BROUTING") { return; }
+    }
+    $rc = `$ebtables -t $_[0] -N $_[1]`;
+    unless($? == 0) {print "ERROR: $rc\n"; exit -1};
 }
 # ==============================
 
 unless (-x $ebtables) { print "ERROR: $ebtables isn't executable\n"; exit -1; };
-$rc = `$ebtables -t filter --init-table`;
-unless($? == 0) { print "ERROR: $rc\n"; exit -1 };
-$rc = `$ebtables -t nat --init-table`;
-unless($? == 0) { print "ERROR: $rc\n"; exit -1 };
-$rc = `$ebtables -t broute --init-table`;
-unless($? == 0) { print "ERROR: $rc\n"; exit -1 };
-
 $line = 0;
 while(<>) {
     $line++;
     if(m/^#/) { next; };
     if(m/^$/) { next; };
     if(m/^\*(.*)/) {
+        if (defined($ENV{'EBTABLES_SAVE_COUNTER'}) && !($ENV{'EBTABLES_SAVE_COUNTER'} eq "yes") && !($table eq "") ) {
+            $rc = `$ebtables -t $table -Z`;
+            unless($? == 0) {print "ERROR: $rc\n"; exit -1};
+        }
         $table = $1;
+        $rc = `$ebtables -t filter --init-table`;
+        unless($? == 0) {print "ERROR: $rc\n"; exit -1};
         next;
     }
     if(m/^\:(.*?)\s(.*)/) {
-	&check_chain($table,$1);
+        &check_chain($table,$1);
         $rc = `$ebtables -t $table -P $1 $2`;
         unless($? == 0) {print "ERROR(line $line): $rc\n"; exit -1};
         next;
@@ -60,3 +59,7 @@
     $rc = `$ebtables -t $table $_`;
     unless($? == 0) {print "ERROR(line $line): $rc\n"; exit -1};
 }
+if (defined($ENV{'EBTABLES_SAVE_COUNTER'}) && !($ENV{'EBTABLES_SAVE_COUNTER'} eq "yes") && !($table eq "")) {
+    $rc = `$ebtables -t $table -Z`;
+    unless($? == 0) {print "ERROR: '-t $table -Z' failed\n"; exit -1};
+}
diff --git a/ebtables-save b/ebtables-save
index df30790..90f62ef 100644
--- a/ebtables-save
+++ b/ebtables-save
@@ -8,6 +8,10 @@
 
 use strict;
 my $table;
+my $ebtables = "__EXEC_PATH__/ebtables";
+my $cnt = "";
+my $version = "1.0";
+my $table_name;
 
 # ========================================================
 # Process filter table
@@ -31,6 +35,9 @@
         if ($line =~ m/^$/) {
             next;
         }
+        if ($cnt eq "--Lc") {
+            $line =~ s/, pcnt = (.*) -- bcnt = (.*)/-c $1 $2/;
+        }
         $rules = $rules . "-A $chain $line\n";
     }
 
@@ -40,14 +47,13 @@
 }
 # ========================================================
 
-unless (-x "/sbin/ebtables") { exit -1 };
-$table =`/sbin/ebtables -t filter -L`;
-unless ($? == 0) { print $table; exit -1 };
-&process_table($table);
-$table =`/sbin/ebtables -t nat -L`;
-unless ($? == 0) { print $table; exit -1 };
-&process_table($table);
-$table =`/sbin/ebtables -t broute -L`;
-unless ($? == 0) { print $table; exit -1 };
-&process_table($table);
-
+unless (-x $ebtables) { exit -1 };
+print "# Generated by ebtables-save v$version on " . `date`;
+if (defined($ENV{'EBTABLES_SAVE_COUNTER'}) && $ENV{'EBTABLES_SAVE_COUNTER'} eq "yes") {
+    $cnt = "--Lc";
+}
+foreach $table_name (split("\n", `grep -E '^ebtable_' /proc/modules | cut -f1 -d' ' | sed s/ebtable_//`)) {
+    $table =`$ebtables -t $table_name -L $cnt`;
+    unless ($? == 0) { print $table; exit -1 };
+    &process_table($table);
+}
diff --git a/ebtables.sysv b/ebtables.sysv
index 5ec94c7..53fd0f6 100644
--- a/ebtables.sysv
+++ b/ebtables.sysv
@@ -2,13 +2,15 @@
 #
 # init script for the Ethernet Bridge filter tables
 #
-# Written by Dag Wieers <dag@wieers.com>.
-# Modified by Rok Papez <rok.papez@arnes.si>.
+# Written by Dag Wieers <dag@wieers.com>
+# Modified by Rok Papez <rok.papez@arnes.si>
+#             Bart De Schuymer <bdschuym@pandora.be>
 #
 # chkconfig: - 15 85
 # description: Ethernet Bridge filtering tables
 #
-# config: /etc/sysconfig/ebtables
+# config: __SYSCONFIG__/ebtables         (text)
+#         __SYSCONFIG__/ebtables.<table> (binary)
 
 source /etc/init.d/functions
 source /etc/sysconfig/network
@@ -16,19 +18,34 @@
 # Check that networking is up.
 [ ${NETWORKING} = "no" ] && exit 0
 
-[ -x /sbin/ebtables ] || exit 1
-[ -x /sbin/ebtables-save ] || exit 1
-[ -x /sbin/ebtables-restore ] || exit 1
-
-[ "$1" == "save" -o -r /etc/sysconfig/ebtables ] || exit 1
+[ -x __EXEC_PATH__/ebtables ] || exit 1
+[ -x __EXEC_PATH__/ebtables-save ] || exit 1
+[ -x __EXEC_PATH__/ebtables-restore ] || exit 1
 
 RETVAL=0
 prog="ebtables"
 desc="Ethernet bridge filtering"
 
+#default configuration
+EBTABLES_TEXT_FORMAT="yes"
+EBTABLES_BINARY_FORMAT="yes"
+EBTABLES_MODULES_UNLOAD="yes"
+EBTABLES_SAVE_ON_STOP="no"
+EBTABLES_SAVE_ON_RESTART="no"
+EBTABLES_SAVE_COUNTER="no"
+
+config=__SYSCONFIG__/$prog-config
+[ -f "$config" ] && . "$config"
+
 start() {
 	echo -n $"Starting $desc ($prog): "
-	/sbin/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1
+	if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then
+		for table in $(ls __SYSCONFIG__/ebtables.* | sed s/*ebtables.//); do
+			__EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.filter --atomic-commit || RETVAL=1
+		done
+	else
+		__EXEC_PATH__/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1
+	fi
 
 	if [ $RETVAL -eq 0 ]; then
 		success "$prog startup"
@@ -36,30 +53,28 @@
 	else
 		failure "$prog startup"
 	fi
-
 	echo
-	return $RETVAL
 }
 
 stop() {
 	echo -n $"Stopping $desc ($prog): "
-	/sbin/ebtables -t filter --init-table || RETVAL=1
-	/sbin/ebtables -t nat --init-table || RETVAL=1
-	/sbin/ebtables -t broute --init-table || RETVAL=1
-
-	for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -f1 -d' ') ebtables; do
-		rmmod $mod || RETVAL=1
+	for table in $(grep -E '^ebtable_' /proc/modules | cut -f1 -d' ' | sed s/ebtable_//); do
+		__EXEC_PATH__/ebtables -t $table --init-table || RETVAL=1
 	done
 
+	if [ "$EBTABLES_MODULE_UNLOAD" = "yes" ]; then
+		for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -f1 -d' ') ebtables; do
+			rmmod $mod || RETVAL=1
+		done
+	fi
+
 	if [ $RETVAL -eq 0 ]; then
 		success "$prog shutdown"
 		rm -f %{_localstatedir}/lock/subsys/$prog
 	else
 		failure "$prog shutdown"
 	fi
-
 	echo
-	return $RETVAL
 }
 
 restart() {
@@ -69,7 +84,17 @@
 
 save() {
 	echo -n $"Saving $desc ($prog): "
-	/sbin/ebtables-save > /etc/sysconfig/ebtables || RETVAL=1
+	if [ "$EBTABLES_TEXT_FORMAT" = "yes" ]; then
+		__EXEC_PATH__/ebtables-save > /etc/sysconfig/ebtables || RETVAL=1
+	fi
+	if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then
+		for mod in $(grep -E '^ebtable_' /proc/modules | cut -f1 -d' ' | sed s/ebtable_//); do
+			__EXEC_PATH__/ebtables -t $mod --atomic-file __SYSCONFIG__/ebtables.$mod --atomic-save || RETVAL=1
+			if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then
+				__EXEC_PATH__/ebtables -t $mod --atomic-file __SYSCONFIG__/ebtables.$mod -Z || RETVAL=1
+			fi
+		done
+	fi
 
 	if [ $RETVAL -eq 0 ]; then
 		success "$prog saved"
@@ -84,9 +109,11 @@
 	start
 	;;
   stop)
+	[ "$IPTABLES_SAVE_ON_STOP" = "yes" ] && save
 	stop
 	;;
   restart|reload)
+	[ "$IPTABLES_SAVE_ON_RESTART" = "yes" ] && save
 	restart
 	;;
   condrestart)
@@ -97,7 +124,7 @@
 	save
 	;;
   status)
-	/sbin/ebtables-save
+	__EXEC_PATH__/ebtables-save
 	RETVAL=$?
 	;;
   *)