Re: Need stateless NAT

2008-04-09 Thread Trevor Talbot

Adam Richards wrote:

I need to be able to create *stateless* nat rules for at least  
150,000 entries, potentially to grow to 1/2million entries.  The  
reason has to do with being able to work in an asymetric routing  
environment -- stateless nat must be used because traffic might not  
egress at the same location it ingressed.  In other words I want to  
do a unidirectional translation and then fahgettaboutit.



[...] there are some unique requirements this network brings which  
make public IP consumption unworkable.



[...] table-management operations -- perhaps 10's of operations per  
second on a table of 500,000 entries/mappings.  (operations, like  
inserts or deletes)



Maybe for resilliency, or for ISP cost reasons, you want to take  
advantage of asymetric routing, or nearest-exit routing, in a  
unified multi-site network?  That is, routing where no Traffic  
Engineering priciples are used. Clearly stateful tracking inhibits  
nearest-exit routing by nature.  (Side note: to ensure TCP  
connections are maintained in a stateless enviornment you'd  
obviously need to enforce 1:1 binat mappings).



I'm seeing mixed messages from the above quotes. It's your project,  
but consider this a friendly thought-check :)


You're looking at creating 1:1 mappings from internal IPs to 150-500k  
public IPs. You talk about a high rate of mapping changes, so clearly  
you're managing entries dynamically, which is just another way of  
keeping state.


You mention NAT being an impediment to asymmetric routing, but NAT is  
unrelated to routing, so I can infer some possibilities here:


* You want to distribute NAT by implementing it on or near each  
border. In order for anything bidirectional to function, the mappings  
must be consistent, so that implies synchronizing state between them.  
You consider pf's stateful behavior to be ill-suited to this use case,  
so you're investigating stateless options.


* You are implementing routing on the same device that runs pf, and  
you believe pf's state-keeping will prevent asymmetric routing from  
taking place.


Are either of these correct?

If you are trying to do distributed NAT, I would ask if that is  
actually a design requirement. It may be easier to place NAT near the  
internal devices instead. In a dynamic environment, it may reduce  
complexity and failure modes simply by avoiding the synchronization  
needed for distributed mappings.


Re: match value question

2008-04-09 Thread Jordi Espasa Clofent

¿anybody knows?

--
Thanks,
Jordi Espasa Clofent


Re: Need stateless NAT

2008-04-09 Thread Ryan McBride
On Tue, Apr 08, 2008 at 11:59:11PM -0700, Adam Richards wrote:
 Maybe a pf.conf knob that allows me to turn off stateful tracking
 for a particular nat on iface ... rule?

Ah, you keep mentioning 'nat' and 'rdr', which confused me before, but I
guess what you're actually talking about is called 'binat' in pf:

binat
A binat rule specifies a bidirectional mapping between an external
IP netblock and an internal IP netblock.

You're right, it should be relatively easy to give binat a 'no state'
option...

But not for a /18 of arbitrary mappings with a high rate of change.
With the current translation code this would require a rule for every
mapping, and every packet is going to require a linear search of this
ruleset.  Fixing this is going to require fairly major changes to how
binat works.  Are you willing to pay someone to make this happen?

BTW: What kind of packet forwarding rate are you hoping to get with this
solution? Much of pf's performance comes from the fact that packets
matching state entries are not evaluated against the ruleset.

-Ryan


Re: Need stateless NAT

2008-04-09 Thread Ryan McBride
On Wed, Apr 09, 2008 at 05:36:57PM +0900, Ryan McBride wrote:
 You're right, it should be relatively easy to give binat a 'no state'
 option...

Try the attached diff, eg:

binat on egress from 192.168.100.1 to any - 10.99.99.99 no state

Index: sys/net/pf.c
===
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.567
diff -u -r1.567 pf.c
--- sys/net/pf.c20 Feb 2008 23:40:13 -  1.567
+++ sys/net/pf.c9 Apr 2008 11:41:02 -
@@ -3321,7 +3321,8 @@
return (PF_DROP);
}
 
-   if (!state_icmp  (r-keep_state || nr != NULL ||
+   if (!state_icmp  (r-keep_state ||
+   (nr != NULL  nr-keep_state) ||
(pd-flags  PFDESC_TCP_NORM))) {
/* create new state */
struct pf_state *s = NULL;
Index: sbin/pfctl/parse.y
===
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.536
diff -u -r1.536 parse.y
--- sbin/pfctl/parse.y  1 Feb 2008 06:58:45 -   1.536
+++ sbin/pfctl/parse.y  9 Apr 2008 11:41:02 -
@@ -439,7 +439,7 @@
 %type  v.number  number icmptype icmp6type uid gid
 %type  v.number  tos not yesno
 %type  v.probability probability
-%type  v.i   no dir af fragcache optimizer
+%type  v.i   no dir af fragcache optimizer binatkeep
 %type  v.i   sourcetrack flush unaryop statelock
 %type  v.b   action nataction natpasslog scrubaction
 %type  v.b   flags flag blockspec
@@ -3741,6 +3741,7 @@
memset(r, 0, sizeof(r));
 
r.action = $1.b1;
+   r.keep_state = 1;
r.natpass = $1.b2;
r.log = $1.w;
r.logif = $1.w2;
@@ -3889,8 +3890,12 @@
}
;
 
+binatkeep  : /* empty */   { $$ = 1; }
+   | NO STATE  { $$ = 0; }
+   ;   
+
 binatrule  : no BINAT natpasslog interface af proto FROM host TO ipspec tag
-   tagged rtable redirection
+   tagged rtable redirection binatkeep
{
struct pf_rule  binat;
struct pf_pooladdr  *pa;
@@ -3915,6 +3920,7 @@
binat.log = $3.b2;
binat.logif = $3.w2;
binat.af = $5;
+   binat.keep_state = $15;
if (!binat.af  $8 != NULL  $8-af)
binat.af = $8-af;
if (!binat.af  $10 != NULL  $10-af)
Index: sbin/pfctl/pfctl_parser.c
===
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.235
diff -u -r1.235 pfctl_parser.c
--- sbin/pfctl/pfctl_parser.c   15 Oct 2007 02:16:35 -  1.235
+++ sbin/pfctl/pfctl_parser.c   9 Apr 2008 11:41:02 -
@@ -986,6 +986,8 @@
printf( - );
print_pool(r-rpool, r-rpool.proxy_port[0],
r-rpool.proxy_port[1], r-af, r-action);
+   if (!r-keep_state  r-action == PF_BINAT)
+   printf( no state);
}
 }