I'm trying to get a raw BPF bytecode packet filter working on FreeBSD using a combination of ipfw with ng_ipfw, ng_bpf and ng_tag.
However none of the documentation or presentations I can find include any complete working examples. The ng_tag man page only shows the bpf_prog code for passing a non-matched packet back thru ng_bpf but not how to generate the correct hooks for the whole netgraph.
#!/bin/sh
cookie=41
tag=412
mtag_ipfw=1148380143 # IPFW-tagged cookie from <netinet/ip_var.h>
prog=$(./bpfgen | ./bytecode_to_ngbpf) # generate BPF code here
ngctl shutdown ipfw:$cookie
ngctl -f- <<-__END__
mkpeer ipfw: bpf $cookie filter
name ipfw:$cookie CLASSIFIER
msg CLASSIFIER: setprogram { thisHook="filter" ifMatch="match" ifNotMatch="notmatch" $prog }
mkpeer CLASSIFIER: tag match tag_bad
name CLASSIFIER:match TAGGER
connect CLASSIFIER: TAGGER: notmatch tag_good
msg CLASSIFIER: setprogram { thisHook="match" ifMatch="ipfw" bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] }
msg CLASSIFIER: setprogram { thisHook="notmatch" ifMatch="ipfw" bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] }
msg TAGGER: sethookin { thisHook="tag_bad" ifNotMatch="tag_bad" }
msg TAGGER: sethookout { thisHook="tag_bad" tag_cookie=$mtag_ipfw tag_id=$tag }
msg TAGGER: sethookin { thisHook="tag_good" ifNotMatch="tag_good" }
msg TAGGER: sethookout { thisHook="tag_good" tag_cookie=$mtag_ipfw }
__END__
ipfw add 2000 netgraph $cookie udp from any to any
ipfw add 2010 allow log udp from any to any tagged $tag
sysctl net.inet.ip.fw.one_pass=0
This is my best guess, but all that happens is that any packet matching the ipfw rule that drops stuff into netgraph gets dropped.
The intent was to have inbound packets that match the BPF program get tagged with the MTAG_IPFW cookie and the desired tag, and that packets that don't match only get tagged with the former, and the packets that are being returned from the ng_tag module both get forwarded back upstream to the ng_ipfw module via the single instruction program ret 8192 (code=6, k=8192).
Can anyone spot what's wrong, or point me at a complete online example of how to correctly tag a packet this way?