Efficient use of Dummynet pipes in IPFW

Brett Glass brett at lariat.org
Mon Sep 19 00:32:45 PDT 2005


At 12:56 AM 9/19/2005, Luigi Rizzo wrote:
 
>[see long original request below]
>
>Bret, you want a block structured ipfw control language, but
>ipfw is an assembly language. You have to live with that.
>Your only way out is
>A. write a translator from high level to low level language
>   (many people do use sh scripts to generate ipfw configurations)

I've tried this. Alas, it quickly gets out of hand because objects
in IPFW (for example pipes) aren't named. You wind up literally 
having to build a symbol table to keep track of rule numbers, pipe
numbers, etc. Yes, you can do it, but it's very awkward.

>B. write the sequential blocks of instructions you need,
>   and connect them through skipto. It can be tedious, but generally
>   ipfw configurations are not so complex, _and_ when they are
>   is not terribly complex to generate this through scripts.

Unfortunately, this requires inverting the sense of rules. And in IPFW's
very simplistic language, you can't invert a single rule with more
than one condition into another single rule because you can only
negate each individual criterion and not the whole rule. Thus, when
you do the NAND->OR conversion (DeMorgan's Theorem), you will
find yourself with an explosion in the number of rules. What's more, 
the inversion can't be easily automated (there are quite a lot of IPFW
options, and some are not directly invertable). So, every time you add
a rule you have to write its inverse manually as multiple rules, with
skipto's whose targets may change if you ever edit the rule set. 
It's total spaghetti.

It occurs to me that there might be a simpler way. What if one could add 
an IPFW option called "resume" to a rule, with the following syntax and
semantics?

pipe 25 ip from 0.0.0.1 to any in via tun* resume 5000

The semantics would be as follows: If the rule was matched and the packet
was sent off to a Dummynet pipe (or queue), a "skipto 5000" would be
executed when the packet was re-injected into IPFW. This would skip you
around the other bandwidth throttling rules. Problem solved. The
same option might also be useful if you wanted to combine some other
action that doesn't terminate the search (e.g. logging) with a "skipto".
It wouldn't be valid if the action terminated the search.

I believe that there's a field that goes along with a packet into 
Dummynet which carries information about where to reinject the packet
if ip.fw.one_pass is set to 0. Thus, adding this option might just be a 
simple matter of modifying that field. 

I've looked at the source and it's fragmented and virtually undocumented,
so I'd probably spend a long time blundering around trying to add this
and get it right (and also have the rules display correctly, etc.).
I seem to recall (correct me if I'm wrong here) that you've hacked on
both IPFilter and IPFW. How hard would this be to add?

--Brett Glass



More information about the freebsd-net mailing list