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_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:
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:
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.
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:
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!
# 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).
$ 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
+FW_GENERIC_MATCH(OPT_FOO) = 'foo:bar' : '' +FW_GENERIC_MATCH6(OPT_FOO) = 'foo:bar' : ''