Patches for IPFW
by Alter (alterX@alter.org.ua (remove X))
- adds commands zshow (zero+show), replace (del+add)
- option -Q for ignoring ALL errors
- skipto tablearg
- via table(), you can insert interface name into table
- condition if-index - number of interface (e.g. for vlan55 it would be 55)
(deprecated)
- indexing of rules in kernel (index table) for fast handling of skipto tablearg,
and effective add/remove of large amount of rules.
- mapped table - for tables containing many single IPs (e.g, /32)
we perform large subnet lookup via b-tree (e.g, /23, controlled by sysctl net.inet.ip.fw.def_map_mlen),
and inside each /23 perform table lookup. Works much faster.
- map table - hash-based division of large IP block on several small ones. For example,
/16 can be divided into 256 subnets. We can do it by 3rd octet (hoffset 16, hlen 8). Also, we can do it
by 4th octet (hoffset 24, hlen 8).
hoffset defines number of the 1st bit of hash, hlen - hash length in bits.
Also, we define base IP and netmask for map table to match large IP block.
- packet/byte counter for each table element
- indexed pipe lookup table (controlled by sysctl net.inet.ip.dummynet.full_indexing)
- traffic counter/limiter - count-upd, count-check, count-exceed.
- nexthop ipfw action. In contrast to fwd it just sets next-hop for packet
and continue rule procesing.
- optimized dummynet io_fast. Value 2 makes dummynet just forwarding packet
without placing to the queue, if bandwith limit is not exceeded. When value is set to 1 packet
is added and then immediately removed from queue (it is bit slower).
- it is possible to use bmap instead of port list.
It gives performance benefit when you have large list of services.
Lookup time doesn't depend on list size. Rather useful to QoS game traffic.
- Fast ipfw tagging (ftag) - you can assign up to 32 ftags on packet.
All ftags are stored in single memory block as bitmap. Are faster than usual tags,
those allocate separate memory block for each tag.
- Local ipfw tagging (ltag) - you can assign up to 32 ftags on packet.
Ltags are not preserved when packet leaves ipfw ruleset (e.g. is sent to another interface,
diverted or passed through pipe). The benefit is performance - ltag does not require memory allocation
at all.
Patchs for IPFW, 7.2-RELEASE.
ipfw.72.20110501.patch.gz
Includes all features described above. You can find examples of usage below
FreeBSD bugtrack ID: 156770
Patch is compatible with 7.3 and 7.4 except conflict with (yet unused)
#define IP_FW3 48 /* generic ipfw v.3 sockopts */
#define IP_DUMMYNET3 49 /* generic dummynet v.3 sockopts */
in in.h
Example 1
# interface-based dispatch
ipfw table 1 add %vlan516 55
ipfw table 1 add %em0 10
ipfw add 1 skipto tablearg ip from any to any via table(1)
# IP-based dispatch
ipfw table 60 add mapped 192.168.0.2 1602
ipfw table 60 add mapped 192.168.0.3 1603
ipfw table 60 add mapped 192.168.0.4 1604
ipfw add 2 skipto tablearg ip from any to table(60)
# port-based dispatch (TCP/UDP only)
ipfw bmap 13 add 25,137-139,445
ipfw add 3 deny ip from any to any dst-port bmap(13)
# Limit traffic amount for some IPs
ipfw counter create 4096 # init counter table, up to 4096 items
ipfw counter add @2 set-limit 10g # init counter 2 with 10Gb limit
ipfw counter add @4 set-limit 10g # init counter 4 with 10Gb limit
ipfw counter set-limit @2 5g # reconfig counter 2 with 5Gb limit
# make dispatch table
ipfw table 50 add mapped 192.168.0.2 2
ipfw table 50 add mapped 192.168.0.4 4
# update counters
ipfw add 4 count ip from any to table(50) count-upd tablearg
# block users exceeded traffic limit
ipfw add 5 deny ip from any to table(50) count-exceed tablearg
# count traffic and block users with exceeded limit (variant 2)
ipfw add 4 deny ip from any to table(50) count-check tablearg
Example 2
#!/bin/sh
. /etc/rc.conf
# Tables
# 1 - UA
# 2 - Google peer
# 6 - local nets
# 7 - peer nets
# 8 - lan nets
# 10 - transparent proxy users
# 11 - blocked users
# 50 - UA-out
# 51 - UA-in
# 60 - W-out
# 61 - W-in
# Tags
# 1 - from UA-IX
# 2 - to UA-IX
# 6 - local traffic (directly between server and clients)
# 7 - peer traffic
# 8 - internal (lan, inter-lan) traffic
# 16 - from LOCAL (locally handled clients) - out
# 26 - to LOCAL - in
# 17 - from PEER
# 27 - to PEER
# 18 - from LAN (all handled networks)
# 28 - to LAN
# 19 - from ME
# 29 - to ME
ftag=${ipfw_ftag:-"tag"}
trusted_smtp_clients="table(14)"
blocked_smtp_clients="table(15)"
local_nets="table(6)"
peer_nets=" table(7) or table(2) "
lan_nets="table(8)"
win_ports="$win_ports"
rule_game_ports_out="bmap(2)"
rule_game_ports_in="bmap(3)"
rule_win_ports="$win_ports"
rule_denied_ports="$win_ports,25"
cat > /etc/firewall.conf.1 << EOF
replace 1 allow ip from any to any
replace 51001 allow ip from any to any
# out
table 40 flush
table 40 add %$user_if 16
table 40 add %$user9_if 16
table 40 add %$user7_if 16
table 40 add %$user3_if 16
table 40 add %$user2_if 16
table 40 add %$user12_if 16
table 40 add %$user8_if 16
table 40 add %$user10_if 27
table 40 add %$user11_if 27
table 40 add %vlan522 16
table 40 add %$user88_if 16
table 40 add %$core_if 16
table 40 add %$world_if 3
table 40 add %$world0_if 3
table 40 add %lo0 4
table 40 add %vlan4089 4
# in
table 41 flush
table 41 add %$user_if 40
table 41 add %$user9_if 40
table 41 add %$user7_if 40
table 41 add %$user3_if 40
table 41 add %$user2_if 40
table 41 add %$user12_if 40
table 41 add %$user8_if 40
table 41 add %$user10_if 28
table 41 add %$user11_if 28
table 41 add %vlan522 40
table 41 add %$user88_if 40
table 41 add %$core_if 19
table 41 add %$world_if 18
table 41 add %$world0_if 18
table 41 add %lo0 19
table 41 add %vlan4089 19
#client->server DST games+http(s)+telnet+ssh+dns
bmap 2 add 53,23,22,443
bmap 2 add $game_ports
bmap 2 add $web_ports
bmap 2 add $video_ports
bmap 2 add $skype_ports
#server->client SRC games+https+telnet+ssh+dns
bmap 3 add 53,23,22,443
bmap 3 add $game_ports
bmap 3 add $video_ports
bmap 3 add $skype_ports
bmap 13 add $win_ports
bmap 14 add $win_ports
bmap 14 add 25
replace 2 skipto 5 ip6 from any to any
# separate in/out
add 2 skipto 7 ip from any to any in
# dispatch according to interface (out)
add 2 skipto tablearg ip from any to any via table(40)
replace 3 divert natd ip from { $local_nat_nets } to any
replace 4 allow ip from any to any
replace 5 allow ip6 from any to any in
add 5 allow ip6 from any to any
# allow external SMTP, block Win-ports
del 7
add 7 skipto 9 ip from any to any not $rule_denied_ports
replace 8 deny ip from { $blocked_smtp_clients } to any 25
add 8 skipto 14 tcp from { $trusted_smtp_clients } to any 25
add 8 skipto 14 tcp from { $local_nets } to { $world_mx_ip or $our_relay or me } 25
add 8 deny log { tcp or udp } from { $local_nets } to any 25
add 8 allow ip from me to me
add 8 deny { tcp or udp } from any to any $win_ports
# dispatch according to interface (in)
replace 15 skipto tablearg ip from any to any via table(41)
add 15 skipto 40 ip from any to any
# out, user if(s)
replace 16 allow ip from any to not table(11)
add 16 allow tcp from { $pay_system_ips } 80,443 to any
add 16 allow ip from me to any
add 16 deny ip from any to any
# in, world if(s)
replace 18 divert natd ip from any to $user_nat_ip
del 19
add 19 allow tag 29 ip from any to me
add 19 skipto 115 tag 26 ip from any to any
######## WiFi shapers #########
### to 37/xxx, 12/xxx
pipe 100 config delay 100ms bw 5000kbit/s
pipe 101 config bw 18000kbit/s
pipe 103 config bw 18000kbit/s
delete 27
add 27 allow icmp from any to any
add 27 allow ip from $game_servers to any
add 27 allow { tcp or udp } from any 53,23,22 to any
add 27 allow { tcp or udp } from any $rule_game_ports_in to any
add 27 pipe 100 udp from any to any
add 27 pipe tablearg ip from any to table(101)
add 27 allow tcp from any 80 to any
add 27 allow ip from any to any
### from 37/xxx, 12/xxx
pipe 102 config bw 10000kbit/s
pipe 104 config bw 8000kbit/s
delete 28
add 28 skipto 40 icmp from any to any
add 28 skipto 40 ip from any to $game_servers
add 28 skipto 40 { tcp or udp } from any to any 53,23,22,80,443
add 28 skipto 40 { tcp or udp } from any to any $rule_game_ports_out
add 28 pipe tablearg ip from table(102) to any
add 28 pipe 100 udp from any to any
add 28 skipto 40 ip from any to any
### regular rules (continue) ###
# in, user if(s)
replace 40 skipto 110 tag 16 ip from not table(11) to any
# blocked users
del 109
add 109 count untag 6 ip from any to any
add 109 count untag 8 ip from any to any
add 109 allow { tcp or udp } from any to { $master_servers or me } 53
add 109 fwd 127.0.0.1,80 tcp from any to any 80
add 109 deny ip from any to any
replace 110 skipto 111 ip from any to any not tagged 16,19
add 110 skipto 120 tag 6 ip from any to any tagged 26,29
# only local interfaces are checked here!
# so, local traffic will be checked
replace 112 skipto 120 ip from any to any tagged 1-2,7-8
#### IN (via local) ####
add 112 skipto 115 ip from any to any out
add 112 skipto 120 tag 8 ip from any to { $lan_nets or me }
add 112 skipto 120 tag 7 ip from any to { $peer_nets }
replace 113 skipto 120 tag 2 ip from any to table(1)
add 113 skipto 19001 ip from any to any tagged 16
add 113 skipto 120 ip from any to any
#### OUT (via local) / IN (via WORLD) ####
replace 115 skipto 120 tag 8 ip from { $lan_nets or me } to any
add 115 skipto 120 tag 7 ip from { $peer_nets } to any
replace 116 skipto 120 tag 1 ip from table(1) to any
#############################
# here comes dispatch rules
#############################
replace 900 skipto 19000 ip from any to any not ftagged 1,2
replace 1500 skipto 1502 ip from any to any ftagged 26
add 1500 skipto tablearg ip from table(50) to any
add 1500 skipto tablearg ip from any to table(51)
add 1500 count ip from any to any
replace 1501 skipto tablearg ip from table(50) to any
add 1501 skipto 38000 ftag 12 ip from any to any
replace 1502 skipto tablearg ip from any to table(51)
add 1502 skipto 38000 ftag 12 ip from any to any
replace 1503 allow ip from any to any
# fill mapped dispatch table
table 50 add mapped 10.0.0.10 1600
table 50 add mapped 10.0.0.11 1610
table 50 add mapped 10.0.0.12 1620
replace 51000 allow ip from any to any
delete 1 51000
EOF
echo "$ftag"
sed -e "s/tag/$ftag/g" < /etc/firewall.conf.1 > /etc/firewall.conf.2
sed -e "s/unftag/funtag/g" -e "s/unltag/luntag/g" < /etc/firewall.conf.2 > /etc/firewall.conf.1
cp /etc/firewall.conf.1 /etc/firewall.conf
ipfw -Q /etc/firewall.conf
2011.05.02
Patchs for IPFW, FreeBSD 7.1-RELEASE and 7.2-RELEASE.
ipfw.71.patch.gz
ipfw.72.patch.gz
Adds commands zshow, replace. -i option (ignore all errors) is united with -q.
If 7.2 man clarisies meaning of error ignoring when -q is used. So, separate option -Q
for ignoring all errors is revoked.
ipfw_idx.70.patch.gz
ipfw_idx.71.patch.gz
ipfw_idx.72.patch.gz
skipto tablearg
indexing of rules in kernel (index table) for fast handling of skipto tablearg,
and effective add/remove of large amount of rules
2010.01.01
Patch for IPFW, FreeBSD 7.0-STABLE.
ipfw.70.patch.gz
Still adds commands zshow, replace. -i option is united with -q,
2008.06.30
Patch for IPFW from FreeBSD 6.3.
ipfw.63.patch.gz
All listed below patches
FreeBSD bugtrack ID: 116009
2008.06.30
Patches for IPFW from FreeBSD 6.2-RELEASE-p5.
all updates
ipfw.62.patch.gz
All listed below patches
2007.09.03
zshow
ipfw-zshow.patch.gz
Adds 'zshow' command, which shows rule counters and immediately resets them to zero. Is useful for traffic counters.
ipfw zshow 1000
2007.09.03
ignore errors + replace
ipfw-ignore_err_opt.patch.gz
Adds 'replace' command, which adds rule if it doesn't exist yet or replaces existing.
ipfw replace 200 count ip from any to any via fxp0
Also adds '-i' switch to command line and ruleset file format. When '-i' is used, all rules containing errors will be
rejected, but correct rules will be applied. IPFW shall not stop on the 1st invalid rule. It is useful when loading ruleset from file.
ipfw -i /etc/firewall.conf
2007.09.03
alterX@alter.org.ua (remove X)
|