summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Gilligan <gilligan@sydney.vyatta.com>2007-12-10 17:40:27 -0800
committerBob Gilligan <gilligan@sydney.vyatta.com>2007-12-10 17:40:27 -0800
commita6d5039dd4936734b0a28d04a1e497280a342491 (patch)
tree880fc1a49a87850129c1b8be50f97646cf79cd86
downloadvyatta-cfg-firewall-a6d5039dd4936734b0a28d04a1e497280a342491.tar.gz
vyatta-cfg-firewall-a6d5039dd4936734b0a28d04a1e497280a342491.zip
Initial setup of vyatta-cfg-firewall package.
-rw-r--r--AUTHORS1
-rw-r--r--COPYING27
-rw-r--r--ChangeLog0
-rw-r--r--Makefile.am22
-rw-r--r--NEWS1
-rw-r--r--README1
-rw-r--r--configure.ac30
-rw-r--r--debian/README6
-rwxr-xr-xdebian/autogen.sh37
-rw-r--r--debian/changelog5
-rw-r--r--debian/compat1
-rw-r--r--debian/control23
-rw-r--r--debian/copyright34
-rw-r--r--debian/docs2
-rw-r--r--debian/linda1
-rw-r--r--debian/lintian2
-rwxr-xr-xdebian/rules101
-rw-r--r--debian/vyatta-cfg-firewall.postinst.in70
-rw-r--r--scripts/firewall/VyattaIpTablesAddressFilter.pm250
-rw-r--r--scripts/firewall/VyattaIpTablesRule.pm262
-rwxr-xr-xscripts/firewall/firewall.init45
-rw-r--r--scripts/firewall/firewall.tp557
-rwxr-xr-xscripts/firewall/vyatta-firewall.pl374
-rwxr-xr-xscripts/firewall/vyatta-show-firewall.pl90
-rw-r--r--templates/firewall/broadcast-ping/node.def11
-rw-r--r--templates/firewall/ip-src-route/node.def11
-rw-r--r--templates/firewall/log-martians/node.def11
-rw-r--r--templates/firewall/name/node.def4
-rw-r--r--templates/firewall/name/node.tag/description/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.def4
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/action/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/description/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/address/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/network/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/port-name/node.def10
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/port-number/node.def4
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/port-range/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/port-range/start/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/port-range/stop/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/range/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/range/start/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/destination/range/stop/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/icmp/code/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/icmp/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/icmp/type/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/log/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/protocol/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/address/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/mac-address/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/network/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/port-name/node.def10
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/port-number/node.def4
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/port-range/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/port-range/start/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/port-range/stop/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/range/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/range/start/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/source/range/stop/node.def2
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/state/established/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/state/invalid/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/state/new/node.def3
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/state/node.def1
-rw-r--r--templates/firewall/name/node.tag/rule/node.tag/state/related/node.def3
-rw-r--r--templates/firewall/node.def4
-rw-r--r--templates/firewall/receive-redirects/node.def11
-rw-r--r--templates/firewall/send-redirects/node.def11
-rw-r--r--templates/firewall/syn-cookies/node.def8
69 files changed, 2119 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ee635b2
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+eng@vyatta.com
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d033fc9
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,27 @@
+/*
+ * Package: vyatt-cfg-firewall
+ *
+ * **** License ****
+ * Version: VPL 1.0
+ *
+ * The contents of this file are subject to the Vyatta Public License
+ * Version 1.0 ("License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.vyatta.com/vpl
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This code was originally developed by Vyatta, Inc.
+ * Portions created by Vyatta are Copyright (C) "YEAR" Vyatta, Inc.
+ * All Rights Reserved.
+ *
+ * Author: eng@vyatta.com
+ * Date: 2007
+ * Description: Vyatta system-level configuration templates/scripts
+ *
+ * **** End License ****
+ *
+ */
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ChangeLog
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..a155f70
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,22 @@
+cfgdir = $(datadir)/vyatta-cfg/templates
+share_perl5dir = /opt/vyatta/share/perl5
+
+bin_SCRIPTS =
+sbin_SCRIPTS =
+sysconf_DATA =
+share_perl5_DATA =
+
+sbin_SCRIPTS += scripts/firewall/vyatta-firewall.pl
+sbin_SCRIPTS += scripts/firewall/vyatta-show-firewall.pl
+
+share_perl5_DATA += scripts/firewall/VyattaIpTablesAddressFilter.pm
+share_perl5_DATA += scripts/firewall/VyattaIpTablesRule.pm
+
+
+cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \
+ cpio -0pd
+
+install-exec-hook:
+ mkdir -p $(DESTDIR)$(cfgdir)
+ cd templates; $(cpiop) $(DESTDIR)$(cfgdir)
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..78fdaa6
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
+see http://www.vyatta.com/news/
diff --git a/README b/README
new file mode 100644
index 0000000..64b37b4
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This package has the Vyatta system-level configuration templates and scripts.
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..cf40e61
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,30 @@
+# Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.59)
+
+m4_define([VERSION_ID], [m4_esyscmd([
+ if test -f .version ; then
+ head -n 1 .version | tr -d \\n
+ else
+ echo -n 2.4
+ fi])])
+AC_INIT([vyatta-cfg-firewall], VERSION_ID, [vyatta-support@vyatta.com])
+
+test -n "$VYATTA_VERSION" || VYATTA_VERSION=$PACKAGE_VERSION
+
+AC_CONFIG_AUX_DIR([config])
+AM_INIT_AUTOMAKE([gnu no-dist-gzip dist-bzip2 subdir-objects])
+AC_PREFIX_DEFAULT([/opt/vyatta])
+
+AC_ARG_ENABLE([nostrip],
+ AC_HELP_STRING([--enable-nostrip],
+ [include -nostrip option during packaging]),
+ [NOSTRIP=-nostrip], [NOSTRIP=])
+
+AC_CONFIG_FILES(
+ [Makefile]
+ [debian/vyatta-cfg-firewall.postinst])
+
+AC_SUBST(NOSTRIP)
+
+AC_OUTPUT
+
diff --git a/debian/README b/debian/README
new file mode 100644
index 0000000..4165bbe
--- /dev/null
+++ b/debian/README
@@ -0,0 +1,6 @@
+The Debian Package vyatta-cfg-firewall
+----------------------------
+
+This package has the Vyatta firewall configuration templates and scripts.
+
+ -- Bob Gilligan <gilligan@vyatta.com>, Dec. 10, 2007
diff --git a/debian/autogen.sh b/debian/autogen.sh
new file mode 100755
index 0000000..ff125d1
--- /dev/null
+++ b/debian/autogen.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+
+if [ -d .git ] ; then
+# generate GNU/Debian format ChangeLog from git log
+
+ rm -f ChangeLog
+
+ if which git2cl >/dev/null ; then
+ git-log --pretty --numstat --summary | git2cl >> ChangeLog
+ else
+ git-log --pretty=short >> ChangeLog
+ fi
+
+# append repository reference
+
+ url=` git repo-config --get remote.origin.url`
+ test "x$url" = "x" && url=`pwd`
+
+ branch=`git-branch --no-color | sed '/^\* /!d; s/^\* //'`
+ test "x$branch" = "x" && branch=master
+
+ sha=`git log --pretty=oneline --no-color -n 1 | cut -c-8`
+ test "x$sha" = "x" && sha=00000000
+
+ echo "$url#$branch-$sha" >> ChangeLog
+
+fi
+
+rm -rf config
+rm -f aclocal.m4 config.guess config.statusconfig.sub configure INSTALL
+
+autoreconf --force --install
+
+rm -f config.sub config.guess
+ln -s /usr/share/misc/config.sub .
+ln -s /usr/share/misc/config.guess .
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..d894733
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,5 @@
+vyatta-cfg-firewall (0.1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Bob Gilligan <gilligan@vyatta.com> Mon, 10 Dec 2007 11:03:18 -0700
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..0dad8ed
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,23 @@
+Source: vyatta-cfg-firewall
+Section: contrib/net
+Priority: extra
+Maintainer: Bob Gilligan <gilligan@vyatta.com>
+Build-Depends: debhelper (>= 5), autotools-dev
+Standards-Version: 3.7.2
+
+Package: vyatta-cfg-firewall
+Architecture: all
+Depends: bash (>= 3.1),
+ sed (>= 4.1.5),
+ perl (>= 5.8.8),
+ procps (>= 1:3.2.7-3),
+ coreutils (>= 5.97-5.3),
+ vyatta-cfg, sysv-rc, ifrename, ntp, sysklogd, busybox, ssh, whois, sudo,
+ snmpd, keepalived, vyatta-bash
+Suggests: util-linux (>= 2.13-5),
+ net-tools,
+ ethtool,
+ ncurses-bin (>= 5.5-5),
+ ntpdate
+Description: Vyatta firewall configuration templates/scripts
+ Vyatta firewall configuration templates and scripts.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..335ee79
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,34 @@
+This package was debianized by Bob Gilligan <gilligan@vyatta.com> on
+Monday Dec 10, 2007
+
+It's original content from the GIT repository <http://vyatt.com/git/>
+
+Upstream Author:
+
+ <eng@vyatta.com>
+
+Copyright:
+
+ Copyright (C) 2007 Vyatta, Inc.
+ All Rights Reserved.
+
+License:
+
+ The contents of this package are subject to the Vyatta Public License
+ Version 1.0 ("License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.vyatta.com/vpl
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ This code was originally developed by Vyatta, Inc.
+ Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc.
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2007, Vyatta, Inc. and
+is licensed under the GPL, see above.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..50bd824
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,2 @@
+NEWS
+README
diff --git a/debian/linda b/debian/linda
new file mode 100644
index 0000000..0381d9d
--- /dev/null
+++ b/debian/linda
@@ -0,0 +1 @@
+Tag: file-in-opt
diff --git a/debian/lintian b/debian/lintian
new file mode 100644
index 0000000..8504a44
--- /dev/null
+++ b/debian/lintian
@@ -0,0 +1,2 @@
+vyatta-cfg-firewall: file-in-unusual-dir
+vyatta-cfg-firewall: dir-or-file-in-opt
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..018dcf9
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,101 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+PACKAGE=vyatta-cfg-firewall
+PKGDIR=$(CURDIR)/debian/$(PACKAGE)
+
+CFLAGS = -Wall -g
+
+configure = ./configure
+configure += --host=$(DEB_HOST_GNU_TYPE)
+configure += --build=$(DEB_BUILD_GNU_TYPE)
+configure += --prefix=/opt/vyatta
+configure += --mandir=\$${prefix}/share/man
+configure += --infodir=\$${prefix}/share/info
+configure += CFLAGS="$(CFLAGS)"
+configure += LDFLAGS="-Wl,-z,defs"
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+configure: configure.ac Makefile.am
+ chmod +x debian/autogen.sh
+ debian/autogen.sh
+
+config.status: configure
+ dh_testdir
+ rm -f config.cache
+ $(configure)
+
+build: build-stamp
+
+build-stamp: config.status
+ dh_testdir
+ $(MAKE)
+ touch $@
+
+clean: clean-patched
+
+# Clean everything up, including everything auto-generated
+# at build time that needs not to be kept around in the Debian diff
+clean-patched:
+ dh_testdir
+ dh_testroot
+ if test -f Makefile ; then $(MAKE) clean distclean ; fi
+ rm -f build-stamp
+ rm -f config.status config.sub config.guess config.log
+ rm -f aclocal.m4 configure Makefile.in Makefile INSTALL
+ rm -rf config
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ $(MAKE) DESTDIR=$(PKGDIR) install
+
+ install -D --mode=0644 debian/lintian $(PKGDIR)/usr/share/lintian/overrides/$(PACKAGE)
+ install -D --mode=0644 debian/linda $(PKGDIR)/usr/share/linda/overrides/$(PACKAGE)
+
+# Build architecture-independent files here.
+binary-indep: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs ChangeLog
+ dh_installdocs
+ dh_install
+ dh_installdebconf
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+# Build architecture-dependent files here.
+binary-arch: build install
+# This is an architecture independent package
+# so; we have nothing to do by default.
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/vyatta-cfg-firewall.postinst.in b/debian/vyatta-cfg-firewall.postinst.in
new file mode 100644
index 0000000..4208536
--- /dev/null
+++ b/debian/vyatta-cfg-firewall.postinst.in
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sysconfdir=@sysconfdir@
+bindir=@bindir@
+sbindir=@sbindir@
+
+# remove init of daemons that we start/stop
+for init in ntp ssh snmpd keepalived ipvsadm; do
+ update-rc.d -f ${init} remove >/dev/null
+done
+
+# create symlinks
+for bb in telnetd telnet tftp ftpget ftpput; do
+ ln -sf /bin/busybox ${sbindir}/${bb}
+done
+ln -sf ${bindir}/progress-indicator /usr/bin/progress-indicator
+
+if [ "$sysconfdir" != "/etc" ]; then
+ # remove the config files and replace with blank ones
+ for conf in motd.tail ntp.conf syslog.conf logrotate.d/messages \
+ default/ssh ssh/ssh_host_key quagga/daemons quagga/zebra.conf \
+ quagga/bgpd.conf quagga/ospfd.conf quagga/ospf6d.conf \
+ quagga/ripd.conf quagga/ripngd.conf quagga/isisd.conf \
+ snmp/snmpd.conf snmp/snmptrapd.conf keepalived/keepalived.conf \
+ ipvsadm.rules default/ipvsadm
+ do
+ [ -f /etc/$conf ] && mv -f /etc/$conf /etc/$conf.vyatta-save
+ touch /etc/$conf
+ done
+
+ # use our config files
+ for conf in motd.tail syslog.conf; do
+ cp $sysconfdir/$conf /etc/$conf
+ done
+ cp $sysconfdir/logrotate_messages /etc/logrotate.d/messages
+ cp $sysconfdir/default_ssh /etc/default/ssh
+
+ # sudoers
+ [ -f /etc/sudoers ] && cp -pf /etc/sudoers /etc/sudoers.vyatta-save
+ if ! grep -q '%quaggavty ALL=NOPASSWD: ALL' /etc/sudoers; then
+ echo -e "\n%quaggavty ALL=NOPASSWD: ALL" >> /etc/sudoers
+ fi
+ echo "Defaults env_keep+=VYATTA_*" >> /etc/sudoers
+
+ # ssh v1. remove the empty key file
+ rm /etc/ssh/ssh_host_key
+
+ # remove unnecessary files
+ rm /etc/logrotate.d/*.vyatta-save >& /dev/null
+
+ # quagga/daemons
+ sed 's/=no/=yes/' /etc/quagga/daemons.vyatta-save > /etc/quagga/daemons
+ echo "log syslog warnings" >> /etc/quagga/zebra.conf
+fi
+
+# update crontab for logrotate
+grep -v logrotate /etc/crontab>/etc/crontab.$$
+echo "*/10 * * * * /usr/sbin/logrotate /etc/logrotate.conf" >> /etc/crontab.$$
+rm /etc/crontab
+mv /etc/crontab.$$ /etc/crontab
+crontab /etc/crontab
+
+# create needed directories
+mkdir -p /etc/raddb
+mkdir -p /var/log/{user,vrrpd}
+
+touch /etc/environment
+
diff --git a/scripts/firewall/VyattaIpTablesAddressFilter.pm b/scripts/firewall/VyattaIpTablesAddressFilter.pm
new file mode 100644
index 0000000..4747e5e
--- /dev/null
+++ b/scripts/firewall/VyattaIpTablesAddressFilter.pm
@@ -0,0 +1,250 @@
+package VyattaIpTablesAddressFilter;
+
+use VyattaConfig;
+
+my %_protocolswithports = (
+ tcp => 1,
+ udp => 1,
+ 6 => 1,
+ 17 => 1,
+);
+
+my %fields = (
+ _srcdst => undef,
+ _range_start => undef,
+ _range_stop => undef,
+ _network => undef,
+ _address => undef,
+ _portname => undef,
+ _portrange_start => undef,
+ _portrange_stop => undef,
+ _portnumber => undef,
+ _protocol => undef,
+ _src_mac => undef,
+);
+
+sub new {
+ my $that = shift;
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+
+ bless $self, $class;
+ return $self;
+}
+
+sub setup {
+ my ($self, $level) = @_;
+ my $config = new VyattaConfig;
+
+ $config->setLevel("$level");
+
+ # setup needed parent nodes
+ $self->{_srcdst} = $config->returnParent("..");
+ $self->{_protocol} = $config->returnValue(".. protocol");
+
+ # setup address filter nodes
+ $self->{_range_start} = $config->returnValue("range start");
+ $self->{_range_stop} = $config->returnValue("range stop");
+ $self->{_network} = $config->returnValue("network");
+ $self->{_address} = $config->returnValue("address");
+ my @tmp = $config->returnValues("port-number");
+ $self->{_portnumber} = [ @tmp ];
+ @tmp = $config->returnValues("port-name");
+ $self->{_portname} = [ @tmp ];
+ $self->{_portrange_start} = $config->returnValue("port-range start");
+ $self->{_portrange_stop} = $config->returnValue("port-range stop");
+
+ $self->{_src_mac} = $config->returnValue("mac-address");
+
+ return 0;
+}
+
+sub setupOrig {
+ my ($self, $level) = @_;
+ my $config = new VyattaConfig;
+
+ $config->setLevel("$level");
+
+ # setup needed parent nodes
+ $self->{_srcdst} = $config->returnParent("..");
+ $self->{_protocol} = $config->returnOrigValue(".. protocol");
+
+ # setup address filter nodes
+ $self->{_range_start} = $config->returnOrigValue("range start");
+ $self->{_range_stop} = $config->returnOrigValue("range stop");
+ $self->{_network} = $config->returnOrigValue("network");
+ $self->{_address} = $config->returnOrigValue("address");
+ my @tmp = $config->returnOrigValues("port-number");
+ $self->{_portnumber} = [ @tmp ];
+ @tmp = $config->returnOrigValues("port-name");
+ $self->{_portname} = [ @tmp ];
+ $self->{_portrange_start} = $config->returnOrigValue("port-range start");
+ $self->{_portrange_stop} = $config->returnOrigValue("port-range stop");
+
+ $self->{_src_mac} = $config->returnValue("mac-address");
+
+ return 0;
+}
+
+sub print {
+ my ($self) = @_;
+
+ print "srcdst: $self->{_srcdst}\n" if defined $self->{_srcdst};
+ print "range start: $self->{_range_start}\n" if defined $self->{_range_start};
+ print "range stop: $self->{_range_stop}\n" if defined $self->{_range_stop};
+ print "network: $self->{_network}\n" if defined $self->{_network};
+ print "address: $self->{_address}\n" if defined $self->{_address};
+ print "port-name: " . (join ',', $self->{_portname}) . "\n"
+ if defined $self->{_portname};
+ print "port-range start: $self->{_portrange_start}\n" if defined $self->{_portrange_start};
+ print "port-range stop: $self->{_portrange_stop}\n" if defined $self->{_portrange_stop};
+ print "port-number: " . (join ',', $self->{_portnumber}) . "\n"
+ if defined $self->{_portnumber};
+ print "protocol: $self->{_protocol}\n" if defined $self->{_protocol};
+ print "src-mac: $self->{_src_mac}\n" if defined $self->{_src_mac};
+
+ return 0;
+}
+
+sub handle_ports {
+ my $num_ref = shift;
+ my $name_ref = shift;
+ my $pstart = shift;
+ my $pstop = shift;
+ my $can_use_port = shift;
+ my $prefix = shift;
+ my $proto = shift;
+
+ my $rule_str = "";
+ my ($ports, $prange) = (0, 0);
+ my @pnums = @{$num_ref};
+ my @pnames = @{$name_ref};
+ $ports = ($#pnums + 1) + ($#pnames + 1);
+
+ if (defined($pstart) && defined($pstop)) {
+ if ($pstop < $pstart) {
+ return (undef, "invalid port range $pstart-$pstop");
+ }
+ $ports += ($pstop - $pstart + 1);
+ $prange = ($pstop - $pstart - 1);
+ }
+ if (($ports > 0) && (!$can_use_port)) {
+ return (undef, "ports can only be specified when protocol is \"tcp\" "
+ . "or \"udp\" (currently \"$proto\")");
+ }
+ if (($ports - $prange) > 15) {
+ return (undef, "source/destination port specification only supports "
+ . "up to 15 ports (port range counts as 2)");
+ }
+ if ($ports > 1) {
+ $rule_str .= " -m multiport --${prefix}ports ";
+ my $first = 1;
+ if ($#pnums >= 0) {
+ my $pstr = join(',', @pnums);
+ $rule_str .= "$pstr";
+ $first = 0;
+ }
+ if ($#pnames >= 0) {
+ if ($first == 0) {
+ $rule_str .= ",";
+ }
+ my $pstr = join(',', @pnames);
+ $rule_str .= "$pstr";
+ $first = 0;
+ }
+ if (defined($pstart) && defined($pstop)) {
+ if ($first == 0) {
+ $rule_str .= ",";
+ }
+ if ($pstart == $pstop) {
+ $rule_str .= "$pstart";
+ } else {
+ $rule_str .= "$pstart:$pstop";
+ }
+ $first = 0;
+ }
+ } elsif ($ports > 0) {
+ $rule_str .= " --${prefix}port ";
+ if ($#pnums >= 0) {
+ $rule_str .= "$pnums[0]";
+ } elsif ($#pnames >= 0) {
+ $rule_str .= "$pnames[0]";
+ } else {
+ # no number, no name, range of 1
+ $rule_str .= "$pstart";
+ }
+ }
+ return ($rule_str, undef);
+}
+
+sub rule {
+ my ($self) = @_;
+ my $rule = "";
+ my $can_use_port = 1;
+
+ if (!defined($self->{_protocol})
+ || !defined($_protocolswithports{$self->{_protocol}})) {
+ $can_use_port = 0;
+ }
+
+ if (($self->{_srcdst} eq "source") && (defined($self->{_src_mac}))) {
+ # handle src mac
+ my $str = $self->{_src_mac};
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "-m mac --mac-source $str ";
+ }
+
+ # set the address filter parameters
+ if (defined($self->{_network})) {
+ my $str = $self->{_network};
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "--$self->{_srcdst} $str ";
+ } elsif (defined($self->{_address})) {
+ my $str = $self->{_address};
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "--$self->{_srcdst} $str ";
+ } elsif ((defined $self->{_range_start}) && (defined $self->{_range_stop})) {
+ if ("$self->{_srcdst}" eq "source") {
+ $rule .= ("-m iprange "
+ . "--src-range $self->{_range_start}-$self->{_range_stop} ");
+ }
+ elsif ("$self->{_srcdst}" eq "destination") {
+ $rule .= ("-m iprange "
+ . "--dst-range $self->{_range_start}-$self->{_range_stop} ");
+ }
+ }
+
+ my ($port_str, $port_err)
+ = handle_ports($self->{_portnumber},
+ $self->{_portname},
+ $self->{_portrange_start},
+ $self->{_portrange_stop},
+ $can_use_port,
+ ($self->{_srcdst} eq "source") ? "s" : "d",
+ $self->{_protocol});
+ return (undef, $port_err) if (!defined($port_str));
+ $rule .= $port_str;
+ return ($rule, undef);
+}
+
+sub outputXmlElem {
+ my ($name, $value, $fh) = @_;
+ print $fh " <$name>$value</$name>\n";
+}
+
+sub outputXml {
+ my ($self, $prefix, $fh) = @_;
+ outputXmlElem("${prefix}_addr", $self->{_address}, $fh);
+ outputXmlElem("${prefix}_net", $self->{_network}, $fh);
+ outputXmlElem("${prefix}_addr_start", $self->{_range_start}, $fh);
+ outputXmlElem("${prefix}_addr_stop", $self->{_range_stop}, $fh);
+ outputXmlElem("${prefix}_port_num",
+ (join ',', @{$self->{_portnumber}}), $fh);
+ outputXmlElem("${prefix}_port_name",
+ (join ',', @{$self->{_portname}}), $fh);
+ outputXmlElem("${prefix}_port_start", $self->{_portrange_start}, $fh);
+ outputXmlElem("${prefix}_port_stop", $self->{_portrange_stop}, $fh);
+}
+
diff --git a/scripts/firewall/VyattaIpTablesRule.pm b/scripts/firewall/VyattaIpTablesRule.pm
new file mode 100644
index 0000000..c2174c4
--- /dev/null
+++ b/scripts/firewall/VyattaIpTablesRule.pm
@@ -0,0 +1,262 @@
+package VyattaIpTablesRule;
+
+use VyattaConfig;
+use VyattaIpTablesAddressFilter;
+
+my $src = new VyattaIpTablesAddressFilter;
+my $dst = new VyattaIpTablesAddressFilter;
+
+my %fields = (
+ _name => undef,
+ _rule_number => undef,
+ _protocol => undef,
+ _state => {
+ _established => undef,
+ _new => undef,
+ _related => undef,
+ _invalid => undef,
+ },
+ _action => undef,
+ _log => undef,
+ _icmp_code => undef,
+ _icmp_type => undef,
+);
+
+my %dummy_rule = (
+ _rule_number => 1025,
+ _protocol => "all",
+ _state => {
+ _established => undef,
+ _new => undef,
+ _related => undef,
+ _invalid => undef,
+ },
+ _action => "DROP",
+ _log => undef,
+ _icmp_code => undef,
+ _icmp_type => undef,
+);
+
+sub new {
+ my $that = shift;
+ my $class = ref ($that) || $that;
+ my $self = {
+ %fields,
+ };
+
+ bless $self, $class;
+ return $self;
+}
+
+sub setupDummy {
+ my $self = shift;
+ %{$self} = %dummy_rule;
+ $src = new VyattaIpTablesAddressFilter;
+ $dst = new VyattaIpTablesAddressFilter;
+}
+
+sub setup {
+ my ( $self, $level ) = @_;
+ my $config = new VyattaConfig;
+
+ $config->setLevel("$level");
+
+ # for documentation sake. nodes returns an array so must transform
+ # and ".. .. .." means go up three levels in the current hierarchy
+ $self->{_name} = $config->returnParent(".. .. ..");
+ $self->{_rule_number} = $config->returnParent("..");
+
+ $self->{_protocol} = $config->returnValue("protocol");
+ $self->{_state}->{_established} = $config->returnValue("state established");
+ $self->{_state}->{_new} = $config->returnValue("state new");
+ $self->{_state}->{_related} = $config->returnValue("state related");
+ $self->{_state}->{_invalid} = $config->returnValue("state invalid");
+ $self->{_action} = $config->returnValue("action");
+ $self->{_log} = $config->returnValue("log");
+ $self->{_icmp_code} = $config->returnValue("icmp code");
+ $self->{_icmp_type} = $config->returnValue("icmp type");
+
+ # TODO: need $config->exists("$level source") in VyattaConfig.pm
+ $src->setup("$level source");
+ $dst->setup("$level destination");
+
+ return 0;
+}
+
+sub setupOrig {
+ my ( $self, $level ) = @_;
+ my $config = new VyattaConfig;
+
+ $config->setLevel("$level");
+
+ # for documentation sake. nodes returns an array so must transform
+ # and ".. .. .." means go up three levels in the current hierarchy
+ $self->{_name} = $config->returnParent(".. .. ..");
+ $self->{_rule_number} = $config->returnParent("..");
+
+ $self->{_protocol} = $config->returnOrigValue("protocol");
+ $self->{_state}->{_established}
+ = $config->returnOrigValue("state established");
+ $self->{_state}->{_new} = $config->returnOrigValue("state new");
+ $self->{_state}->{_related} = $config->returnOrigValue("state related");
+ $self->{_state}->{_invalid} = $config->returnOrigValue("state invalid");
+ $self->{_action} = $config->returnOrigValue("action");
+ $self->{_log} = $config->returnOrigValue("log");
+ $self->{_icmp_code} = $config->returnOrigValue("icmp code");
+ $self->{_icmp_type} = $config->returnOrigValue("icmp type");
+
+ # TODO: need $config->exists("$level source") in VyattaConfig.pm
+ $src->setupOrig("$level source");
+ $dst->setupOrig("$level destination");
+
+ return 0;
+}
+
+sub print {
+ my ( $self ) = @_;
+
+ print "name: $self->{_name}\n" if defined $self->{_name};
+ print "rulenum: $self->{_rule_number}\n" if defined $self->{_rule_number};
+ print "protocol: $self->{_protocol}\n" if defined $self->{_protocol};
+ print "state: $self->{_state}\n" if defined $self->{_state};
+ print "action: $self->{_action}\n" if defined $self->{_action};
+ print "log: $self->{_log}\n" if defined $self->{_log};
+ print "icmp code: $self->{_icmp_code}\n" if defined $self->{_icmp_code};
+ print "icmp type: $self->{_icmp_type}\n" if defined $self->{_icmp_type};
+
+ $src->print();
+ $dst->print();
+
+}
+
+sub is_stateful {
+ my $self = shift;
+ my @states = qw(established new related invalid);
+ foreach (@states) {
+ if (defined($self->{_state}->{"_$_"})
+ && $self->{_state}->{"_$_"} eq "enable") {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub get_state_str {
+ my $self = shift;
+ my @states = qw(established new related invalid);
+ my @add_states = ();
+ foreach (@states) {
+ if (defined($self->{_state}->{"_$_"})
+ && $self->{_state}->{"_$_"} eq "enable") {
+ push @add_states, $_;
+ }
+ }
+ if ($#add_states >= 0) {
+ my $str = join ',', @add_states;
+ return $str;
+ } else {
+ return "";
+ }
+}
+
+sub get_num_ipt_rules {
+ my $self = shift;
+ my $ipt_rules = 1;
+ if (("$self->{_log}" eq "enable") && (("$self->{_action}" eq "drop")
+ || ("$self->{_action}" eq "accept")
+ || ("$self->{_action}" eq "reject"))) {
+ $ipt_rules += 1;
+ }
+ return $ipt_rules;
+}
+
+sub rule {
+ my ( $self ) = @_;
+ my $rule = undef;
+ my $srcrule = $dstrule = undef;
+ my $err_str = undef;
+
+ # set the protocol
+ if (defined($self->{_protocol})) {
+ my $str = $self->{_protocol};
+ $str =~ s/^\!(.*)$/! $1/;
+ $rule .= "--protocol $str ";
+ }
+
+ # set the session state if protocol tcp
+ my $state_str = uc (get_state_str($self));
+ if ($state_str ne "") {
+ $rule .= "-m state --state $state_str ";
+ }
+
+ # set the icmp code and type if applicable
+ if (($self->{_protocol} eq "icmp") || ($self->{_protocol} eq "1")) {
+ if (defined $self->{_icmp_type}) {
+ $rule .= "--icmp-type $self->{_icmp_type}";
+ if (defined $self->{_icmp_code}) {
+ $rule .= "/$self->{_icmp_code}";
+ }
+ $rule .= " ";
+ } elsif (defined $self->{_icmp_code}) {
+ return ("ICMP code can only be defined if ICMP type is defined", );
+
+ }
+ } elsif (defined($self->{_icmp_type}) || defined($self->{_icmp_code})) {
+ return ("ICMP type/code can only be defined if protocol is ICMP", );
+ }
+
+ # add the source and destination rules
+ ($srcrule, $err_str) = $src->rule();
+ return ($err_str, ) if (!defined($srcrule));
+ ($dstrule, $err_str) = $dst->rule();
+ return ($err_str, ) if (!defined($dstrule));
+ $rule .= " $srcrule $dstrule ";
+
+ my $chain = $self->{_name};
+ my $rule_num = $self->{_rule_number};
+ my $rule2 = undef;
+ # set the jump target. Depends on action and log
+ if ("$self->{_log}" eq "enable") {
+ $rule2 = $rule;
+ $rule2 .= "-j LOG --log-prefix '[$chain $rule_num $self->{_action}] ' ";
+ }
+ if ("$self->{_action}" eq "drop") {
+ $rule .= "-j DROP ";
+ } elsif ("$self->{_action}" eq "accept") {
+ $rule .= "-j RETURN ";
+ } elsif ("$self->{_action}" eq "reject") {
+ $rule .= "-j REJECT ";
+ } else {
+ return ("\"action\" must be defined", );
+ }
+ if (defined($rule2)) {
+ my $tmp = $rule2;
+ $rule2 = $rule;
+ $rule = $tmp;
+ }
+ return (undef, $rule, $rule2, );
+}
+
+sub outputXmlElem {
+ my ($name, $value, $fh) = @_;
+ print $fh " <$name>$value</$name>\n";
+}
+
+sub outputXml {
+ my ($self, $fh) = @_;
+ outputXmlElem("protocol", $self->{_protocol}, $fh);
+ my $state_str = get_state_str($self);
+ if ($state_str ne "") {
+ $state_str =~ s/,/%2C/g;
+ $state_str .= "+";
+ }
+ outputXmlElem("state", $state_str, $fh);
+ outputXmlElem("action", uc($self->{_action}), $fh);
+ outputXmlElem("log", $self->{_log}, $fh);
+ outputXmlElem("icmp_type", $self->{_icmp_type}, $fh);
+ outputXmlElem("icmp_code", $self->{_icmp_code}, $fh);
+
+ $src->outputXml("src", $fh);
+ $dst->outputXml("dst", $fh);
+}
+
diff --git a/scripts/firewall/firewall.init b/scripts/firewall/firewall.init
new file mode 100755
index 0000000..b58d4d5
--- /dev/null
+++ b/scripts/firewall/firewall.init
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# source the shared functions
+. /etc/init.d/vyatta-functions
+
+ACTION=$1
+
+start() {
+ echo -n "Initializing firewall: "
+ # progress_indicator "start" $INIT_PID
+
+ OUTPUT=`/opt/vyatta/sbin/vyatta-firewall.pl --setup 2>&1`;
+ # progress_indicator "stop" $INIT_PID
+
+ echo "OK"
+}
+
+stop() {
+ echo -n "Reseting firewall: "
+ # progress_indicator "start" $INIT_PID
+ OUTPUT=`/opt/vyatta/sbin/vyatta-firewall.pl --setup 2>&1`;
+
+ # progress_indicator "stop" $INIT_PID
+ echo "OK"
+}
+
+case "$ACTION" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ *)
+ echo "usage: $0 {start|stop|restart}"
+ exit 1
+ ;;
+esac
+
+exit 0
+
diff --git a/scripts/firewall/firewall.tp b/scripts/firewall/firewall.tp
new file mode 100644
index 0000000..08d2cbe
--- /dev/null
+++ b/scripts/firewall/firewall.tp
@@ -0,0 +1,557 @@
+/*
+ * Module: firewall.tp
+ *
+ * **** License ****
+ * Version: VPL 1.0
+ *
+ * The contents of this file are subject to the Vyatta Public License
+ * Version 1.0 ("License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.vyatta.com/vpl
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This code was originally developed by Vyatta, Inc.
+ * Portions setd by Vyatta are Copyright (C) 2005, 2006, 2007 Vyatta, Inc.
+ * All Rights Reserved.
+ *
+ * Author: Michael Larson
+ * Date: 2005
+ * Description:
+ *
+ * **** End License ****
+ *
+ */
+firewall {
+ targetname: txt = "rl_firewall";
+/* disable: toggle = true;*/
+
+ log-martians: txt = "enable";
+ send-redirects: txt = "disable";
+ receive-redirects:txt = "disable";
+ ip-src-route: txt = "disable";
+ broadcast-ping: txt = "disable";
+ syn-cookies: txt = "enable";
+
+ name @: txt {
+ description: txt;
+ rule @: u32 {
+ protocol: txt = "all";
+ icmp {
+ type: txt;
+ code: txt;
+ }
+
+ state {
+ established: txt;
+ new: txt;
+ related: txt;
+ invalid: txt;
+ }
+
+ action: txt;
+ log: txt = "disable";
+
+ source {
+ address: ipv4;
+ network: ipv4net;
+ range {
+ start: ipv4;
+ stop: ipv4;
+ }
+
+ port-number: u32;
+ port-name: txt;
+ port-range {
+ start: u32;
+ stop: u32;
+ }
+
+ }
+ destination {
+ address: ipv4;
+ network: ipv4net;
+ range {
+ start: ipv4;
+ stop: ipv4;
+ }
+
+ port-number: u32;
+ port-name: txt;
+ port-range {
+ start: u32;
+ stop: u32;
+ }
+ }
+ }
+ }
+}
+
+interfaces {
+ ethernet @: txt {
+ firewall {
+
+ in {
+ name: txt;
+ }
+ out {
+ name: txt;
+ }
+ local {
+ name: txt;
+ }
+ }
+
+ vif @: txt {
+ firewall {
+ in {
+ name: txt;
+ }
+ out {
+ name: txt;
+ }
+ local {
+ name: txt;
+ }
+ }
+ }
+ }
+}
+
+firewall {
+ %help: short "Firewall configuration";
+ %modinfo: provides firewall;
+
+ %modinfo: path "libexec/xorp/xorp_rl_firewall";
+ %modinfo: default_targetname "rl_firewall";
+ %modinfo: start_commit program "/opt/vyatta/sbin/xorp_tmpl_tool cleanup";
+ %modinfo: end_commit program "/opt/vyatta/sbin/xorp_tmpl_tool commit";
+ %modinfo: status_method xrl "$(firewall.targetname)/common/0.1/get_status->status:u32&reason:txt";
+ /*
+ %modinfo: shutdown_method xrl "$(firewall.targetname)/rl_firewall/0.1/shutdown_firewall";
+ */
+ %modinfo: shutdown_method program "/opt/vyatta/sbin/xorp_tmpl_tool cleanup && /opt/vyatta/sbin/xorp_tmpl_tool delete firewall && /opt/vyatta/sbin/xorp_tmpl_tool commit && /opt/vyatta/sbin/xorp_tmpl_tool rtrmgr_indirect_cleanup";
+
+ /*
+ %delete: xrl "$(firewall.targetname)/rl_firewall/0.1/delete_rl_firewall";
+ */
+ %delete: ;
+
+ targetname {
+ %user-hidden: "XRL target name";
+ %help: short "Set the target name";
+ }
+
+ log-martians {
+ %help: short "Configure log martians";
+ %allow: $(@) "enable" %help: "Enable log martians";
+ %allow: $(@) "disable" %help: "Disable log martians";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall log-martians $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall log-martians";
+ }
+
+ send-redirects {
+ %help: short "Configure send redirects";
+ %allow: $(@) "enable" %help: "Enable send redirects";
+ %allow: $(@) "disable" %help: "Disable send redirects";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall send-redirects $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall send-redirects";
+ }
+
+ receive-redirects {
+ %help: short "Configure receive redirects";
+ %allow: $(@) "enable" %help: "Enable receive redirects";
+ %allow: $(@) "disable" %help: "Disable receive redirects";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall receive-redirects $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall receive-redirects";
+ }
+
+ ip-src-route {
+ %help: short "Configure IP source route";
+ %allow: $(@) "enable" %help: "Enable IP source route";
+ %allow: $(@) "disable" %help: "Disable IP source route";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall ip-src-route $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall ip-src-route";
+ }
+
+ broadcast-ping {
+ %help: short "Configure broadcast ping";
+ %allow: $(@) "enable" %help: "Enable broadcast ping";
+ %allow: $(@) "disable" %help: "Disable broadcast ping";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall broadcast-ping $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall broadcast-ping";
+ }
+
+ syn-cookies {
+ %help: short "Configure SYN cookies";
+ %allow: $(@) "enable" %help: "Enable SYN cookies";
+ %allow: $(@) "disable" %help: "Disable SYN cookies";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall syn-cookies $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall syn-cookies";
+ }
+ name @: txt {
+ %help: short "Configure firewall rule set name";
+
+ %create: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name '$(@)'";
+ %update: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name '$(@)'";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name '$(@)'";
+
+ description {
+ %help: short "Firewall description";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) description '$(@)'";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) description";
+
+ }
+
+ rule @: u32 {
+ %help: short "Firewall rule number in range from 1 to 1024";
+ %order: sorted-numeric;
+ %allow-range: $(@) "1" "1024" %help: "Firewall rule number";
+
+ %create: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(@)";
+ %update: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(@)";
+
+ protocol {
+ %help: short "Configure Protocol";
+ %allow: $(@) "all" %help: "";
+ %allow: $(@) "tcp" %help: "";
+ %allow: $(@) "udp" %help: "";
+ %allow: $(@) "icmp" %help: "";
+ %allow: $(@) "igmp" %help: "";
+ %allow: $(@) "ipencap" %help: "";
+ %allow: $(@) "gre" %help: "";
+ %allow: $(@) "esp" %help: "";
+ %allow: $(@) "ah" %help: "";
+ %allow: $(@) "ospf" %help: "";
+ %allow: $(@) "pim" %help: "";
+ %allow: $(@) "vrrp" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) protocol $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) protocol";
+ }
+
+ icmp {
+ %help: short "ICMP type and code settings";
+ %mandatory: $(@.type);
+
+ type {
+ %help: short "ICMP type";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) icmp type $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) icmp type";
+ }
+
+ code {
+ %help: short "ICMP code";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) icmp code $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) icmp code";
+ }
+ }
+
+ state {
+ %help: short "Rule state";
+
+ established {
+ %help: short "Configure established state";
+ %allow: $(@) "enable" %help: "Enable established state";
+ %allow: $(@) "disable" %help: "Disable established state";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) state established $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) state established";
+ }
+
+ new {
+ %help: short "Configure new state";
+ %allow: $(@) "enable" %help: "Enable new state";
+ %allow: $(@) "disable" %help: "Disable new state";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) state new $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) state new";
+ }
+
+ related {
+ %help: short "Configure related state";
+ %allow: $(@) "enable" %help: "Enable related state";
+ %allow: $(@) "disable" %help: "Disable related state";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) state related $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) state related";
+ }
+
+ invalid {
+ %help: short "Configure invalid state";
+ %allow: $(@) "enable" %help: "Enable invalid state";
+ %allow: $(@) "disable" %help: "Disable invalid state";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) state invalid $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) state invalid";
+ }
+ }
+
+ action {
+ %help: short "Configure rule action";
+ %allow: $(@) "accept" %help: "Accept packet";
+ %allow: $(@) "drop" %help: "Silently drop packet";
+ %allow: $(@) "reject" %help: "Reject packet with TCP reset";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) action $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) action";
+ }
+
+ log {
+ %help: short "Configure firewall logging";
+ %allow: $(@) "enable" %help: "Enable firewall logging";
+ %allow: $(@) "disable" %help: "Disable firewall logging";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) log $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) log";
+ }
+
+ source {
+ %help: short "Firewall source parameters";
+
+ address {
+ %help: short "Source address";
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source address $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source address";
+ }
+
+ network {
+ %help: short "Source network";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source network $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source network";
+ }
+ range {
+ %mandatory: $(@.start);
+ %mandatory: $(@.stop);
+ %help: short "Source range start and stop";
+
+ start {
+ %help: short "Source range start";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source range start $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source range start";
+ }
+ stop {
+ %help: short "Source range stop";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source range stop $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source range stop";
+ }
+ }
+
+ port-number {
+ %help: short "Source port number";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source port-number $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source port-number";
+ }
+
+ port-name {
+ %help: short "Source port name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source port-name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source port-name";
+ }
+
+ port-range {
+ %help: short "Source port range start and stop";
+ %mandatory: $(@.start);
+ %mandatory: $(@.stop);
+
+ start {
+ %help: short "Source port range start";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source port-range start $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source port-range start";
+
+ }
+ stop {
+ %help: short "Source port range stop";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) source port-range stop $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) source port-range stop";
+ }
+ }
+ }
+ destination {
+ %help: short "Firewall destination parameters";
+
+ address {
+ %help: short "Destination address";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination address $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination address";
+ }
+
+ network {
+ %help: short "Destination network";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination network $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination network";
+ }
+
+ range {
+ %help: short "Destination range start and stop";
+ %mandatory: $(@.start);
+ %mandatory: $(@.stop);
+
+ start {
+ %help: short "Destination range start";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination range start $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination range start";
+ }
+
+ stop {
+ %help: short "Destination range stop";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination range stop $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination range stop";
+ }
+ }
+
+ port-number {
+ %help: short "Destination port number";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination port-number $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination port-number";
+ }
+
+ port-name {
+ %help: short "Destination port name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination port-name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination port-name";
+ }
+
+ port-range {
+ %help: short "Port range start and stop";
+ %mandatory: $(@.start);
+ %mandatory: $(@.stop);
+
+ start {
+ %help: short "Destination port range start";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination port-range start $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination port-range start";
+ }
+ stop {
+ %help: short "Destination port range stop";
+ %allow-range: $(@) "1" "65535" %help: "";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set firewall name $(name.@) rule $(rule.@) destination port-range stop $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete firewall name $(name.@) rule $(rule.@) destination port-range stop";
+ }
+ }
+ }
+ }
+ }
+}
+
+interfaces {
+ ethernet @: txt {
+ firewall {
+ %help: short "Configure firewall options";
+
+ in {
+ %mandatory: $(@.name);
+ %help: short "Filter forwarded packets on inbound interface";
+
+ name {
+ %help: short "Inbound interface filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) firewall in name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) firewall in name";
+ }
+
+ }
+
+ out {
+ %mandatory: $(@.name);
+ %help: short "Filter forwarded packets on outbound interface";
+
+ name {
+ %help: short "Outbound interface filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) firewall out name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) firewall out name";
+ }
+
+ }
+
+ local {
+ %mandatory: $(@.name);
+ %help: short "Filter packets destined for this router";
+
+ name {
+ %help: short "Local filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) firewall local name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) firewall local name";
+ }
+
+ }
+ }
+
+ vif @: txt {
+ firewall {
+ %help: short "Configure firewall options";
+
+ in {
+ %mandatory: $(@.name);
+ %help: short "Filter forwarded packets on inbound interface";
+
+ name {
+ %help: short "Inbound interface filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) vif $(vif.@) firewall in name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) vif $(vif.@) firewall in name";
+ }
+ }
+
+ out {
+ %mandatory: $(@.name);
+ %help: short "Filter forwarded packets on outbound interface";
+
+ name {
+ %help: short "Outbound interface filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) vif $(vif.@) firewall out name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) vif $(vif.@) firewall out name";
+ }
+ }
+
+ local {
+ %mandatory: $(@.name);
+ %help: short "Filter packets destined for this router";
+
+ name {
+ %help: short "Local filter name";
+
+ %set: program "/opt/vyatta/sbin/xorp_tmpl_tool set interfaces ethernet $(ethernet.@) vif $(vif.@) firewall local name $(@)";
+ %delete: program "/opt/vyatta/sbin/xorp_tmpl_tool delete interfaces ethernet $(ethernet.@) vif $(vif.@) firewall local name";
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/scripts/firewall/vyatta-firewall.pl b/scripts/firewall/vyatta-firewall.pl
new file mode 100755
index 0000000..93cbd09
--- /dev/null
+++ b/scripts/firewall/vyatta-firewall.pl
@@ -0,0 +1,374 @@
+#!/usr/bin/perl
+
+use lib "/opt/vyatta/share/perl5/";
+use VyattaConfig;
+use VyattaIpTablesRule;
+use VyattaIpTablesAddressFilter;
+use Getopt::Long;
+
+my @updateints = ();
+GetOptions("setup" => \$setup,
+ "teardown" => \$teardown,
+ "update-rules" => \$updaterules,
+ "update-interfaces=s{4}" => \@updateints,
+);
+
+if (defined $setup) {
+ setup_iptables();
+ exit 0;
+}
+
+if (defined $updaterules) {
+ update_rules();
+ exit 0;
+}
+
+if ($#updateints == 3) {
+ update_ints(@updateints);
+ exit 0;
+}
+
+if (defined $teardown) {
+ teardown_iptables();
+ exit 0;
+}
+
+help();
+exit 1;
+
+sub help() {
+ print "usage: vyatta-firewall.pl\n";
+ print "\t--setup setup Vyatta specific iptables settings\n";
+ print "\t--update-rules update iptables with the current firewall rules\n";
+ print "\t--update-interfaces update the rules applpied to interfaces\n";
+ print "\t (<action> <interface> <direction> <chain name>)\n";
+ print "\t--teardown teardown all user rules and iptables settings\n";
+ print "\n";
+}
+
+sub update_rules() {
+ my $config = new VyattaConfig;
+ my $name = undef;
+ my %nodes = ();
+
+ $config->setLevel("firewall name");
+
+ %nodes = $config->listNodeStatus();
+ if ((scalar (keys %nodes)) == 0) {
+ # no names. teardown the user chains and return.
+ teardown_iptables();
+ return;
+ }
+
+ # by default, nothing needs to be tracked.
+ my $stateful = 0;
+
+ for $name (keys %nodes) {
+ if ($nodes{$name} eq "static") {
+ # not changed. check if stateful.
+ $config->setLevel("firewall name $name rule");
+ my @rules = $config->listOrigNodes();
+ foreach (sort numerically @rules) {
+ my $node = new VyattaIpTablesRule;
+ $node->setupOrig("firewall name $name rule $_");
+ if ($node->is_stateful()) {
+ $stateful = 1;
+ last;
+ }
+ }
+ next;
+ } elsif ($nodes{$name} eq "added") {
+ # create the chain
+ print "creating chain $name\n";
+ setup_chain("$name");
+ # handle the rules below.
+ } elsif ($nodes{$name} eq "deleted") {
+ # delete the chain
+ print "deleting chain $name\n";
+ delete_chain("$name");
+ next;
+ } elsif ($nodes{$name} eq "changed") {
+ # handle the rules below.
+ }
+
+ print "firewall name $name\n";
+ #print "-----------------------------------------------\n";
+
+ # set our config level to rule and get the rule numbers
+ $config->setLevel("firewall name $name rule");
+
+ # Let's find the status of the rule nodes
+ my %rulehash = ();
+ %rulehash = $config->listNodeStatus();
+ if ((scalar (keys %rulehash)) == 0) {
+ # no rules. flush the user rules.
+ # note that this clears the counters on the default DROP rule.
+ # we could delete rule one by one if those are important.
+ system("iptables -F $name");
+ system("iptables -A $name -j DROP");
+ next;
+ }
+
+ my $iptablesrule = 1;
+ foreach $rule (sort numerically keys %rulehash) {
+ #print "rule: $rule\t\t$rulehash{$rule}\n";
+
+ if ("$rulehash{$rule}" eq "static") {
+ my $node = new VyattaIpTablesRule;
+ $node->setupOrig("firewall name $name rule $rule");
+ if ($node->is_stateful()) {
+ $stateful = 1;
+ }
+ my $ipt_rules = $node->get_num_ipt_rules();
+ $iptablesrule += $ipt_rules;
+ } elsif ("$rulehash{$rule}" eq "added") {
+ # create a new iptables object of the current rule
+ my $node = new VyattaIpTablesRule;
+ $node->setup("firewall name $name rule $rule");
+ if ($node->is_stateful()) {
+ $stateful = 1;
+ }
+
+ #print "node print:\n";
+ #$node->print();
+ my ($err_str, @rule_strs) = $node->rule();
+ if (defined($err_str)) {
+ print STDERR "Firewall config error: $err_str\n";
+ exit 1;
+ }
+ foreach (@rule_strs) {
+ if (!defined) {
+ last;
+ }
+ print "iptables --insert $name $iptablesrule $_\n";
+ system ("iptables --insert $name $iptablesrule $_") == 0
+ || die "iptables error: $? - $_\n";
+ $iptablesrule++;
+ }
+ } elsif ("$rulehash{$rule}" eq "changed") {
+ # create a new iptables object of the current rule
+ my $oldnode = new VyattaIpTablesRule;
+ $oldnode->setupOrig("firewall name $name rule $rule");
+ my $node = new VyattaIpTablesRule;
+ $node->setup("firewall name $name rule $rule");
+ if ($node->is_stateful()) {
+ $stateful = 1;
+ }
+
+ my ($err_str, @rule_strs) = $node->rule();
+ if (defined($err_str)) {
+ print STDERR "Firewall config error: $err_str\n";
+ exit 1;
+ }
+
+ my $ipt_rules = $oldnode->get_num_ipt_rules();
+ for (1 .. $ipt_rules) {
+ print "iptables --delete $name $iptablesrule\n";
+ system ("iptables --delete $name $iptablesrule") == 0
+ || die "iptables error: $? - $rule\n";
+ }
+
+ foreach (@rule_strs) {
+ if (!defined) {
+ last;
+ }
+ print "iptables --insert $name $iptablesrule $_\n";
+ system ("iptables --insert $name $iptablesrule $_") == 0
+ || die "iptables error: $? - $rule_str\n";
+ $iptablesrule++;
+ }
+ } elsif ("$rulehash{$rule}" eq "deleted") {
+ my $node = new VyattaIpTablesRule;
+ $node->setupOrig("firewall name $name rule $rule");
+
+ my $ipt_rules = $node->get_num_ipt_rules();
+ for (1 .. $ipt_rules) {
+ print "iptables --delete $name $iptablesrule\n";
+ system ("iptables --delete $name $iptablesrule") == 0
+ || die "iptables error: $? - $rule\n";
+ }
+ }
+ }
+ }
+ if ($stateful) {
+ enable_fw_conntrack();
+ } else {
+ disable_fw_conntrack();
+ }
+}
+
+sub chain_configured($) {
+ my $chain = shift;
+
+ my $config = new VyattaConfig;
+ my %chains = ();
+ $config->setLevel("firewall name");
+ %chains = $config->listNodeStatus();
+
+ if (grep(/^$chain$/, (keys %chains))) {
+ if ($chains{$chain} ne "deleted") {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub update_ints() {
+ my ($action, $int_name, $direction, $chain) = @_;
+ my $interface = undef;
+
+ if (! defined $action || ! defined $int_name || ! defined $direction || ! defined $chain) {
+ return -1;
+ }
+
+ if ($action eq "update") {
+ # make sure chain exists
+ setup_chain($chain);
+ }
+
+ $_ = $direction;
+ my $dir_str = $direction;
+
+ CASE: {
+ /^in/ && do {
+ $direction = "FORWARD";
+ $interface = "--in-interface $int_name";
+ last CASE;
+ };
+
+ /^out/ && do {
+ $direction = "FORWARD";
+ $interface = "--out-interface $int_name";
+ last CASE;
+ };
+
+ /^local/ && do {
+ $direction = "INPUT";
+ $interface = "--in-interface $int_name";
+ last CASE;
+ };
+ }
+
+ my $grep = "| grep $int_name";
+ my $line = `iptables -L $direction -n -v --line-numbers | egrep ^[0-9] $grep`;
+ my ($num, $ignore, $ignore, $oldchain, $ignore, $ignore, $in, $out, $ignore, $ignore) = split /\s+/, $line;
+
+ if ("$action" eq "update") {
+ if (($num =~ /.+/) && (($dir_str eq "in" && $in eq $int_name)
+ || ($dir_str eq "out" && $out eq $int_name)
+ || ($dir_str eq "local"))) {
+ $action = "replace";
+ $rule = "--replace $direction $num $interface --jump $chain";
+ } else {
+ $rule = "--append $direction $interface --jump $chain";
+ }
+ }
+ else {
+ $rule = "--$action $direction $num";
+ }
+
+ print "iptables $rule\n";
+ $ret = system("iptables $rule");
+ if ($ret >> 8) {
+ exit 1;
+ }
+ if ($action eq "replace" || $action eq "delete") {
+ if (!chain_configured($oldchain)) {
+ if (!chain_referenced($oldchain)) {
+ delete_chain($oldchain);
+ }
+ }
+ }
+ return 0;
+}
+
+sub enable_fw_conntrack {
+ # potentially we can add rules in the FW_CONNTRACK chain to provide
+ # finer-grained control over which packets are tracked.
+ system("iptables -t raw -R FW_CONNTRACK 1 -j ACCEPT");
+}
+
+sub disable_fw_conntrack {
+ system("iptables -t raw -R FW_CONNTRACK 1 -j RETURN");
+}
+
+sub teardown_iptables() {
+ my @chains = `iptables -L -n`;
+ my $chain;
+
+ # $chain is going to look like this...
+ # Chain inbound (0 references)
+ foreach $chain (@chains) {
+ # chains start with Chain
+ if ($chain =~ s/^Chain//) {
+ # all we need to do is make sure this is a user chain
+ # by looking at the references keyword and then
+ if ($chain =~ /references/) {
+ ($chain) = split /\(/, $chain;
+ $chain =~ s/\s//g;
+ delete_chain("$chain");
+ }
+ }
+ }
+
+ # remove the conntrack setup.
+ my @lines
+ = `iptables -t raw -L PREROUTING -vn --line-numbers | egrep ^[0-9]`;
+ foreach (@lines) {
+ my ($num, $ignore, $ignore, $chain, $ignore, $ignore, $in, $out,
+ $ignore, $ignore) = split /\s+/;
+ if ($chain eq "FW_CONNTRACK") {
+ system("iptables -t raw -D PREROUTING $num");
+ system("iptables -t raw -D OUTPUT $num");
+ system("iptables -t raw -F FW_CONNTRACK");
+ system("iptables -t raw -X FW_CONNTRACK");
+ last;
+ }
+ }
+}
+
+sub setup_iptables() {
+ teardown_iptables();
+ # by default, nothing is tracked (the last rule in raw/PREROUTING).
+ system("iptables -t raw -N FW_CONNTRACK");
+ system("iptables -t raw -A FW_CONNTRACK -j RETURN");
+ system("iptables -t raw -I PREROUTING 1 -j FW_CONNTRACK");
+ system("iptables -t raw -I OUTPUT 1 -j FW_CONNTRACK");
+ return 0;
+}
+
+sub setup_chain($) {
+ my $chain = shift;
+ my $configured = `iptables -n -L $chain 2>&1 | head -1`;
+
+ $_ = $configured;
+ if (!/^Chain $chain/) {
+ system("iptables --new-chain $chain") == 0 || die "iptables error: $chain --new-chain: $?\n";
+ system("iptables -A $chain -j DROP");
+ }
+}
+
+sub chain_referenced($) {
+ my $chain = shift;
+ my $line = `iptables -n -L $chain |head -n1`;
+ if ($line =~ m/^Chain $chain \((\d+) references\)$/) {
+ if ($1 > 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub delete_chain($) {
+ my $chain = shift;
+ my $configured = `iptables -n -L $chain 2>&1 | head -1`;
+
+ if ($configured =~ /^Chain $chain/) {
+ system("iptables --flush $chain") == 0 || die "iptables error: $chain --flush: $?\n";
+ if (!chain_referenced($chain)) {
+ system("iptables --delete-chain $chain") == 0 || die "iptables error: $chain --delete-chain: $?\n";
+ }
+ }
+}
+
+sub numerically { $a <=> $b; }
diff --git a/scripts/firewall/vyatta-show-firewall.pl b/scripts/firewall/vyatta-show-firewall.pl
new file mode 100755
index 0000000..241a03a
--- /dev/null
+++ b/scripts/firewall/vyatta-show-firewall.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+use lib "/opt/vyatta/share/perl5/";
+use VyattaConfig;
+use VyattaIpTablesRule;
+use VyattaIpTablesAddressFilter;
+
+exit 1 if ($#ARGV < 1);
+my $chain_name = $ARGV[0];
+my $xsl_file = $ARGV[1];
+my $rule_num = $ARGV[2]; # rule number to match (optional)
+
+sub numerically { $a <=> $b; }
+
+sub show_chain {
+ my $chain = shift;
+ my $fh = shift;
+
+ open(STATS, "iptables -L $chain -vn |") or exit 1;
+ my @stats = ();
+ while (<STATS>) {
+ if (!/^\s*(\d+[KMG]?)\s+(\d+[KMG]?)\s/) {
+ next;
+ }
+ push @stats, ($1, $2);
+ }
+ close STATS;
+
+ print $fh "<opcommand name='firewallrules'><format type='row'>\n";
+ my $config = new VyattaConfig;
+ $config->setLevel("firewall name $chain rule");
+ my @rules = sort numerically $config->listOrigNodes();
+ foreach (@rules) {
+ # just take the stats from the 1st iptables rule and remove unneeded stats
+ # (if this rule corresponds to multiple iptables rules). note that
+ # depending on how our rule is translated into multiple iptables rules,
+ # this may actually need to be the sum of all corresponding iptables stats
+ # instead of just taking the first pair.
+ my $pkts = shift @stats;
+ my $bytes = shift @stats;
+ my $rule = new VyattaIpTablesRule;
+ $rule->setupOrig("firewall name $chain rule $_");
+ my $ipt_rules = $rule->get_num_ipt_rules();
+ splice(@stats, 0, (($ipt_rules - 1) * 2));
+
+ if (defined($rule_num) && $rule_num != $_) {
+ next;
+ }
+ print $fh " <row>\n";
+ print $fh " <rule_number>$_</rule_number>\n";
+ print $fh " <pkts>$pkts</pkts>\n";
+ print $fh " <bytes>$bytes</bytes>\n";
+ $rule->outputXml($fh);
+ print $fh " </row>\n";
+ }
+ if (!defined($rule_num)) {
+ # dummy rule
+ print $fh " <row>\n";
+ print $fh " <rule_number>1025</rule_number>\n";
+ my $pkts = shift @stats;
+ my $bytes = shift @stats;
+ print $fh " <pkts>$pkts</pkts>\n";
+ print $fh " <bytes>$bytes</bytes>\n";
+ my $rule = new VyattaIpTablesRule;
+ $rule->setupDummy();
+ $rule->outputXml($fh);
+ print $fh " </row>\n";
+ }
+ print $fh "</format></opcommand>\n";
+}
+
+if ($chain_name eq "-all") {
+ my $config = new VyattaConfig;
+ $config->setLevel("firewall name");
+ my @chains = $config->listOrigNodes();
+ foreach (@chains) {
+ print "Firewall \"$_\":\n";
+ open(RENDER, "| /opt/vyatta/libexec/xorp/render_xml $xsl_file") or exit 1;
+ show_chain($_, *RENDER{IO});
+ close RENDER;
+ print "-" x 80 . "\n";
+ }
+} else {
+ open(RENDER, "| /opt/vyatta/libexec/xorp/render_xml $xsl_file") or exit 1;
+ show_chain($chain_name, *RENDER{IO});
+ close RENDER;
+}
+
+exit 0;
+
diff --git a/templates/firewall/broadcast-ping/node.def b/templates/firewall/broadcast-ping/node.def
new file mode 100644
index 0000000..f49831c
--- /dev/null
+++ b/templates/firewall/broadcast-ping/node.def
@@ -0,0 +1,11 @@
+type: txt
+help: "ignore all ICMP ECHO and TIMESTAMP requests sent via broadcast/multicast"
+default: "disable"
+syntax: $(@) in "enable", "disable"; "broadcast-ping must be enable or disable"
+create: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts; \
+ else echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts; fi"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts; \
+ else echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts; fi"
+delete: "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts"
diff --git a/templates/firewall/ip-src-route/node.def b/templates/firewall/ip-src-route/node.def
new file mode 100644
index 0000000..eb8bc0a
--- /dev/null
+++ b/templates/firewall/ip-src-route/node.def
@@ -0,0 +1,11 @@
+type: txt
+help: "Accept packets with SRR option"
+default: "disable"
+syntax: $(@) in "enable", "disable"; "ip-src-route must be enable or disable"
+create: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/accept_source_route; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route; fi"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/accept_source_route; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route; fi"
+delete: "echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route"
diff --git a/templates/firewall/log-martians/node.def b/templates/firewall/log-martians/node.def
new file mode 100644
index 0000000..928a23a
--- /dev/null
+++ b/templates/firewall/log-martians/node.def
@@ -0,0 +1,11 @@
+type: txt
+help: "Allow syslog logging of packets with impossible addresses"
+default: "enable"
+syntax: $(@) in "enable", "disable"; "log-martians must be enable or disable"
+create: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/log_martians; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/log_martians; fi"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/log_martians; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/log_martians; fi"
+delete: "echo 1 > /proc/sys/net/ipv4/conf/all/log_martians"
diff --git a/templates/firewall/name/node.def b/templates/firewall/name/node.def
new file mode 100644
index 0000000..5591c1f
--- /dev/null
+++ b/templates/firewall/name/node.def
@@ -0,0 +1,4 @@
+tag:
+type: txt
+syntax: pattern $(@) "^[^-]" ; "Firewall rule set name cannot start with \"-\""
+help: "Configure firewall rule set name"
diff --git a/templates/firewall/name/node.tag/description/node.def b/templates/firewall/name/node.tag/description/node.def
new file mode 100644
index 0000000..3df7bc0
--- /dev/null
+++ b/templates/firewall/name/node.tag/description/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Configure firewall description"
diff --git a/templates/firewall/name/node.tag/rule/node.def b/templates/firewall/name/node.tag/rule/node.def
new file mode 100644
index 0000000..b7a1c0c
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.def
@@ -0,0 +1,4 @@
+tag:
+type: u32
+help: "Configure firewall rule number from 1 to 1024"
+syntax: $(@) > 0 && $(@) < 1025; "firewall rule number must be between 1 and 1024"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/action/node.def b/templates/firewall/name/node.tag/rule/node.tag/action/node.def
new file mode 100644
index 0000000..c8ea6c5
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/action/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure firewall rule action"
+syntax: $(@) in "drop", "reject", "accept"; "action must be one of drop, reject, or accept"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/description/node.def b/templates/firewall/name/node.tag/rule/node.tag/description/node.def
new file mode 100644
index 0000000..3648c8a
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/description/node.def
@@ -0,0 +1,2 @@
+type: txt
+help: "Configure rule description"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/address/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/address/node.def
new file mode 100644
index 0000000..89546fa
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/address/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure firewall destination address"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl ipv4_negate '$(@)'" ; "invalid destination address \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/network/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/network/node.def
new file mode 100644
index 0000000..dfc93f9
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/network/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure firewall destination network"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl ipv4net_negate '$(@)'" ; "invalid destination network \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/node.def
new file mode 100644
index 0000000..8b12941
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/node.def
@@ -0,0 +1 @@
+help: "Configure firewall destination parameters"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/port-name/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/port-name/node.def
new file mode 100644
index 0000000..89c7ee9
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/port-name/node.def
@@ -0,0 +1,10 @@
+multi:
+type: txt
+help: "Configure destination port name"
+syntax: exec "sh -c 'if grep -q '\\''^$(@)[ \t]'\\'' /etc/services; \
+then exit 0; else \
+ if grep -q \
+ '\\''^[^ \t]\\+[ \t]\\+[^ \t]\\+[^#]*[ \t]$(@)\\([ \t]\\|\\$\\)'\\'' \
+ /etc/services; then exit 0; else exit 1; \
+ fi; \
+fi' " ; "invalid port name $(@)"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/port-number/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/port-number/node.def
new file mode 100644
index 0000000..9afe6c8
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/port-number/node.def
@@ -0,0 +1,4 @@
+multi:
+type: u32; "destination port must be between 1 and 65535"
+help: "Configure destination port number"
+syntax: $(@) > 0 && $(@) < 65536; "destination port must be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/node.def
new file mode 100644
index 0000000..2dcf2f4
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/node.def
@@ -0,0 +1 @@
+help: "Configure destination port range"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/start/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/start/node.def
new file mode 100644
index 0000000..5e8610d
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/start/node.def
@@ -0,0 +1,3 @@
+type: u32; "destination port start should be between 1 and 65535"
+help: "Configure destination port range start"
+syntax: $(@) > 0 && $(@) < 65536; "destination port start should be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/stop/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/stop/node.def
new file mode 100644
index 0000000..22c5e89
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/port-range/stop/node.def
@@ -0,0 +1,3 @@
+type: u32; "destination port stop should be between 1 and 65535"
+help: "Configure destination port range start"
+syntax: $(@) > 0 && $(@) < 65536; "destination port stop should be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/range/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/range/node.def
new file mode 100644
index 0000000..89f6456
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/range/node.def
@@ -0,0 +1 @@
+help: "Configure destination address range"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/range/start/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/range/start/node.def
new file mode 100644
index 0000000..f83ec75
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/range/start/node.def
@@ -0,0 +1,2 @@
+type: ipv4; "destination range start should be an IPv4 address"
+help: "Configure destination range start"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/destination/range/stop/node.def b/templates/firewall/name/node.tag/rule/node.tag/destination/range/stop/node.def
new file mode 100644
index 0000000..17673c2
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/destination/range/stop/node.def
@@ -0,0 +1,2 @@
+type: ipv4; "destination range stop should be an IPv4 address"
+help: "Configure destination range stop"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/icmp/code/node.def b/templates/firewall/name/node.tag/rule/node.tag/icmp/code/node.def
new file mode 100644
index 0000000..318b7b5
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/icmp/code/node.def
@@ -0,0 +1,3 @@
+type: u32; "ICMP code must be between 0 and 255"
+help: "ICMP code must be between 0 and 255"
+syntax: $(@) >=0 && $(@) <= 255; "ICMP code must be between 0 and 255"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/icmp/node.def b/templates/firewall/name/node.tag/rule/node.tag/icmp/node.def
new file mode 100644
index 0000000..db820cf
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/icmp/node.def
@@ -0,0 +1 @@
+help: "Configure rule ICMP type and code settings"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/icmp/type/node.def b/templates/firewall/name/node.tag/rule/node.tag/icmp/type/node.def
new file mode 100644
index 0000000..cb1043d
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/icmp/type/node.def
@@ -0,0 +1,3 @@
+type: u32; "ICMP type must be between 0 and 255"
+help: "ICMP type must be between 0 and 255"
+syntax: $(@) >=0 && $(@) <= 255; "ICMP type must be between 0 and 255"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/log/node.def b/templates/firewall/name/node.tag/rule/node.tag/log/node.def
new file mode 100644
index 0000000..dac6966
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/log/node.def
@@ -0,0 +1,3 @@
+type: txt; "firwall logging must be enable or disable"
+help: "Configure firewall logging"
+syntax: $(@) in "enable", "disable"; "firwall logging must be enable or disable"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/protocol/node.def b/templates/firewall/name/node.tag/rule/node.tag/protocol/node.def
new file mode 100644
index 0000000..06d0cbe
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/protocol/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure which protocol to match (this can be a protocol name in /etc/protocols, a protocol number, or \"all\")"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl protocol_negate '$(@)'" ; "invalid protocol \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/address/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/address/node.def
new file mode 100644
index 0000000..13d2813
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/address/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure firewall source address"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl ipv4_negate '$(@)'" ; "invalid source address \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/mac-address/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/mac-address/node.def
new file mode 100644
index 0000000..c72d1c7
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/mac-address/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure source MAC address"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl macaddr_negate '$(@)'" ; "invalid MAC address \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/network/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/network/node.def
new file mode 100644
index 0000000..141d325
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/network/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure firewall source network"
+syntax: exec "/opt/vyatta/sbin/vyatta-validate-type.pl ipv4net_negate '$(@)'" ; "invalid source network \"$(@)\""
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/node.def
new file mode 100644
index 0000000..c2eabc3
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/node.def
@@ -0,0 +1 @@
+help: "Configure firewall source parameters"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/port-name/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/port-name/node.def
new file mode 100644
index 0000000..b67c597
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/port-name/node.def
@@ -0,0 +1,10 @@
+multi:
+type: txt
+help: "Configure source port name"
+syntax: exec "sh -c 'if grep -q '\\''^$(@)[ \t]'\\'' /etc/services; \
+then exit 0; else \
+ if grep -q \
+ '\\''^[^ \t]\\+[ \t]\\+[^ \t]\\+[^#]*[ \t]$(@)\\([ \t]\\|\\$\\)'\\'' \
+ /etc/services; then exit 0; else exit 1; \
+ fi; \
+fi' " ; "invalid port name $(@)"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/port-number/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/port-number/node.def
new file mode 100644
index 0000000..6440da9
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/port-number/node.def
@@ -0,0 +1,4 @@
+multi:
+type: u32; "source port must be between 1 and 65535"
+help: "Configure source port number"
+syntax: $(@) > 0 && $(@) < 65536; "source port must be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/port-range/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/node.def
new file mode 100644
index 0000000..0f9e60c
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/node.def
@@ -0,0 +1 @@
+help: "Configure source port range"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/port-range/start/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/start/node.def
new file mode 100644
index 0000000..0835d4c
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/start/node.def
@@ -0,0 +1,3 @@
+type: u32; "source port start should be between 1 and 65535"
+help: "Configure source port range start"
+syntax: $(@) > 0 && $(@) < 65536; "source port start should be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/port-range/stop/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/stop/node.def
new file mode 100644
index 0000000..e032b60
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/port-range/stop/node.def
@@ -0,0 +1,3 @@
+type: u32; "source port stop should be between 1 and 65535"
+help: "Configure source port range start"
+syntax: $(@) > 0 && $(@) < 65536; "source port stop should be between 1 and 65535"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/range/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/range/node.def
new file mode 100644
index 0000000..b02f8cb
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/range/node.def
@@ -0,0 +1 @@
+help: "Configure source address range"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/range/start/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/range/start/node.def
new file mode 100644
index 0000000..01de6f8
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/range/start/node.def
@@ -0,0 +1,2 @@
+type: ipv4; "source range start should be an IPv4 address"
+help: "Configure source range start"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/source/range/stop/node.def b/templates/firewall/name/node.tag/rule/node.tag/source/range/stop/node.def
new file mode 100644
index 0000000..fdec72b
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/source/range/stop/node.def
@@ -0,0 +1,2 @@
+type: ipv4; "source range stop should be an IPv4 address"
+help: "Configure source range stop"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/state/established/node.def b/templates/firewall/name/node.tag/rule/node.tag/state/established/node.def
new file mode 100644
index 0000000..9fa8224
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/state/established/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure established state"
+syntax: $(@) in "enable", "disable" ; "state value must be enable or disable"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/state/invalid/node.def b/templates/firewall/name/node.tag/rule/node.tag/state/invalid/node.def
new file mode 100644
index 0000000..d944257
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/state/invalid/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure invalid state"
+syntax: $(@) in "enable", "disable" ; "state value must be enable or disable"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/state/new/node.def b/templates/firewall/name/node.tag/rule/node.tag/state/new/node.def
new file mode 100644
index 0000000..5d78f83
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/state/new/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure new state"
+syntax: $(@) in "enable", "disable" ; "state value must be enable or disable"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/state/node.def b/templates/firewall/name/node.tag/rule/node.tag/state/node.def
new file mode 100644
index 0000000..b0b50aa
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/state/node.def
@@ -0,0 +1 @@
+help: "Session state"
diff --git a/templates/firewall/name/node.tag/rule/node.tag/state/related/node.def b/templates/firewall/name/node.tag/rule/node.tag/state/related/node.def
new file mode 100644
index 0000000..7ab397a
--- /dev/null
+++ b/templates/firewall/name/node.tag/rule/node.tag/state/related/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: "Configure related state"
+syntax: $(@) in "enable", "disable" ; "state value must be enable or disable"
diff --git a/templates/firewall/node.def b/templates/firewall/node.def
new file mode 100644
index 0000000..8ffda0a
--- /dev/null
+++ b/templates/firewall/node.def
@@ -0,0 +1,4 @@
+help: "Configure firewall"
+end: "/opt/vyatta/sbin/vyatta-firewall.pl --update-rules"
+create: "/opt/vyatta/sbin/vyatta-firewall.pl --setup"
+delete: "/opt/vyatta/sbin/vyatta-firewall.pl --teardown"
diff --git a/templates/firewall/receive-redirects/node.def b/templates/firewall/receive-redirects/node.def
new file mode 100644
index 0000000..cd3504b
--- /dev/null
+++ b/templates/firewall/receive-redirects/node.def
@@ -0,0 +1,11 @@
+type: txt
+help: "accept redirects"
+default: "disable"
+syntax: $(@) in "enable", "disable"; "receive-redirects must be enable or disable"
+create: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/accept_redirects; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects; fi"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/accept_redirects; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects; fi"
+delete: "echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects"
diff --git a/templates/firewall/send-redirects/node.def b/templates/firewall/send-redirects/node.def
new file mode 100644
index 0000000..f5ecea7
--- /dev/null
+++ b/templates/firewall/send-redirects/node.def
@@ -0,0 +1,11 @@
+type: txt
+help: "send ICMP redirects"
+default: "disable"
+syntax: $(@) in "enable", "disable"; "send-redirects must be enable or disable"
+create: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/send_redirects; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects; fi"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/conf/all/send_redirects; \
+ else echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects; fi"
+delete: "echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects"
diff --git a/templates/firewall/syn-cookies/node.def b/templates/firewall/syn-cookies/node.def
new file mode 100644
index 0000000..df9f5a9
--- /dev/null
+++ b/templates/firewall/syn-cookies/node.def
@@ -0,0 +1,8 @@
+type: txt
+help: "use TCP syn cookies"
+default: "enable"
+syntax: $(@) in "enable", "disable"; "syn-cookies must be enable or disable"
+update: "if [ x$(@) == xenable ]; \
+ then echo 1 > /proc/sys/net/ipv4/tcp_syncookies; \
+ else echo 0 > /proc/sys/net/ipv4/tcp_syncookies; fi"
+delete: "echo 1 > /proc/sys/net/ipv4/tcp_syncookies"