Date: Fri, 7 Jan 2000 16:31:00 -0800 (PST) From: "Rodney W. Grimes" <freebsd@gndrsh.dnsmgr.net> To: luigi@info.iet.unipi.it (Luigi Rizzo) Cc: patrick@mindstep.com (Patrick Bihan-Faou), logix@foobar.franken.de (Harold Gutch), freebsd-current@FreeBSD.ORG, nate@mt.sri.com (Nate Williams) Subject: Re: ipfw optimizations Message-ID: <200001080031.QAA13581@gndrsh.dnsmgr.net> In-Reply-To: <200001072340.AAA06578@info.iet.unipi.it> from Luigi Rizzo at "Jan 8, 2000 00:40:53 am"
next in thread | previous in thread | raw e-mail | index | archive | help
> > No, this is completly reasonable now that I understand what it is your > > proposing. Even the memory footprint is minimal if pointers to the > > actual rules is all we store in the per interface list, my largest set > > duplicated over 8 interfaces would only be 3200 rules. Stored as > > I'd be curious to know what your 400-rule set looks like, what is > the longest search path through that ruleset, and whether that > ruleset could be made more efficient to run by implementing some > kind of switch() statement (eg. for selecting based on interfaces), > or hash tables (e.g. you want to allow/deny to a list of random > addresses...). If you search the archives you'll find a function I wrote in /bin/sh called clnsrv is what creates 90% of the rules. Ahh.. hech.. here... # clnsrv(action, proto, sport, dport, clients, servers) clnsrv() { action=$1; shift proto=$1; shift sport=$1; shift dport=$1; shift clients=$1; shift servers=$1; shift if [ X"${proto}" = X"tcp" ]; then setup="setup" base=10000 else setup="" base=40000 fi if [ X"${dport}" = X"" ]; then ruleoffset=${sport} else ruleoffset=${dport} fi if [ ${ruleoffset} -gt 1899 ]; then ruleoffset=1900 fi rule=`expr ${base} + \( ${ruleoffset} \* 10 \)` for cln in ${clients} ; do for srv in ${servers} ; do ${fadd} ${rule} ${action} ${proto} \ from ${cln} ${sport} to ${srv} ${dport} ${setup} done done rule=`expr ${rule} + 9` ${fadd} ${rule} ${CLASS} log ${proto} from any ${sport} to any ${dport} } Then this is called like so: clnsrv "allow " tcp 20 "" "${tcp_ftpdata_c}" "${tcp_ftpdata_s}" clnsrv "allow " tcp "" 21 "${tcp_ftp_c}" "${tcp_ftp_s}" clnsrv "allow " tcp "" 22 "${tcp_ssh_c}" "${tcp_ssh_s}" clnsrv "allow " tcp "" 23 "${tcp_telnet_c}" "${tcp_telnet_s}" clnsrv "allow " tcp "" 25 "${tcp_smtp_c}" "${tcp_smtp_s}" clnsrv "allow " tcp "" 43 "${tcp_nicname_c}" "${tcp_nicname_s}" clnsrv "allow " tcp "" 53 "${tcp_domain_c}" "${tcp_domain_s}" clnsrv "allow " tcp "" 79 "${tcp_finger_c}" "${tcp_finger_s}" clnsrv "allow " tcp "" 80 "${tcp_http_c}" "${tcp_http_s}" clnsrv "allow " tcp "" 110 "${tcp_pop3_c}" "${tcp_pop3_s}" clnsrv "allow " tcp "" 111 "${tcp_sunrpc_c}" "${tcp_sunrpc_s}" clnsrv "allow " tcp "" 113 "${tcp_ident_c}" "${tcp_ident_s}" ... on and on up to the 1024 and then a few splattered after that. Note that those variables ``tcp_ftp_c'' are often long lists of IP prefixes, and tcp_ftp_s is a single IP or ``any'', dependent on where this firewall is in the network topology, so these calls can quickly build into fairly long ipfw lists. Often the _c and _s will be lists, causing the double nested loop to product a few not so meaningful rules, but that has been fairly rare, bgp being the big exception :-). Also this same routine is called again for a whole pile of udp ports. The single largest optimization would probably be a dispatch based on source or destination port, the latter being more prevelent. I can't easily send out the actual IP firewall list, it may expose what ever router I grabbed it off of to an attack :-) -- Rod Grimes - KD7CAX @ CN85sl - (RWG25) rgrimes@gndrsh.dnsmgr.net To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200001080031.QAA13581>