#!/bin/bash

## iptables

iptables_chain_policy()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -P $@" || print_error "$IPTABLES -t $TABLE -P $@"
}

iptables_create_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -N $@" || print_error "$IPTABLES -t $TABLE -N $@"
}

iptables_delete_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -X $@" || print_error "$IPTABLES -t $TABLE -X $@"
}

iptables_flush_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -F $@" || print_error "$IPTABLES -t $TABLE -F $@"
}

iptables_zero_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -Z $@" || print_error "$IPTABLES -t $TABLE -Z $@"
}

iptables_rename_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -E $@" || print_error "$IPTABLES -t $TABLE -E $@"
}

iptables_list_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IPTABLES -t $TABLE -L $@" || print_error "$IPTABLES -t $TABLE -L $@"
}

iptables_push_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A"|"-I"|"-D"|"-P")
			eval "$IPTABLES -t $TABLE $@" || print_error "$IPTABLES -t $TABLE $@"
			;;
	*)
    			case ${IPTABLES_RULE_EMBEDDING:-APPEND} in
    			    APPEND)
	   			    eval "$IPTABLES -t $TABLE -A $@" || print_error "$IPTABLES -t $TABLE -A $@"
				    ;;
			    INSERT)
	    	    		    eval "$IPTABLES -t $TABLE -I $@" || print_error "$IPTABLES -t $TABLE -I $@"
				    ;;
			    *)
				    print_error "Unknown type of rule embedding $IPTABLES_RULE_EMBEDDING"
				    ;;
			esac
			;;
    esac
}

iptables_pop_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A")
		shift
		eval "$IPTABLES -t $TABLE -D $@" || print_error "$IPTABLES -t $TABLE -D $@"	    	    
		;;
	"-I")
		PRE="$2"
		case $3 in
		    [0-9]*)
			    shift 3
			    ;;
		    *)
			    shift 2
			    ;;
		esac
		eval "$IPTABLES -t $TABLE -D $PRE $@" || print_error "$IPTABLES -t $TABLE -D $PRE $@"
		;;	
	"-D")
		shift
		iptables_push_rule -t $TABLE $@
		;;
	"-P")
		continue
		;;
	*)
    		eval "$IPTABLES -t $TABLE -D $@" || print_error "$IPTABLES -t $TABLE -D $@"	    	        	
		;;
    esac
}

iptables_load_syntax()
{
    : ${1:?missing 1st arg to $FUNCNAME}
    [ ! -f "$1" ] || [ ! -s "$1" ] && 
	{
	    export IPTABLES_SYNTAX=
	    return 1
	}
    export IPTABLES_SYNTAX=$(< "$1")
}

iptables_create_sed_rules()
{
    local REPLACES=${1:?missing 1st arg to $FUNCNAME}
    local SEARCH
    local REPLACE
    local OLDIFS
    local COUNTER=0
    IPTABLES_SED_RULES=
    print_message -n -e "\nLoading iptables data"
    OLDIFS="$IFS"
    IFS=":"
    while read SEARCH REPLACE; do
        [ $COUNTER -eq 20 ] && print_progress && COUNTER=0
        IPTABLES_SED_RULES="${IPTABLES_SED_RULES}s/\(^\|[^-._]\b\)$SEARCH\(\b[^-._]\|$\)/\1$REPLACE\2/g;"
        COUNTER=$(( COUNTER+1 ))
    done < <(echo "$REPLACES"|egrep "^[^#]"|sed -e 's,/,\\\\/,g')
    IFS="$OLDIFS"
    export IPTABLES_SED_RULES
    print_message
}

iptables_expand_string()
{
    [ -z "$1" ] && echo && return
    local RULE
    if is_yes "$IPTABLES_HUMAN_SYNTAX"; then
	[ -z "$IPTABLES_SED_RULES" ] && print_error "Human syntax is enabled but no syntax file is loaded"
	RULE=$(eval 'printf "%s\n" "$@"'|sed  -e "$IPTABLES_SED_RULES;s/[[:space:]]\+/\ /g")
    else
	RULE=$(eval 'printf "%s\n" "$@"')
    fi
    printf "%s\n" "$RULE"|egrep -q "^[^#]" && printf "%s\n" "$RULE" || echo
}

iptables_preload()
{
    is_yes "$IPTABLES_HUMAN_SYNTAX" && [ -z "$IPTABLES_SYNTAX" ] && 
	{ 
	    iptables_load_syntax ${IPTABLES_SYNTAX_DIR:=/etc/net/ifaces/default/fw/iptables}/syntax
	    iptables_create_sed_rules "$IPTABLES_SYNTAX"
	}			
}

# iptables_load_rules_from_file <table> <chain>
iptables_load_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ] && [ -s "$TABLE/$CHAIN" ]; then
	print_message -n -e "\tLoading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
	RULES=$(< "$TABLE/$CHAIN")
	while read RULE; do
	    RULE=$(iptables_expand_string "$RULE")
	    [ -z "$RULE" ] || 
		{
		    read FIRST SECOND REST < <(echo $RULE)
    		    case $FIRST in
		        "-A"|"-D"|"-I"|"-P")
    	    			    iptables_push_rule $TABLE $FIRST $CHAIN $SECOND $REST
				    ;;
			*)
    	    			    iptables_push_rule $TABLE $CHAIN $FIRST $SECOND $REST
				    ;;
		    esac
		}
	    print_progress
	done < <(echo "$RULES"|egrep "^[^#]")
	print_message
    fi
}

# iptables_flush_rules_from_file <table> <chain> [flush]
iptables_flush_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ]; then
	if [ "$NAME" != "default" ] && [ "$3" != "flush" ]; then
	    [ ! -s "$TABLE/$CHAIN" ] && return
	    print_message -n -e "\tUnloading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
	    RULES=$(tac "$TABLE/$CHAIN")
	    while read RULE; do
		RULE=$(iptables_expand_string "$RULE")
		[ -z "$RULE" ] || 
		    {
		        read  FIRST SECOND REST < <(echo $RULE)
		        case $FIRST in
		            "-A"|"-D"|"-I"|"-P")
					iptables_pop_rule $TABLE $FIRST $CHAIN $SECOND $REST
					;;
			    *)
        			        iptables_pop_rule $TABLE $CHAIN $FIRST $SECOND $REST
				        ;;
			esac
		    }				
		print_progress
	    done < <(echo "$RULES"|egrep "^[^#]")
	    print_message
	else
	    # Flush rules only when stop networking
	    print_message -e "\tFlushing the \"$CHAIN\" chain in the \"$TABLE\" table"
	    iptables_flush_chain $TABLE $CHAIN
	fi
    fi
}


iptables_start()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    local ARGS
    [ "$NAME" = "default" ] &&  print_message "Starting iptables for $NAME" ||  print_message -e "\nStarting iptables for $NAME"
    # Set defaut policy
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	[ -z "$IPTABLES_INPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $IPTABLES_INPUT_POLICY policy for the \"INPUT\" chain in the \"$TABLE\" table"
		iptables_chain_policy $TABLE INPUT "$IPTABLES_INPUT_POLICY"
	    }
	[ -z "$IPTABLES_FORWARD_POLICY" ] || 
	    {
		print_message -e "\tSetting $IPTABLES_FORWARD_POLICY policy for the \"FORWARD\" chain in the \"$TABLE\" table"
		iptables_chain_policy $TABLE FORWARD "$IPTABLES_FORWARD_POLICY"
	    }
	[ -z "$IPTABLES_OUTPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $IPTABLES_OUTPUT_POLICY policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
		iptables_chain_policy $TABLE OUTPUT "$IPTABLES_OUTPUT_POLICY"
	    }
	TABLE=
    fi
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # Load modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS; do
	    print_message -e "\tLoading module $MODULE"
	    $MODPROBE "$MODULE" $ARGS || print_error "Can't load module $MODULE"
	done < <(egrep "^[^#]" modules)
    fi
    # Create user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	for CHAIN in "$TABLE"/*; do
	    CHAIN=$(basename "$CHAIN")
	    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
	    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
	    egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$IPTABLES_SYSTEM_CHAINS") || 
		{
		    print_message -e "\tCreating the \"$CHAIN\" chain in the \"$TABLE\" table"
		    iptables_create_chain $TABLE $CHAIN
		}
	done
    done
    # FIXME  Double code
    # Load rules after creating _all_ chains
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    iptables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    iptables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(egrep "^[^#]" loadorder)
    else
	for TABLE in *; do
    	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    iptables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    iptables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    [ "$NAME" = "default" ] || print_message -n -e "\t"
}

iptables_stop()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    [ "$NAME" = "default" ] && print_message "Stopping iptables for $NAME" || print_message -e  "\nStopping iptables for $NAME"
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # FIXME  Double code
    # Flush rules
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    iptables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    iptables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(tac loadorder|egrep "^[^#]")
    else
	for TABLE in *; do
    	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    iptables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    iptables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    # Delete user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	    for CHAIN in "$TABLE"/*; do
		CHAIN=$(basename "$CHAIN")
		[ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		"$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$IPTABLES_SYSTEM_CHAINS") || 
		    {
			print_message -e "\tDeleting the \"$CHAIN\" chain from the \"$TABLE\" table"
			iptables_delete_chain $TABLE $CHAIN
		    }
	    done
    done
    # Unload modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS; do
	    print_message -e "\tUnloading module $MODULE"
	    $MODPROBE -r "$MODULE" || print_error "Can't unload module $MODULE"
	done < <(tac modules|egrep "^[^#]")
    fi
    # Set ACCEPT policy
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	print_message -e "\tSetting ACCEPT policy for the \"INPUT\" chain in the \"$TABLE\" table"
	iptables_chain_policy $TABLE INPUT ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"FORWARD\" chain in the \"$TABLE\" table"
	iptables_chain_policy $TABLE FORWARD ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
	iptables_chain_policy $TABLE OUTPUT ACCEPT
	TABLE=
    else
	print_message -n -e "\t"
    fi
}

## ip6tables

ip6tables_chain_policy()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -P $@" || print_error "$IP6TABLES -t $TABLE -P $@"
}

ip6tables_create_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -N $@" || print_error "$IP6TABLES -t $TABLE -N $@"
}

ip6tables_delete_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -X $@" || print_error "$IP6TABLES -t $TABLE -X $@"
}

ip6tables_flush_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -F $@" || print_error "$IP6TABLES -t $TABLE -F $@"
}

ip6tables_zero_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -Z $@" || print_error "$IP6TABLES -t $TABLE -Z $@"
}

ip6tables_rename_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -E $@" || print_error "$IP6TABLES -t $TABLE -E $@"
}

ip6tables_list_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$IP6TABLES -t $TABLE -L $@" || print_error "$IP6TABLES -t $TABLE -L $@"
}

ip6tables_push_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A"|"-I"|"-D"|"-P")
			eval "$IP6TABLES -t $TABLE $@" || print_error "$IP6TABLES -t $TABLE $@"
			;;
	*)
    			case ${IP6TABLES_RULE_EMBEDDING:-APPEND} in
    			    APPEND)
	   			    eval "$IP6TABLES -t $TABLE -A $@" || print_error "$IP6TABLES -t $TABLE -A $@"
				    ;;
			    INSERT)
	    	    		    eval "$IP6TABLES -t $TABLE -I $@" || print_error "$IP6TABLES -t $TABLE -I $@"
				    ;;
			    *)
				    print_error "Unknown type of rule embedding $IP6TABLES_RULE_EMBEDDING"
				    ;;
			esac
			;;
    esac
}

ip6tables_pop_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A")
		shift
		eval "$IP6TABLES -t $TABLE -D $@" || print_error "$IP6TABLES -t $TABLE -D $@"	    	    
		;;
	"-I")
		PRE="$2"
		case $3 in
		    [0-9]*)
			    shift 3
			    ;;
		    *)
			    shift 2
			    ;;
		esac
		eval "$IP6TABLES -t $TABLE -D $PRE $@" || print_error "$IP6TABLES -t $TABLE -D $PRE $@"
		;;	
	"-D")
		shift
		ip6tables_push_rule -t $TABLE $@
		;;
	"-P")
		continue
		;;
	*)
    		eval "$IP6TABLES -t $TABLE -D $@" || print_error "$IP6TABLES -t $TABLE -D $@"	    	        	
		;;
    esac
}

ip6tables_load_syntax()
{
    : ${1:?missing 1st arg to $FUNCNAME}
    [ ! -f "$1" ] || [ ! -s "$1" ] && 
	{
	    export IP6TABLES_SYNTAX=
	    return 1
	}
    export IP6TABLES_SYNTAX=$(< "$1")
}

ip6tables_create_sed_rules()
{
    local REPLACES=${1:?missing 1st arg to $FUNCNAME}
    local SEARCH
    local REPLACE
    local OLDIFS
    local COUNTER=0
    IP6TABLES_SED_RULES=
    print_message -n -e "\nLoading ip6tables data"
    OLDIFS="$IFS"
    IFS=":"
    while read SEARCH REPLACE; do
        [ $COUNTER -eq 20 ] && print_progress && COUNTER=0
        IP6TABLES_SED_RULES="${IP6TABLES_SED_RULES}s/\(^\|[^-]\b\)$SEARCH\(\b[^-]\|$\)/\1$REPLACE\2/g;"
        COUNTER=$(( COUNTER+1 ))
    done < <(echo "$REPLACES"|egrep "^[^#]"|sed -e 's,/,\\\\/,g')
    IFS="$OLDIFS"
    export IP6TABLES_SED_RULES
    print_message
}

ip6tables_expand_string()
{
    [ -z "$1" ] && echo && return
    local RULE
    if is_yes "$IP6TABLES_HUMAN_SYNTAX"; then
	[ -z "$IP6TABLES_SED_RULES" ] && print_error "Human syntax is enabled but no syntax file is loaded"
	RULE=$(eval 'printf "%s\n" "$@"'|sed  -e "$IP6TABLES_SED_RULES;s/[[:space:]]\+/\ /g")
    else
	RULE=$(eval 'printf "%s\n" "$@"')
    fi
    printf "%s\n" "$RULE"|egrep -q "^[^#]" && printf "%s\n" "$RULE" || echo
}

ip6tables_preload()
{
    is_yes "$IP6TABLES_HUMAN_SYNTAX" && [ -z "$IP6TABLES_SYNTAX" ] && 
	{ 
	    ip6tables_load_syntax ${IP6TABLES_SYNTAX_DIR:=/etc/net/ifaces/default/fw/ip6tables}/syntax
	    ip6tables_create_sed_rules "$IP6TABLES_SYNTAX"
	}			
}

# ip6tables_load_rules_from_file <table> <chain>
ip6tables_load_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ] && [ -s "$TABLE/$CHAIN" ]; then
	print_message -n -e "\tLoading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
	RULES=$(< "$TABLE/$CHAIN")
	while read RULE; do
	    RULE=$(ip6tables_expand_string "$RULE")
	    [ -z "$RULE" ] || 
		{
		    read FIRST SECOND REST < <(echo $RULE)
    		    case $FIRST in
		        "-A"|"-D"|"-I"|"-P")
    	    			    ip6tables_push_rule $TABLE $FIRST $CHAIN $SECOND $REST
				    ;;
			*)
    	    			    ip6tables_push_rule $TABLE $CHAIN $FIRST $SECOND $REST
				    ;;
		    esac
		}
	    print_progress
	done < <(echo "$RULES"|egrep "^[^#]")
	print_message
    fi
}

# ip6tables_flush_rules_from_file <table> <chain> [flush]
ip6tables_flush_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ]; then
	if [ "$NAME" != "default" ] && [ "$3" != "flush" ]; then
	    [ ! -s "$TABLE/$CHAIN" ] && return
	    print_message -n -e "\tUnloading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
	    RULES=$(tac "$TABLE/$CHAIN")
	    while read RULE; do
		RULE=$(ip6tables_expand_string "$RULE")
		[ -z "$RULE" ] || 
		    {
		        read  FIRST SECOND REST < <(echo $RULE)
		        case $FIRST in
		            "-A"|"-D"|"-I"|"-P")
					ip6tables_pop_rule $TABLE $FIRST $CHAIN $SECOND $REST
					;;
			    *)
        			        ip6tables_pop_rule $TABLE $CHAIN $FIRST $SECOND $REST
				        ;;
			esac
		    }				
		print_progress
	    done < <(echo "$RULES"|egrep "^[^#]")
	    print_message
	else
	    # Flush rules only when stop networking
	    print_message -e "\tFlushing the \"$CHAIN\" chain in the \"$TABLE\" table"
	    ip6tables_flush_chain $TABLE $CHAIN
	fi
    fi
}


ip6tables_start()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    local ARGS
    [ "$NAME" = "default" ] &&  print_message "Starting ip6tables for $NAME" ||  print_message -e "\nStarting ip6tables for $NAME"
    # Set defaut policy
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	[ -z "$IP6TABLES_INPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $IP6TABLES_INPUT_POLICY policy for the \"INPUT\" chain in the \"$TABLE\" table"
		ip6tables_chain_policy $TABLE INPUT "$IP6TABLES_INPUT_POLICY"
	    }
	[ -z "$IP6TABLES_FORWARD_POLICY" ] || 
	    {
		print_message -e "\tSetting $IP6TABLES_FORWARD_POLICY policy for the \"FORWARD\" chain in the \"$TABLE\" table"
		ip6tables_chain_policy $TABLE FORWARD "$IP6TABLES_FORWARD_POLICY"
	    }
	[ -z "$IP6TABLES_OUTPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $IP6TABLES_OUTPUT_POLICY policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
		ip6tables_chain_policy $TABLE OUTPUT "$IP6TABLES_OUTPUT_POLICY"
	    }
	TABLE=
    fi
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # Load modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS; do
	    print_message -e "\tLoading module $MODULE"
	    $MODPROBE "$MODULE" $ARGS || print_error "Can't load module $MODULE"
	done < <(egrep "^[^#]" modules)
    fi
    # Create user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	for CHAIN in "$TABLE"/*; do
	    CHAIN=$(basename "$CHAIN")
	    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
	    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
	    egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$IP6TABLES_SYSTEM_CHAINS") || 
		{
		    print_message -e "\tCreating the \"$CHAIN\" chain in the \"$TABLE\" table"
		    ip6tables_create_chain $TABLE $CHAIN
		}
	done
    done
    # FIXME  Double code
    # Load rules after creating _all_ chains
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ip6tables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ip6tables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(egrep "^[^#]" loadorder)
    else
	for TABLE in *; do
    	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ip6tables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ip6tables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    [ "$NAME" = "default" ] || print_message -n -e "\t"
}

ip6tables_stop()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    local ARGS
    [ "$NAME" = "default" ] && print_message "Stopping ip6tables for $NAME" || print_message -e  "\nStopping ip6tables for $NAME"
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # FIXME  Double code
    # Flush rules
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ip6tables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ip6tables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(tac loadorder|egrep "^[^#]")
    else
	for TABLE in *; do
    	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ip6tables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ip6tables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    # Delete user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	    for CHAIN in "$TABLE"/*; do
		CHAIN=$(basename "$CHAIN")
		[ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		"$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$IP6TABLES_SYSTEM_CHAINS") || 
		    {
			print_message -e "\tDeleting the \"$CHAIN\" chain from the \"$TABLE\" table"
			ip6tables_delete_chain $TABLE $CHAIN
		    }
	    done
    done
    # Unload modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS; do
	    print_message -e "\tUnloading module $MODULE"
	    $MODPROBE -r "$MODULE" || print_error "Can't unload module $MODULE"
	done < <(tac modules|egrep "^[^#]")
    fi
    # Set ACCEPT policy
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	print_message -e "\tSetting ACCEPT policy for the \"INPUT\" chain in the \"$TABLE\" table"
	ip6tables_chain_policy $TABLE INPUT ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"FORWARD\" chain in the \"$TABLE\" table"
	ip6tables_chain_policy $TABLE FORWARD ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
	ip6tables_chain_policy $TABLE OUTPUT ACCEPT
	TABLE=
    else
	print_message -n -e "\t"
    fi
}

## ebtables
ebtables_chain_policy()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -P $@" || print_error "$EBTABLES -t $TABLE -P $@"
}

ebtables_create_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -N $@" || print_error "$EBTABLES -t $TABLE -N $@"
}

ebtables_delete_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -X $@" || print_error "$EBTABLES -t $TABLE -X $@"
}

ebtables_flush_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -F $@" || print_error "$EBTABLES -t $TABLE -F $@"
}

ebtables_zero_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -Z $@" || print_error "$EBTABLES -t $TABLE -Z $@"
}

ebtables_rename_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    eval "$EBTABLES -t $TABLE -E $@" || print_error "$EBTABLES -t $TABLE -E $@"
}

ebtables_list_chain()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    eval "$EBTABLES -t $TABLE -L $@" || print_error "$EBTABLES -t $TABLE -L $@"
}

ebtables_push_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A"|"-I"|"-D"|"-P")
			eval "$EBTABLES -t $TABLE $@" || print_error "$EBTABLES -t $TABLE $@"
			;;
        *)
			case ${EBTABLES_RULE_EMBEDDING:-APPEND} in
			    APPEND)
				    eval "$EBTABLES -t $TABLE -A $@" || print_error "$EBTABLES -t $TABLE -A $@"
				    ;;
			    INSERT)
				    eval "$EBTABLES -t $TABLE -I $@" || print_error "$EBTABLES -t $TABLE -I $@"
				    ;;
			    *)
				    print_error "Unknown type of rule embedding $EBTABLES_RULE_EMBEDDING"
				    ;;
			esac
			;;
    esac
}

ebtables_pop_rule()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    shift
    : ${@:?missing args to $FUNCNAME}
    case $1 in
	"-A")
		shift
		eval "$EBTABLES -t $TABLE -D $@" || print_error "$EBTABLES -t $TABLE -D $@"	    	    
		;;
	"-I")
		PRE="$2"
		case $3 in
		    [0-9]*)
			    shift 3
			    ;;
		    *)
			    shift 2
			    ;;
		esac
		eval "$EBTABLES -t $TABLE -D $PRE $@" || print_error "$EBTABLES -t $TABLE -D $PRE $@"
		;;	
	"-D")
		shift
		ebtables_push_rule $TABLE $@
		;;
	"-P")
		continue
		;;
	*)
		eval "$EBTABLES -t $TABLE -D $@" || print_error "$EBTABLES -t $TABLE -D $@"	    	        	
		;;
    esac
}

ebtables_expand_string()
{
    [ -z "$1" ] && echo && return
    local RULE
    RULE=$(eval 'printf "%s\n" "$@"')
    printf "%s\n" "$RULE"|egrep -q "^[^#]" && printf "%s\n" "$RULE" || echo
}

# ebtables_load_rules_from_file <table> <chain>
ebtables_load_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ] && [ -s "$TABLE/$CHAIN" ]; then
        print_message -n -e "\tLoading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
        RULES=$(< "$TABLE/$CHAIN")
        while read RULE; do
	    RULE=$(ebtables_expand_string "$RULE")
	    [ -z "$RULE" ] || 
	        {
		    read FIRST SECOND REST < <(echo $RULE)
		    case $FIRST in
		        "-A"|"-D"|"-I"|"-P")
				    ebtables_push_rule $TABLE $FIRST $CHAIN $SECOND $REST
				    ;;
			*)
				    ebtables_push_rule $TABLE $CHAIN $FIRST $SECOND $REST
				    ;;
		    esac
		}
	    print_progress
	done < <(echo "$RULES"|egrep "^[^#]")
	print_message
    fi
}

# ebtables_flush_rules_from_file <table> <chain> [flush]
ebtables_flush_rules_from_file()
{
    local TABLE=${1:?missing 1st arg to $FUNCNAME}
    local CHAIN=${2:?missing 2nd arg to $FUNCNAME}
    local RULE
    local RULES
    if [ -f "$TABLE/$CHAIN" ]; then
	if [ "$NAME" != "default" ] && [ "$3" != "flush" ]; then
	    [ ! -s "$TABLE/$CHAIN" ] && return
	    print_message -n -e "\tUnloading rules for the \"$CHAIN\" chain in the \"$TABLE\" table"
	    RULES=$(tac "$TABLE/$CHAIN")
	    while read RULE; do
		RULE=$(ebtables_expand_string "$RULE")
		[ -z "$RULE" ] || 
		    {
			read  FIRST SECOND REST < <(echo $RULE)
			case $FIRST in
			    "-A"|"-D"|"-I"|"-P")
					ebtables_pop_rule $TABLE $FIRST $CHAIN $SECOND $REST
					;;
			    *)
        				ebtables_pop_rule $TABLE $CHAIN $FIRST $SECOND $REST
					;;
			esac
		    }				
		print_progress
	    done < <(echo "$RULES"|egrep "^[^#]")
	    print_message
	else
	    # Flush rules only when stop networking
	    print_message -e "\tFlushing the \"$CHAIN\" chain in the \"$TABLE\" table"
	    ebtables_flush_chain $TABLE $CHAIN 
	fi
    fi
}


ebtables_start()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    local ARGS
    [ "$NAME" = "default" ] &&  print_message "Starting ebtables for $NAME" ||  print_message -e "\nStarting ebtables for $NAME"
    # Set defaut policy (filter table)
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	[ -z "$EBTABLES_INPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $EBTABLES_INPUT_POLICY policy for the \"INPUT\" chain in the \"$TABLE\" table"
		ebtables_chain_policy $TABLE INPUT "$EBTABLES_INPUT_POLICY"
	    }
	[ -z "$EBTABLES_FORWARD_POLICY" ] || 
	    {
		print_message -e "\tSetting $EBTABLES_FORWARD_POLICY policy for the \"FORWARD\" chain in the \"$TABLE\" table"
		ebtables_chain_policy $TABLE FORWARD "$EBTABLES_FORWARD_POLICY"
	    }
	[ -z "$EBTABLES_OUTPUT_POLICY" ] || 
	    {
		print_message -e "\tSetting $EBTABLES_OUTPUT_POLICY policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
		ebtables_chain_policy $TABLE OUTPUT "$EBTABLES_OUTPUT_POLICY"
	    }
	TABLE=
    fi
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # Load modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS ; do
	    print_message -e "\tLoading module $MODULE"
	    $MODPROBE "$MODULE" $ARGS || print_error "Can't load module $MODULE"
	done < <(egrep "^[^#]" modules)
    fi
    # Create user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	for CHAIN in "$TABLE"/*; do
	    CHAIN=$(basename "$CHAIN")
	    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
	    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
	    egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$EBTABLES_SYSTEM_CHAINS") || 
		{
		    print_message -e "\tCreating the \"$CHAIN\" chain in the \"$TABLE\" table"
		    ebtables_create_chain $TABLE $CHAIN 
		}
	done
    done
    # FIXME  Double code
    # Load rules after creating _all_ chains
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ebtables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ebtables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(egrep "^[^#]" loadorder)
    else
	for TABLE in *; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ebtables_load_rules_from_file "$TABLE" "$CHAIN"
		done < <(egrep "^[^#]" "$TABLE/loadorder")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ebtables_load_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    [ "$NAME" = "default" ] || print_message -n -e "\t"
}

ebtables_stop()
{
    local NAME=${1:?missing 1st arg to $FUNCNAME}
    local MODULE
    local TABLE
    local CHAIN
    [ "$NAME" = "default" ] && print_message "Stopping ebtables for $NAME" || print_message -e  "\nStopping ebtables for $NAME"
    local cfwdir
    profiled_filename_dir cfwdir "$MYIFACEDIR/fw/$CFW_TYPE" &&
	    cd "$cfwdir" ||
	    return 0
    # FIXME  Double code
    # Flush rules
    if [ -f "loadorder" ] && [ -s "loadorder" ]; then
	while read TABLE; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ebtables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ebtables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done < <(tac loadorder|egrep "^[^#]")
    else
	for TABLE in *; do
	    [ ! -d "$TABLE" ] && continue
	    if [ -f "$TABLE/loadorder" ] && [ -s "$TABLE/loadorder" ]; then
		while read CHAIN; do
		    ebtables_flush_rules_from_file "$TABLE" "$CHAIN"
		done < <(tac "$TABLE/loadorder"|egrep "^[^#]")
	    else
		for CHAIN in "$TABLE"/*; do
		    CHAIN=$(basename "$CHAIN")
		    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
		    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
		    ebtables_flush_rules_from_file "$TABLE" "$CHAIN"
		done
	    fi
	done
    fi
    # Delete user chains
    for TABLE in *; do
	[ ! -d "$TABLE" ] && continue
	for CHAIN in "$TABLE"/*; do
	    CHAIN=$(basename "$CHAIN")
	    [ "$TABLE/$CHAIN" != "$TABLE/loadorder" -a  -f "$TABLE/$CHAIN" -a \
	    "$TABLE/${CHAIN%.rpm*}" = "$TABLE/$CHAIN" -a "$TABLE/${CHAIN%\~}" = "$TABLE/$CHAIN" ] || continue
	    egrep -q "([^-]\b|^)$CHAIN(\b[^-]|$)" < <(echo "$EBTABLES_SYSTEM_CHAINS") || 
		{
		    print_message -e "\tDeleting the \"$CHAIN\" chain from the \"$TABLE\" table"
		    ebtables_delete_chain $TABLE $CHAIN
		}
	done
    done
    # Unload modules
    if [ -f "modules" ] && [ -s "modules" ]; then
	while read MODULE ARGS; do
	    print_message -e "\tUnloading module $MODULE"
	    $MODPROBE -r "$MODULE" || print_error "Can't unload module $MODULE"
	done < <(tac modules|egrep "^[^#]")
    fi
    # Set ACCEPT policy
    if [ "$NAME" = "default" ]; then
	TABLE=filter
	print_message -e "\tSetting ACCEPT policy for the \"INPUT\" chain in the \"$TABLE\" table"
	ebtables_chain_policy $TABLE INPUT ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"FORWARD\" chain in the \"$TABLE\" table"
	ebtables_chain_policy $TABLE FORWARD ACCEPT
	print_message -e "\tSetting ACCEPT policy for the \"OUTPUT\" chain in the \"$TABLE\" table"
	ebtables_chain_policy $TABLE OUTPUT ACCEPT
	TABLE=
    else
	print_message -n -e "\t"
    fi
}
