diff options
Diffstat (limited to 'main/ipset/ipset.initd')
-rw-r--r-- | main/ipset/ipset.initd | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/main/ipset/ipset.initd b/main/ipset/ipset.initd index 6e3294c8e0..fdca0a15f4 100644 --- a/main/ipset/ipset.initd +++ b/main/ipset/ipset.initd @@ -3,22 +3,110 @@ # Copyright (C) 2012 Kaarle Ritvanen # Licensed under the terms of the GPL2 +extra_started_commands="save reload" + + +IPSET=/usr/sbin/ipset +DIR=/etc/ipset.d +STATUS=0 + +ipset() { + $IPSET $* || STATUS=1 +} + +set_files() { + (cd $DIR && ls) +} + +set_file() { + grep -v ^# $DIR/$1 +} + +set_exists() { + $IPSET save $1 &> /dev/null +} + +sets() { + $IPSET save | sed "s/^create \\([^ ]\\+\\) ${1:+$1 }.*/\\1/;ta;d;:a" +} + + depend() { before iptables ip6tables } start() { - if ls /etc/ipset.d/* &> /dev/null; then - ebegin "Loading firewall IP sets" - for f in /etc/ipset.d/*; do - /usr/sbin/ipset restore < $f - done - eend $? - fi + reload } stop() { ebegin "Flushing firewall IP sets" - /usr/sbin/ipset destroy - eend $? + + for name in $(sets list:set); do + ipset destroy $name + done + + for name in $(sets); do + ipset destroy $name + done + + eend $STATUS +} + +save() { + ebegin "Saving firewall IP sets" + + ipset save | while read cmd; do + set -- $cmd + local action=$1 + local file=$DIR/$2 + shift 2 + if [ "$action" = create ]; then + echo $* > $file + elif [ "$action" = add ]; then + echo $* >> $file + fi + done + + for name in $(set_files); do + set_exists $name || rm -f $DIR/$name + done + + eend $STATUS +} + +reload() { + ebegin "Loading firewall IP sets" + + local swap= + for name in $(set_files); do + local new=$name + if set_exists $name; then + new=_init_$name + swap="$swap $name" + fi + ipset create $new $(set_file $name | head -n 1) + done + + for name in $(set_files); do + local new=$name + set_exists _init_$name && new=_init_$name + set_file $name | tail -n +2 | while read m; do + ipset add $new $m + done + done + + for name in $swap; do + ipset swap $name _init_$name + done + + for name in $(sets list:set); do + [ -f $DIR/$name ] || ipset destroy $name + done + + for name in $(sets); do + [ -f $DIR/$name ] || ipset destroy $name + done + + eend $STATUS } |