The Cobra Project
Component based Routing Architecture
for Linux 2.4+
   

Developer: Amir Guindehi
Core Team: Amir Guindehi, Ralph Keller, Lukas Ruf

What's Happening?

Wednesday December 26, 2001

I've released COBRA 1.01. It fixes some small bugs and typos. I've also released PBRD 0.98, a control protocol for COBRA. It allows to do flow based routing along paths and also allows to remotly bind flows to cobra plugins.

Friday October 5, 2001

I did the last changes. I've added my semester thesis.

Friday May 18, 2001 - The Cobra day!

So, finally I found the time to test out the new instance hash table code. It works fine. I've added status information about loaded instances. You can see a sample output here (I've loaded 5 instances):

xcore:/ # cat /proc/net/rp_status 


Registered Router Plugins: 2
Registered Router Plugins Instances: 5


        Plugin TEST     Module RP_TEST
        Instances 1,2,3


        Plugin LOG      Module RP_LOG
        Instances 4,5


xcore:/ #

All functionallity is implemented!

I've added reconfiguration over /proc/net/rp_status. I think everything works now. I've made a sample walktrough... In it I will create 3 instances of the TEST router plugin, 1 instance of the LOG plugin (each of them configured in an other way). After this setup, I will add a secondary filter to one of the TEST instances so that this instance will be called for two different streams. After having done this, I will reconfigure the LOG plugin instance. Afterwards I will remove each of the filters for those instances and then when no filter is setup anymore I will unload all modules.

Let's do it:

xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.2 -j RP --plugin TEST --autoinstance --config 'initial config string for first instance' 
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: parse() trying to load module ipt_RP
libipt_RP: autoinstance, requesting unique instance from kernel.
libipt_RP: got unique instance 1 from kernel.
Router plugin instance is 1
libipt_RP: load_module() trying to load module rp_TEST
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.3 -j RP --plugin TEST --autoinstance --config 'initial config string for second instance'      
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: parse() trying to load module ipt_RP
libipt_RP: autoinstance, requesting unique instance from kernel.
libipt_RP: got unique instance 2 from kernel.
Router plugin instance is 2
libipt_RP: load_module() trying to load module rp_TEST
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.4 -j RP --plugin TEST --autoinstance --config 'initial config string for third instance'       
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: parse() trying to load module ipt_RP
libipt_RP: autoinstance, requesting unique instance from kernel.
libipt_RP: got unique instance 3 from kernel.
Router plugin instance is 3
libipt_RP: load_module() trying to load module rp_TEST
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.5 -j RP --plugin LOG --autoinstance --config 'initial config string for first instance'          
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: parse() trying to load module ipt_RP
libipt_RP: autoinstance, requesting unique instance from kernel.
libipt_RP: got unique instance 4 from kernel.
Router plugin instance is 4
libipt_RP: load_module() trying to load module rp_LOG
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.6 -j RP --plugin TEST --instance 1                                                       
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: load_module() trying to load module rp_TEST
xcore:/ # iptables -t rp -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
RP         all  --  172.16.7.2           anywhere           RP TEST#1 
RP         all  --  trash.guindehi.ch    anywhere           RP TEST#2 
RP         all  --  172.16.7.4           anywhere           RP TEST#3 
RP         all  --  172.16.7.5           anywhere           RP LOG#4 
RP         all  --  172.16.7.6           anywhere           RP TEST#1 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
xcore:/ # cat /proc/net/rp_status

Registered Router Plugins: 2
Registered Router Plugins Instances: 4

        Plugin TEST     Module RP_TEST
        Instances 1,2,3

        Plugin LOG      Module RP_LOG
        Instances 4

xcore:/ # cat > /proc/net/rp_status
LOG#4 new configuration for instance 4
xcore:/ # iptables -t rp -D PREROUTING 1                                       
xcore:/ # iptables -t rp -D PREROUTING 1
xcore:/ # iptables -t rp -D PREROUTING 1
xcore:/ # iptables -t rp -D PREROUTING 1
xcore:/ # iptables -t rp -D PREROUTING 1
xcore:/ # rmmod rp_TEST rp_LOG iptable_rp ipt_RP ip_tables              
xcore:/ # 

Here you see the debug output. You can see the loading and uloading of the router plugins and you also see that all configuration requests have been executed...

May 18 18:08:54 xcore kernel: ip_tables: (c)2000 Netfilter core team
May 18 18:08:54 xcore kernel: RPT: init() called...
May 18 18:08:54 xcore kernel: RPT: init() - create_proc_entry('/proc/net/rp_instance') succeeded...
May 18 18:08:54 xcore kernel: RPT: init() - create_proc_entry('/proc/net/rp_status') succeeded...
May 18 18:08:54 xcore kernel: RPT: init() succeded...
May 18 18:08:54 xcore kernel: RPT: pf_instance_read - returning instance 1
May 18 18:08:54 xcore kernel: RP: rp_init(TEST) called...
May 18 18:08:54 xcore kernel: RP_TEST: load() called...
May 18 18:08:54 xcore kernel: RP_TEST: load() succeded...
May 18 18:08:54 xcore kernel: RPT: rp_register(TEST) called...
May 18 18:08:54 xcore kernel: RP: rp_init(TEST) succeded...
May 18 18:08:54 xcore kernel: RP_TABLE: init() called...
May 18 18:08:54 xcore kernel: RP_TABLE: registering table rp...
May 18 18:08:54 xcore kernel: RP_TABLE: registering ipt_ops[0]...
May 18 18:08:54 xcore kernel: RP_TABLE: registering ipt_ops[1]...
May 18 18:08:54 xcore kernel: RP_TABLE: registering ipt_ops[2]...
May 18 18:08:54 xcore kernel: RP_TABLE: registering ipt_ops[3]...
May 18 18:08:54 xcore kernel: RP_TABLE: registering ipt_ops[4]...
May 18 18:08:54 xcore kernel: RP_TABLE: init() succeded
May 18 18:08:54 xcore kernel: RPT: configuring plugin TEST instance 1.
May 18 18:08:54 xcore kernel: RPT: config() dispatching to plugin TEST#1
May 18 18:08:54 xcore kernel: RP_TEST: config() called for plugin TEST#1 with config 'initial config string for first instance'
May 18 18:08:54 xcore kernel: RPT: checkentry(TEST): adding plugin instance 1
May 18 18:09:04 xcore kernel: RPT: pf_instance_read - returning instance 2
May 18 18:09:04 xcore kernel: RPT: configuring plugin TEST instance 2.
May 18 18:09:04 xcore kernel: RPT: config() dispatching to plugin TEST#2
May 18 18:09:04 xcore kernel: RP_TEST: config() called for plugin TEST#2 with config 'initial config string for second instance'
May 18 18:09:04 xcore kernel: RPT: checkentry(TEST): adding plugin instance 2
May 18 18:09:16 xcore kernel: RPT: pf_instance_read - returning instance 3
May 18 18:09:16 xcore kernel: RPT: configuring plugin TEST instance 3.
May 18 18:09:16 xcore kernel: RPT: config() dispatching to plugin TEST#3
May 18 18:09:16 xcore kernel: RP_TEST: config() called for plugin TEST#3 with config 'initial config string for third instance'
May 18 18:09:16 xcore kernel: RPT: checkentry(TEST): adding plugin instance 3
May 18 18:09:32 xcore kernel: RPT: pf_instance_read - returning instance 4
May 18 18:09:32 xcore kernel: RP: rp_init(LOG) called...
May 18 18:09:32 xcore kernel: RP_LOG: load() called...
May 18 18:09:32 xcore kernel: RP_LOG: load() succeded...
May 18 18:09:32 xcore kernel: RPT: rp_register(LOG) called...
May 18 18:09:32 xcore kernel: RP: rp_init(LOG) succeded...
May 18 18:09:32 xcore kernel: RPT: configuring plugin LOG instance 4.
May 18 18:09:32 xcore kernel: RPT: config() dispatching to plugin LOG#4
May 18 18:09:32 xcore kernel: RP_LOG: config() called for plugin LOG#4 with config 'initial config string for first instance'
May 18 18:09:32 xcore kernel: RPT: checkentry(LOG): adding plugin instance 4
May 18 18:10:23 xcore kernel: RPT: hashprint(TEST)
May 18 18:10:23 xcore kernel: RPT: hashprint(TEST) - Instance 1
May 18 18:10:23 xcore kernel: RPT: hashprint(TEST) - Instance 2
May 18 18:10:23 xcore kernel: RPT: hashprint(TEST) - Instance 3
May 18 18:10:23 xcore kernel: RPT: hashprint(LOG)
May 18 18:10:23 xcore kernel: RPT: hashprint(LOG) - Instance 4
May 18 18:10:23 xcore kernel: RPT: pf_status_read - returning 156 bytes
May 18 18:10:50 xcore kernel: RPT: pf_status_write - accepting 39 bytes
May 18 18:10:50 xcore kernel: RPT: reconfiguring plugin LOG instance 4.
May 18 18:10:50 xcore kernel: RP_LOG: reconfig() called for plugin LOG#4 with config 'new configuration for instance 4'
May 18 18:11:53 xcore kernel: RP_TEST: rp_exit(TEST) called...
May 18 18:11:53 xcore kernel: RPT: rp_unregister(TEST) called...
May 18 18:11:53 xcore kernel: RPT: rp_unregister(TEST): removing instance 1
May 18 18:11:53 xcore kernel: RPT: rp_unregister(TEST): removing instance 2
May 18 18:11:53 xcore kernel: RPT: rp_unregister(TEST): removing instance 3
May 18 18:11:53 xcore kernel: RPT: rp_unregister(LOG): removing instance 4
May 18 18:11:53 xcore kernel: RP_TEST: unload() called...
May 18 18:11:53 xcore kernel: RP_TEST: unload() succeded...
May 18 18:11:53 xcore kernel: RP_TEST: rp_exit(TEST) succeded...
May 18 18:11:53 xcore kernel: RP_TEST: rp_exit(LOG) called...
May 18 18:11:53 xcore kernel: RPT: rp_unregister(LOG) called...
May 18 18:11:53 xcore kernel: RP_LOG: unload() called...
May 18 18:11:53 xcore kernel: RP_LOG: unload() succeded...
May 18 18:11:53 xcore kernel: RP_TEST: rp_exit(LOG) succeded...
May 18 18:11:53 xcore kernel: RP_TABLE: fini() called...
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering ipt_ops[0]..
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering ipt_ops[1]..
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering ipt_ops[2]..
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering ipt_ops[3]..
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering ipt_ops[4]..
May 18 18:11:53 xcore kernel: RP_TABLE: unregistering rp table...
May 18 18:11:53 xcore kernel: RP_TABLE: fini() succeded
May 18 18:11:53 xcore kernel: RPT: fini() called...
May 18 18:11:53 xcore kernel: RPT: fini() succeded...

Success on the whole line! Questions? Comments? Ralph? Lukas?
I think that's it!

Now it's time for some documentation!

Friday May 11, 2001

I added an instance hash table. The code is written and compiles but is yet untested.

Friday May 4, 2001

So, I found time to work further on the project. I've implemented a second /proc file named /proc/net/rp_status over which one can get status informations over which router plugins are loaded. The runtime configuration of router plugins will by done by writing information to that file. I've included a sample session:

xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.2 -j RP --plugin LOG --instance 0
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: load_module() trying to load module rp_LOG
xcore:/ # lsmod
Module                  Size  Used by
iptable_rp              3376   0  (autoclean) (unused)
rp_LOG                  3736   0  (unused)
ipt_RP                  4504   1  [rp_LOG]
ip_tables              14488   2  [iptable_rp ipt_RP]
ipv6                  156928  -1  (autoclean)
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]
xcore:/ # la /proc/net/rp*
-rw-rw-rw-   1 root     root            0 May  6 18:57 /proc/net/rp_instance
-rw-rw-rw-   1 root     root            0 May  6 18:57 /proc/net/rp_status
xcore:/ # cat /proc/net/rp_status 
Registred Router Plugins: 1
        Plugin LOG      Module RP_LOG
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.2 -j RP --plugin TEST --instance 0
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: load_module() trying to load module rp_TEST
xcore:/ # cat /proc/net/rp_status                                               
Registred Router Plugins: 2
        Plugin TEST     Module RP_TEST
        Plugin LOG      Module RP_LOG
xcore:/ #
Now the only thing to solve is the instance configuration of single router plugins at load time and on runtime.

Wednesday April 25, 2001

Yes, I've finally come round to implementing /proc support in ipt_RP. At the moment one file /proc/net/rp_instance will be created which will output one of the next free instance numbers. These numbers will be unique. It's a central way to receive unique instance numbers for loading plugins. iptables will use these instance numbers to allocate unique instance numbers to loaded plugin instances [nice said, right? ;-))]

Doing this in the command line:

xcore:/ # modprobe ip_tables
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.1 -j RP --plugin LOG --instance 0
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: load_module() trying to load module rp_LOG
xcore:/ #
xcore:/ # la /proc/net/rp_instance  
-r--r--r--   1 root     root            0 Apr 25 16:29 /proc/net/rp_instance
xcore:/ # cat /proc/net/rp_instance   
1
xcore:/ # cat /proc/net/rp_instance 
2
xcore:/ # cat /proc/net/rp_instance 
3
xcore:/ # cat /proc/net/rp_instance 
4
xcore:/ # cat /proc/net/rp_instance 
5
xcore:/ # cat /proc/net/rp_instance 
6

The debug log output will look like this:

Apr 25 16:29:20 xcore kernel: RPT: init() called...
Apr 25 16:29:20 xcore kernel: RPT: init() succeded...
Apr 25 16:29:20 xcore kernel: RP: rp_init(LOG) called...
Apr 25 16:29:20 xcore kernel: RP_LOG: load() called...
Apr 25 16:29:20 xcore kernel: RP_LOG: load() succeded...
Apr 25 16:29:20 xcore kernel: RPT: rp_register(LOG) called... hashing...
Apr 25 16:29:20 xcore kernel: RPT: hashfn(LOG) = 34
Apr 25 16:29:20 xcore kernel: RP: rp_init(LOG) succeded...
Apr 25 16:29:20 xcore kernel: RP_TABLE: init() called...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering table rp...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering ipt_ops[0]...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering ipt_ops[1]...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering ipt_ops[2]...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering ipt_ops[3]...
Apr 25 16:29:20 xcore kernel: RP_TABLE: registering ipt_ops[4]...
Apr 25 16:29:20 xcore kernel: RP_TABLE: init() succeded

Apr 25 16:30:10 xcore kernel: RPT: proc read - returning instance 1
Apr 25 16:30:13 xcore kernel: RPT: proc read - returning instance 2
Apr 25 16:30:14 xcore kernel: RPT: proc read - returning instance 3
Apr 25 16:30:15 xcore kernel: RPT: proc read - returning instance 4
Apr 25 16:30:15 xcore kernel: RPT: proc read - returning instance 5
Apr 25 16:30:15 xcore kernel: RPT: proc read - returning instance 6

Tuesday April 10, 2001

Implemented rp_LOG, a small router plugin which dumps matched packets via printk. This plugin exists only to demonstrate what packets are received by the plgin framework.

After configuring the plugin like this:

xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.1 -j RP --plugin LOG --instance 0
You get the following output:
Apr 10 20:03:32 xcore kernel: RPT: target() dispatching to plugin LOG#0
Apr 10 20:03:32 xcore kernel: RP_LOG: target() called for plugin LOG#0 for hock 0
Apr 10 20:03:32 xcore kernel: RP_LOG: IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:50:04:78:9c:e9:08:00 
SRC=172.16.7.1 DST=172.16.7.255 LEN=252 TOS=0x00 PREC=0xC0 TTL=1 ID=39933 PROTO=UDP 
SPT=520 DPT=520 LEN=232
[...]
Nice, isn't it? I know what you wanna say! It's exactly the same dump routine as in ipt_LOG... ;-)

Thursday April 4, 2001

Had a short meeting with Ralph and Lukas. We discussed part two of the Cobra project which consists of implementing the active router plugin part. They will write down a target description for me...

Added a score table for bug solvers! Tremblin pushed me to do that since he found three bugs for me, two prototype errors and my braindead ghash hashcmp() bug...

Tuesday April 2, 2001

Yeah! What a weekend! Didn't work... No further comments ;-)

The router plugin framework works! Look at the following run:

xcore:/ # modprobe ip_tables
xcore:/ # lsmod
Module                  Size  Used by
ip_tables              14488   0  (unused)

ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.1 -j RP --plugin TEST --instance 0
libipt_RP: init() called...
libipt_RP: init() succeded...
libipt_RP: load_module() trying to load rp_TEST
libipt_RP: load_module() executing '/sbin/modprobe rp_TEST'
xcore:/ # lsmod
Module                  Size  Used by
rp_TEST                 1236   0  (unused)
ipt_RP                  2824   1  [rp_TEST]
iptable_rp              3376   0  (autoclean) (unused)
ip_tables              14488   2  [iptable_rp ipt_RP]
ipv6                  156928  -1  (autoclean)
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]
xcore:/ # iptables -t rp -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
RP         all  --  agamemnon-eth1.guindehi.ch  anywhere           RP TEST#0 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

This generates the following debug output:

Apr  3 23:34:33 xcore kernel: ip_tables: (c)2000 Netfilter core team
Apr  3 23:34:53 xcore kernel: RPT: init() called...
Apr  3 23:34:53 xcore kernel: RPT: init() succeded...
Apr  3 23:34:53 xcore kernel: RP: rp_init(TEST) called...
Apr  3 23:34:53 xcore kernel: RP_TEST: load() called...
Apr  3 23:34:53 xcore kernel: RP_TEST: load() succeded...
Apr  3 23:34:53 xcore kernel: RPT: rp_register(TEST) called... hashing...
Apr  3 23:34:53 xcore kernel: RPT: hashfn(TEST) = 0
Apr  3 23:34:53 xcore kernel: RP: rp_init(TEST) succeded...
Apr  3 23:34:53 xcore kernel: RP_TABLE: init() called...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering table rp...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering ipt_ops[0]...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering ipt_ops[1]...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering ipt_ops[2]...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering ipt_ops[3]...
Apr  3 23:34:53 xcore kernel: RP_TABLE: registering ipt_ops[4]...
Apr  3 23:34:53 xcore kernel: RP_TABLE: init() succeded
Apr  3 23:35:41 xcore kernel: RPT: target() called for plugin TEST#0
Apr  3 23:35:41 xcore kernel: RPT: hashfn(TEST) = 0
Apr  3 23:35:41 xcore kernel: RPT: hashcmp(TEST,TEST) = 0
Apr  3 23:35:41 xcore kernel: RPT: hasheq(TEST,TEST) = 1
Apr  3 23:35:41 xcore kernel: RPT: target() dispatching to plugin TEST#0
Apr  3 23:35:41 xcore kernel: RP_TEST: target() called for plugin TEST#0 for hock 0
[...]

As you can see the netfilter target RPT is called and dispatches the arriving packets to the router plugin framework and it's test plugin rp_TEST which has been successfully and automatically loaded on creation of a new RP target rule in the iptable 'rp'.

So next I will have to clean up the code, write some documentation implement the /proc configuration and add a --init flag to iptables, that should be all... Hopefully Ralph does not get new ideas... ;-)

I've checked in the new working code...

Thursday March 29, 2001

Hmm... shuffled the code around. Looks nicer now. ipt_RP.h only defines those things that are needed and excludes the ghash.h code if _IPT_RP_ghash is not defined.

Got ipt_RP.c to compile with ghash.h. rp_register() and rp_unregister() use it. But there is a problem. I can put something in the hash, but when I try to find it again it fails... will have to search the bug.

Wednesday March, 28, 2001

Today I've tried to find out how include/linux.ghash.h works. It's a realy cool framework for ganeric hashes, but a bit clumsy to use. I think it even has a bug which prevents the use of arbitrary hash function names (at one place not the defie HASHFN but the function name hashfn is used). I'm not sure if I should patch ghash.h to work correctly since it has nothing to do with RP. One should make a separate patch and send it to the kernel folks... Meanwhile I've choosen my hash function name the same as a workaround. The kernel seems to compile. Tomorrow we will see what memory leaks I've made... I've used vmalloc.h ... ;-)

Tuesday March 27, 2001

I coded the rp_init() and rp_exit() defines, moved the code to rp.h changed ipt_RP.c to include a rp_register() function and included the register callup to ipt_RP in rp_init(). I had a hell of a day tracing all those f***ing "function declaration isn't a prototype" errors. Used gcc -E option a lot to trace preprocessor problems. Tremblin came by this night. Together we fixed the last of those fancy bugs. Hey, thanks Tremblin! Did you know that func() is not the same than func(void)?! I did not...

Anyway! Registering of loading modules works! Look at this debug output:

Mar 27 22:10:06 xcore kernel: ip_tables: (c)2000 Netfilter core team
Mar 27 22:10:06 xcore kernel: RPT: init() called...
Mar 27 22:10:06 xcore kernel: RPT: init() succeded...
Mar 27 22:10:06 xcore kernel: RP: rp_init(TEST) called...
Mar 27 22:10:06 xcore kernel: RP_TEST: load() called...
Mar 27 22:10:06 xcore kernel: RP_TEST: load() succeded...
Mar 27 22:10:06 xcore kernel: RPT: rp_register() called..
Mar 27 22:10:06 xcore kernel: RP: rp_init(TEST) succeded...
Mar 27 22:10:37 xcore kernel: RP_TABLE: init() called...

rp_register() already receives the callback function pointer for the ipt_RP target! Hey, even depmod works perfectly with my new modules and sees all dependencies! Look at this:

xcore:/ # modprobe rp_TEST
xcore:/ # lsmod
Module                  Size  Used by
rp_TEST                 1220   0  (unused)
ipt_RP                  1296   0  [rp_TEST]
ip_tables              14488   1  [ipt_RP]
ipv6                  156928  -1  (autoclean)
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]
So this says rp_TEST needs ipt_RP with needs ip_tables. The module iptable_rp is not yet loaded and will get loaded as soon as you use the -t rp flag with iptables... Perfect!

Monday March 26. 2001

Didn't code much. Discussed the RP configuration problem with Ralph. RP's will be configured by /proc. I will add an --init option for initialization parameters to iptables. Need to find out if there is already a hash structure available in the kernel. I need this to dispatch (in ipt_RP.c, the target) to the right router plugin instance. Tried to code two defines named rp_init() and rp_exit(). They should work like module_init() and module_exit(). But the defines do not work. I get tons of errors... We will see tomorrow.

Tonight I have a date with a good old friend of mine. I didn't see her for a long time! We will go out for dinner...

Sunday March 25, 2001

I was right, it was fun. Came home 0900... will sleep the rest of the day.

Saturday March 24, 2001

I'm still a little groggy from last night... I've made a small announcement of Cobra on the netfilter-devl mailing list. I think it was a bit early in the development to make such an anouncement, but Ralph pushed me to do it. I hope nobody kicks my butt because of the stolen webserver layout ;-)

Did nothing today. Had to relax because I will go out this night again. This time it's time for a good house party... This will be fun!

Friday March 23, 2001

Still busy coding libipt_RP.c.

Yeah! The shared library works and proves that the second module ipt_RP works nicely! This works out just perfectly!
Look at this:

xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.1 -j RP --plugin TEST --instance 0
xcore:/ # iptables -t rp -A PREROUTING -s 172.16.7.2 -j RP --plugin TEST --instance 1 
xcore:/ # iptables -t rp -A PREROUTING -p TCP --sport 25 -j RP --plugin DEMO --instance 0
xcore:/ # iptables -t rp -A PREROUTING -p TCP --sport 25 -j RP --plugin DEMO --instance 1

xcore:/ # iptables -t rp -L

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
RP         all  --  172.16.7.1           anywhere                       RP TEST#0 
RP         all  --  172.16.7.2           anywhere                       RP TEST#1 
RP         tcp  --  anywhere             anywhere           tcp spt:25  RP DEMO#0 
RP         tcp  --  anywhere             anywhere           tcp spt:25  RP DEMO#1 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

xcore:/ # lsmod

Module                  Size  Used by
ipt_RP                  1212   4  (autoclean)
ipv6                  156928  -1  (autoclean)
iptable_rp              3024   0  (autoclean) (unused)
ip_tables              14488   2  [ipt_RP iptable_rp]
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]

Really, I like this framework! Hey Rusty, this is way cool! Ralph, what do you think? Looks great, doesn't it? I will have to check, if the RP dispatcher really sees and gets those packets matching the filters, but I think it will, because, I've already seen the ipt_hook() called a lot (see further down), and this function does the upcall to ip_do_table(). It simple has to work! I will check this, but before I will have to take a nap of sleep.

I'm really happy with my progress! It seems that we will meet our targets! So, let's go to bed now...

... and back infront of the keyboard! It seems that my RP target receives maching packets:

Mar 23 13:21:34 xcore kernel: RPT: target() called: plugin 'TEST', instance 0
Mar 23 13:24:06 xcore last message repeated 23 times
Mar 23 13:25:03 xcore last message repeated 15 times

So, now I have to build the RP plugin displatcher and figure out how to build a loadable module which ipt_RP can load on need.

I began writing a test router plugin named rp_TEST.c. It will do nothing except getting loaded by the ipt_RP router plugin dispatcher and it will be called with the matching packets. I will have to figure a way to configure RP instances. Don't know how at the moment. I've added a new config option in the kernel and made CONFIG_IP_NF_RP_DEBUG configurable since those messages will make a real performance impact. I've updated Documentation/Configure.help. After the new rp_TEST module loads I will try to figure out how to get it loaded when the user adds a new rule with this plugin as target. Eventually I can go the easy way and get iptables to load the module from userspace when it sees the new plugin name. This would be cool, because it's easy in userspace to check for an existing module and such... we will see!

Yeah! The first router plugin can be loaded by hand:

xcore:/ # modprobe rp_TEST

xcore:/ # lsmod
Module                  Size  Used by
rp_TEST                  708   0  (unused)
ipt_RP                  1212   1  (autoclean)
iptable_rp              3024   0  (autoclean) (unused)
ip_tables              14488   2  [ipt_RP iptable_rp]
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]

This router plugin module still does nothing and is empty, but it's the first step. Now I have to get iptables to automatically load it on rule addition. First I wanted to do this in the final_check method, but there I do not get my target_info pointer. I will have to store the information in static variables. I will think a bit about this one. I do not like this solution...

... It's time for weekend! I will go to the gym now, and afterwards I will do some dancing with some friends of mine! Off we go...

Thursday March 22, 2001

Success on the whole line! Look at this small shell protocol:

xcore:~ # modprobe ip_tables 
xcore:~ # lsmod
Module                  Size  Used by
ip_tables              17784   0  (unused)
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]
xcore:~ # iptables -t rp -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
xcore:~ # lsmod
Module                  Size  Used by
iptable_rp              3056   0  (autoclean) (unused)
ip_tables              17784   1  [iptable_rp]
ne2k-pci                5436   1  (autoclean)
8390                    7184   0  (autoclean) [ne2k-pci]

My new `rp' table works as expected! Let's see what happens if I enter a filter ;-))

I've added an Email Page to the Cobra main page where I will publish interesting emails concerning Cobra. Doing this I decided that it would be nicer if all web pages would have a standard design and converted them all to template based pages...

I made the time tracking page private. Only folks coming from the domain guindehi.ch may read it. Others will get a fancy access denied web page. I hope you will not go crazy about this, but nobody except me need to know how much time it has cost me to build the thingy! I need to finish this fast, and I can't have someone telling me I have to implement this and that because I was too fast...
... Sorry guys!

Yeah, it seems that my hooks work, look at this:

Mar 22 13:34:43 xcore kernel: RP: ipt_hook() called...
Mar 22 18:42:19 xcore last message repeated 224 times
Mar 22 18:42:43 xcore last message repeated 66 times

This happened after some typing in a shell on the box used remotely by ssh! So each of the tcp packets really flow through my hooks up to ip_table's ipt_do_table() function...

I'm currently hacking on ipt_RP.c. Hopefully I will have a runing target named RP soon.

I've setup the cobra mailing list. Feel free to join. The cobra main web page explains how. It's hosted by DataCore GmbH and is reachable under majordomo@datacore.ch. The list itself is named cobra@datacore.ch. DataCore is a really cool ISP and Consulting company which kindly hosts our mailing list.

Yeah! ipt_RP.c compiles... I can not yet use it as a target because iptables complains that it does not find the corresponding shared library to configure it. So I will have to write that user space shared library first. It's ongoing... The library is named libipt_RP.c. I'm busy coding it. Hopefully I will finish it today ;-)) Yeah, it's after midnight! I will have to switch to the next entry in my diary now...

Ah! One thing I forgot! Today Stefan Raab lost his box fight against Regina! He got really kicked and it was fun to look how Regina played with his nose! Hope you all saw it ;-))

Wednesday March, 21, 2001

I just gave Ralph a call and discussed on which hooks we want to be able to call RP modules. He told me that this has to be configurable, and that it should be possible to add RPs on every hook. So I have to go back to the roots and add all hooks to iptable_rp.c. *grumble* I just kicked them out of the source yesterday...

I added the right lines to net/ipv4/netfilter/Config.in, added documentation to Documentation/Configure.html and patched the Makefile so that iptable_rp.c will get compiled. I've fixed the compilation errors in iptable.c and the module builds now. The built kernel still boots, but as soon as I try to load the iptable_rp module I get a "Init_module: Invalid argument" error. I do not yet see why. I've added a lot of kprintf()'s I can't find out where they should appear or else they do not appear... Arghh... it's the 9th kernel I've built!
Enough for now!

After I've come home for the gym I had to fix that f***ing module! I've some searching and rereading code I've found the bugs! There where some array sizes wrong so that ipt_register_table() complained with invalid argument.

The iptable_rp module loads and unloads now. It also seems to register the table as well as the five hooks. On an unload (rmmod) it correctly unregisters the table as well as the hooks. I'm happy for today. Ralph, am I fast enough? ;-))

It looks really pretty:

Module      Size Used by 
iptable_rp  2928  0  (unused) 
ip_tables  14488  1  [iptable_rp]
Tomorrow I will have to compile the user space iptable binary so that I can play around with the new table! Now it's time to go to bed!

Tuesday March 20, 2001

I just found out that the CVS documentation (the PDF file) on the main page was a broken. I loaded it into Adobe Acrobat Distiller, which detected the error and fixed it. Now it's readable again.

I hat a meeting with Ralph and Lukas. We discussed the second project I will eventually do with them. Its target would be to extend the plugin loader in a way so that we can load plugins over the network. It's open if encryption and authentication would be also part of it. We will see... It seems that Ralph and Lukas are speculating the my work will be usable for them ;-)) The probably wont be happy when I fail with it, because they would have to find another madman who would do the work for them ;-)

I did some source reading in linux-2.4.2/net/ipv4/netfilter. After some thinking I adapted a iptable_rp.c. We will see if this works. It should implement a new table named 'rp' on the NF_IP_POST_ROUTING hook. For now I think it's enough to hook in there. We should see all the system packets which will leave the system. Source NAT also plugs in there. It looks simple to plug into some more hooks if there is need for it.

I added LXR a source and identifier browser. After 1.5 hour of `find . -type f -exec grep SOME_IDENTIFIER {} \;` I had enough and remembered Ralph saying that LXR is cool. I took a look at it, found it cool too and installed it. It's now on the main page available. It indexes the CVS Linux source. I've even added a Makefile target to update the index, so it will be also possible to browser our own kernel source extensions...

It's now 0120, I'm drunk (since a was to lazy to do some cooking I went for a mexican bar to eat something and drink come Caipirinias with my friend Ueli) and I have to get some sleep... Tomorrow I will try to compile iptable.rp.c. This will get funny!

Monday March 19, 2001

Today I began the kernel compile session two. After a long time I found out that the kernel works if I disable sound and usb. Since I anyway do not use those features I've disabled them. Sometime in the future I will have to include usb... The beauty works fine now on my router. IPv6 and Netfilter for IPv6 is compiled in. I gave Ralph a long phone call and discussed the new target description he sent me. It seems that we have found a way so that both of us are happy ;-))

The next problem I found was that the tlan.o module always crashes my test box. It seems that this driver does not work reliably under 2.4.2. I searched through my old cards and found a NE2000 pci card. The ne2k-pci.o module seems to work fine under 2.4.2 so I switched to that and disabled the onboard ethernet card. Finally I have a working test box running my own compiled 2.4.2. Now I will have to add the shared memory and semaphore patches my friend Tremblin made so that also Oracle will be happy with this kernel. Yeah, you probably ask yourself why that... It's because I want to have one, and only one, kernel to maintain. So even that I build a new module for netfilter I want the kernel to be exactly the same as on my other boxes...

I checked in iptables 1.2 as a vendor branch. Hopefully I will be able to update the iptables source after my changes are made. It looks good as far as I can tell looking at it with cvsweb... we will see when the next version appears.
The Linux source code was also checked in as a vendor branch... hopefully the same applies here...

In short words: We are ready to do some kernel hacking...

Sunday March 18, 2001

I have setup the CVS repository and made an initial checkin. I also wrote a time tracking page and moved the webserver to its new address cobra.digital-impact.ch. I've added cvsweb.cgi to the main webpage. Doing this I found out that cvs 1.10.8 has a bug which prevents the checking of cvsweb.cgi (cvs crashes on checkin) and upgraded cvs to version 1.11. I tried a long time to setup CVSROOT/passwd for new users without an account (we need this for anonymous access), but failed. The only user for which it works is mine, it looks to me as if the user name mapping does not work for users like cvs which do not have a local account and should be mapped to my account.

I began compiling Linux 2.4.2, wrote a Makefile to automate this and found out that the configuration I have chosen crashes on my router after kernel decompression. Fiddled a long time with the kernel option but did not yet found out what causes the crashes. I checked in the source to cvs. The kernel crashes if when I take on old configuration.. ;-(

Friday March 16, 2001

I had a meeting with Ralph, my Assistant. We discussed the targets of my work, defined a small timeline (which I still have to adapt and put on the web). We also took a look at the current netfilter documentation (which I've already put on the main webpage).

Thursday March 15, 2001

I set up the web page cobra.digital-impact.ch/cobra and made a first webserver design.


Last update: Wednesday, 26 December, 2001 23:37
© 2001 by Digital Impact GmbH, Amir Guindehi