xeno add
[firewall-squeep] / common.sh
index f4da792d9fcdb455cd923cac167b76424c6a7b36..5c2ed1a56e052dc5b53a08e20dfeb4e4099e49d0 100644 (file)
--- a/common.sh
+++ b/common.sh
@@ -5,6 +5,7 @@ set -e
 IPTABLES=$(which iptables)
 IP6TABLES=$(which ip6tables)
 IPSET=$(which ipset)
+TC=$(which tc)
 
 err(){
        echo "$@" 1>&2
@@ -18,7 +19,7 @@ die(){
 }
 
 function decommentcat(){
-       sed 's/\s*#.*$//;/^\s*$/d' "$@"
+       cat "$@" | sed 's/\s*#.*$//;/^\s*$/d'
 }
 
 function create_set(){
@@ -77,14 +78,48 @@ function insert_setmatch_rules(){
        done
 }
 
+# try to recreate sets faster than one-at-a-time by generating restore rules
+function ipset_restore_from_cidr(){
+       local vmatch
+       local set_name="$1"
+
+       for v in '' '6'
+       do
+               case "$v" in
+               6) vmatch=':';;
+               *) vmatch='\.';;
+               esac
+               # extract existing set configuration to create temporary set
+               (set -o pipefail; $IPSET save "${set_name}${v}" 2>/dev/null | grep -m 1 '^create ' | sed "s/\(create ${set_name}${v}\)/\1-tmp/") || continue
+               # populate with new data
+               decommentcat "${set_name}.cidr" "${set_name}.cidr.$(hostname -s)" 2>/dev/null | sed -n 's/\(.*'"${vmatch}"'.*\)/add '"${set_name}${v}-tmp"' \1/p' | sort -n | uniq
+       done
+}
+
 function reload_cidr_sets(){
+       local v n
+       local set_name="$1"
+
+       ipset_restore_from_cidr "${set_name}" | ipset restore
+        for v in '' 6
+        do
+                n="${set_name}${v}"
+                $IPSET swap "${n}-tmp" "${n}"
+                $IPSET destroy "${n}-tmp"
+                $IPSET list -t "${n}"
+        done
+}
+
+function _old_reload_cidr_sets(){
+       local sfx n s v
        local set_name="$1"
+       shift
 
        # init new temporary sets
        echo "updating set '${set_name}'"
 
-       create_set "${set_name}-tmp" hash:net
-       create_set "${set_name}6-tmp" hash:net family inet6
+       create_set "${set_name}-tmp" hash:net "$@"
+       create_set "${set_name}6-tmp" hash:net "$@" family inet6
 
        # populate them
        for sfx in '' .$(hostname -s)
@@ -125,13 +160,13 @@ function add_service_entry(){
 }
 
 function allow_services(){
-       local s proto port
+       local s
        for s in "$@"
        do
                case "${s}" in
                */*)    add_service_entry "${s}"
                        ;;
-               *)      for svc in $(getent services "${s}" | awk '{print $2}')
+               *)      for svc in $(egrep "^${s}\s+" /etc/services | decommentcat | awk '{print $2}')
                        do
                                add_service_entry "${svc}"
                        done