Subsections

8.5 Using The Packet Filter

8.5.1 Adding Own Chains And Rules

A set of routines is provided to manipulate the packet filter to add or delete so-called ``chains'' and ``rules''. A chain is a named list of ordered rules. There is a set of predefined chains (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING), using this set of routines more chains can be created as needed.

add_chain/add_nat_chain <chain>:
Adds a chain to the ``filter-'' or ``nat-'' table.
flush_chain/flush_nat_chain <chain>:
Deletes all rules from a chain of the ``filter-'' or ``nat-'' table.
del_chain/del_nat_chain <chain>:
Deletes a chain from the ``filter-'' or ``nat-'' table. Chains must be empty prior to deleting and all references to them have to be deleted as well before. Such a reference i.e. can be a JUMP-action with the chain defined as its target.
add_rule/ins_rule/del_rule:
Adds rules to the end (add_rule) resp. at any place of a chain (ins_rule) or deletes rules from a chain (del_rule). Use the syntax like here:

    add_rule <table> <chain> <rule> <comment>
    ins_rule <table> <chain> <rule> <position> <comment>
    del_rule <table> <chain> <rule> <comment>

where the parameters have the following meaning:

table
The table in which the chain is
chain
The chain, in which the rule is to be inserted
rule
The rule which is to be inserted, the format corresponds to that used in the configuration file
position
The position at which the rule will be added (only in ins_rule)
comment
A comment that appears with the rule when somebody looks at the packet filter.

8.5.2 Integrating Into Existing Rules

fli4l configures the packet filter with a certain default rule set. If you want to add your own rules, you will usually want to insert them after the default rule set. You will also need to know what the action is desired by the user when dropping a packet. This information can be obtained for FORWARD- and INPUT chains by calling two functions, get_defaults and get_count. After calling

    get_defaults <chain>

the following results are obtained:

drop:
This variable contains the chain to which is branched when a packet is discarded.
reject:
This variable contains the chain to which is branched when a packet is rejected.

After calling

    get_count <chain>

the variable res contains the number of rules in the chain <chain>. This position is of importance because you can not simply use add_rule to add a rule at the end of the predefined ``filter''-chains INPUT, FORWARD and OUTPUT. This is because these chains are completed with a default rule valid for all remaining packets depending on the content of the PF_<chain>_POLICY-variable. Adding a rule after this last rule hence has no effect. The function get_count instead allows to detect the position right in front of this last rule and to pass this position to the ins_rule-function as a parameter <position> in order to add the rule in the place at the end of the appropriate chain, but right in front of this last default rule targeting all remaining packets.

An example from the script opt/etc/rc.d/rc390.dns_dhcp from the package ``dns_dhcp'' shall make this clear:

    case $OPT_DHCPRELAY in
        yes)
            begin_script DHCRELAY "starting dhcprelay ..."

            idx=1
            interfaces=""
            while [ $idx -le $DHCPRELAY_IF_N ]
            do
                eval iface='$DHCPRELAY_IF_'$idx

                get_count INPUT
                ins_rule filter INPUT "prot:udp  if:$iface:any 68 67 ACCEPT" \
                    $res "dhcprelay access"

                interfaces=$interfaces' -i '$iface
                idx=`expr $idx + 1`
            done
            dhcrelay $interfaces $DHCPRELAY_SERVER

            end_script
        ;;
  esac

Here you can see in the middle of the loop a call to get_count followed by a call to the ins_rule function and, among other things, the res variable is passed as position parameter.

8.5.3 Extending The Packet Filter Tests

fli4l uses the syntax match:params in packet filter rules to add additional conditions for packet matching (see mac:, limit:, length:, prot:, ...). If you want to add tests you have to do this as follows:

  1. Define a suitable name. The first character of this name has to be lower case a-z. The rest of the name can consist of any character or digit.


    If the packet filter test is used within IPv6 rules it is to make sure that the name is not a valid IPv6 address component!

  2. Creating a file opt/etc/rc.d/fwrules-<name>.ext. The content of this file is something like this:

        # IPv4 extension is available
        foo_p=yes
    
        # the actual IPv4 extension, adding matches to match_opt
        do_foo()
        {
            param=$1
            get_negation $param
            match_opt="$match_opt -m foo $neg_opt --fooval $param"
        }
    
        # IPv6 extension is available
        foo6_p=yes
    
        # the actual IPv6 extension, adding matches to match_opt
        do6_foo()
        {
            param=$1
            get_negation6 $param
            match_opt="$match_opt -m foo $neg_opt --fooval $param"
        }
    

    redThe packet filter test does not have to be implemented for both IPv4 and IPv6 (though this would be preferred if reasonable for both layer 3 protocols).

  3. Testing the extension:

        $ cd opt/etc/rc.d
        $ sh test-rules.sh 'foo:bar ACCEPT'
        add_rule filter FORWARD 'foo:bar ACCEPT'
        iptables -t filter -A FORWARD -m foo --fooval bar -s 0.0.0.0/0 \
            -d 0.0.0.0/0 -m comment --comment foo:bar ACCEPT -j ACCEPT
    

  4. Adding the extension and all other needed files (iptables components) to the archive using the known mechanisms.
  5. Allowing the extension in the configuration by extending of FW_GENERIC_MATCH and/or FW_GENERIC_MATCH6 in an exp-file, for example:

        +FW_GENERIC_MATCH(OPT_FOO) = 'foo:bar' : ''
        +FW_GENERIC_MATCH6(OPT_FOO) = 'foo:bar' : ''
    

© 2001-2019 The fli4l-Team - 28 April 2019