Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Mar 2013 20:29:34 +0000
From:      Ben Choi <bchoi@sandvine.com>
To:        "freebsd-ipfw@freebsd.org" <freebsd-ipfw@freebsd.org>
Subject:   UDP forward issue with ipfw on Freebsd8
Message-ID:  <AF8B0C74BF66CD40B1F04C486BE4E1B4AD076DE1@wtl-exch-2.sandvine.com>

next in thread | raw e-mail | index | archive | help
Hi

When I try to forward incoming UDP packets to local host without providing =
destination port, no packets are forwarded.
My ipfw rule is:

     # ipfw add 100 fwd 127.0.0.1 ipv4 from any to any dst-port 8000-11999 =
recv em1

Since I am not giving any port number after 127.0.0.1, ipfw should forward =
the packets with the destination port in the packets, but it does not.

I checked ipfw code and udp_input() in udp_usrreq.c, and modified it to for=
ward to the original ports in the packets like below.

#ifdef IPFIREWALL_FORWARD
                /*
                * Grab info from PACKET_TAG_IPFORWARD tag prepended to the =
chain.
                */
                fwd_tag =3D m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
                if (fwd_tag !=3D NULL) {
                                struct sockaddr_in *next_hop;

                               /*
                                * Do the hack.
                                */
                                next_hop =3D (struct sockaddr_in *)(fwd_tag=
 + 1);
                                ip->ip_dst =3D next_hop->sin_addr;
                                if (next_hop->sin_port) {      // Add this =
line
                                                uh->uh_dport =3D htons(next=
_hop->sin_port);
                               }       // and this line
                                /*
                                * Remove the tag from the packet.  We don't=
 need it anymore.
                                */
                                m_tag_delete(m, fwd_tag);
                }
#endif

Basically, only if forwarding port is given, the destination port is modifi=
ed. If not, it leaves the original destination port.

After this changes ipfw can forward the packets to the local host. But I am=
 facing another issue: I cannot send any packets with the same socket which=
 I received the packets from.

I checked the codes thoroughly again and found that udp_input() changes the=
 destination IP address and destination port with forward rule and calls in=
_pcblookup_hash() function with forward destination IP and port while in Fr=
eebsd6, the destination IP and port on mbuf are not modified and in_pcblook=
up_hash() is called with the original desitnation IP and port.
I am not very familiar with the Kernel codes so I don't know if this differ=
ence is the reason why that application cannot send response through the fo=
rwarded UDP sockets.
Does anyone have any idea on how to debug it or even to solve it?

Thank you very much for your help in advance,

Ben Choi




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AF8B0C74BF66CD40B1F04C486BE4E1B4AD076DE1>