--- /etc/init.d/nftables.old 2015-09-20 07:34:28.846035519 -0400 +++ /etc/init.d/nftables 2015-09-20 14:15:49.923543499 -0400 @@ -28,37 +28,53 @@ checkconfig() { fi return 0 } getfamilies() { - local families - for l3f in ip arp ip6 bridge inet; do - if nft list tables ${l3f} > /dev/null 2>&1; then - families="${families}${l3f} " + echo "ip arp ip6 bridge inet" +} + +manualwalk() { + nft list tables | read line + if [ $(echo $line | wc -w) -lt 3 ]; then + true + fi + false +} + +deletetable() { + # family is $1 + # table name is $2 + nft flush table $1 $2 + nft list table $1 $2 | while read l; do + chain=$(echo $l | grep -o 'chain [^[:space:]]\+' | cut -d ' ' -f2) + if [ -n "${chain}" ]; then + nft flush chain $1 $2 ${chain} + nft delete chain $1 $2 ${chain} fi done - echo ${families} + nft delete table $1 $2 } clearNFT() { - local l3f line table chain + local l3f line table chain first_line - for l3f in $(getfamilies); do - nft list tables ${l3f} | while read line; do - table=$(echo ${line} | sed "s/table[ \t]*//") - nft flush table ${l3f} ${table} - nft list table ${l3f} ${table} | while read l; do - chain=$(echo $l | grep -o 'chain [^[:space:]]\+' |\ - cut -d ' ' -f2) - if [ -n "${chain}" ]; then - nft flush chain ${l3f} ${table} ${chain} - nft delete chain ${l3f} ${table} ${chain} - fi + first_line=1 + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + table=$(echo ${line} | sed "s/table[ \t]*//") + deletetable ${l3f} ${table} done - nft delete table ${l3f} ${table} done - done + else + nft list tables | while read line; do + l3f=$(echo ${line} | cut -d ' ' -f2) + table=$(echo ${line} | cut -d ' ' -f3) + deletetable ${l3f} ${table} + done + fi } addpanictable() { local l3f=$1 nft add table ${l3f} panic @@ -107,45 +123,58 @@ clear() { } list() { local l3f - for l3f in $(getfamilies); do - nft list tables ${l3f} | while read line; do - line=$(echo ${line} | sed "s/table/table ${l3f}/") + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + echo "$(nft list ${line})" + done + done + else + nft list tables | while read line; do echo "$(nft list ${line})" done - done + fi } save() { ebegin "Saving nftables state" checkpath -q -d "$(dirname "${NFTABLES_SAVE}")" checkpath -q -m 0600 -f "${NFTABLES_SAVE}" local l3f line tmp_save="${NFTABLES_SAVE}.tmp" touch "${tmp_save}" - for l3f in $(getfamilies); do - nft list tables ${l3f} | while read line; do - line=$(echo ${line} | sed "s/table/table ${l3f}/") - # The below substitution fixes an issue where nft -n output may not - # always be parsable by nft -f. For example, nft -n might print - # - # ip6 saddr ::1 ip6 daddr ::1 counter packets 0 bytes 0 accept - # - # but nft -f refuses to parse that string with error: - # - # In file included from internal:0:0-0: - # /var/lib/nftables/rules-save:1:1-2: Error: Could not process rule: - # Invalid argument - # table ip6 filter { - # ^^ + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + # The below substitution fixes an issue where nft -n output may + # not always be parsable by nft -f. For example, nft -n might + # print + # + # ip6 saddr ::1 ip6 daddr ::1 counter packets 0 bytes 0 accept + # + # but nft -f refuses to parse that string with error: + # + # In file included from internal:0:0-0: + # /var/lib/nftables/rules-save:1:1-2: Error: Could not + # process rule: Invalid argument table ip6 filter { + # ^^ + echo "$(nft ${SAVE_OPTIONS} list ${line} |\ + sed 's/\(::[0-9a-fA-F]\+\)\([^/]\)/\1\/128\2/g')" >> "${tmp_save}" + done + done + else + nft list tables | while read line; do echo "$(nft ${SAVE_OPTIONS} list ${line} |\ - sed 's/\(::[0-9a-fA-F]\+\)\([^/]\)/\1\/128\2/g')" >> "${tmp_save}" + sed 's/\(::[0-9a-fA-F]\+\)\([^/]\)/\1\/128\2/g')" >> "${tmp_save}" done - done + fi mv "${tmp_save}" "${NFTABLES_SAVE}" } panic() { checkkernel || return 1