1#!/bin/sh
2
3[ -x /usr/sbin/ebtables-legacy ] || exit 1
4
5EBTABLES_DUMPFILE_STEM=/etc/ebtables/dump
6
7RETVAL=0
8prog="ebtables"
9desc="Ethernet bridge filtering"
10umask 0077
11
12#default configuration
13EBTABLES_MODULES_UNLOAD="yes"
14EBTABLES_LOAD_ON_START="no"
15EBTABLES_SAVE_ON_STOP="no"
16EBTABLES_SAVE_ON_RESTART="no"
17EBTABLES_SAVE_COUNTER="no"
18EBTABLES_BACKUP_SUFFIX="~"
19
20config=/etc/default/$prog
21[ -f "$config" ] && . "$config"
22
23get_supported_tables() {
24	EBTABLES_SUPPORTED_TABLES=
25	/usr/sbin/ebtables-legacy -t filter -L 2>&1 1>/dev/null | grep -q permission
26	if [ $? -eq 0 ]; then
27		echo "Error: insufficient privileges to access the ebtables rulesets."
28		exit 1
29	fi
30	for table in filter nat broute; do
31		/usr/sbin/ebtables-legacy -t $table -L &> /dev/null
32		if [ $? -eq 0 ]; then
33			EBTABLES_SUPPORTED_TABLES="${EBTABLES_SUPPORTED_TABLES} $table"
34		fi
35	done
36}
37
38load() {
39	RETVAL=0
40	get_supported_tables
41	echo -n "Restoring ebtables rulesets: "
42	for table in $EBTABLES_SUPPORTED_TABLES; do
43		echo -n "$table "
44		if [ -s ${EBTABLES_DUMPFILE_STEM}.$table ]; then
45			/usr/sbin/ebtables-legacy -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-commit
46			RET=$?
47			if [ $RET -ne 0 ]; then
48				echo -n "(failed) "
49				RETVAL=$RET
50			fi
51		else
52			echo -n "(no saved state) "
53		fi
54	done
55	if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then
56		echo -n "no kernel support. "
57	else
58		echo -n "done. "
59	fi
60	if [ $RETVAL -eq 0 ]; then
61		echo "ok"
62	else
63		echo "fail"
64	fi
65}
66
67clear_rules() {
68	RETVAL=0
69	get_supported_tables
70	echo -n "Clearing ebtables rulesets: "
71	for table in $EBTABLES_SUPPORTED_TABLES; do
72		echo -n "$table "
73		/usr/sbin/ebtables-legacy -t $table --init-table
74	done
75
76	if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then
77		for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -d' ' -f1) ebtables; do
78			rmmod $mod 2> /dev/null
79		done
80	fi
81	if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then
82		echo -n "no kernel support. "
83	else
84		echo -n "done. "
85	fi
86	if [ $RETVAL -eq 0 ]; then
87		echo "ok"
88	else
89		echo "fail"
90	fi
91}
92
93save() {
94	RETVAL=0
95	get_supported_tables
96	echo -n "Saving ebtables rulesets: "
97	for table in $EBTABLES_SUPPORTED_TABLES; do
98		echo -n "$table "
99		[ -n "$EBTABLES_BACKUP_SUFFIX" ] && [ -s ${EBTABLES_DUMPFILE_STEM}.$table ] && \
100			mv ${EBTABLES_DUMPFILE_STEM}.$table ${EBTABLES_DUMPFILE_STEM}.$table$EBTABLES_BACKUP_SUFFIX
101		/usr/sbin/ebtables-legacy -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table --atomic-save
102		RET=$?
103		if [ $RET -ne 0 ]; then
104			echo -n "(failed) "
105			RETVAL=$RET
106		else
107			if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then
108				/usr/sbin/ebtables-legacy -t $table --atomic-file ${EBTABLES_DUMPFILE_STEM}.$table -Z
109			fi
110		fi
111	done
112	if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then
113		echo -n "no kernel support. "
114	else
115		echo -n "done. "
116	fi
117	if [ $RETVAL -eq 0 ]; then
118		echo "ok"
119	else
120		echo "fail"
121	fi
122}
123
124case "$1" in
125	start)
126		[ "$EBTABLES_LOAD_ON_START" = "yes" ] && load
127		;;
128	stop)
129		[ "$EBTABLES_SAVE_ON_STOP" = "yes" ] && save
130		clear_rules
131		;;
132	restart|reload|force-reload)
133		[ "$EBTABLES_SAVE_ON_RESTART" = "yes" ] && save
134		clear_rules
135		[ "$EBTABLES_LOAD_ON_START" = "yes" ] && load
136		;;
137	load)
138		load
139		;;
140	save)
141		save
142		;;
143	status)
144		get_supported_tables
145		if [ -z "$EBTABLES_SUPPORTED_TABLES" ]; then
146			echo "No kernel support for ebtables."
147			RETVAL=1
148		else
149			echo -n "Ebtables support available, number of installed rules: "
150			for table in $EBTABLES_SUPPORTED_TABLES; do
151				COUNT=$(( $(/usr/sbin/ebtables-legacy -t $table -L | sed -e "/^Bridge chain/! d" -e "s/^.*entries: //" -e "s/,.*$/ +/") 0 ))
152				echo -n "$table($COUNT) "
153			done
154			echo ok
155			RETVAL=0
156		fi
157		;;
158	*)
159		echo "Usage: $0 {start|stop|restart|reload|force-reload|load|save|status}" >&2
160		RETVAL=1
161esac
162
163exit $RETVAL
164