Jan Jurák wrote:
> Hi All!
> 
> I have new in opensolaris and mailing list too, so i don't know if
> appeal for help here is right.
> 
> my problem: I want redirect port for one machine, but have a problem:
> 
> % cat /etc/ipf/ipnat.conf
> rdr bnx0 from 10.101.3.136/32 to 10.100.0.2/32 port = 25 -> 10.100.0.2
> port 5056
> 
> % ipnat -CF -f /etc/ipf/ipnat.conf
> 0 entries flushed from NAT table
> 4 entries flushed from NAT list
> 3:ioctl(add/insert nat rule): Invalid argument
> 
> 

BTW, I took a look at the code and the problem was pretty clear.

There is a check in the kernel that makes no sense for this situation.

In ip_nat.c

       if (n->in_flags & NAT_TCPUDPICMPQ) {
               if (ntohs(n->in_pmax) < ntohs(n->in_pmin))
                       return EINVAL;
       }

This check is supposed to be for map rules with ports, but it gets
incorrectly applied to redirect rules with ports also.

The in_pmin part of the NAT structure is overloaded for the redirect
port, but the in_pmax is unused so this always fails and returns EINVAL,
which is what you're seeing in that ugly error message.

You can work around it in user land by making this change in the ipnat
command:
diff -r 324bab2b3370 usr/src/cmd/ipf/tools/ipnat_y.y
--- a/usr/src/cmd/ipf/tools/ipnat_y.y   Tue Nov 03 23:15:19 2009 -0800
+++ b/usr/src/cmd/ipf/tools/ipnat_y.y   Fri Nov 13 15:01:18 2009 -0500
@@ -549,6 +549,7 @@
                                          nat->in_dcmp = $3.pc;
                                          if (nat->in_redir == NAT_REDIRECT)
                                                nat->in_pmin = htons($3.p1);
+                                               nat->in_pmax = htons($3.p1);
                                        }
        ;

Building an ipnat command like that will get you going.


but IMO, the better fix is to not do this check in the kernel when
redirection is used.


=== *Suggested Fix*
==========================================================
diff -r 324bab2b3370 usr/src/uts/common/inet/ipf/ip_nat.c
--- a/usr/src/uts/common/inet/ipf/ip_nat.c      Tue Nov 03 23:15:19 2009 -0800
+++ b/usr/src/uts/common/inet/ipf/ip_nat.c      Fri Nov 13 15:07:59 2009 -0500
@@ -939,7 +939,7 @@
                n->in_space = ~ntohl(n->in_outmsk);
        else
                n->in_space = 1;
-       if (n->in_flags & NAT_TCPUDPICMPQ) {
+       if ((n->in_flags & NAT_TCPUDPICMPQ) && n->in_redir != NAT_REDIRECT) {
                if (ntohs(n->in_pmax) < ntohs(n->in_pmin))
                        return EINVAL;
        }

I tried building an ipf kernel module with that change and it seems to
do the trick.

Not sure if you've been trying to develop on OpenSolaris, but since this
is a development list I thought I would give you some options :)

-Paul
_______________________________________________
networking-discuss mailing list
networking-discuss@opensolaris.org

Reply via email to