Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NAT implementation #476

Open
p4pe opened this issue Jan 15, 2021 · 7 comments
Open

NAT implementation #476

p4pe opened this issue Jan 15, 2021 · 7 comments

Comments

@p4pe
Copy link

p4pe commented Jan 15, 2021

Hello, I'm currently implement a simple NAT click configuration which is like this:

FromDevice(enp6s0f1)
-> Strip(14)
-> CheckIPHeader()
//-> GetIPAddress(16)
->rw::IPRewriter(pattern 27.32.11.3 1000 - 1001 0 1);



rw[0]->IPPrint("NAT")->Queue->ToDevice(enp6s0f0);

rw[1] -> IPPrint(rw1) -> Discard;

Script(wait 1, print rw.udp_table, loop);

I generate traffic in the source:

FastUDPSource(50000, 100000000, 60, 3c:fd:fe:05:ce:c2, 192.168.2.2, 1234,                                                                                                                                    
                                    3c:fd:fe:05:94:c2, 192.168.2.7, 1234)                                                                                                                         
  -> ToDevice(enp6s0f1); 


From what I've understand my NAT configuration seems ok (print the udp_table)
nat

My question is how can I create a big NAT table with many entries (e.g 10k) ?
To be more precise, I would like to observe if there is a degradation(e.g throughput) due to many lookups in the NAT table.

Can I do this(feel the NAT table with many entries) within click?

Thank you in advance for your help

@ahenning
Copy link

The question is not clear to me. Do you have trouble configuring large NAT tables? What prevents creating large NAT tables? Perhaps take a look if the element support write handlers which will allow to update the table through the control socket while the router is running and if that is not possible use a bash/perl/python script to generate a click config with 10k rules and reload the router. Perhaps I am missing the issue, but there should normally not be an issue with creating large configs. One notable exception is that if the config is larger than 65K, then by default reloading the config via hotswapping (click -R) will not work, but I doubt you need it for this test.

Regarding the intended throughput test. One thing to consider with tests like this is that the traffic L3/L4 headers needs to be fairly random. If the traffic is static/predictable for example using the same source and destination ports and addresses, then the traffic would match one rule irrespective if there are 10 patterns or 10k patterns and will give the illusion there is little or no performance hit. To accurately test the traffic needs to match rules up and down the table/tree.

@p4pe
Copy link
Author

p4pe commented Jan 15, 2021

The issue is that I don't know how to configure the large table.. :D
If I understood well ' in this configuration rw::IPRewriter(pattern 27.32.11.3 1000 - 1001 0 1);

This means that change the source ipX with 27.32.11.3 and srcport with 1000, dst ip will stay the same, and srcport will change to 1001.

0 and 1 are the output ports.

So with this configuration every packet (even if src is 192.168.2.2 or 192.168.4.5 ) will enter the IPRewritter and will hit this pattern

The question is and sorry if it is a silly question, how can i configure for example

src:192.168.2.2 to match with pattern 1
   src: 192.168.4.2 to match with patern 2 etc etc..

Thank you for your time

@ahenning
Copy link

Maybe the solution is not to create more static nat rules, but to create more random source ports in the traffic generator. Each new source port will create a dynamic entry in the iprewriter table until you reached 10k rules.

rw::IPRewriter(pattern 192.168.1.1 50000-60000 - - 0 1);

@p4pe
Copy link
Author

p4pe commented Jan 15, 2021

Good idea @ahenning , I will see if i can do this with, FastUDPSource or InfiniteSource.
Or if you have to suggest me something else as traffic generator

Thank you for your time.

@p4pe
Copy link
Author

p4pe commented Jan 16, 2021

Seems that is working.
nat_table

I change the IPs manually in the FastUDPSource, I have to automate this.

Do you know if this is possible inside the click configuratio (i.e with script element) or i have to use python etc?

@ahenning
Copy link

ahenning commented Jan 18, 2021

Maybe SetRandIPAddress does what you need?

https://github.com/kohler/click/wiki/SetRandIPAddress

InfiniteSource(LENGTH 1000, LIMIT 3, STOP true)
-> SetRandIPAddress(192.168.0.0/24, 32)
-> UDPIPEncap(1.1.1.1,123, DST_ANNO, 123)
-> ipsec_rt::RadixIPsecLookup( 10.10.1.1/32 0,
192.168.0.0/24 10.10.2.1 1 111 1111111111111111 1111111111111111 1 0 ,
0.0.0.0/0 2
);

I have not tried Random IP address annotations with FastUDPSource, but I am fairly sure at 220k pkts/s FastUDPSource is not needed and if it is really needed, perhaps copy the Random IP code from SetRandIPAddress into a FastUDPSource to create a new element called something like FastRandUDPSource.

@p4pe
Copy link
Author

p4pe commented Jan 19, 2021

Finally I used the INTERVAL feauture of the FastUDPSource element, and I manage to feed the NAT table with 65k of flow mappings.

May I ask you something, if you know, what do you think is the best way to measure the throughput on the sink?
i) Sending random IPs:ports with FastUDPsource
ii) Sending static IPs:ports with FastUDPsource

Does IPRewritter do some kind of caching and it does not have to Lookup all the time in the table (I observe that if I send the same IP from the source, the throughput on the sink is higher)
Does a smaller range in the IPRewritter (e.g rw::IPRewriter(pattern 27.32.11.3 1024-10000 - - 0 1);
Which element is better for this AverageCounter or Counter?

I really appreciate your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants