[PATCH] multiple instances of ipfw(4)

Vadim Goncharov vadim_nuclight at mail.ru
Wed Feb 1 14:10:55 UTC 2012


Hi Ermal Lu?i! 

On Tue, 31 Jan 2012 09:53:30 +0100; Ermal Lu?i wrote about 'Re: [PATCH] multiple instances of ipfw(4)':

>>> It is used in conjuction with this tool
>>> https://raw.github.com/bsdperimeter/pfsense-tools/master/pfPorts/ipfw_context/files/ipfw_context.c
>>> It allows creation of contextes/instances and assignment of specific
>>> interfaces to specific contexts/instances.
>>
>> It is not clear how to add a rule to a specific instance with this program.
>>
> Simple example:
> - Create a context with members
> ipfw_context -a testctx
> ipfw_context -a testctx -n myiface0
> ipfw_context -a testctx -n myiface1
> - Set the context
> ipfw_context -s testctx
> - Continue business as usual with ipfw/dummynet
> ipfw add ....
> ipfw pipe create ....
> ipfw table add ....

So one must need change context between invocations of ipfw? Not very user
friendly and subject to races. How are you going to fix them?

>>> Surely i know that this is not the best way to implement generically
>>> but it gets the job done for us as it is, read below.
>>
>>> What i would like to know is if there is interest to see such
>>> functionality in FreeBSD?
>>
>>> I am asking first to see if there is some consensus about this as a
>>> feature, needed or not!
>>> If interest is shown i will transform the patch to allow:
>>> - ipfw(8) to manage the contextes create/destroy
>>> - ipfw(8) to manage interface membership. Closing the race of two
>>> parallell clients modifying different contextes.
>>
>>> There is another design choice to be made about storing the membership
>>> of interfaces into contexts/instances, but i do not see that as
>>> blocking.
>>
>>> It is quite handy feature, which can be exploited even to scale on SMP
>>> machines by extending it to bind a specific instance(with its
>>> interaces) to a specific CPU/core?!
>>
>> Not so simple/straightforward questions. On the one hand, there are at least
>> /some/ people who need this. So the ipfw 'call'/'return' actions were already
>> implemented, first appearing in 9.0-R / 8.3-R. And melifaro@ has patches to
>> ipfw table allowing matching againt ifname, setting tablearg, which in
>> conjunction with 'call' or 'skipto' could be used to make essentially the same
>> functionality as your proposed patch, already in stock FreeBSD.
>>
> Well it tends to get messy if you do not have a smart consumer
> handling the jumps.
> Its almost as reprogramming in ipfw language and somehow an admin
> needs to read this!
> The intention was be practical and allow easy troubleshooting.

Agreed that it is not easy, but that is just something available *right now*
already allowing to simplify some messy rulesets with skipto's. It was done as
a short-term solution until something more powerful will be done.

>> On the other hand, both ipfw contexts and ipfw 'call' are very half-measures.
>> The only goal was to give people something right now, and see how much this
>> will be demanded, what feedback they'll give, etc. It is obvious there is no
>> wide testing of 9.0-R (and 8.3-R too) right now.
>>
> It depends on the needs, surely and how colorful you want it to be.

Yes, it's easier to get feedback on what people need when at least something
was presented (implemented) to them.

>> What I mean here about half-measures? The ipfw 'call' is just a sketch of my
>> old ideas to completely reorganize ipfw to support multiple rulesets. To be
>> generic and Right Thing(tm), this is a HUGE work, because:
>>
>> - each ipfw chain becomes independent netgraph(4) node
>> - generic ng_pfil node usable not only for firewalls
>> - chains may be called from each other (see iptables)
>> - chains (actually netgraph nodes) may be bind to ifaces or any other place
>> - main unnamed chain is called from pfil as before
>> - rewrite ipfw & dummynet management from setsockopt() to netgraph messages
>> - completely rewrite ipfw dynamic rules to not conflict with multiple
>>   rulesets, as now they just jump to parent static rule (need to be more like
>>   pf or iptables states). This item is hard but essential (you'll get a mess
>>   jumping to another ruleset), and ipfw contexts don't handle ot
>> - while here, do other needed things, e.g. adding support for modules in both
>>   kernel and userland, loadable opcodes, keywords, etc.
>>
> if you write a ip/tcp/udp/... stack on netgraph than i will write this :)
> Surely ipfw has seen a lot of hacks in the past and will see in the
> future but i thik usability is more of a target
> rather than fancy design.

No, point is not in design, but in usability first (perhaps my English was too
bad?). Design here is just a way to handle desired usability. How this will be
for user:

  ipfw chain mychain create
  ipfw chain common create default-policy allow
  ipfw chain lanusers create
  ipfw chain mychain add 200 ...
  ipfw chain mychain delete 300 ...
  ipfw chain mychain destroy
  ipfw add 100 call common ip from any to any   # call from main ruleset
  ipfw ng_bpf mypktbody create
  ipfw ng_bpf mypktbody config proto udp and udp[42:4]=0x01020304
  ipfw add 200 deny ngmatch mypktbody
  ipfw bind mychain to interface em0 direction out
  ipfw bind lanusers to interface vlan100
  ipfw pfil-order move ipfilter bottom

Hope that's enough user-intuitive. And netgraph-based design here is very
straightforward: for examples above, you just create netgraph nodes named
"ipfwmychain", "ipfwcommon", etc., then do send NGM_IPFW_ADD message to the
node with name of appropriate "chain" keyword, or main ng_ipfw if none.
Netgraph here is not a stack, but a clean alternative to hack raw_ip.c for
new setsockopt()'s (not very modular) or for user to be able manually assign
node in complex configuration (usually the /sbin/ipfw will do). Aside that,
netgraph messages do provide clean versioning - it was hard to keep compatible
interfaces when ABI changed in 8.2.

There is no more Netgraph or even stacks in this stacks, it just suits very
well :)

> Though its a matter of preference and how much work its needed to
> accomplish this!

Unfortunatelly, no. Here is the problem with dynamic rules which is the main:

- suppose you have router with interfaces X, Y. 
- you have TCP/UDP session from A to B, incoming on X and leaving through Y
- you have per-interface rules, for X on input, for Y on output

Then, if a packet entered via iface X, and there is a *state* (dynamic rule)
there, then, whatever you write in rules for Y - the first keep-state will
accept packet, no matter what rule, it will be accepted.

You can try to expoit the fact that in ipfw, dynamic rule just jumps to parent
rule's action part, and, if that was "skipto", continues on a static ruleset
(where it could be checked, which interface). But this becomes unmaintainable
mess even on 3-4 interfaces (it's like assembly language programming), and if
you have hundreds of ifaces, you may encounter there is not enough numbers in
65536 to handle all X*Y combinations (not all ifaces need be stateful) even if
config is somehow generated automatically. There is company which really comes
up to such situation, and ipfw context can't handle it.

Then you encounter dynamic rules must be redesigned. Given another users'
polls, they do need something like iptables chains, for maintenance. Then you
look at hacks present in ipfw code from past, and eventually come up to
something like I described earlier - another design which also allows several
other good new features.

>> Even if not add something like bpf, that's ipfw_ng is probably a more major
>> change than both ipfw2 and ipfw3 :)
>>
>> Due to various reasons in my private life, I was unable to do it in my spare
>> time previous years. My new employer is a provider using FreeBSD on most
>> machines, so I hope I could finally begin doing it at work (and for work),
>> but only several months later after more actual tasks.
>>
>> But, all of this only makes sense to be generic for needs of broad masses of
>> our users. And in pfSense ipfw users are actually only it's authors (all
>> others see web interface), so it's better and more practical to not rely on
>> such complex solution, but rather on something more simple and specialized for
>> their needs. Such as your proposed ipfw contexts.
>>

> Surely enough you can take shortcuts in a customization but its not
> the point here.

> But surely nothing should stop both ways.

I wanted to say, don't be afraid or upset that ipfw context are not generic
enough for broader needs. If that allows to solve your practical problems
right now (relatively fast), then do it, it is good, it's better than wait
for a more comprehensive solution. I've implemented "ipfw call" from the
exactly the same thinking.

-- 
WBR, Vadim Goncharov. ICQ#166852181       mailto:vadim_nuclight at mail.ru
[Anti-Greenpeace][Sober FreeBSD zealot][http://nuclight.livejournal.com]



More information about the freebsd-hackers mailing list